LCOV - code coverage report
Current view: top level - toolkit/source/helper - formpdfexport.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1 257 0.4 %
Date: 2014-11-03 Functions: 2 7 28.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10