1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: formpdfexport.cxx,v $
11 * $Revision: 1.2.6.1 $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_toolkit.hxx"
35 #ifndef _TOOLKIT_HELPER_FORM_FORMPDFEXPORT_HXX
36 #include <toolkit/helper/formpdfexport.hxx>
39 /** === begin UNO includes === **/
40 #ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_
41 #include <com/sun/star/container/XIndexAccess.hpp>
43 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
44 #include <com/sun/star/container/XNameAccess.hpp>
46 #ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
47 #include <com/sun/star/container/XNameContainer.hpp>
49 #ifndef _COM_SUN_STAR_FORM_XFORM_HPP_
50 #include <com/sun/star/form/XForm.hpp>
52 #ifndef _COM_SUN_STAR_CONTAINER_XCHILD_HPP_
53 #include <com/sun/star/container/XChild.hpp>
55 #ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
56 #include <com/sun/star/lang/XServiceInfo.hpp>
58 #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
59 #include <com/sun/star/beans/XPropertySet.hpp>
61 #ifndef _COM_SUN_STAR_FORM_FORMCOMPONENTTYPE_HPP_
62 #include <com/sun/star/form/FormComponentType.hpp>
64 #ifndef _COM_SUN_STAR_AWT_TEXTALIGN_HPP_
65 #include <com/sun/star/awt/TextAlign.hpp>
67 #ifndef _COM_SUN_STAR_STYLE_VERTICALALIGNMENT_HPP_
68 #include <com/sun/star/style/VerticalAlignment.hpp>
70 #ifndef _COM_SUN_STAR_FORM_FORMBUTTONTYPE_HPP_
71 #include <com/sun/star/form/FormButtonType.hpp>
73 #ifndef _COM_SUN_STAR_FORM_SUBMITMETHOD_HPP_
74 #include <com/sun/star/form/FormSubmitMethod.hpp>
76 /** === end UNO includes === **/
78 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
79 #include <toolkit/helper/vclunohelper.hxx>
81 #ifndef _VCL_PDFEXTOUTDEVDATA_HXX
82 #include <vcl/pdfextoutdevdata.hxx>
84 #ifndef _SV_OUTDEV_HXX
85 #include <vcl/outdev.hxx>
91 //........................................................................
94 //........................................................................
96 using namespace ::com::sun::star
;
97 using namespace ::com::sun::star::uno
;
98 using namespace ::com::sun::star::awt
;
99 using namespace ::com::sun::star::style
;
100 using namespace ::com::sun::star::beans
;
101 using namespace ::com::sun::star::form
;
102 using namespace ::com::sun::star::lang
;
103 using namespace ::com::sun::star::container
;
106 static const ::rtl::OUString
FM_PROP_CLASSID(RTL_CONSTASCII_USTRINGPARAM("ClassId"));
107 static const ::rtl::OUString
FM_PROP_NAME(RTL_CONSTASCII_USTRINGPARAM("Name"));
108 static const ::rtl::OUString
FM_PROP_STRINGITEMLIST(RTL_CONSTASCII_USTRINGPARAM("StringItemList"));
109 static const ::rtl::OUString
FM_PROP_HELPTEXT(RTL_CONSTASCII_USTRINGPARAM("HelpText"));
110 static const ::rtl::OUString
FM_PROP_TEXT(RTL_CONSTASCII_USTRINGPARAM("Text"));
111 static const ::rtl::OUString
FM_PROP_LABEL(RTL_CONSTASCII_USTRINGPARAM("Label"));
112 static const ::rtl::OUString
FM_PROP_READONLY(RTL_CONSTASCII_USTRINGPARAM("ReadOnly"));
113 static const ::rtl::OUString
FM_PROP_BORDER(RTL_CONSTASCII_USTRINGPARAM("Border"));
114 static const ::rtl::OUString
FM_PROP_BACKGROUNDCOLOR(RTL_CONSTASCII_USTRINGPARAM("BackgroundColor"));
115 static const ::rtl::OUString
FM_PROP_TEXTCOLOR(RTL_CONSTASCII_USTRINGPARAM("TextColor"));
116 static const ::rtl::OUString
FM_PROP_MULTILINE(RTL_CONSTASCII_USTRINGPARAM("MultiLine"));
117 static const ::rtl::OUString
FM_PROP_ALIGN(RTL_CONSTASCII_USTRINGPARAM("Align"));
118 static const ::rtl::OUString
FM_PROP_FONT(RTL_CONSTASCII_USTRINGPARAM("FontDescriptor"));
119 static const ::rtl::OUString
FM_PROP_MAXTEXTLEN(RTL_CONSTASCII_USTRINGPARAM("MaxTextLen"));
120 static const ::rtl::OUString
FM_PROP_TARGET_URL(RTL_CONSTASCII_USTRINGPARAM("TargetURL"));
121 static const ::rtl::OUString
FM_PROP_STATE(RTL_CONSTASCII_USTRINGPARAM("State"));
122 static const ::rtl::OUString
FM_PROP_REFVALUE(RTL_CONSTASCII_USTRINGPARAM("RefValue"));
123 static const ::rtl::OUString
FM_PROP_DROPDOWN(RTL_CONSTASCII_USTRINGPARAM("Dropdown"));
124 static const ::rtl::OUString
FM_SUN_COMPONENT_FILECONTROL(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.form.component.FileControl"));
128 //--------------------------------------------------------------------
129 /** determines the FormComponentType of a form control
131 sal_Int16
classifyFormControl( const Reference
< XPropertySet
>& _rxModel
) SAL_THROW(( Exception
))
133 sal_Int16 nControlType
= FormComponentType::CONTROL
;
135 Reference
< XPropertySetInfo
> xPSI
;
137 xPSI
= _rxModel
->getPropertySetInfo();
138 if ( xPSI
.is() && xPSI
->hasPropertyByName( FM_PROP_CLASSID
) )
140 OSL_VERIFY( _rxModel
->getPropertyValue( FM_PROP_CLASSID
) >>= nControlType
);
146 //--------------------------------------------------------------------
147 /** (default-)creates a PDF widget according to a given FormComponentType
149 ::vcl::PDFWriter::AnyWidget
* createDefaultWidget( sal_Int16 _nFormComponentType
)
151 switch ( _nFormComponentType
)
153 case FormComponentType::COMMANDBUTTON
:
154 return new ::vcl::PDFWriter::PushButtonWidget
;
155 case FormComponentType::CHECKBOX
:
156 return new ::vcl::PDFWriter::CheckBoxWidget
;
157 case FormComponentType::RADIOBUTTON
:
158 return new ::vcl::PDFWriter::RadioButtonWidget
;
159 case FormComponentType::LISTBOX
:
160 return new ::vcl::PDFWriter::ListBoxWidget
;
161 case FormComponentType::COMBOBOX
:
162 return new ::vcl::PDFWriter::ComboBoxWidget
;
164 case FormComponentType::TEXTFIELD
:
165 case FormComponentType::FILECONTROL
:
166 case FormComponentType::DATEFIELD
:
167 case FormComponentType::TIMEFIELD
:
168 case FormComponentType::NUMERICFIELD
:
169 case FormComponentType::CURRENCYFIELD
:
170 case FormComponentType::PATTERNFIELD
:
171 return new ::vcl::PDFWriter::EditWidget
;
176 //--------------------------------------------------------------------
177 /** determines a unique number for the radio group which the given radio
178 button model belongs to
180 The number is guaranteed to be
181 <ul><li>unique within the document in which the button lives</li>
182 <li>the same for subsequent calls with other radio button models,
183 which live in the same document, and belong to the same group</li>
187 the model must be part of the form component hierarchy in a document
189 sal_Int32
determineRadioGroupId( const Reference
< XPropertySet
>& _rxRadioModel
) SAL_THROW((Exception
))
191 OSL_ENSURE( classifyFormControl( _rxRadioModel
) == FormComponentType::RADIOBUTTON
,
192 "determineRadioGroupId: this *is* no radio button model!" );
193 // The fact that radio button groups need to be unique within the complete
194 // host document makes it somewhat difficult ...
195 // Problem is that two form radio buttons belong to the same group if
196 // - they have the same parent
197 // - AND they have the same name
198 // This implies that we need some knowledge about (potentially) *all* radio button
199 // groups in the document.
201 // get the root-level container
202 Reference
< XChild
> xChild( _rxRadioModel
, UNO_QUERY
);
203 Reference
< XForm
> xParentForm( xChild
.is() ? xChild
->getParent() : Reference
< XInterface
>(), UNO_QUERY
);
204 OSL_ENSURE( xParentForm
.is(), "determineRadioGroupId: no parent form -> group id!" );
205 if ( !xParentForm
.is() )
208 while ( xParentForm
.is() )
210 xChild
= xParentForm
.get();
211 xParentForm
= xParentForm
.query( xChild
->getParent() );
213 Reference
< XIndexAccess
> xRoot( xChild
->getParent(), UNO_QUERY
);
214 OSL_ENSURE( xRoot
.is(), "determineRadioGroupId: unable to determine the root of the form component hierarchy!" );
218 // count the leafs in the hierarchy, until we encounter radio button
219 ::std::vector
< Reference
< XIndexAccess
> > aAncestors
;
220 ::std::vector
< sal_Int32
> aPath
;
222 Reference
< XInterface
> xNormalizedLookup( _rxRadioModel
, UNO_QUERY
);
223 ::rtl::OUString sRadioGroupName
;
224 OSL_VERIFY( _rxRadioModel
->getPropertyValue( FM_PROP_NAME
) >>= sRadioGroupName
);
226 Reference
< XIndexAccess
> xCurrentContainer( xRoot
);
227 sal_Int32 nStartWithChild
= 0;
228 sal_Int32 nGroupsEncountered
= 0;
231 Reference
< XNameAccess
> xElementNameAccess( xCurrentContainer
, UNO_QUERY
);
232 OSL_ENSURE( xElementNameAccess
.is(), "determineRadioGroupId: no name container?" );
233 if ( !xElementNameAccess
.is() )
236 if ( nStartWithChild
== 0 )
237 { // we encounter this container the first time. In particular, we did not
239 nGroupsEncountered
+= xElementNameAccess
->getElementNames().getLength();
240 // this is way too much: Not all of the elements in the current container
241 // may form groups, especially if they're forms. But anyway, this number is
242 // sufficient for our purpose. Finally, the container contains *at most*
246 sal_Int32 nCount
= xCurrentContainer
->getCount();
248 for ( i
= nStartWithChild
; i
< nCount
; ++i
)
250 Reference
< XInterface
> xElement( xCurrentContainer
->getByIndex( i
), UNO_QUERY
);
251 if ( !xElement
.is() )
253 OSL_ENSURE( sal_False
, "determineRadioGroupId: very suspicious!" );
257 Reference
< XIndexAccess
> xNewContainer( xElement
, UNO_QUERY
);
258 if ( xNewContainer
.is() )
260 // step down the hierarchy
261 aAncestors
.push_back( xCurrentContainer
);
262 xCurrentContainer
= xNewContainer
;
263 aPath
.push_back( i
);
266 // out of the inner loop, but continue with the outer loop
269 if ( xElement
.get() == xNormalizedLookup
.get() )
271 // look up the name of the radio group in the list of all element names
272 Sequence
< ::rtl::OUString
> aElementNames( xElementNameAccess
->getElementNames() );
273 const ::rtl::OUString
* pElementNames
= aElementNames
.getConstArray();
274 const ::rtl::OUString
* pElementNamesEnd
= pElementNames
+ aElementNames
.getLength();
275 while ( pElementNames
!= pElementNamesEnd
)
277 if ( *pElementNames
== sRadioGroupName
)
279 sal_Int32 nLocalGroupIndex
= pElementNames
- aElementNames
.getConstArray();
280 OSL_ENSURE( nLocalGroupIndex
< xElementNameAccess
->getElementNames().getLength(),
281 "determineRadioGroupId: inconsistency!" );
283 sal_Int32 nGlobalGroupId
= nGroupsEncountered
- xElementNameAccess
->getElementNames().getLength() + nLocalGroupIndex
;
284 return nGlobalGroupId
;
288 OSL_ENSURE( sal_False
, "determineRadioGroupId: did not find the radios element name!" );
292 if ( !( i
< nCount
) )
294 // the loop terminated because there were no more elements
295 // -> step up, if possible
296 if ( aAncestors
.empty() )
299 xCurrentContainer
= aAncestors
.back(); aAncestors
.pop_back();
300 nStartWithChild
= aPath
.back() + 1; aPath
.pop_back();
307 //--------------------------------------------------------------------
308 /** copies a StringItemList to a PDF widget's list
310 void getStringItemVector( const Reference
< XPropertySet
>& _rxModel
, ::std::vector
< ::rtl::OUString
>& _rVector
)
312 Sequence
< ::rtl::OUString
> aListEntries
;
313 OSL_VERIFY( _rxModel
->getPropertyValue( FM_PROP_STRINGITEMLIST
) >>= aListEntries
);
314 ::std::copy( aListEntries
.getConstArray(), aListEntries
.getConstArray() + aListEntries
.getLength(),
315 ::std::back_insert_iterator
< ::std::vector
< ::rtl::OUString
> >( _rVector
) );
319 //--------------------------------------------------------------------
320 /** creates a PDF compatible control descriptor for the given control
322 void TOOLKIT_DLLPUBLIC
describePDFControl( const Reference
< XControl
>& _rxControl
, ::std::auto_ptr
< ::vcl::PDFWriter::AnyWidget
>& _rpDescriptor
) SAL_THROW(())
324 _rpDescriptor
.reset( NULL
);
325 OSL_ENSURE( _rxControl
.is(), "describePDFControl: invalid (NULL) control!" );
326 if ( !_rxControl
.is() )
331 Reference
< XPropertySet
> xModelProps( _rxControl
->getModel(), UNO_QUERY
);
332 sal_Int16 nControlType
= classifyFormControl( xModelProps
);
333 _rpDescriptor
.reset( createDefaultWidget( nControlType
) );
334 if ( !_rpDescriptor
.get() )
335 // no PDF widget available for this
338 Reference
< XPropertySetInfo
> xPSI( xModelProps
->getPropertySetInfo() );
339 Reference
< XServiceInfo
> xSI( xModelProps
, UNO_QUERY
);
340 OSL_ENSURE( xSI
.is(), "describePDFControl: no service info!" );
341 // if we survived classifyFormControl, then it's a real form control, and they all have
344 // ================================
345 // set the common widget properties
347 // --------------------------------
348 // Name, Description, Text
349 OSL_VERIFY( xModelProps
->getPropertyValue( FM_PROP_NAME
) >>= _rpDescriptor
->Name
);
350 OSL_VERIFY( xModelProps
->getPropertyValue( FM_PROP_HELPTEXT
) >>= _rpDescriptor
->Description
);
352 if ( xPSI
->hasPropertyByName( FM_PROP_TEXT
) )
353 aText
= xModelProps
->getPropertyValue( FM_PROP_TEXT
);
354 else if ( xPSI
->hasPropertyByName( FM_PROP_LABEL
) )
355 aText
= xModelProps
->getPropertyValue( FM_PROP_LABEL
);
356 if ( aText
.hasValue() )
357 OSL_VERIFY( aText
>>= _rpDescriptor
->Text
);
359 // --------------------------------
361 if ( xPSI
->hasPropertyByName( FM_PROP_READONLY
) )
362 OSL_VERIFY( xModelProps
->getPropertyValue( FM_PROP_READONLY
) >>= _rpDescriptor
->ReadOnly
);
364 // --------------------------------
367 if ( xPSI
->hasPropertyByName( FM_PROP_BORDER
) )
369 sal_Int16 nBorderType
= 0;
370 OSL_VERIFY( xModelProps
->getPropertyValue( FM_PROP_BORDER
) >>= nBorderType
);
371 _rpDescriptor
->Border
= ( nBorderType
!= 0 );
373 ::rtl::OUString
sBorderColorPropertyName( RTL_CONSTASCII_USTRINGPARAM( "BorderColor" ) );
374 if ( xPSI
->hasPropertyByName( sBorderColorPropertyName
) )
376 sal_Int32 nBoderColor
= COL_TRANSPARENT
;
377 if ( xModelProps
->getPropertyValue( sBorderColorPropertyName
) >>= nBoderColor
)
378 _rpDescriptor
->BorderColor
= Color( nBoderColor
);
380 _rpDescriptor
->BorderColor
= Color( COL_BLACK
);
385 // --------------------------------
387 if ( xPSI
->hasPropertyByName( FM_PROP_BACKGROUNDCOLOR
) )
389 sal_Int32 nBackColor
= COL_TRANSPARENT
;
390 xModelProps
->getPropertyValue( FM_PROP_BACKGROUNDCOLOR
) >>= nBackColor
;
391 _rpDescriptor
->Background
= true;
392 _rpDescriptor
->BackgroundColor
= Color( nBackColor
);
395 // --------------------------------
397 if ( xPSI
->hasPropertyByName( FM_PROP_TEXTCOLOR
) )
399 sal_Int32 nTextColor
= COL_TRANSPARENT
;
400 xModelProps
->getPropertyValue( FM_PROP_TEXTCOLOR
) >>= nTextColor
;
401 _rpDescriptor
->TextColor
= Color( nTextColor
);
404 // --------------------------------
406 _rpDescriptor
->TextStyle
= 0;
407 // ............................
408 // multi line and word break
409 // The MultiLine property of the control is mapped to both the "MULTILINE" and
410 // "WORDBREAK" style flags
411 if ( xPSI
->hasPropertyByName( FM_PROP_MULTILINE
) )
413 sal_Bool bMultiLine
= sal_False
;
414 OSL_VERIFY( xModelProps
->getPropertyValue( FM_PROP_MULTILINE
) >>= bMultiLine
);
416 _rpDescriptor
->TextStyle
|= TEXT_DRAW_MULTILINE
| TEXT_DRAW_WORDBREAK
;
418 // ............................
419 // horizontal alignment
420 if ( xPSI
->hasPropertyByName( FM_PROP_ALIGN
) )
422 sal_Int16 nAlign
= awt::TextAlign::LEFT
;
423 xModelProps
->getPropertyValue( FM_PROP_ALIGN
) >>= nAlign
;
424 // TODO: when the property is VOID - are there situations/UIs where this
425 // means something else than LEFT?
428 case awt::TextAlign::LEFT
: _rpDescriptor
->TextStyle
|= TEXT_DRAW_LEFT
; break;
429 case awt::TextAlign::CENTER
: _rpDescriptor
->TextStyle
|= TEXT_DRAW_CENTER
; break;
430 case awt::TextAlign::RIGHT
: _rpDescriptor
->TextStyle
|= TEXT_DRAW_RIGHT
; break;
432 OSL_ENSURE( sal_False
, "describePDFControl: invalid text align!" );
435 // ............................
436 // vertical alignment
438 ::rtl::OUString
sVertAlignPropertyName( RTL_CONSTASCII_USTRINGPARAM( "VerticalAlign" ) );
439 if ( xPSI
->hasPropertyByName( sVertAlignPropertyName
) )
441 sal_Int16 nAlign
= VerticalAlignment_MIDDLE
;
442 xModelProps
->getPropertyValue( sVertAlignPropertyName
) >>= nAlign
;
445 case VerticalAlignment_TOP
: _rpDescriptor
->TextStyle
|= TEXT_DRAW_TOP
; break;
446 case VerticalAlignment_MIDDLE
: _rpDescriptor
->TextStyle
|= TEXT_DRAW_VCENTER
; break;
447 case VerticalAlignment_BOTTOM
: _rpDescriptor
->TextStyle
|= TEXT_DRAW_BOTTOM
; break;
449 OSL_ENSURE( sal_False
, "describePDFControl: invalid vertical text align!" );
455 if ( xPSI
->hasPropertyByName( FM_PROP_FONT
) )
457 FontDescriptor aUNOFont
;
458 OSL_VERIFY( xModelProps
->getPropertyValue( FM_PROP_FONT
) >>= aUNOFont
);
459 _rpDescriptor
->TextFont
= VCLUnoHelper::CreateFont( aUNOFont
, Font() );
463 rtl::OUString
aTabIndexString( RTL_CONSTASCII_USTRINGPARAM( "TabIndex" ) );
464 if ( xPSI
->hasPropertyByName( aTabIndexString
) )
466 sal_Int16 nIndex
= -1;
467 OSL_VERIFY( xModelProps
->getPropertyValue( aTabIndexString
) >>= nIndex
);
468 _rpDescriptor
->TabOrder
= nIndex
;
471 // ================================
472 // special widget properties
473 // --------------------------------
475 if ( _rpDescriptor
->getType() == ::vcl::PDFWriter::Edit
)
477 ::vcl::PDFWriter::EditWidget
* pEditWidget
= static_cast< ::vcl::PDFWriter::EditWidget
* >( _rpDescriptor
.get() );
478 // ............................
479 // multiline (already flagged in the TextStyle)
480 pEditWidget
->MultiLine
= ( _rpDescriptor
->TextStyle
& TEXT_DRAW_MULTILINE
) != 0;
481 // ............................
483 ::rtl::OUString
sEchoCharPropName( RTL_CONSTASCII_USTRINGPARAM( "EchoChar" ) );
484 if ( xPSI
->hasPropertyByName( sEchoCharPropName
) )
486 sal_Int16 nEchoChar
= 0;
487 if ( ( xModelProps
->getPropertyValue( sEchoCharPropName
) >>= nEchoChar
) && ( nEchoChar
!= 0 ) )
488 pEditWidget
->Password
= true;
490 // ............................
492 if ( xSI
->supportsService( FM_SUN_COMPONENT_FILECONTROL
) )
493 pEditWidget
->FileSelect
= true;
494 // ............................
495 // maximum text length
496 if ( xPSI
->hasPropertyByName( FM_PROP_MAXTEXTLEN
) )
498 sal_Int16 nMaxTextLength
= 0;
499 OSL_VERIFY( xModelProps
->getPropertyValue( FM_PROP_MAXTEXTLEN
) >>= nMaxTextLength
);
500 if ( nMaxTextLength
<= 0 )
501 // "-1" has a special meaning for database-bound controls
503 pEditWidget
->MaxLen
= nMaxTextLength
;
507 // --------------------------------
509 if ( _rpDescriptor
->getType() == ::vcl::PDFWriter::PushButton
)
511 ::vcl::PDFWriter::PushButtonWidget
* pButtonWidget
= static_cast< ::vcl::PDFWriter::PushButtonWidget
* >( _rpDescriptor
.get() );
512 FormButtonType eButtonType
= FormButtonType_PUSH
;
513 OSL_VERIFY( xModelProps
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ButtonType" ) ) ) >>= eButtonType
);
514 if ( eButtonType
== FormButtonType_SUBMIT
)
516 // if a button is a submit button, then it uses the URL at it's parent form
517 Reference
< XChild
> xChild( xModelProps
, UNO_QUERY
);
518 Reference
< XPropertySet
> xParentProps
;
520 xParentProps
= xParentProps
.query( xChild
->getParent() );
521 if ( xParentProps
.is() )
523 Reference
< XServiceInfo
> xParentSI( xParentProps
, UNO_QUERY
);
524 if ( xParentSI
.is() && xParentSI
->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.component.HTMLForm" ) ) ) )
526 OSL_VERIFY( xParentProps
->getPropertyValue( FM_PROP_TARGET_URL
) >>= pButtonWidget
->URL
);
527 pButtonWidget
->Submit
= true;
528 FormSubmitMethod eMethod
= FormSubmitMethod_POST
;
529 OSL_VERIFY( xParentProps
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SubmitMethod" ) ) ) >>= eMethod
);
530 pButtonWidget
->SubmitGet
= (eMethod
== FormSubmitMethod_GET
);
534 else if ( eButtonType
== FormButtonType_URL
)
536 OSL_VERIFY( xModelProps
->getPropertyValue( FM_PROP_TARGET_URL
) >>= pButtonWidget
->URL
);
537 pButtonWidget
->Submit
= false;
541 // In PDF files, buttons are either reset, url or submit buttons. So if we have a simple PUSH button
542 // in a document, then this means that we do not export a SubmitToURL, which means that in PDF,
543 // the button is used as reset button.
544 // Is this desired? If no, we would have to reset _rpDescriptor to NULL here, in case eButtonType
545 // != FormButtonType_SUBMIT && != FormButtonType_RESET
547 // the PDF exporter defaults the text style, if 0. To prevent this, we have to transfer the UNO
548 // defaults to the PDF widget
549 if ( !pButtonWidget
->TextStyle
)
550 pButtonWidget
->TextStyle
= TEXT_DRAW_CENTER
| TEXT_DRAW_VCENTER
;
553 // --------------------------------
555 if ( _rpDescriptor
->getType() == ::vcl::PDFWriter::CheckBox
)
557 ::vcl::PDFWriter::CheckBoxWidget
* pCheckBoxWidget
= static_cast< ::vcl::PDFWriter::CheckBoxWidget
* >( _rpDescriptor
.get() );
558 sal_Int16 nState
= 0;
559 OSL_VERIFY( xModelProps
->getPropertyValue( FM_PROP_STATE
) >>= nState
);
560 pCheckBoxWidget
->Checked
= ( nState
!= 0 );
563 // --------------------------------
565 if ( _rpDescriptor
->getType() == ::vcl::PDFWriter::RadioButton
)
567 ::vcl::PDFWriter::RadioButtonWidget
* pRadioWidget
= static_cast< ::vcl::PDFWriter::RadioButtonWidget
* >( _rpDescriptor
.get() );
568 sal_Int16 nState
= 0;
569 OSL_VERIFY( xModelProps
->getPropertyValue( FM_PROP_STATE
) >>= nState
);
570 pRadioWidget
->Selected
= ( nState
!= 0 );
571 pRadioWidget
->RadioGroup
= determineRadioGroupId( xModelProps
);
574 xModelProps
->getPropertyValue( FM_PROP_REFVALUE
) >>= pRadioWidget
->OnValue
;
578 pRadioWidget
->OnValue
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "On" ) );
582 // --------------------------------
584 if ( _rpDescriptor
->getType() == ::vcl::PDFWriter::ListBox
)
586 ::vcl::PDFWriter::ListBoxWidget
* pListWidget
= static_cast< ::vcl::PDFWriter::ListBoxWidget
* >( _rpDescriptor
.get() );
587 // ............................
589 OSL_VERIFY( xModelProps
->getPropertyValue( FM_PROP_DROPDOWN
) >>= pListWidget
->DropDown
);
590 // ............................
592 OSL_VERIFY( xModelProps
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MultiSelection" ) ) ) >>= pListWidget
->MultiSelect
);
593 // ............................
595 getStringItemVector( xModelProps
, pListWidget
->Entries
);
596 // since we explicitly list the entries in the order in which they appear, they should not be
597 // resorted by the PDF viewer
598 pListWidget
->Sort
= false;
600 // get selected items
601 Sequence
< sal_Int16
> aSelectIndices
;
602 OSL_VERIFY( xModelProps
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SelectedItems" ) ) ) >>= aSelectIndices
);
603 if( aSelectIndices
.getLength() > 0 )
605 pListWidget
->SelectedEntries
.resize( 0 );
606 for( sal_Int32 i
= 0; i
< aSelectIndices
.getLength(); i
++ )
608 sal_Int16 nIndex
= aSelectIndices
.getConstArray()[i
];
609 if( nIndex
>= 0 && nIndex
< (sal_Int16
)pListWidget
->Entries
.size() )
610 pListWidget
->SelectedEntries
.push_back( nIndex
);
615 // --------------------------------
617 if ( _rpDescriptor
->getType() == ::vcl::PDFWriter::ComboBox
)
619 ::vcl::PDFWriter::ComboBoxWidget
* pComboWidget
= static_cast< ::vcl::PDFWriter::ComboBoxWidget
* >( _rpDescriptor
.get() );
620 // ............................
622 getStringItemVector( xModelProps
, pComboWidget
->Entries
);
623 // same reasoning as above
624 pComboWidget
->Sort
= false;
627 // ================================
628 // some post-processing
629 // --------------------------------
631 // some controls may (always or dependent on other settings) return UNIX line ends
632 String
aConverter( _rpDescriptor
->Text
);
633 _rpDescriptor
->Text
= aConverter
.ConvertLineEnd( LINEEND_CRLF
);
635 catch( const Exception
& )
637 OSL_ENSURE( sal_False
, "describePDFControl: caught an exception!" );
641 //........................................................................
642 } // namespace toolkitform
643 //........................................................................