merge the formfield patch from ooo-build
[ooovba.git] / toolkit / source / helper / formpdfexport.cxx
blobd9903f41be537c6c57324d422b6cdf3e51cac68a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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>
37 #endif
39 /** === begin UNO includes === **/
40 #ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_
41 #include <com/sun/star/container/XIndexAccess.hpp>
42 #endif
43 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
44 #include <com/sun/star/container/XNameAccess.hpp>
45 #endif
46 #ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
47 #include <com/sun/star/container/XNameContainer.hpp>
48 #endif
49 #ifndef _COM_SUN_STAR_FORM_XFORM_HPP_
50 #include <com/sun/star/form/XForm.hpp>
51 #endif
52 #ifndef _COM_SUN_STAR_CONTAINER_XCHILD_HPP_
53 #include <com/sun/star/container/XChild.hpp>
54 #endif
55 #ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
56 #include <com/sun/star/lang/XServiceInfo.hpp>
57 #endif
58 #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
59 #include <com/sun/star/beans/XPropertySet.hpp>
60 #endif
61 #ifndef _COM_SUN_STAR_FORM_FORMCOMPONENTTYPE_HPP_
62 #include <com/sun/star/form/FormComponentType.hpp>
63 #endif
64 #ifndef _COM_SUN_STAR_AWT_TEXTALIGN_HPP_
65 #include <com/sun/star/awt/TextAlign.hpp>
66 #endif
67 #ifndef _COM_SUN_STAR_STYLE_VERTICALALIGNMENT_HPP_
68 #include <com/sun/star/style/VerticalAlignment.hpp>
69 #endif
70 #ifndef _COM_SUN_STAR_FORM_FORMBUTTONTYPE_HPP_
71 #include <com/sun/star/form/FormButtonType.hpp>
72 #endif
73 #ifndef _COM_SUN_STAR_FORM_SUBMITMETHOD_HPP_
74 #include <com/sun/star/form/FormSubmitMethod.hpp>
75 #endif
76 /** === end UNO includes === **/
78 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
79 #include <toolkit/helper/vclunohelper.hxx>
80 #endif
81 #ifndef _VCL_PDFEXTOUTDEVDATA_HXX
82 #include <vcl/pdfextoutdevdata.hxx>
83 #endif
84 #ifndef _SV_OUTDEV_HXX
85 #include <vcl/outdev.hxx>
86 #endif
88 #include <functional>
89 #include <algorithm>
91 //........................................................................
92 namespace toolkitform
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;
105 // used strings
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"));
126 namespace
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;
136 if ( _rxModel.is() )
137 xPSI = _rxModel->getPropertySetInfo();
138 if ( xPSI.is() && xPSI->hasPropertyByName( FM_PROP_CLASSID ) )
140 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_CLASSID ) >>= nControlType );
143 return 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;
173 return NULL;
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>
184 </ul>
186 @precond
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() )
206 return -1;
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!" );
215 if ( !xRoot.is() )
216 return -1;
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() )
234 return -1;
236 if ( nStartWithChild == 0 )
237 { // we encounter this container the first time. In particular, we did not
238 // just step up
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*
243 // that much groups
246 sal_Int32 nCount = xCurrentContainer->getCount();
247 sal_Int32 i;
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!" );
254 continue;
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 );
264 nStartWithChild = 0;
265 break;
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;
286 ++pElementNames;
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() )
297 break;
299 xCurrentContainer = aAncestors.back(); aAncestors.pop_back();
300 nStartWithChild = aPath.back() + 1; aPath.pop_back();
303 while ( true );
304 return -1;
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() )
327 return;
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
336 return;
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
342 // service infos
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 );
351 Any aText;
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 // --------------------------------
360 // readonly
361 if ( xPSI->hasPropertyByName( FM_PROP_READONLY ) )
362 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_READONLY ) >>= _rpDescriptor->ReadOnly );
364 // --------------------------------
365 // border
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 );
379 else
380 _rpDescriptor->BorderColor = Color( COL_BLACK );
385 // --------------------------------
386 // background color
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 // --------------------------------
396 // text color
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 // --------------------------------
405 // text style
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 );
415 if ( 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?
426 switch ( nAlign )
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;
431 default:
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;
443 switch ( 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;
448 default:
449 OSL_ENSURE( sal_False, "describePDFControl: invalid vertical text align!" );
454 // font
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() );
462 // tab order
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 // --------------------------------
474 // edits
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 // ............................
482 // password input
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 // ............................
491 // file select
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
502 nMaxTextLength = 0;
503 pEditWidget->MaxLen = nMaxTextLength;
507 // --------------------------------
508 // buttons
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;
519 if ( xChild.is() )
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;
540 // TODO:
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 // --------------------------------
554 // check boxes
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 // --------------------------------
564 // radio buttons
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;
576 catch(...)
578 pRadioWidget->OnValue = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "On" ) );
582 // --------------------------------
583 // list boxes
584 if ( _rpDescriptor->getType() == ::vcl::PDFWriter::ListBox )
586 ::vcl::PDFWriter::ListBoxWidget* pListWidget = static_cast< ::vcl::PDFWriter::ListBoxWidget* >( _rpDescriptor.get() );
587 // ............................
588 // drop down
589 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_DROPDOWN ) >>= pListWidget->DropDown );
590 // ............................
591 // multi selection
592 OSL_VERIFY( xModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MultiSelection" ) ) ) >>= pListWidget->MultiSelect );
593 // ............................
594 // entries
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 // --------------------------------
616 // combo boxes
617 if ( _rpDescriptor->getType() == ::vcl::PDFWriter::ComboBox )
619 ::vcl::PDFWriter::ComboBoxWidget* pComboWidget = static_cast< ::vcl::PDFWriter::ComboBoxWidget* >( _rpDescriptor.get() );
620 // ............................
621 // entries
622 getStringItemVector( xModelProps, pComboWidget->Entries );
623 // same reasoning as above
624 pComboWidget->Sort = false;
627 // ================================
628 // some post-processing
629 // --------------------------------
630 // text line ends
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 //........................................................................