LCOV - code coverage report
Current view: top level - toolkit/source/helper - formpdfexport.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 253 0.0 %
Date: 2012-08-25 Functions: 0 5 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 695 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <toolkit/helper/formpdfexport.hxx>
      31                 :            : 
      32                 :            : #include <com/sun/star/container/XIndexAccess.hpp>
      33                 :            : #include <com/sun/star/container/XNameAccess.hpp>
      34                 :            : #include <com/sun/star/container/XNameContainer.hpp>
      35                 :            : #include <com/sun/star/form/XForm.hpp>
      36                 :            : #include <com/sun/star/container/XChild.hpp>
      37                 :            : #include <com/sun/star/lang/XServiceInfo.hpp>
      38                 :            : #include <com/sun/star/beans/XPropertySet.hpp>
      39                 :            : #include <com/sun/star/form/FormComponentType.hpp>
      40                 :            : #include <com/sun/star/awt/TextAlign.hpp>
      41                 :            : #include <com/sun/star/style/VerticalAlignment.hpp>
      42                 :            : #include <com/sun/star/form/FormButtonType.hpp>
      43                 :            : #include <com/sun/star/form/FormSubmitMethod.hpp>
      44                 :            : 
      45                 :            : #include <toolkit/helper/vclunohelper.hxx>
      46                 :            : #include <vcl/pdfextoutdevdata.hxx>
      47                 :            : #include <vcl/outdev.hxx>
      48                 :            : 
      49                 :            : #include <functional>
      50                 :            : #include <algorithm>
      51                 :            : 
      52                 :            : //........................................................................
      53                 :            : namespace toolkitform
      54                 :            : {
      55                 :            : //........................................................................
      56                 :            : 
      57                 :            :     using namespace ::com::sun::star;
      58                 :            :     using namespace ::com::sun::star::uno;
      59                 :            :     using namespace ::com::sun::star::awt;
      60                 :            :     using namespace ::com::sun::star::style;
      61                 :            :     using namespace ::com::sun::star::beans;
      62                 :            :     using namespace ::com::sun::star::form;
      63                 :            :     using namespace ::com::sun::star::lang;
      64                 :            :     using namespace ::com::sun::star::container;
      65                 :            : 
      66                 :            :     static const char FM_PROP_NAME[] = "Name";
      67                 :            : 
      68                 :            :     namespace
      69                 :            :     {
      70                 :            :         //--------------------------------------------------------------------
      71                 :            :         /** determines the FormComponentType of a form control
      72                 :            :         */
      73                 :          0 :         sal_Int16 classifyFormControl( const Reference< XPropertySet >& _rxModel ) SAL_THROW(( Exception ))
      74                 :            :         {
      75 [ #  # ][ #  # ]:          0 :             static const ::rtl::OUString FM_PROP_CLASSID(RTL_CONSTASCII_USTRINGPARAM("ClassId"));
         [ #  # ][ #  # ]
      76                 :          0 :             sal_Int16 nControlType = FormComponentType::CONTROL;
      77                 :            : 
      78                 :          0 :             Reference< XPropertySetInfo > xPSI;
      79         [ #  # ]:          0 :             if ( _rxModel.is() )
      80 [ #  # ][ #  # ]:          0 :                 xPSI = _rxModel->getPropertySetInfo();
                 [ #  # ]
      81 [ #  # ][ #  # ]:          0 :             if ( xPSI.is() && xPSI->hasPropertyByName( FM_PROP_CLASSID ) )
         [ #  # ][ #  # ]
                 [ #  # ]
      82                 :            :             {
      83 [ #  # ][ #  # ]:          0 :                 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_CLASSID ) >>= nControlType );
      84                 :            :             }
      85                 :            : 
      86                 :          0 :             return nControlType;
      87                 :            :         }
      88                 :            : 
      89                 :            :         //--------------------------------------------------------------------
      90                 :            :         /** (default-)creates a PDF widget according to a given FormComponentType
      91                 :            :         */
      92                 :          0 :         ::vcl::PDFWriter::AnyWidget* createDefaultWidget( sal_Int16 _nFormComponentType )
      93                 :            :         {
      94   [ #  #  #  #  :          0 :             switch ( _nFormComponentType )
                #  #  # ]
      95                 :            :             {
      96                 :            :             case FormComponentType::COMMANDBUTTON:
      97         [ #  # ]:          0 :                 return new ::vcl::PDFWriter::PushButtonWidget;
      98                 :            :             case FormComponentType::CHECKBOX:
      99         [ #  # ]:          0 :                 return new ::vcl::PDFWriter::CheckBoxWidget;
     100                 :            :             case FormComponentType::RADIOBUTTON:
     101         [ #  # ]:          0 :                 return new ::vcl::PDFWriter::RadioButtonWidget;
     102                 :            :             case FormComponentType::LISTBOX:
     103         [ #  # ]:          0 :                 return new ::vcl::PDFWriter::ListBoxWidget;
     104                 :            :             case FormComponentType::COMBOBOX:
     105         [ #  # ]:          0 :                 return new ::vcl::PDFWriter::ComboBoxWidget;
     106                 :            : 
     107                 :            :             case FormComponentType::TEXTFIELD:
     108                 :            :             case FormComponentType::FILECONTROL:
     109                 :            :             case FormComponentType::DATEFIELD:
     110                 :            :             case FormComponentType::TIMEFIELD:
     111                 :            :             case FormComponentType::NUMERICFIELD:
     112                 :            :             case FormComponentType::CURRENCYFIELD:
     113                 :            :             case FormComponentType::PATTERNFIELD:
     114         [ #  # ]:          0 :                 return new ::vcl::PDFWriter::EditWidget;
     115                 :            :             }
     116                 :          0 :             return NULL;
     117                 :            :         }
     118                 :            : 
     119                 :            :         //--------------------------------------------------------------------
     120                 :            :         /** determines a unique number for the radio group which the given radio
     121                 :            :             button model belongs to
     122                 :            : 
     123                 :            :             The number is guaranteed to be
     124                 :            :             <ul><li>unique within the document in which the button lives</li>
     125                 :            :                 <li>the same for subsequent calls with other radio button models,
     126                 :            :                     which live in the same document, and belong to the same group</li>
     127                 :            :             </ul>
     128                 :            : 
     129                 :            :             @precond
     130                 :            :                 the model must be part of the form component hierarchy in a document
     131                 :            :         */
     132                 :          0 :         sal_Int32 determineRadioGroupId( const Reference< XPropertySet >& _rxRadioModel ) SAL_THROW((Exception))
     133                 :            :         {
     134                 :            :             OSL_ENSURE( classifyFormControl( _rxRadioModel ) == FormComponentType::RADIOBUTTON,
     135                 :            :                 "determineRadioGroupId: this *is* no radio button model!" );
     136                 :            :             // The fact that radio button groups need to be unique within the complete
     137                 :            :             // host document makes it somewhat difficult ...
     138                 :            :             // Problem is that two form radio buttons belong to the same group if
     139                 :            :             // - they have the same parent
     140                 :            :             // - AND they have the same name
     141                 :            :             // This implies that we need some knowledge about (potentially) *all* radio button
     142                 :            :             // groups in the document.
     143                 :            : 
     144                 :            :             // get the root-level container
     145         [ #  # ]:          0 :             Reference< XChild > xChild( _rxRadioModel, UNO_QUERY );
     146 [ #  # ][ #  # ]:          0 :             Reference< XForm > xParentForm( xChild.is() ? xChild->getParent() : Reference< XInterface >(), UNO_QUERY );
         [ #  # ][ #  # ]
     147                 :            :             OSL_ENSURE( xParentForm.is(), "determineRadioGroupId: no parent form -> group id!" );
     148         [ #  # ]:          0 :             if ( !xParentForm.is() )
     149                 :          0 :                 return -1;
     150                 :            : 
     151         [ #  # ]:          0 :             while ( xParentForm.is() )
     152                 :            :             {
     153 [ #  # ][ #  # ]:          0 :                 xChild = xParentForm.get();
     154 [ #  # ][ #  # ]:          0 :                 xParentForm = xParentForm.query( xChild->getParent() );
         [ #  # ][ #  # ]
     155                 :            :             }
     156 [ #  # ][ #  # ]:          0 :             Reference< XIndexAccess > xRoot( xChild->getParent(), UNO_QUERY );
                 [ #  # ]
     157                 :            :             OSL_ENSURE( xRoot.is(), "determineRadioGroupId: unable to determine the root of the form component hierarchy!" );
     158         [ #  # ]:          0 :             if ( !xRoot.is() )
     159                 :          0 :                 return -1;
     160                 :            : 
     161                 :            :             // count the leafs in the hierarchy, until we encounter radio button
     162         [ #  # ]:          0 :             ::std::vector< Reference< XIndexAccess > > aAncestors;
     163         [ #  # ]:          0 :             ::std::vector< sal_Int32 >                 aPath;
     164                 :            : 
     165         [ #  # ]:          0 :             Reference< XInterface > xNormalizedLookup( _rxRadioModel, UNO_QUERY );
     166                 :          0 :             ::rtl::OUString sRadioGroupName;
     167 [ #  # ][ #  # ]:          0 :             OSL_VERIFY( _rxRadioModel->getPropertyValue( rtl::OUString(FM_PROP_NAME) ) >>= sRadioGroupName );
     168                 :            : 
     169                 :          0 :             Reference< XIndexAccess > xCurrentContainer( xRoot );
     170                 :          0 :             sal_Int32 nStartWithChild = 0;
     171                 :          0 :             sal_Int32 nGroupsEncountered = 0;
     172                 :          0 :             do
     173                 :            :             {
     174         [ #  # ]:          0 :                 Reference< XNameAccess > xElementNameAccess( xCurrentContainer, UNO_QUERY );
     175                 :            :                 OSL_ENSURE( xElementNameAccess.is(), "determineRadioGroupId: no name container?" );
     176         [ #  # ]:          0 :                 if ( !xElementNameAccess.is() )
     177                 :          0 :                     return -1;
     178                 :            : 
     179         [ #  # ]:          0 :                 if ( nStartWithChild == 0 )
     180                 :            :                 {   // we encounter this container the first time. In particular, we did not
     181                 :            :                     // just step up
     182 [ #  # ][ #  # ]:          0 :                     nGroupsEncountered += xElementNameAccess->getElementNames().getLength();
                 [ #  # ]
     183                 :            :                         // this is way too much: Not all of the elements in the current container
     184                 :            :                         // may form groups, especially if they're forms. But anyway, this number is
     185                 :            :                         // sufficient for our purpose. Finally, the container contains *at most*
     186                 :            :                         // that much groups
     187                 :            :                 }
     188                 :            : 
     189 [ #  # ][ #  # ]:          0 :                 sal_Int32 nCount = xCurrentContainer->getCount();
     190                 :            :                 sal_Int32 i;
     191         [ #  # ]:          0 :                 for ( i = nStartWithChild; i < nCount; ++i )
     192                 :            :                 {
     193 [ #  # ][ #  # ]:          0 :                     Reference< XInterface > xElement( xCurrentContainer->getByIndex( i ), UNO_QUERY );
                 [ #  # ]
     194         [ #  # ]:          0 :                     if ( !xElement.is() )
     195                 :            :                     {
     196                 :            :                         OSL_FAIL( "determineRadioGroupId: very suspicious!" );
     197                 :          0 :                         continue;
     198                 :            :                     }
     199                 :            : 
     200         [ #  # ]:          0 :                     Reference< XIndexAccess > xNewContainer( xElement, UNO_QUERY );
     201         [ #  # ]:          0 :                     if ( xNewContainer.is() )
     202                 :            :                     {
     203                 :            :                         // step down the hierarchy
     204         [ #  # ]:          0 :                         aAncestors.push_back( xCurrentContainer );
     205         [ #  # ]:          0 :                         xCurrentContainer = xNewContainer;
     206         [ #  # ]:          0 :                         aPath.push_back( i );
     207                 :          0 :                         nStartWithChild = 0;
     208                 :            :                         break;
     209                 :            :                             // out of the inner loop, but continue with the outer loop
     210                 :            :                     }
     211                 :            : 
     212 [ #  # ][ #  # ]:          0 :                     if ( xElement.get() == xNormalizedLookup.get() )
                 [ #  # ]
     213                 :            :                     {
     214                 :            :                         // look up the name of the radio group in the list of all element names
     215 [ #  # ][ #  # ]:          0 :                         Sequence< ::rtl::OUString > aElementNames( xElementNameAccess->getElementNames() );
     216                 :          0 :                         const ::rtl::OUString* pElementNames = aElementNames.getConstArray();
     217                 :          0 :                         const ::rtl::OUString* pElementNamesEnd = pElementNames + aElementNames.getLength();
     218         [ #  # ]:          0 :                         while ( pElementNames != pElementNamesEnd )
     219                 :            :                         {
     220         [ #  # ]:          0 :                             if ( *pElementNames == sRadioGroupName )
     221                 :            :                             {
     222                 :          0 :                                 sal_Int32 nLocalGroupIndex = pElementNames - aElementNames.getConstArray();
     223                 :            :                                 OSL_ENSURE( nLocalGroupIndex < xElementNameAccess->getElementNames().getLength(),
     224                 :            :                                     "determineRadioGroupId: inconsistency!" );
     225                 :            : 
     226 [ #  # ][ #  # ]:          0 :                                 sal_Int32 nGlobalGroupId = nGroupsEncountered - xElementNameAccess->getElementNames().getLength() + nLocalGroupIndex;
                 [ #  # ]
     227                 :          0 :                                 return nGlobalGroupId;
     228                 :            :                             }
     229                 :          0 :                             ++pElementNames;
     230                 :            :                         }
     231 [ #  # ][ #  # ]:          0 :                         OSL_FAIL( "determineRadioGroupId: did not find the radios element name!" );
     232                 :            :                     }
     233      [ #  #  # ]:          0 :                 }
           [ #  #  #  # ]
     234                 :            : 
     235         [ #  # ]:          0 :                 if ( !( i < nCount ) )
     236                 :            :                 {
     237                 :            :                     // the loop terminated because there were no more elements
     238                 :            :                     // -> step up, if possible
     239         [ #  # ]:          0 :                     if ( aAncestors.empty() )
     240                 :            :                         break;
     241                 :            : 
     242 [ #  # ][ #  # ]:          0 :                     xCurrentContainer = aAncestors.back(); aAncestors.pop_back();
                 [ #  # ]
     243 [ #  # ][ #  # ]:          0 :                     nStartWithChild = aPath.back() + 1; aPath.pop_back();
     244      [ #  #  # ]:          0 :                 }
     245                 :            :             }
     246                 :            :             while ( true );
     247                 :          0 :             return -1;
     248                 :            :         }
     249                 :            : 
     250                 :            :         //--------------------------------------------------------------------
     251                 :            :         /** copies a StringItemList to a PDF widget's list
     252                 :            :         */
     253                 :          0 :         void getStringItemVector( const Reference< XPropertySet >& _rxModel, ::std::vector< ::rtl::OUString >& _rVector )
     254                 :            :         {
     255 [ #  # ][ #  # ]:          0 :             static const ::rtl::OUString FM_PROP_STRINGITEMLIST(RTL_CONSTASCII_USTRINGPARAM("StringItemList"));
         [ #  # ][ #  # ]
     256         [ #  # ]:          0 :             Sequence< ::rtl::OUString > aListEntries;
     257 [ #  # ][ #  # ]:          0 :             OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_STRINGITEMLIST ) >>= aListEntries );
                 [ #  # ]
     258                 :          0 :             ::std::copy( aListEntries.getConstArray(), aListEntries.getConstArray() + aListEntries.getLength(),
     259 [ #  # ][ #  # ]:          0 :                 ::std::back_insert_iterator< ::std::vector< ::rtl::OUString > >( _rVector ) );
     260                 :          0 :         }
     261                 :            :     }
     262                 :            : 
     263                 :            :     //--------------------------------------------------------------------
     264                 :            :     /** creates a PDF compatible control descriptor for the given control
     265                 :            :     */
     266                 :          0 :     void TOOLKIT_DLLPUBLIC describePDFControl( const Reference< XControl >& _rxControl,
     267                 :            :         ::std::auto_ptr< ::vcl::PDFWriter::AnyWidget >& _rpDescriptor, ::vcl::PDFExtOutDevData& i_pdfExportData ) SAL_THROW(())
     268                 :            :     {
     269                 :          0 :         _rpDescriptor.reset( NULL );
     270                 :            :         OSL_ENSURE( _rxControl.is(), "describePDFControl: invalid (NULL) control!" );
     271         [ #  # ]:          0 :         if ( !_rxControl.is() )
     272                 :          0 :             return;
     273                 :            : 
     274                 :            :         try
     275                 :            :         {
     276 [ #  # ][ #  # ]:          0 :             Reference< XPropertySet > xModelProps( _rxControl->getModel(), UNO_QUERY );
                 [ #  # ]
     277         [ #  # ]:          0 :             sal_Int16 nControlType = classifyFormControl( xModelProps );
     278         [ #  # ]:          0 :             _rpDescriptor.reset( createDefaultWidget( nControlType ) );
     279         [ #  # ]:          0 :             if ( !_rpDescriptor.get() )
     280                 :            :                 // no PDF widget available for this
     281                 :            :                 return;
     282                 :            : 
     283 [ #  # ][ #  # ]:          0 :             Reference< XPropertySetInfo > xPSI( xModelProps->getPropertySetInfo() );
     284         [ #  # ]:          0 :             Reference< XServiceInfo > xSI( xModelProps, UNO_QUERY );
     285                 :            :             OSL_ENSURE( xSI.is(), "describePDFControl: no service info!" );
     286                 :            :                 // if we survived classifyFormControl, then it's a real form control, and they all have
     287                 :            :                 // service infos
     288                 :            : 
     289                 :            :             // ================================
     290                 :            :             // set the common widget properties
     291                 :            : 
     292                 :            :             // --------------------------------
     293                 :            :             // Name, Description, Text
     294 [ #  # ][ #  # ]:          0 :             OSL_VERIFY( xModelProps->getPropertyValue( rtl::OUString(FM_PROP_NAME) ) >>= _rpDescriptor->Name );
     295 [ #  # ][ #  # ]:          0 :             static const ::rtl::OUString FM_PROP_HELPTEXT(RTL_CONSTASCII_USTRINGPARAM("HelpText"));
         [ #  # ][ #  # ]
     296 [ #  # ][ #  # ]:          0 :             OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_HELPTEXT ) >>= _rpDescriptor->Description );
     297                 :          0 :             Any aText;
     298 [ #  # ][ #  # ]:          0 :             static const ::rtl::OUString FM_PROP_TEXT(RTL_CONSTASCII_USTRINGPARAM("Text"));
         [ #  # ][ #  # ]
     299 [ #  # ][ #  # ]:          0 :             static const ::rtl::OUString FM_PROP_LABEL(RTL_CONSTASCII_USTRINGPARAM("Label"));
         [ #  # ][ #  # ]
     300 [ #  # ][ #  # ]:          0 :             if ( xPSI->hasPropertyByName( FM_PROP_TEXT ) )
                 [ #  # ]
     301 [ #  # ][ #  # ]:          0 :                 aText = xModelProps->getPropertyValue( FM_PROP_TEXT );
     302 [ #  # ][ #  # ]:          0 :             else if ( xPSI->hasPropertyByName( FM_PROP_LABEL ) )
                 [ #  # ]
     303 [ #  # ][ #  # ]:          0 :                 aText = xModelProps->getPropertyValue( FM_PROP_LABEL );
     304         [ #  # ]:          0 :             if ( aText.hasValue() )
     305                 :          0 :                 OSL_VERIFY( aText >>= _rpDescriptor->Text );
     306                 :            : 
     307                 :            :             // --------------------------------
     308                 :            :             // readonly
     309 [ #  # ][ #  # ]:          0 :             static const ::rtl::OUString FM_PROP_READONLY(RTL_CONSTASCII_USTRINGPARAM("ReadOnly"));
         [ #  # ][ #  # ]
     310 [ #  # ][ #  # ]:          0 :             if ( xPSI->hasPropertyByName( FM_PROP_READONLY ) )
                 [ #  # ]
     311 [ #  # ][ #  # ]:          0 :                 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_READONLY ) >>= _rpDescriptor->ReadOnly );
     312                 :            : 
     313                 :            :             // --------------------------------
     314                 :            :             // border
     315                 :            :             {
     316 [ #  # ][ #  # ]:          0 :                 static const ::rtl::OUString FM_PROP_BORDER(RTL_CONSTASCII_USTRINGPARAM("Border"));
         [ #  # ][ #  # ]
     317 [ #  # ][ #  # ]:          0 :                 if ( xPSI->hasPropertyByName( FM_PROP_BORDER ) )
                 [ #  # ]
     318                 :            :                 {
     319                 :          0 :                     sal_Int16 nBorderType = 0;
     320 [ #  # ][ #  # ]:          0 :                     OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_BORDER ) >>= nBorderType );
     321                 :          0 :                     _rpDescriptor->Border = ( nBorderType != 0 );
     322                 :            : 
     323         [ #  # ]:          0 :                     ::rtl::OUString sBorderColorPropertyName( RTL_CONSTASCII_USTRINGPARAM( "BorderColor" ) );
     324 [ #  # ][ #  # ]:          0 :                     if ( xPSI->hasPropertyByName( sBorderColorPropertyName ) )
                 [ #  # ]
     325                 :            :                     {
     326                 :          0 :                         sal_Int32 nBoderColor = COL_TRANSPARENT;
     327 [ #  # ][ #  # ]:          0 :                         if ( xModelProps->getPropertyValue( sBorderColorPropertyName ) >>= nBoderColor )
                 [ #  # ]
     328                 :          0 :                             _rpDescriptor->BorderColor = Color( nBoderColor );
     329                 :            :                         else
     330                 :          0 :                             _rpDescriptor->BorderColor = Color( COL_BLACK );
     331                 :          0 :                     }
     332                 :            :                 }
     333                 :            :             }
     334                 :            : 
     335                 :            :             // --------------------------------
     336                 :            :             // background color
     337 [ #  # ][ #  # ]:          0 :             static const ::rtl::OUString FM_PROP_BACKGROUNDCOLOR(RTL_CONSTASCII_USTRINGPARAM("BackgroundColor"));
         [ #  # ][ #  # ]
     338 [ #  # ][ #  # ]:          0 :             if ( xPSI->hasPropertyByName( FM_PROP_BACKGROUNDCOLOR ) )
                 [ #  # ]
     339                 :            :             {
     340                 :          0 :                 sal_Int32 nBackColor = COL_TRANSPARENT;
     341 [ #  # ][ #  # ]:          0 :                 xModelProps->getPropertyValue( FM_PROP_BACKGROUNDCOLOR ) >>= nBackColor;
     342                 :          0 :                 _rpDescriptor->Background = true;
     343                 :          0 :                 _rpDescriptor->BackgroundColor = Color( nBackColor );
     344                 :            :             }
     345                 :            : 
     346                 :            :             // --------------------------------
     347                 :            :             // text color
     348 [ #  # ][ #  # ]:          0 :             static const ::rtl::OUString FM_PROP_TEXTCOLOR(RTL_CONSTASCII_USTRINGPARAM("TextColor"));
         [ #  # ][ #  # ]
     349 [ #  # ][ #  # ]:          0 :             if ( xPSI->hasPropertyByName( FM_PROP_TEXTCOLOR ) )
                 [ #  # ]
     350                 :            :             {
     351                 :          0 :                 sal_Int32 nTextColor = COL_TRANSPARENT;
     352 [ #  # ][ #  # ]:          0 :                 xModelProps->getPropertyValue( FM_PROP_TEXTCOLOR ) >>= nTextColor;
     353                 :          0 :                 _rpDescriptor->TextColor = Color( nTextColor );
     354                 :            :             }
     355                 :            : 
     356                 :            :             // --------------------------------
     357                 :            :             // text style
     358                 :          0 :             _rpDescriptor->TextStyle = 0;
     359                 :            :             // ............................
     360                 :            :             // multi line and word break
     361                 :            :             // The MultiLine property of the control is mapped to both the "MULTILINE" and
     362                 :            :             // "WORDBREAK" style flags
     363 [ #  # ][ #  # ]:          0 :             static const ::rtl::OUString FM_PROP_MULTILINE(RTL_CONSTASCII_USTRINGPARAM("MultiLine"));
         [ #  # ][ #  # ]
     364 [ #  # ][ #  # ]:          0 :             if ( xPSI->hasPropertyByName( FM_PROP_MULTILINE ) )
                 [ #  # ]
     365                 :            :             {
     366                 :          0 :                 sal_Bool bMultiLine = sal_False;
     367 [ #  # ][ #  # ]:          0 :                 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_MULTILINE ) >>= bMultiLine );
     368         [ #  # ]:          0 :                 if ( bMultiLine )
     369                 :          0 :                     _rpDescriptor->TextStyle |= TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK;
     370                 :            :             }
     371                 :            :             // ............................
     372                 :            :             // horizontal alignment
     373 [ #  # ][ #  # ]:          0 :             static const ::rtl::OUString FM_PROP_ALIGN(RTL_CONSTASCII_USTRINGPARAM("Align"));
         [ #  # ][ #  # ]
     374 [ #  # ][ #  # ]:          0 :             if ( xPSI->hasPropertyByName( FM_PROP_ALIGN ) )
                 [ #  # ]
     375                 :            :             {
     376                 :          0 :                 sal_Int16 nAlign = awt::TextAlign::LEFT;
     377 [ #  # ][ #  # ]:          0 :                 xModelProps->getPropertyValue( FM_PROP_ALIGN ) >>= nAlign;
     378                 :            :                 // TODO: when the property is VOID - are there situations/UIs where this
     379                 :            :                 // means something else than LEFT?
     380   [ #  #  #  # ]:          0 :                 switch ( nAlign )
     381                 :            :                 {
     382                 :          0 :                 case awt::TextAlign::LEFT:  _rpDescriptor->TextStyle |= TEXT_DRAW_LEFT; break;
     383                 :          0 :                 case awt::TextAlign::CENTER:  _rpDescriptor->TextStyle |= TEXT_DRAW_CENTER; break;
     384                 :          0 :                 case awt::TextAlign::RIGHT:  _rpDescriptor->TextStyle |= TEXT_DRAW_RIGHT; break;
     385                 :            :                 default:
     386                 :            :                     OSL_FAIL( "describePDFControl: invalid text align!" );
     387                 :            :                 }
     388                 :            :             }
     389                 :            :             // ............................
     390                 :            :             // vertical alignment
     391                 :            :             {
     392         [ #  # ]:          0 :                 ::rtl::OUString sVertAlignPropertyName( RTL_CONSTASCII_USTRINGPARAM( "VerticalAlign" ) );
     393 [ #  # ][ #  # ]:          0 :                 if ( xPSI->hasPropertyByName( sVertAlignPropertyName ) )
                 [ #  # ]
     394                 :            :                 {
     395                 :          0 :                     sal_Int16 nAlign = VerticalAlignment_MIDDLE;
     396 [ #  # ][ #  # ]:          0 :                     xModelProps->getPropertyValue( sVertAlignPropertyName ) >>= nAlign;
     397   [ #  #  #  # ]:          0 :                     switch ( nAlign )
     398                 :            :                     {
     399                 :          0 :                     case VerticalAlignment_TOP:  _rpDescriptor->TextStyle |= TEXT_DRAW_TOP; break;
     400                 :          0 :                     case VerticalAlignment_MIDDLE:  _rpDescriptor->TextStyle |= TEXT_DRAW_VCENTER; break;
     401                 :          0 :                     case VerticalAlignment_BOTTOM:  _rpDescriptor->TextStyle |= TEXT_DRAW_BOTTOM; break;
     402                 :            :                     default:
     403                 :            :                         OSL_FAIL( "describePDFControl: invalid vertical text align!" );
     404                 :            :                     }
     405                 :          0 :                 }
     406                 :            :             }
     407                 :            : 
     408                 :            :             // font
     409 [ #  # ][ #  # ]:          0 :             static const ::rtl::OUString FM_PROP_FONT(RTL_CONSTASCII_USTRINGPARAM("FontDescriptor"));
         [ #  # ][ #  # ]
     410 [ #  # ][ #  # ]:          0 :             if ( xPSI->hasPropertyByName( FM_PROP_FONT ) )
                 [ #  # ]
     411                 :            :             {
     412                 :          0 :                 FontDescriptor aUNOFont;
     413 [ #  # ][ #  # ]:          0 :                 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_FONT ) >>= aUNOFont );
                 [ #  # ]
     414 [ #  # ][ #  # ]:          0 :                 _rpDescriptor->TextFont = VCLUnoHelper::CreateFont( aUNOFont, Font() );
         [ #  # ][ #  # ]
                 [ #  # ]
     415                 :            :             }
     416                 :            : 
     417                 :            :             // tab order
     418         [ #  # ]:          0 :             rtl::OUString aTabIndexString( RTL_CONSTASCII_USTRINGPARAM( "TabIndex" ) );
     419 [ #  # ][ #  # ]:          0 :             if ( xPSI->hasPropertyByName( aTabIndexString ) )
                 [ #  # ]
     420                 :            :             {
     421                 :          0 :                 sal_Int16 nIndex = -1;
     422 [ #  # ][ #  # ]:          0 :                 OSL_VERIFY( xModelProps->getPropertyValue( aTabIndexString ) >>= nIndex );
     423                 :          0 :                 _rpDescriptor->TabOrder = nIndex;
     424                 :            :             }
     425                 :            : 
     426                 :            :             // ================================
     427                 :            :             // special widget properties
     428                 :            :             // --------------------------------
     429                 :            :             // edits
     430         [ #  # ]:          0 :             if ( _rpDescriptor->getType() == ::vcl::PDFWriter::Edit )
     431                 :            :             {
     432                 :          0 :                 ::vcl::PDFWriter::EditWidget* pEditWidget = static_cast< ::vcl::PDFWriter::EditWidget* >( _rpDescriptor.get() );
     433                 :            :                 // ............................
     434                 :            :                 // multiline (already flagged in the TextStyle)
     435                 :          0 :                 pEditWidget->MultiLine = ( _rpDescriptor->TextStyle & TEXT_DRAW_MULTILINE ) != 0;
     436                 :            :                 // ............................
     437                 :            :                 // password input
     438         [ #  # ]:          0 :                 ::rtl::OUString sEchoCharPropName( RTL_CONSTASCII_USTRINGPARAM( "EchoChar" ) );
     439 [ #  # ][ #  # ]:          0 :                 if ( xPSI->hasPropertyByName( sEchoCharPropName ) )
                 [ #  # ]
     440                 :            :                 {
     441                 :          0 :                     sal_Int16 nEchoChar = 0;
     442 [ #  # ][ #  # ]:          0 :                     if ( ( xModelProps->getPropertyValue( sEchoCharPropName ) >>= nEchoChar ) && ( nEchoChar != 0 ) )
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
     443                 :          0 :                         pEditWidget->Password = true;
     444                 :            :                 }
     445                 :            :                 // ............................
     446                 :            :                 // file select
     447 [ #  # ][ #  # ]:          0 :                 static const ::rtl::OUString FM_SUN_COMPONENT_FILECONTROL(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.form.component.FileControl"));
         [ #  # ][ #  # ]
     448 [ #  # ][ #  # ]:          0 :                 if ( xSI->supportsService( FM_SUN_COMPONENT_FILECONTROL ) )
                 [ #  # ]
     449                 :          0 :                     pEditWidget->FileSelect = true;
     450                 :            :                 // ............................
     451                 :            :                 // maximum text length
     452 [ #  # ][ #  # ]:          0 :                 static const ::rtl::OUString FM_PROP_MAXTEXTLEN(RTL_CONSTASCII_USTRINGPARAM("MaxTextLen"));
         [ #  # ][ #  # ]
     453 [ #  # ][ #  # ]:          0 :                 if ( xPSI->hasPropertyByName( FM_PROP_MAXTEXTLEN ) )
                 [ #  # ]
     454                 :            :                 {
     455                 :          0 :                     sal_Int16 nMaxTextLength = 0;
     456 [ #  # ][ #  # ]:          0 :                     OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_MAXTEXTLEN ) >>= nMaxTextLength );
     457         [ #  # ]:          0 :                     if ( nMaxTextLength <= 0 )
     458                 :            :                         // "-1" has a special meaning for database-bound controls
     459                 :          0 :                         nMaxTextLength = 0;
     460                 :          0 :                     pEditWidget->MaxLen = nMaxTextLength;
     461                 :          0 :                 }
     462                 :            :             }
     463                 :            : 
     464                 :            :             // --------------------------------
     465                 :            :             // buttons
     466         [ #  # ]:          0 :             if ( _rpDescriptor->getType() == ::vcl::PDFWriter::PushButton )
     467                 :            :             {
     468                 :          0 :                 ::vcl::PDFWriter::PushButtonWidget* pButtonWidget = static_cast< ::vcl::PDFWriter::PushButtonWidget* >( _rpDescriptor.get() );
     469                 :          0 :                 FormButtonType eButtonType = FormButtonType_PUSH;
     470 [ #  # ][ #  # ]:          0 :                 OSL_VERIFY( xModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ButtonType" ) ) ) >>= eButtonType );
         [ #  # ][ #  # ]
     471 [ #  # ][ #  # ]:          0 :                 static const ::rtl::OUString FM_PROP_TARGET_URL(RTL_CONSTASCII_USTRINGPARAM("TargetURL"));
         [ #  # ][ #  # ]
     472         [ #  # ]:          0 :                 if ( eButtonType == FormButtonType_SUBMIT )
     473                 :            :                 {
     474                 :            :                     // if a button is a submit button, then it uses the URL at it's parent form
     475         [ #  # ]:          0 :                     Reference< XChild > xChild( xModelProps, UNO_QUERY );
     476                 :          0 :                     Reference < XPropertySet > xParentProps;
     477         [ #  # ]:          0 :                     if ( xChild.is() )
     478 [ #  # ][ #  # ]:          0 :                         xParentProps = xParentProps.query( xChild->getParent() );
         [ #  # ][ #  # ]
     479         [ #  # ]:          0 :                     if ( xParentProps.is() )
     480                 :            :                     {
     481         [ #  # ]:          0 :                         Reference< XServiceInfo > xParentSI( xParentProps, UNO_QUERY );
     482 [ #  # ][ #  # ]:          0 :                         if ( xParentSI.is() && xParentSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.component.HTMLForm" ) ) ) )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  # ]
     483                 :            :                         {
     484 [ #  # ][ #  # ]:          0 :                             OSL_VERIFY( xParentProps->getPropertyValue( FM_PROP_TARGET_URL ) >>= pButtonWidget->URL );
     485                 :          0 :                             pButtonWidget->Submit = true;
     486                 :          0 :                             FormSubmitMethod eMethod = FormSubmitMethod_POST;
     487 [ #  # ][ #  # ]:          0 :                             OSL_VERIFY( xParentProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SubmitMethod" ) ) ) >>= eMethod );
         [ #  # ][ #  # ]
     488                 :          0 :                             pButtonWidget->SubmitGet = (eMethod == FormSubmitMethod_GET);
     489                 :          0 :                         }
     490                 :          0 :                     }
     491                 :            :                 }
     492         [ #  # ]:          0 :                 else if ( eButtonType == FormButtonType_URL )
     493                 :            :                 {
     494                 :          0 :                     ::rtl::OUString sURL;
     495 [ #  # ][ #  # ]:          0 :                     OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_TARGET_URL ) >>= sURL );
     496 [ #  # ][ #  # ]:          0 :                     const bool bDocumentLocalTarget = !sURL.isEmpty() && ( sURL.getStr()[0] == '#' );
     497         [ #  # ]:          0 :                     if ( bDocumentLocalTarget )
     498                 :            :                     {
     499                 :            :                         // Register the destination for for future handling ...
     500         [ #  # ]:          0 :                         pButtonWidget->Dest = i_pdfExportData.RegisterDest();
     501                 :            : 
     502                 :            :                         // and put it into the bookmarks, to ensure the future handling really happens
     503         [ #  # ]:          0 :                         ::std::vector< ::vcl::PDFExtOutDevBookmarkEntry >& rBookmarks( i_pdfExportData.GetBookmarks() );
     504                 :          0 :                         ::vcl::PDFExtOutDevBookmarkEntry aBookmark;
     505                 :          0 :                         aBookmark.nDestId = pButtonWidget->Dest;
     506                 :          0 :                         aBookmark.aBookmark = sURL;
     507         [ #  # ]:          0 :                         rBookmarks.push_back( aBookmark );
     508                 :            :                     }
     509                 :            :                     else
     510                 :          0 :                         pButtonWidget->URL = sURL;
     511                 :            : 
     512                 :          0 :                     pButtonWidget->Submit = false;
     513                 :            :                 }
     514                 :            : 
     515                 :            :                // TODO:
     516                 :            :                 // In PDF files, buttons are either reset, url or submit buttons. So if we have a simple PUSH button
     517                 :            :                 // in a document, then this means that we do not export a SubmitToURL, which means that in PDF,
     518                 :            :                 // the button is used as reset button.
     519                 :            :                 // Is this desired? If no, we would have to reset _rpDescriptor to NULL here, in case eButtonType
     520                 :            :                 // != FormButtonType_SUBMIT && != FormButtonType_RESET
     521                 :            : 
     522                 :            :                 // the PDF exporter defaults the text style, if 0. To prevent this, we have to transfer the UNO
     523                 :            :                 // defaults to the PDF widget
     524         [ #  # ]:          0 :                 if ( !pButtonWidget->TextStyle )
     525                 :          0 :                     pButtonWidget->TextStyle = TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER;
     526                 :            :             }
     527                 :            : 
     528                 :            :             // --------------------------------
     529                 :            :             // check boxes
     530 [ #  # ][ #  # ]:          0 :             static const ::rtl::OUString FM_PROP_STATE(RTL_CONSTASCII_USTRINGPARAM("State"));
         [ #  # ][ #  # ]
     531         [ #  # ]:          0 :             if ( _rpDescriptor->getType() == ::vcl::PDFWriter::CheckBox )
     532                 :            :             {
     533                 :          0 :                 ::vcl::PDFWriter::CheckBoxWidget* pCheckBoxWidget = static_cast< ::vcl::PDFWriter::CheckBoxWidget* >( _rpDescriptor.get() );
     534                 :          0 :                 sal_Int16 nState = 0;
     535 [ #  # ][ #  # ]:          0 :                 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_STATE ) >>= nState );
     536                 :          0 :                 pCheckBoxWidget->Checked = ( nState != 0 );
     537                 :            :             }
     538                 :            : 
     539                 :            :             // --------------------------------
     540                 :            :             // radio buttons
     541         [ #  # ]:          0 :             if ( _rpDescriptor->getType() == ::vcl::PDFWriter::RadioButton )
     542                 :            :             {
     543                 :          0 :                 ::vcl::PDFWriter::RadioButtonWidget* pRadioWidget = static_cast< ::vcl::PDFWriter::RadioButtonWidget* >( _rpDescriptor.get() );
     544                 :          0 :                 sal_Int16 nState = 0;
     545 [ #  # ][ #  # ]:          0 :                 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_STATE ) >>= nState );
     546                 :          0 :                 pRadioWidget->Selected = ( nState != 0 );
     547         [ #  # ]:          0 :                 pRadioWidget->RadioGroup = determineRadioGroupId( xModelProps );
     548                 :            :                 try
     549                 :            :                 {
     550 [ #  # ][ #  # ]:          0 :                     static const ::rtl::OUString FM_PROP_REFVALUE(RTL_CONSTASCII_USTRINGPARAM("RefValue"));
         [ #  # ][ #  # ]
     551 [ #  # ][ #  # ]:          0 :                     xModelProps->getPropertyValue( FM_PROP_REFVALUE ) >>= pRadioWidget->OnValue;
     552                 :            :                 }
     553         [ #  # ]:          0 :                 catch(...)
     554                 :            :                 {
     555         [ #  # ]:          0 :                     pRadioWidget->OnValue = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "On" ) );
     556                 :            :                 }
     557                 :            :             }
     558                 :            : 
     559                 :            :             // --------------------------------
     560                 :            :             // list boxes
     561         [ #  # ]:          0 :             if ( _rpDescriptor->getType() == ::vcl::PDFWriter::ListBox )
     562                 :            :             {
     563                 :          0 :                 ::vcl::PDFWriter::ListBoxWidget* pListWidget = static_cast< ::vcl::PDFWriter::ListBoxWidget* >( _rpDescriptor.get() );
     564                 :            :                 // ............................
     565                 :            :                 // drop down
     566 [ #  # ][ #  # ]:          0 :                 static const ::rtl::OUString FM_PROP_DROPDOWN(RTL_CONSTASCII_USTRINGPARAM("Dropdown"));
         [ #  # ][ #  # ]
     567 [ #  # ][ #  # ]:          0 :                 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_DROPDOWN ) >>= pListWidget->DropDown );
     568                 :            :                 // ............................
     569                 :            :                 // multi selection
     570 [ #  # ][ #  # ]:          0 :                 OSL_VERIFY( xModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MultiSelection" ) ) ) >>= pListWidget->MultiSelect );
                 [ #  # ]
     571                 :            :                 // ............................
     572                 :            :                 // entries
     573         [ #  # ]:          0 :                 getStringItemVector( xModelProps, pListWidget->Entries );
     574                 :            :                 // since we explicitly list the entries in the order in which they appear, they should not be
     575                 :            :                 // resorted by the PDF viewer
     576                 :          0 :                 pListWidget->Sort = false;
     577                 :            : 
     578                 :            :                 // get selected items
     579         [ #  # ]:          0 :                 Sequence< sal_Int16 > aSelectIndices;
     580 [ #  # ][ #  # ]:          0 :                 OSL_VERIFY( xModelProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SelectedItems" ) ) ) >>= aSelectIndices );
         [ #  # ][ #  # ]
     581         [ #  # ]:          0 :                 if( aSelectIndices.getLength() > 0 )
     582                 :            :                 {
     583         [ #  # ]:          0 :                     pListWidget->SelectedEntries.resize( 0 );
     584         [ #  # ]:          0 :                     for( sal_Int32 i = 0; i < aSelectIndices.getLength(); i++ )
     585                 :            :                     {
     586                 :          0 :                         sal_Int16 nIndex = aSelectIndices.getConstArray()[i];
     587 [ #  # ][ #  # ]:          0 :                         if( nIndex >= 0 && nIndex < (sal_Int16)pListWidget->Entries.size() )
                 [ #  # ]
     588         [ #  # ]:          0 :                             pListWidget->SelectedEntries.push_back( nIndex );
     589                 :            :                     }
     590         [ #  # ]:          0 :                 }
     591                 :            :             }
     592                 :            : 
     593                 :            :             // --------------------------------
     594                 :            :             // combo boxes
     595         [ #  # ]:          0 :             if ( _rpDescriptor->getType() == ::vcl::PDFWriter::ComboBox )
     596                 :            :             {
     597                 :          0 :                 ::vcl::PDFWriter::ComboBoxWidget* pComboWidget = static_cast< ::vcl::PDFWriter::ComboBoxWidget* >( _rpDescriptor.get() );
     598                 :            :                 // ............................
     599                 :            :                 // entries
     600         [ #  # ]:          0 :                 getStringItemVector( xModelProps, pComboWidget->Entries );
     601                 :            :                 // same reasoning as above
     602                 :          0 :                 pComboWidget->Sort = false;
     603                 :            :             }
     604                 :            : 
     605                 :            :             // ================================
     606                 :            :             // some post-processing
     607                 :            :             // --------------------------------
     608                 :            :             // text line ends
     609                 :            :             // some controls may (always or dependent on other settings) return UNIX line ends
     610 [ #  # ][ #  # ]:          0 :             _rpDescriptor->Text = convertLineEnd(_rpDescriptor->Text, LINEEND_CRLF);
                 [ #  # ]
     611                 :            :         }
     612                 :          0 :         catch( const Exception& )
     613                 :            :         {
     614                 :            :             OSL_FAIL( "describePDFControl: caught an exception!" );
     615                 :            :         }
     616                 :            :     }
     617                 :            : 
     618                 :            : //........................................................................
     619                 :            : } // namespace toolkitform
     620                 :            : //........................................................................
     621                 :            : 
     622                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10