25#include <unordered_map>
28#include <com/sun/star/container/XIndexAccess.hpp>
29#include <com/sun/star/form/XForm.hpp>
30#include <com/sun/star/container/XChild.hpp>
31#include <com/sun/star/lang/XServiceInfo.hpp>
32#include <com/sun/star/beans/XPropertySet.hpp>
33#include <com/sun/star/form/FormComponentType.hpp>
34#include <com/sun/star/awt/TextAlign.hpp>
35#include <com/sun/star/awt/XControl.hpp>
36#include <com/sun/star/style/VerticalAlignment.hpp>
37#include <com/sun/star/form/FormButtonType.hpp>
38#include <com/sun/star/form/FormSubmitMethod.hpp>
51 if ( !rDescr.Name.isEmpty() )
53 if ( !rDescr.StyleName.isEmpty() )
59 if (
static_cast<rtl_TextEncoding
>(rDescr.CharSet) != RTL_TEXTENCODING_DONTKNOW )
60 aFont.
SetCharSet(
static_cast<rtl_TextEncoding
>(rDescr.CharSet) );
63 if ( rDescr.CharacterWidth )
67 if ( rDescr.Slant != css::awt::FontSlant_DONTKNOW )
102 sal_Int16 classifyFormControl(
const Reference< XPropertySet >& _rxModel )
105 sal_Int16 nControlType = FormComponentType::CONTROL;
107 Reference< XPropertySetInfo > xPSI;
109 xPSI = _rxModel->getPropertySetInfo();
112 if( ! (_rxModel->getPropertyValue(
FM_PROP_CLASSID ) >>= nControlType) ) {
123 std::unique_ptr<vcl::PDFWriter::AnyWidget> createDefaultWidget( sal_Int16 _nFormComponentType )
125 switch ( _nFormComponentType )
127 case FormComponentType::COMMANDBUTTON:
128 return std::make_unique<vcl::PDFWriter::PushButtonWidget>();
129 case FormComponentType::CHECKBOX:
130 return std::make_unique<vcl::PDFWriter::CheckBoxWidget>();
131 case FormComponentType::RADIOBUTTON:
132 return std::make_unique<vcl::PDFWriter::RadioButtonWidget>();
133 case FormComponentType::LISTBOX:
134 return std::make_unique<vcl::PDFWriter::ListBoxWidget>();
135 case FormComponentType::COMBOBOX:
136 return std::make_unique<vcl::PDFWriter::ComboBoxWidget>();
138 case FormComponentType::TEXTFIELD:
139 case FormComponentType::FILECONTROL:
140 case FormComponentType::DATEFIELD:
141 case FormComponentType::TIMEFIELD:
142 case FormComponentType::NUMERICFIELD:
143 case FormComponentType::CURRENCYFIELD:
144 case FormComponentType::PATTERNFIELD:
145 return std::make_unique<vcl::PDFWriter::EditWidget>();
163 sal_Int32 determineRadioGroupId(
const Reference< XPropertySet >& _rxRadioModel )
165 OSL_ENSURE( classifyFormControl( _rxRadioModel ) == FormComponentType::RADIOBUTTON,
166 "determineRadioGroupId: this *is* no radio button model!" );
176 Reference< XChild > xChild( _rxRadioModel, UNO_QUERY );
177 Reference< XForm > xParentForm( xChild.is() ? xChild->getParent() : Reference< XInterface >(), UNO_QUERY );
178 OSL_ENSURE( xParentForm.is(),
"determineRadioGroupId: no parent form -> group id!" );
179 if ( !xParentForm.is() )
182 while ( xParentForm.is() )
184 xChild = xParentForm.get();
185 xParentForm.set(xChild->getParent(), css::uno::UNO_QUERY);
187 Reference< XIndexAccess > xRoot( xChild->getParent(), UNO_QUERY );
188 OSL_ENSURE( xRoot.is(),
"determineRadioGroupId: unable to determine the root of the form component hierarchy!" );
193 ::std::vector< Reference< XIndexAccess > > aAncestors;
194 ::std::vector< sal_Int32 > aPath;
196 Reference< XInterface > xNormalizedLookup( _rxRadioModel, UNO_QUERY );
197 Reference< XIndexAccess > xCurrentContainer( xRoot );
198 sal_Int32 nStartWithChild = 0;
199 sal_Int32 nGroupsEncountered = 0;
202 std::unordered_map<OUString,sal_Int32> GroupNameMap;
203 std::unordered_map<OUString,sal_Int32> SharedNameMap;
204 sal_Int32
nCount = xCurrentContainer->getCount();
206 for (
i = nStartWithChild;
i <
nCount; ++
i )
208 Reference< XInterface > xElement( xCurrentContainer->getByIndex(
i ), UNO_QUERY );
209 if ( !xElement.is() )
211 OSL_FAIL(
"determineRadioGroupId: very suspicious!" );
215 Reference< XIndexAccess > xNewContainer( xElement, UNO_QUERY );
216 if ( xNewContainer.is() )
219 aAncestors.push_back( xCurrentContainer );
220 xCurrentContainer = xNewContainer;
221 aPath.push_back(
i );
227 if ( xElement.get() == xNormalizedLookup.get() )
235 xElement.set( xCurrentContainer->getByIndex(
i ), UNO_QUERY_THROW );
236 Reference< XServiceInfo > xModelSI( xElement, UNO_QUERY_THROW );
237 if ( xModelSI->supportsService(
"com.sun.star.awt.UnoControlRadioButtonModel") )
239 Reference< XPropertySet > aProps( xElement, UNO_QUERY_THROW );
242 aProps->getPropertyValue(
"GroupName") >>= sGroupName;
243 if ( !sGroupName.isEmpty() )
247 GroupNameMap.emplace( sGroupName, nGroupsEncountered +
i );
249 if ( xElement.get() == xNormalizedLookup.get() )
250 return GroupNameMap[sGroupName];
255 aProps->getPropertyValue(
FM_PROP_NAME ) >>= sGroupName;
256 SharedNameMap.emplace( sGroupName, nGroupsEncountered +
i );
258 if ( xElement.get() == xNormalizedLookup.get() )
259 return SharedNameMap[sGroupName];
264 catch( uno::Exception& )
269 SAL_WARN(
"toolkit.helper",
"determineRadioGroupId: did not find the radios element's group!" );
274 if ( nStartWithChild == 0 )
280 nGroupsEncountered +=
nCount;
287 if ( aAncestors.empty() )
290 xCurrentContainer = aAncestors.back(); aAncestors.pop_back();
291 nStartWithChild = aPath.back() + 1; aPath.pop_back();
301 void getStringItemVector(
const Reference< XPropertySet >& _rxModel, ::std::vector< OUString >& _rVector )
303 Sequence< OUString > aListEntries;
304 if( ! (_rxModel->getPropertyValue(
"StringItemList" ) >>= aListEntries) ) {
305 SAL_WARN(
"toolkit.helper",
"getStringItemVector: unable to get property StringItemList");
307 _rVector.insert( _rVector.end(), std::cbegin(aListEntries), std::cend(aListEntries) );
314 std::unique_ptr<vcl::PDFWriter::AnyWidget>
describePDFControl(
const Reference< XControl >& _rxControl,
317 std::unique_ptr<vcl::PDFWriter::AnyWidget> Descriptor;
318 OSL_ENSURE( _rxControl.is(),
"describePDFControl: invalid (NULL) control!" );
319 if ( !_rxControl.is() )
324 Reference< XPropertySet > xModelProps( _rxControl->getModel(), UNO_QUERY );
325 sal_Int16 nControlType = classifyFormControl( xModelProps );
326 Descriptor = createDefaultWidget( nControlType );
331 Reference< XPropertySetInfo > xPSI( xModelProps->getPropertySetInfo() );
332 Reference< XServiceInfo > xSI( xModelProps, UNO_QUERY );
333 OSL_ENSURE( xSI.is(),
"describePDFControl: no service info!" );
342 if( ! (xModelProps->getPropertyValue(
FM_PROP_NAME ) >>= Descriptor->Name) ) {
345 if( ! (xModelProps->getPropertyValue(
"HelpText" ) >>= Descriptor->Description) ) {
346 SAL_INFO(
"toolkit.helper",
"describePDFControl: unable to get property HelpText");
359 if (xModelProps->getPropertyValue(
FM_PROP_VALUE ) >>= aValue)
360 aText <<= OUString::number(aValue);
363 if ( aText.hasValue() ) {
364 if( ! (aText >>= Descriptor->Text) ) {
365 SAL_WARN(
"toolkit.helper",
"describePDFControl: unable to assign aText to Descriptor->Text");
373 if( ! (xModelProps->getPropertyValue(
FM_PROP_READONLY ) >>= Descriptor->ReadOnly) )
382 sal_Int16 nBorderType = 0;
383 if( ! (xModelProps->getPropertyValue(
FM_PROP_BORDER ) >>= nBorderType) )
385 Descriptor->Border = ( nBorderType != 0 );
387 OUString sBorderColorPropertyName(
"BorderColor" );
388 if ( xPSI->hasPropertyByName( sBorderColorPropertyName ) )
391 if ( xModelProps->getPropertyValue( sBorderColorPropertyName ) >>= nBorderColor )
392 Descriptor->BorderColor = nBorderColor;
406 Descriptor->Background =
true;
407 Descriptor->BackgroundColor = nBackColor;
417 Descriptor->TextColor = nTextColor;
430 bool bMultiLine =
false;
441 sal_Int16 nAlign = awt::TextAlign::LEFT;
451 OSL_FAIL(
"describePDFControl: invalid text align!" );
457 OUString sVertAlignPropertyName(
"VerticalAlign" );
458 if ( xPSI->hasPropertyByName( sVertAlignPropertyName ) )
460 VerticalAlignment nAlign = VerticalAlignment_MIDDLE;
461 xModelProps->getPropertyValue( sVertAlignPropertyName ) >>= nAlign;
468 OSL_FAIL(
"describePDFControl: invalid vertical text align!" );
474 static constexpr OUStringLiteral
FM_PROP_FONT =
u"FontDescriptor";
477 FontDescriptor aUNOFont;
478 if( ! (xModelProps->getPropertyValue(
FM_PROP_FONT ) >>= aUNOFont) )
480 Descriptor->TextFont =
CreateFont( aUNOFont );
484 OUString aTabIndexString(
"TabIndex" );
485 if ( xPSI->hasPropertyByName( aTabIndexString ) )
488 if( ! (xModelProps->getPropertyValue( aTabIndexString ) >>=
nIndex) )
489 SAL_WARN(
"toolkit.helper",
"describePDFControl: unable to get property " << aTabIndexString);
490 Descriptor->TabOrder =
nIndex;
505 OUString sEchoCharPropName(
"EchoChar" );
506 if ( xPSI->hasPropertyByName( sEchoCharPropName ) )
508 sal_Int16 nEchoChar = 0;
509 if ( ( xModelProps->getPropertyValue( sEchoCharPropName ) >>= nEchoChar ) && ( nEchoChar != 0 ) )
514 if ( xSI->supportsService(
"com.sun.star.form.component.FileControl" ) )
521 sal_Int16 nMaxTextLength = 0;
524 if ( nMaxTextLength <= 0 )
527 pEditWidget->
MaxLen = nMaxTextLength;
530 switch ( nControlType )
532 case FormComponentType::CURRENCYFIELD:
533 case FormComponentType::NUMERICFIELD:
541 OUString sCurrencySymbol;
547 static constexpr OUStringLiteral FM_PROP_DECIMALACCURACY =
u"DecimalAccuracy";
548 if ( xPSI->hasPropertyByName( FM_PROP_DECIMALACCURACY ) )
550 sal_Int32 nDecimalAccuracy = 0;
551 if( ! (xModelProps->getPropertyValue( FM_PROP_DECIMALACCURACY ) >>= nDecimalAccuracy) )
552 SAL_WARN(
"toolkit.helper",
"describePDFControl: unable to get property " << FM_PROP_DECIMALACCURACY);
556 static constexpr OUStringLiteral FM_PROP_PREPENDCURRENCYSYMBOL =
u"PrependCurrencySymbol";
557 if ( xPSI->hasPropertyByName( FM_PROP_PREPENDCURRENCYSYMBOL ) )
559 bool bPrependCurrencySymbol =
true;
560 if( ! (xModelProps->getPropertyValue( FM_PROP_PREPENDCURRENCYSYMBOL ) >>= bPrependCurrencySymbol) )
561 SAL_WARN(
"toolkit.helper",
"describePDFControl: unable to get property " << FM_PROP_PREPENDCURRENCYSYMBOL);
565 case FormComponentType::TIMEFIELD:
572 sal_Int32 nTimeFormat = 0;
576 switch ( nTimeFormat )
593 case FormComponentType::DATEFIELD:
600 sal_Int32 nDateFormat = 0;
604 switch ( nDateFormat )
648 FormButtonType eButtonType = FormButtonType_PUSH;
649 if( ! (xModelProps->getPropertyValue(
"ButtonType") >>= eButtonType) )
650 SAL_WARN(
"toolkit.helper",
"describePDFControl: unable to get property ButtonType");
652 if ( eButtonType == FormButtonType_SUBMIT )
655 Reference< XChild > xChild( xModelProps, UNO_QUERY );
656 Reference < XPropertySet > xParentProps;
658 xParentProps.set(xChild->getParent(), css::uno::UNO_QUERY);
659 if ( xParentProps.is() )
661 Reference< XServiceInfo > xParentSI( xParentProps, UNO_QUERY );
662 if ( xParentSI.is() && xParentSI->supportsService(
"com.sun.star.form.component.HTMLForm") )
666 pButtonWidget->
Submit =
true;
667 FormSubmitMethod eMethod = FormSubmitMethod_POST;
668 if( ! (xParentProps->getPropertyValue(
"SubmitMethod") >>= eMethod) )
670 pButtonWidget->
SubmitGet = (eMethod == FormSubmitMethod_GET);
674 else if ( eButtonType == FormButtonType_URL )
679 const bool bDocumentLocalTarget = sURL.startsWith(
"#");
680 if ( bDocumentLocalTarget )
686 ::std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks( i_pdfExportData.
GetBookmarks() );
690 rBookmarks.push_back( aBookmark );
693 pButtonWidget->
URL = sURL;
695 pButtonWidget->
Submit =
false;
724 xModelProps->getPropertyValue(
"RefValue" ) >>= pCheckBoxWidget->
OnValue;
732 xModelProps->getPropertyValue(
"SecondaryRefValue" ) >>= pCheckBoxWidget->
OffValue;
748 pRadioWidget->
RadioGroup = determineRadioGroupId( xModelProps );
751 xModelProps->getPropertyValue(
"RefValue" ) >>= pRadioWidget->
OnValue;
759 xModelProps->getPropertyValue(
"SecondaryRefValue" ) >>= pRadioWidget->
OffValue;
773 if( ! (xModelProps->getPropertyValue(
"Dropdown" ) >>= pListWidget->
DropDown) )
774 SAL_WARN(
"toolkit.helper",
"describePDFControl: unable to get property Dropdown");
777 if( ! (xModelProps->getPropertyValue(
"MultiSelection") >>= pListWidget->
MultiSelect) )
778 SAL_WARN(
"toolkit.helper",
"describePDFControl: unable to get property MultiSelection");
781 getStringItemVector( xModelProps, pListWidget->
Entries );
784 Sequence< sal_Int16 > aSelectIndices;
785 if( ! (xModelProps->getPropertyValue(
"SelectedItems") >>= aSelectIndices) )
786 SAL_WARN(
"toolkit.helper",
"describePDFControl: unable to get property SelectedItems");
787 if( aSelectIndices.hasElements() )
790 auto nEntriesSize =
static_cast<sal_Int16
>(pListWidget->
Entries.size());
791 std::copy_if(std::cbegin(aSelectIndices), std::cend(aSelectIndices), std::back_inserter(pListWidget->
SelectedEntries),
792 [&nEntriesSize](
const sal_Int16
nIndex) { return nIndex >= 0 && nIndex < nEntriesSize; });
803 getStringItemVector( xModelProps, pComboWidget->
Entries );
void SetFontSize(const Size &)
void SetOrientation(Degree10 nLineOrientation)
void SetWidthType(FontWidth)
void SetStyleName(const OUString &rStyleName)
void SetWordLineMode(bool bWordLine)
void SetPitch(FontPitch ePitch)
void SetItalic(FontItalic)
void SetWeight(FontWeight)
void SetFamily(FontFamily)
void SetUnderline(FontLineStyle)
void SetCharSet(rtl_TextEncoding)
void SetKerning(FontKerning nKerning)
void SetFamilyName(const OUString &rFamilyName)
void SetStrikeout(FontStrikeout)
std::vector< PDFExtOutDevBookmarkEntry > & GetBookmarks()
sal_Int32 RegisterDest()
registers a destination for which a destination ID needs to be known immediately, instead of later on...
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
constexpr ::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
constexpr OUStringLiteral FM_PROP_READONLY
constexpr OUStringLiteral FM_PROP_DATEFORMAT
constexpr OUStringLiteral FM_PROP_CLASSID
#define FM_PROP_BACKGROUNDCOLOR
constexpr OUStringLiteral FM_PROP_TIMEFORMAT
constexpr OUStringLiteral FM_PROP_MULTILINE
constexpr OUStringLiteral FM_PROP_LABEL
constexpr OUStringLiteral FM_PROP_TEXT
constexpr OUStringLiteral FM_PROP_TARGET_URL
constexpr OUStringLiteral FM_PROP_ALIGN
#define FM_PROP_TEXTCOLOR
constexpr OUStringLiteral FM_PROP_STATE
constexpr OUStringLiteral FM_PROP_FONT
constexpr OUStringLiteral FM_PROP_BORDER
constexpr OUStringLiteral FM_PROP_MAXTEXTLEN
constexpr OUStringLiteral FM_PROP_VALUE
constexpr OUStringLiteral FM_PROP_CURRENCYSYMBOL
TOOLS_DLLPUBLIC OString convertLineEnd(const OString &rIn, LineEnd eLineEnd)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
VCL_DLLPUBLIC css::awt::FontSlant ConvertFontSlant(FontItalic eWeight)
VCL_DLLPUBLIC float ConvertFontWidth(FontWidth eWidth)
VCL_DLLPUBLIC float ConvertFontWeight(FontWeight eWeight)
OUString aBookmark
link target name, respectively destination name
sal_Int32 nDestId
ID of the named destination denoted by the bookmark, or -1 if the entry denotes a link instead of a n...