fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / toolkit / source / helper / formpdfexport.cxx
blob6d4824acf30ee8c40fe7517d424b71b5d0932e26
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <toolkit/helper/formpdfexport.hxx>
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>
36 #include <toolkit/helper/vclunohelper.hxx>
37 #include <vcl/pdfextoutdevdata.hxx>
38 #include <vcl/outdev.hxx>
40 #include <functional>
41 #include <algorithm>
43 //........................................................................
44 namespace toolkitform
46 //........................................................................
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;
57 static const char FM_PROP_NAME[] = "Name";
59 namespace
61 //--------------------------------------------------------------------
62 /** determines the FormComponentType of a form control
64 sal_Int16 classifyFormControl( const Reference< XPropertySet >& _rxModel ) SAL_THROW(( Exception ))
66 static const OUString FM_PROP_CLASSID("ClassId");
67 sal_Int16 nControlType = FormComponentType::CONTROL;
69 Reference< XPropertySetInfo > xPSI;
70 if ( _rxModel.is() )
71 xPSI = _rxModel->getPropertySetInfo();
72 if ( xPSI.is() && xPSI->hasPropertyByName( FM_PROP_CLASSID ) )
74 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_CLASSID ) >>= nControlType );
77 return nControlType;
80 //--------------------------------------------------------------------
81 /** (default-)creates a PDF widget according to a given FormComponentType
83 ::vcl::PDFWriter::AnyWidget* createDefaultWidget( sal_Int16 _nFormComponentType )
85 switch ( _nFormComponentType )
87 case FormComponentType::COMMANDBUTTON:
88 return new ::vcl::PDFWriter::PushButtonWidget;
89 case FormComponentType::CHECKBOX:
90 return new ::vcl::PDFWriter::CheckBoxWidget;
91 case FormComponentType::RADIOBUTTON:
92 return new ::vcl::PDFWriter::RadioButtonWidget;
93 case FormComponentType::LISTBOX:
94 return new ::vcl::PDFWriter::ListBoxWidget;
95 case FormComponentType::COMBOBOX:
96 return new ::vcl::PDFWriter::ComboBoxWidget;
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 return new ::vcl::PDFWriter::EditWidget;
107 return NULL;
110 //--------------------------------------------------------------------
111 /** determines a unique number for the radio group which the given radio
112 button model belongs to
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>
120 @precond
121 the model must be part of the form component hierarchy in a document
123 sal_Int32 determineRadioGroupId( const Reference< XPropertySet >& _rxRadioModel ) SAL_THROW((Exception))
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.
135 // get the root-level container
136 Reference< XChild > xChild( _rxRadioModel, UNO_QUERY );
137 Reference< XForm > xParentForm( xChild.is() ? xChild->getParent() : Reference< XInterface >(), UNO_QUERY );
138 OSL_ENSURE( xParentForm.is(), "determineRadioGroupId: no parent form -> group id!" );
139 if ( !xParentForm.is() )
140 return -1;
142 while ( xParentForm.is() )
144 xChild = xParentForm.get();
145 xParentForm = xParentForm.query( xChild->getParent() );
147 Reference< XIndexAccess > xRoot( xChild->getParent(), UNO_QUERY );
148 OSL_ENSURE( xRoot.is(), "determineRadioGroupId: unable to determine the root of the form component hierarchy!" );
149 if ( !xRoot.is() )
150 return -1;
152 // count the leafs in the hierarchy, until we encounter radio button
153 ::std::vector< Reference< XIndexAccess > > aAncestors;
154 ::std::vector< sal_Int32 > aPath;
156 Reference< XInterface > xNormalizedLookup( _rxRadioModel, UNO_QUERY );
157 OUString sRadioGroupName;
158 OSL_VERIFY( _rxRadioModel->getPropertyValue( OUString(FM_PROP_NAME) ) >>= sRadioGroupName );
160 Reference< XIndexAccess > xCurrentContainer( xRoot );
161 sal_Int32 nStartWithChild = 0;
162 sal_Int32 nGroupsEncountered = 0;
165 Reference< XNameAccess > xElementNameAccess( xCurrentContainer, UNO_QUERY );
166 OSL_ENSURE( xElementNameAccess.is(), "determineRadioGroupId: no name container?" );
167 if ( !xElementNameAccess.is() )
168 return -1;
170 if ( nStartWithChild == 0 )
171 { // we encounter this container the first time. In particular, we did not
172 // just step up
173 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
180 sal_Int32 nCount = xCurrentContainer->getCount();
181 sal_Int32 i;
182 for ( i = nStartWithChild; i < nCount; ++i )
184 Reference< XInterface > xElement( xCurrentContainer->getByIndex( i ), UNO_QUERY );
185 if ( !xElement.is() )
187 OSL_FAIL( "determineRadioGroupId: very suspicious!" );
188 continue;
191 Reference< XIndexAccess > xNewContainer( xElement, UNO_QUERY );
192 if ( xNewContainer.is() )
194 // step down the hierarchy
195 aAncestors.push_back( xCurrentContainer );
196 xCurrentContainer = xNewContainer;
197 aPath.push_back( i );
198 nStartWithChild = 0;
199 break;
200 // out of the inner loop, but continue with the outer loop
203 if ( xElement.get() == xNormalizedLookup.get() )
205 // look up the name of the radio group in the list of all element names
206 Sequence< OUString > aElementNames( xElementNameAccess->getElementNames() );
207 const OUString* pElementNames = aElementNames.getConstArray();
208 const OUString* pElementNamesEnd = pElementNames + aElementNames.getLength();
209 while ( pElementNames != pElementNamesEnd )
211 if ( *pElementNames == sRadioGroupName )
213 sal_Int32 nLocalGroupIndex = pElementNames - aElementNames.getConstArray();
214 OSL_ENSURE( nLocalGroupIndex < xElementNameAccess->getElementNames().getLength(),
215 "determineRadioGroupId: inconsistency!" );
217 sal_Int32 nGlobalGroupId = nGroupsEncountered - xElementNameAccess->getElementNames().getLength() + nLocalGroupIndex;
218 return nGlobalGroupId;
220 ++pElementNames;
222 OSL_FAIL( "determineRadioGroupId: did not find the radios element name!" );
226 if ( !( i < nCount ) )
228 // the loop terminated because there were no more elements
229 // -> step up, if possible
230 if ( aAncestors.empty() )
231 break;
233 xCurrentContainer = aAncestors.back(); aAncestors.pop_back();
234 nStartWithChild = aPath.back() + 1; aPath.pop_back();
237 while ( true );
238 return -1;
241 //--------------------------------------------------------------------
242 /** copies a StringItemList to a PDF widget's list
244 void getStringItemVector( const Reference< XPropertySet >& _rxModel, ::std::vector< OUString >& _rVector )
246 static const OUString FM_PROP_STRINGITEMLIST("StringItemList");
247 Sequence< OUString > aListEntries;
248 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_STRINGITEMLIST ) >>= aListEntries );
249 ::std::copy( aListEntries.getConstArray(), aListEntries.getConstArray() + aListEntries.getLength(),
250 ::std::back_insert_iterator< ::std::vector< OUString > >( _rVector ) );
254 //--------------------------------------------------------------------
255 /** creates a PDF compatible control descriptor for the given control
257 void TOOLKIT_DLLPUBLIC describePDFControl( const Reference< XControl >& _rxControl,
258 ::std::auto_ptr< ::vcl::PDFWriter::AnyWidget >& _rpDescriptor, ::vcl::PDFExtOutDevData& i_pdfExportData ) SAL_THROW(())
260 _rpDescriptor.reset( NULL );
261 OSL_ENSURE( _rxControl.is(), "describePDFControl: invalid (NULL) control!" );
262 if ( !_rxControl.is() )
263 return;
267 Reference< XPropertySet > xModelProps( _rxControl->getModel(), UNO_QUERY );
268 sal_Int16 nControlType = classifyFormControl( xModelProps );
269 _rpDescriptor.reset( createDefaultWidget( nControlType ) );
270 if ( !_rpDescriptor.get() )
271 // no PDF widget available for this
272 return;
274 Reference< XPropertySetInfo > xPSI( xModelProps->getPropertySetInfo() );
275 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
280 // ================================
281 // set the common widget properties
283 // --------------------------------
284 // Name, Description, Text
285 OSL_VERIFY( xModelProps->getPropertyValue( OUString(FM_PROP_NAME) ) >>= _rpDescriptor->Name );
286 static const OUString FM_PROP_HELPTEXT("HelpText");
287 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_HELPTEXT ) >>= _rpDescriptor->Description );
288 Any aText;
289 static const OUString FM_PROP_TEXT("Text");
290 static const OUString FM_PROP_LABEL("Label");
291 if ( xPSI->hasPropertyByName( FM_PROP_TEXT ) )
292 aText = xModelProps->getPropertyValue( FM_PROP_TEXT );
293 else if ( xPSI->hasPropertyByName( FM_PROP_LABEL ) )
294 aText = xModelProps->getPropertyValue( FM_PROP_LABEL );
295 if ( aText.hasValue() )
296 OSL_VERIFY( aText >>= _rpDescriptor->Text );
298 // --------------------------------
299 // readonly
300 static const OUString FM_PROP_READONLY("ReadOnly");
301 if ( xPSI->hasPropertyByName( FM_PROP_READONLY ) )
302 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_READONLY ) >>= _rpDescriptor->ReadOnly );
304 // --------------------------------
305 // border
307 static const OUString FM_PROP_BORDER("Border");
308 if ( xPSI->hasPropertyByName( FM_PROP_BORDER ) )
310 sal_Int16 nBorderType = 0;
311 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_BORDER ) >>= nBorderType );
312 _rpDescriptor->Border = ( nBorderType != 0 );
314 OUString sBorderColorPropertyName( "BorderColor" );
315 if ( xPSI->hasPropertyByName( sBorderColorPropertyName ) )
317 sal_Int32 nBoderColor = COL_TRANSPARENT;
318 if ( xModelProps->getPropertyValue( sBorderColorPropertyName ) >>= nBoderColor )
319 _rpDescriptor->BorderColor = Color( nBoderColor );
320 else
321 _rpDescriptor->BorderColor = Color( COL_BLACK );
326 // --------------------------------
327 // background color
328 static const OUString FM_PROP_BACKGROUNDCOLOR("BackgroundColor");
329 if ( xPSI->hasPropertyByName( FM_PROP_BACKGROUNDCOLOR ) )
331 sal_Int32 nBackColor = COL_TRANSPARENT;
332 xModelProps->getPropertyValue( FM_PROP_BACKGROUNDCOLOR ) >>= nBackColor;
333 _rpDescriptor->Background = true;
334 _rpDescriptor->BackgroundColor = Color( nBackColor );
337 // --------------------------------
338 // text color
339 static const OUString FM_PROP_TEXTCOLOR("TextColor");
340 if ( xPSI->hasPropertyByName( FM_PROP_TEXTCOLOR ) )
342 sal_Int32 nTextColor = COL_TRANSPARENT;
343 xModelProps->getPropertyValue( FM_PROP_TEXTCOLOR ) >>= nTextColor;
344 _rpDescriptor->TextColor = Color( nTextColor );
347 // --------------------------------
348 // text style
349 _rpDescriptor->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 static const OUString FM_PROP_MULTILINE("MultiLine");
355 if ( xPSI->hasPropertyByName( FM_PROP_MULTILINE ) )
357 sal_Bool bMultiLine = sal_False;
358 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_MULTILINE ) >>= bMultiLine );
359 if ( bMultiLine )
360 _rpDescriptor->TextStyle |= TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK;
362 // ............................
363 // horizontal alignment
364 static const OUString FM_PROP_ALIGN("Align");
365 if ( xPSI->hasPropertyByName( FM_PROP_ALIGN ) )
367 sal_Int16 nAlign = awt::TextAlign::LEFT;
368 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 switch ( nAlign )
373 case awt::TextAlign::LEFT: _rpDescriptor->TextStyle |= TEXT_DRAW_LEFT; break;
374 case awt::TextAlign::CENTER: _rpDescriptor->TextStyle |= TEXT_DRAW_CENTER; break;
375 case awt::TextAlign::RIGHT: _rpDescriptor->TextStyle |= TEXT_DRAW_RIGHT; break;
376 default:
377 OSL_FAIL( "describePDFControl: invalid text align!" );
380 // ............................
381 // vertical alignment
383 OUString sVertAlignPropertyName( "VerticalAlign" );
384 if ( xPSI->hasPropertyByName( sVertAlignPropertyName ) )
386 sal_Int16 nAlign = VerticalAlignment_MIDDLE;
387 xModelProps->getPropertyValue( sVertAlignPropertyName ) >>= nAlign;
388 switch ( nAlign )
390 case VerticalAlignment_TOP: _rpDescriptor->TextStyle |= TEXT_DRAW_TOP; break;
391 case VerticalAlignment_MIDDLE: _rpDescriptor->TextStyle |= TEXT_DRAW_VCENTER; break;
392 case VerticalAlignment_BOTTOM: _rpDescriptor->TextStyle |= TEXT_DRAW_BOTTOM; break;
393 default:
394 OSL_FAIL( "describePDFControl: invalid vertical text align!" );
399 // font
400 static const OUString FM_PROP_FONT("FontDescriptor");
401 if ( xPSI->hasPropertyByName( FM_PROP_FONT ) )
403 FontDescriptor aUNOFont;
404 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_FONT ) >>= aUNOFont );
405 _rpDescriptor->TextFont = VCLUnoHelper::CreateFont( aUNOFont, Font() );
408 // tab order
409 OUString aTabIndexString( "TabIndex" );
410 if ( xPSI->hasPropertyByName( aTabIndexString ) )
412 sal_Int16 nIndex = -1;
413 OSL_VERIFY( xModelProps->getPropertyValue( aTabIndexString ) >>= nIndex );
414 _rpDescriptor->TabOrder = nIndex;
417 // ================================
418 // special widget properties
419 // --------------------------------
420 // edits
421 if ( _rpDescriptor->getType() == ::vcl::PDFWriter::Edit )
423 ::vcl::PDFWriter::EditWidget* pEditWidget = static_cast< ::vcl::PDFWriter::EditWidget* >( _rpDescriptor.get() );
424 // ............................
425 // multiline (already flagged in the TextStyle)
426 pEditWidget->MultiLine = ( _rpDescriptor->TextStyle & TEXT_DRAW_MULTILINE ) != 0;
427 // ............................
428 // password input
429 OUString sEchoCharPropName( "EchoChar" );
430 if ( xPSI->hasPropertyByName( sEchoCharPropName ) )
432 sal_Int16 nEchoChar = 0;
433 if ( ( xModelProps->getPropertyValue( sEchoCharPropName ) >>= nEchoChar ) && ( nEchoChar != 0 ) )
434 pEditWidget->Password = true;
436 // ............................
437 // file select
438 static const OUString FM_SUN_COMPONENT_FILECONTROL("com.sun.star.form.component.FileControl");
439 if ( xSI->supportsService( FM_SUN_COMPONENT_FILECONTROL ) )
440 pEditWidget->FileSelect = true;
441 // ............................
442 // maximum text length
443 static const OUString FM_PROP_MAXTEXTLEN("MaxTextLen");
444 if ( xPSI->hasPropertyByName( FM_PROP_MAXTEXTLEN ) )
446 sal_Int16 nMaxTextLength = 0;
447 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_MAXTEXTLEN ) >>= nMaxTextLength );
448 if ( nMaxTextLength <= 0 )
449 // "-1" has a special meaning for database-bound controls
450 nMaxTextLength = 0;
451 pEditWidget->MaxLen = nMaxTextLength;
455 // --------------------------------
456 // buttons
457 if ( _rpDescriptor->getType() == ::vcl::PDFWriter::PushButton )
459 ::vcl::PDFWriter::PushButtonWidget* pButtonWidget = static_cast< ::vcl::PDFWriter::PushButtonWidget* >( _rpDescriptor.get() );
460 FormButtonType eButtonType = FormButtonType_PUSH;
461 OSL_VERIFY( xModelProps->getPropertyValue( OUString( "ButtonType" ) ) >>= eButtonType );
462 static const OUString FM_PROP_TARGET_URL("TargetURL");
463 if ( eButtonType == FormButtonType_SUBMIT )
465 // if a button is a submit button, then it uses the URL at it's parent form
466 Reference< XChild > xChild( xModelProps, UNO_QUERY );
467 Reference < XPropertySet > xParentProps;
468 if ( xChild.is() )
469 xParentProps = xParentProps.query( xChild->getParent() );
470 if ( xParentProps.is() )
472 Reference< XServiceInfo > xParentSI( xParentProps, UNO_QUERY );
473 if ( xParentSI.is() && xParentSI->supportsService( OUString( "com.sun.star.form.component.HTMLForm" ) ) )
475 OSL_VERIFY( xParentProps->getPropertyValue( FM_PROP_TARGET_URL ) >>= pButtonWidget->URL );
476 pButtonWidget->Submit = true;
477 FormSubmitMethod eMethod = FormSubmitMethod_POST;
478 OSL_VERIFY( xParentProps->getPropertyValue( OUString( "SubmitMethod" ) ) >>= eMethod );
479 pButtonWidget->SubmitGet = (eMethod == FormSubmitMethod_GET);
483 else if ( eButtonType == FormButtonType_URL )
485 OUString sURL;
486 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_TARGET_URL ) >>= sURL );
487 const bool bDocumentLocalTarget = !sURL.isEmpty() && ( sURL.getStr()[0] == '#' );
488 if ( bDocumentLocalTarget )
490 // Register the destination for for future handling ...
491 pButtonWidget->Dest = i_pdfExportData.RegisterDest();
493 // and put it into the bookmarks, to ensure the future handling really happens
494 ::std::vector< ::vcl::PDFExtOutDevBookmarkEntry >& rBookmarks( i_pdfExportData.GetBookmarks() );
495 ::vcl::PDFExtOutDevBookmarkEntry aBookmark;
496 aBookmark.nDestId = pButtonWidget->Dest;
497 aBookmark.aBookmark = sURL;
498 rBookmarks.push_back( aBookmark );
500 else
501 pButtonWidget->URL = sURL;
503 pButtonWidget->Submit = false;
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 _rpDescriptor to NULL here, in case eButtonType
511 // != FormButtonType_SUBMIT && != FormButtonType_RESET
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 if ( !pButtonWidget->TextStyle )
516 pButtonWidget->TextStyle = TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER;
519 // --------------------------------
520 // check boxes
521 static const OUString FM_PROP_STATE("State");
522 if ( _rpDescriptor->getType() == ::vcl::PDFWriter::CheckBox )
524 ::vcl::PDFWriter::CheckBoxWidget* pCheckBoxWidget = static_cast< ::vcl::PDFWriter::CheckBoxWidget* >( _rpDescriptor.get() );
525 sal_Int16 nState = 0;
526 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_STATE ) >>= nState );
527 pCheckBoxWidget->Checked = ( nState != 0 );
530 // --------------------------------
531 // radio buttons
532 if ( _rpDescriptor->getType() == ::vcl::PDFWriter::RadioButton )
534 ::vcl::PDFWriter::RadioButtonWidget* pRadioWidget = static_cast< ::vcl::PDFWriter::RadioButtonWidget* >( _rpDescriptor.get() );
535 sal_Int16 nState = 0;
536 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_STATE ) >>= nState );
537 pRadioWidget->Selected = ( nState != 0 );
538 pRadioWidget->RadioGroup = determineRadioGroupId( xModelProps );
541 static const OUString FM_PROP_REFVALUE("RefValue");
542 xModelProps->getPropertyValue( FM_PROP_REFVALUE ) >>= pRadioWidget->OnValue;
544 catch(...)
546 pRadioWidget->OnValue = OUString( "On" );
550 // --------------------------------
551 // list boxes
552 if ( _rpDescriptor->getType() == ::vcl::PDFWriter::ListBox )
554 ::vcl::PDFWriter::ListBoxWidget* pListWidget = static_cast< ::vcl::PDFWriter::ListBoxWidget* >( _rpDescriptor.get() );
555 // ............................
556 // drop down
557 static const OUString FM_PROP_DROPDOWN("Dropdown");
558 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_DROPDOWN ) >>= pListWidget->DropDown );
559 // ............................
560 // multi selection
561 OSL_VERIFY( xModelProps->getPropertyValue( OUString( "MultiSelection" ) ) >>= pListWidget->MultiSelect );
562 // ............................
563 // entries
564 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 pListWidget->Sort = false;
569 // get selected items
570 Sequence< sal_Int16 > aSelectIndices;
571 OSL_VERIFY( xModelProps->getPropertyValue( OUString( "SelectedItems" ) ) >>= aSelectIndices );
572 if( aSelectIndices.getLength() > 0 )
574 pListWidget->SelectedEntries.resize( 0 );
575 for( sal_Int32 i = 0; i < aSelectIndices.getLength(); i++ )
577 sal_Int16 nIndex = aSelectIndices.getConstArray()[i];
578 if( nIndex >= 0 && nIndex < (sal_Int16)pListWidget->Entries.size() )
579 pListWidget->SelectedEntries.push_back( nIndex );
584 // --------------------------------
585 // combo boxes
586 if ( _rpDescriptor->getType() == ::vcl::PDFWriter::ComboBox )
588 ::vcl::PDFWriter::ComboBoxWidget* pComboWidget = static_cast< ::vcl::PDFWriter::ComboBoxWidget* >( _rpDescriptor.get() );
589 // ............................
590 // entries
591 getStringItemVector( xModelProps, pComboWidget->Entries );
592 // same reasoning as above
593 pComboWidget->Sort = false;
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 _rpDescriptor->Text = convertLineEnd(_rpDescriptor->Text, LINEEND_CRLF);
603 catch( const Exception& )
605 OSL_FAIL( "describePDFControl: caught an exception!" );
609 //........................................................................
610 } // namespace toolkitform
611 //........................................................................
613 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */