1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
20 #include "elementexport.hxx"
22 #include "strings.hxx"
24 #include <xmloff/xmlnamespace.hxx>
25 #include "eventexport.hxx"
26 #include "formenums.hxx"
27 #include "formcellbinding.hxx"
28 #include <xmloff/xformsexport.hxx>
29 #include "property_meta_data.hxx"
31 #include <com/sun/star/text/XText.hpp>
32 #include <com/sun/star/lang/XServiceInfo.hpp>
33 #include <com/sun/star/io/XPersistObject.hpp>
34 #include <com/sun/star/util/Duration.hpp>
35 #include <com/sun/star/form/FormComponentType.hpp>
36 #include <com/sun/star/form/FormSubmitEncoding.hpp>
37 #include <com/sun/star/form/FormSubmitMethod.hpp>
38 #include <com/sun/star/sdb/CommandType.hpp>
39 #include <com/sun/star/form/NavigationBarMode.hpp>
40 #include <com/sun/star/form/TabulatorCycle.hpp>
41 #include <com/sun/star/form/FormButtonType.hpp>
42 #include <com/sun/star/awt/ScrollBarOrientation.hpp>
43 #include <com/sun/star/awt/VisualEffect.hpp>
44 #include <com/sun/star/form/ListSourceType.hpp>
45 #include <com/sun/star/awt/ImagePosition.hpp>
47 #include <sax/tools/converter.hxx>
48 #include <tools/gen.hxx>
49 #include <xmloff/txtprmap.hxx>
50 #include <com/sun/star/form/binding/XBindableValue.hpp>
51 #include <com/sun/star/form/binding/XListEntrySink.hpp>
52 #include <tools/urlobj.hxx>
53 #include <xmloff/xmlexp.hxx>
54 #include <xmloff/namespacemap.hxx>
55 #include <xmloff/XMLEventExport.hxx>
56 #include <xmloff/xmluconv.hxx>
57 #include <xmloff/xmltoken.hxx>
58 #include <xmloff/maptype.hxx>
59 #include <tools/time.hxx>
60 #include <comphelper/diagnose_ex.hxx>
61 #include <comphelper/extract.hxx>
62 #include <sal/log.hxx>
69 #if OSL_DEBUG_LEVEL > 0
70 #define RESET_BIT( bitfield, bit ) \
71 bitfield = bitfield & ~bit
73 #define RESET_BIT( bitfield, bit )
76 using namespace ::xmloff::token
;
77 using namespace ::com::sun::star
;
78 using namespace ::com::sun::star::uno
;
79 using namespace ::com::sun::star::sdb
;
80 using namespace ::com::sun::star::awt
;
81 using namespace ::com::sun::star::form
;
82 using namespace ::com::sun::star::lang
;
83 using namespace ::com::sun::star::beans
;
84 using namespace ::com::sun::star::container
;
85 using namespace ::com::sun::star::script
;
86 using namespace ::com::sun::star::io
;
87 using namespace ::com::sun::star::text
;
88 using namespace ::com::sun::star::form::binding
;
91 OElementExport::OElementExport(IFormsExportContext
& _rContext
, const Reference
< XPropertySet
>& _rxProps
,
92 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
93 :OPropertyExport(_rContext
, _rxProps
)
98 OElementExport::~OElementExport()
102 void OElementExport::doExport()
104 // collect some general information about the element
107 // first add the attributes necessary for the element
108 m_rContext
.getGlobalContext().ClearAttrList();
110 // add the attributes
113 // start the XML element
114 implStartElement(getXMLElementName());
116 // the sub elements (mostly control type dependent)
122 void OElementExport::examine()
124 // nothing to do here
127 void OElementExport::exportAttributes()
129 // nothing to do here
132 void OElementExport::exportSubTags()
134 // the properties which where not exported 'til now
135 exportRemainingProperties();
137 // the script:events sub tags
141 void OElementExport::implStartElement(const OUString
& _pName
)
143 m_pXMLElement
= std::make_unique
<SvXMLElementExport
>(m_rContext
.getGlobalContext(), XML_NAMESPACE_FORM
, _pName
, true, true);
146 void OElementExport::implEndElement()
148 m_pXMLElement
.reset();
151 void OElementExport::exportServiceNameAttribute()
153 Reference
< XPersistObject
> xPersistence(m_xProps
, UNO_QUERY
);
154 if (!xPersistence
.is())
156 OSL_FAIL("OElementExport::exportServiceNameAttribute: no XPersistObject!");
160 OUString sServiceName
= xPersistence
->getServiceName();
161 // we don't want to write the old service name directly: it's a name used for compatibility reasons, but
162 // as we start some kind of new file format here (with this xml export), we don't care about
164 // So we translate the old persistence service name into new ones, if possible
166 OUString sToWriteServiceName
= sServiceName
;
167 #define CHECK_N_TRANSLATE( persistentComponent, serviceName ) \
168 else if (sServiceName == persistentComponent) \
169 sToWriteServiceName = serviceName
171 if (sServiceName
== SERVICE_PERSISTENT_COMPONENT_EDIT
)
173 // special handling for the edit field: we have two controls using this as persistence service name
174 sToWriteServiceName
= SERVICE_EDIT
;
175 Reference
< XServiceInfo
> xSI(m_xProps
, UNO_QUERY
);
176 if (xSI
.is() && xSI
->supportsService(SERVICE_FORMATTEDFIELD
))
177 sToWriteServiceName
= SERVICE_FORMATTEDFIELD
;
179 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_FORM
, SERVICE_FORM
);
180 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_LISTBOX
, SERVICE_LISTBOX
);
181 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_COMBOBOX
, SERVICE_COMBOBOX
);
182 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_RADIOBUTTON
, SERVICE_RADIOBUTTON
);
183 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_GROUPBOX
, SERVICE_GROUPBOX
);
184 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_FIXEDTEXT
, SERVICE_FIXEDTEXT
);
185 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_COMMANDBUTTON
, SERVICE_COMMANDBUTTON
);
186 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_CHECKBOX
, SERVICE_CHECKBOX
);
187 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_GRID
, SERVICE_GRID
);
188 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_IMAGEBUTTON
, SERVICE_IMAGEBUTTON
);
189 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_FILECONTROL
, SERVICE_FILECONTROL
);
190 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_TIMEFIELD
, SERVICE_TIMEFIELD
);
191 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_DATEFIELD
, SERVICE_DATEFIELD
);
192 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_NUMERICFIELD
, SERVICE_NUMERICFIELD
);
193 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_CURRENCYFIELD
, SERVICE_CURRENCYFIELD
);
194 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_PATTERNFIELD
, SERVICE_PATTERNFIELD
);
195 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_HIDDENCONTROL
, SERVICE_HIDDENCONTROL
);
196 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_IMAGECONTROL
, SERVICE_IMAGECONTROL
);
197 CHECK_N_TRANSLATE( SERVICE_PERSISTENT_COMPONENT_FORMATTEDFIELD
, SERVICE_FORMATTEDFIELD
);
198 #if OSL_DEBUG_LEVEL > 0
199 Reference
< XServiceInfo
> xSI(m_xProps
, UNO_QUERY
);
200 OSL_ENSURE(xSI
.is() && xSI
->supportsService(sToWriteServiceName
),
201 "OElementExport::exportServiceNameAttribute: wrong service name translation!");
204 sToWriteServiceName
=
205 m_rContext
.getGlobalContext().GetNamespaceMap().GetQNameByKey(
206 XML_NAMESPACE_OOO
, sToWriteServiceName
);
210 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::ServiceName
),
211 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::ServiceName
),
212 sToWriteServiceName
);
215 void OElementExport::exportEvents()
217 if (!m_aEvents
.hasElements())
221 Reference
< XNameReplace
> xWrapper
= new OEventDescriptorMapper(m_aEvents
);
222 m_rContext
.getGlobalContext().GetEventExport().Export(xWrapper
);
226 OControlExport::OControlExport(IFormsExportContext
& _rContext
, const Reference
< XPropertySet
>& _rxControl
,
227 OUString _sControlId
, OUString _sReferringControls
,
228 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
229 :OElementExport(_rContext
, _rxControl
, _rEvents
)
230 ,m_sControlId(std::move(_sControlId
))
231 ,m_sReferringControls(std::move(_sReferringControls
))
232 ,m_nClassId(FormComponentType::CONTROL
)
234 ,m_nIncludeCommon(CCAFlags::NONE
)
235 ,m_nIncludeDatabase(DAFlags::NONE
)
236 ,m_nIncludeSpecial(SCAFlags::NONE
)
237 ,m_nIncludeEvents(EAFlags::NONE
)
238 ,m_nIncludeBindings(BAFlags::NONE
)
240 OSL_ENSURE(m_xProps
.is(), "OControlExport::OControlExport: invalid arguments!");
243 void OControlExport::exportOuterAttributes()
246 if (CCAFlags::Name
& m_nIncludeCommon
)
248 exportStringPropertyAttribute(
249 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Name
),
250 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Name
),
253 #if OSL_DEBUG_LEVEL > 0
254 // reset the bit for later checking
255 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::Name
;
260 if (m_nIncludeCommon
& CCAFlags::ServiceName
)
262 exportServiceNameAttribute();
263 #if OSL_DEBUG_LEVEL > 0
264 // reset the bit for later checking
265 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::ServiceName
;
270 void OControlExport::exportInnerAttributes()
273 if (CCAFlags::ControlId
& m_nIncludeCommon
)
275 OSL_ENSURE(!m_sControlId
.isEmpty(), "OControlExport::exportInnerAttributes: have no control id for the control!");
276 m_rContext
.getGlobalContext().AddAttributeIdLegacy(
277 XML_NAMESPACE_FORM
, m_sControlId
);
278 #if OSL_DEBUG_LEVEL > 0
279 // reset the bit for later checking
280 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::ControlId
;
284 // "new-style" properties ...
285 exportGenericHandlerAttributes();
287 // common control attributes
288 exportCommonControlAttributes();
290 // common database attributes
291 exportDatabaseAttributes();
293 // attributes related to external bindings
294 exportBindingAttributes();
296 // attributes special to the respective control type
297 exportSpecialAttributes();
299 // add the style references to the attributes
300 flagStyleProperties();
303 void OControlExport::exportAttributes()
305 exportOuterAttributes();
308 void OControlExport::exportSubTags()
310 // for the upcoming exportRemainingProperties:
311 // if a control has the LabelControl property, this is not stored with the control itself, but instead with
312 // the control which is referenced by this property. As the base class' exportRemainingProperties doesn't
313 // know anything about this, we need to prevent that it tries to export this property
314 exportedProperty(PROPERTY_CONTROLLABEL
);
316 // if it's a control supporting XText, then we need to declare all text-related properties
317 // as "already exported". This prevents them from being exported as generic "form:property"-tags.
318 // *If* we would export them this way, they would be completely superfluous, and sometimes even
319 // disastrous, since they may, at import time, override paragraph properties which already have
321 Reference
< XText
> xControlText( m_xProps
, UNO_QUERY
);
322 if ( xControlText
.is() )
324 const XMLPropertyMapEntry
* pCharAttributeProperties
= XMLTextPropertySetMapper::getPropertyMapForType( TextPropMap::TEXT
);
325 while ( !pCharAttributeProperties
->IsEnd() )
327 exportedProperty( pCharAttributeProperties
->getApiName() );
328 ++pCharAttributeProperties
;
331 const XMLPropertyMapEntry
* pParaAttributeProperties
= XMLTextPropertySetMapper::getPropertyMapForType( TextPropMap::SHAPE_PARA
);
332 while ( !pParaAttributeProperties
->IsEnd() )
334 exportedProperty( pParaAttributeProperties
->getApiName() );
335 ++pParaAttributeProperties
;
338 // the RichText property is not exported. The presence of the text:p element
339 // will be used - upon reading - as indicator for the value of the RichText property
340 exportedProperty( PROPERTY_RICH_TEXT
);
342 // strange thing: paragraphs support both a CharStrikeout and a CharCrossedOut property
343 // The former is a short/enum value, the latter a boolean. The former has a real meaning
344 // (the strikeout type), the latter hasn't. But, when the CharCrossedOut is exported and
345 // later on imported, it overwrites anything which has previously been imported for
348 exportedProperty( u
"CharCrossedOut"_ustr
);
351 if ( m_eType
== LISTBOX
)
353 // will be exported in exportListSourceAsElements:
354 if ( controlHasUserSuppliedListEntries() )
355 exportedProperty( PROPERTY_DEFAULT_SELECT_SEQ
);
357 // will not be exported in a generic way. Either exportListSourceAsElements cares
358 // for them, or we don't need them
359 exportedProperty( PROPERTY_STRING_ITEM_LIST
);
360 exportedProperty( PROPERTY_VALUE_SEQ
);
361 exportedProperty( PROPERTY_SELECT_SEQ
);
362 exportedProperty( PROPERTY_LISTSOURCE
);
364 if ( m_eType
== COMBOBOX
)
365 exportedProperty( PROPERTY_STRING_ITEM_LIST
);
367 // let the base class export the remaining properties and the events
368 OElementExport::exportSubTags();
370 // special sub tags for some controls
374 // don't export the list entries if the are not provided by the user, but obtained implicitly
375 // from other sources
377 if ( controlHasUserSuppliedListEntries() )
378 exportListSourceAsElements();
381 { // a grid control requires us to store all columns as sub elements
382 Reference
< XIndexAccess
> xColumnContainer(m_xProps
, UNO_QUERY
);
383 OSL_ENSURE(xColumnContainer
.is(), "OControlExport::exportSubTags: a grid control which is no IndexAccess?!!");
384 if (xColumnContainer
.is())
385 m_rContext
.exportCollectionElements(xColumnContainer
);
389 { // a combox box description has sub elements: the items
390 DBG_CHECK_PROPERTY( PROPERTY_STRING_ITEM_LIST
, Sequence
< OUString
> );
392 // don't export the list entries if the are not provided by the user, but obtained implicitly
393 // from other sources
395 if ( controlHasUserSuppliedListEntries() )
398 Sequence
< OUString
> aListItems
;
399 m_xProps
->getPropertyValue(PROPERTY_STRING_ITEM_LIST
) >>= aListItems
;
400 // loop through it and write the sub elements
401 for (const auto& rListItem
: aListItems
)
403 m_rContext
.getGlobalContext().ClearAttrList();
405 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Label
),
406 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Label
),
408 SvXMLElementExport
aFormElement(m_rContext
.getGlobalContext(), XML_NAMESPACE_FORM
, u
"item"_ustr
, true, true);
416 // if we act as rich text control, we need to export some text:p elements
417 if ( xControlText
.is() )
419 bool bActingAsRichText
= false;
420 if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_RICH_TEXT
) )
422 OSL_VERIFY(m_xProps
->getPropertyValue( PROPERTY_RICH_TEXT
) >>= bActingAsRichText
);
425 if ( bActingAsRichText
)
426 m_rContext
.getGlobalContext().GetTextParagraphExport()->exportText( xControlText
);
436 void OControlExport::exportGenericHandlerAttributes()
438 const Sequence
< Property
> aProperties
= m_xPropertyInfo
->getProperties();
439 for ( auto const & prop
: aProperties
)
443 // see if this property can already be handled with an IPropertyHandler (which, on the long
444 // term, should be the case for most, if not all, properties)
445 const PropertyDescription
* propDescription
= metadata::getPropertyDescription( prop
.Name
);
446 if ( propDescription
== nullptr )
449 // let the factory provide the concrete handler. Note that caching, if desired, is the task
451 PPropertyHandler handler
= (*propDescription
->factory
)( propDescription
->propertyId
);
454 SAL_WARN( "xmloff.forms", "OControlExport::exportGenericHandlerAttributes: invalid property handler provided by the factory!" );
458 // that's a property which has a direct mapping to an attribute
459 if ( !shouldExportProperty( prop
.Name
) )
460 // TODO: in the future, we surely need a more sophisticated approach to this, involving the property
461 // handler, or the property description
463 exportedProperty( prop
.Name
);
467 const Any propValue
= m_xProps
->getPropertyValue( prop
.Name
);
468 OUString attributeValue
= handler
->getAttributeValue( propValue
);
471 propDescription
->attribute
.namespacePrefix
,
472 token::GetXMLToken( propDescription
->attribute
.attributeToken
),
476 exportedProperty( prop
.Name
);
478 catch( const Exception
& )
480 DBG_UNHANDLED_EXCEPTION("xmloff.forms");
485 void OControlExport::exportCommonControlAttributes()
489 // I decided to handle all the properties here with some static arrays describing the property-attribute
490 // relations. This leads to somewhat ugly code :), but the only alternative I can think of right now
491 // would require maps and O(log n) searches, which seems somewhat expensive as this code is used
494 // the extra indents for the respective blocks are to ensure that there is no copy'n'paste error, using
495 // map identifiers from the wrong block
497 // some string properties
499 // the attribute ids of all properties which are expected to be of type string
500 static const CCAFlags nStringPropertyAttributeIds
[] =
502 CCAFlags::Label
, CCAFlags::Title
504 // the names of all properties which are expected to be of type string
505 static constexpr OUString aStringPropertyNames
[] =
507 PROPERTY_LABEL
, PROPERTY_TITLE
509 OSL_ENSURE( std::size(aStringPropertyNames
) ==
510 std::size(nStringPropertyAttributeIds
),
511 "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (1)!");
513 for (i
=0; i
<std::size(nStringPropertyAttributeIds
); ++i
)
514 if (nStringPropertyAttributeIds
[i
] & m_nIncludeCommon
)
516 exportStringPropertyAttribute(
517 OAttributeMetaData::getCommonControlAttributeNamespace(nStringPropertyAttributeIds
[i
]),
518 OAttributeMetaData::getCommonControlAttributeName(nStringPropertyAttributeIds
[i
]),
519 aStringPropertyNames
[i
]
521 #if OSL_DEBUG_LEVEL > 0
522 // reset the bit for later checking
523 m_nIncludeCommon
= m_nIncludeCommon
& ~nStringPropertyAttributeIds
[i
];
528 // some boolean properties
530 static const CCAFlags nBooleanPropertyAttributeIds
[] =
532 CCAFlags::CurrentSelected
, CCAFlags::Disabled
, CCAFlags::Dropdown
, CCAFlags::Printable
, CCAFlags::ReadOnly
, CCAFlags::Selected
, CCAFlags::TabStop
, CCAFlags::EnableVisible
534 static constexpr OUString pBooleanPropertyNames
[] =
536 PROPERTY_STATE
, PROPERTY_ENABLED
,
537 PROPERTY_DROPDOWN
, PROPERTY_PRINTABLE
,
538 PROPERTY_READONLY
, PROPERTY_DEFAULT_STATE
,
539 PROPERTY_TABSTOP
, PROPERTY_ENABLEVISIBLE
541 static const BoolAttrFlags nBooleanPropertyAttrFlags
[] =
542 { // attribute defaults
543 BoolAttrFlags::DefaultFalse
, BoolAttrFlags::DefaultFalse
| BoolAttrFlags::InverseSemantics
, BoolAttrFlags::DefaultFalse
, BoolAttrFlags::DefaultTrue
, BoolAttrFlags::DefaultFalse
, BoolAttrFlags::DefaultFalse
, BoolAttrFlags::DefaultVoid
, BoolAttrFlags::DefaultFalse
545 #if OSL_DEBUG_LEVEL > 0
546 static const sal_Int32 nIdCount
= std::size(nBooleanPropertyAttributeIds
);
547 static const sal_Int32 nNameCount
= std::size(pBooleanPropertyNames
);
548 static const sal_Int32 nFlagsCount
= std::size(nBooleanPropertyAttrFlags
);
549 OSL_ENSURE((nIdCount
== nNameCount
) && (nNameCount
== nFlagsCount
),
550 "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (2)!");
552 for (i
=0; i
<std::size(nBooleanPropertyAttributeIds
); ++i
)
553 if (nBooleanPropertyAttributeIds
[i
] & m_nIncludeCommon
)
555 exportBooleanPropertyAttribute(
556 OAttributeMetaData::getCommonControlAttributeNamespace(nBooleanPropertyAttributeIds
[i
]),
557 OAttributeMetaData::getCommonControlAttributeName(nBooleanPropertyAttributeIds
[i
]),
558 pBooleanPropertyNames
[i
],
559 nBooleanPropertyAttrFlags
[i
]);
560 #if OSL_DEBUG_LEVEL > 0
561 // reset the bit for later checking
562 m_nIncludeCommon
= m_nIncludeCommon
& ~nBooleanPropertyAttributeIds
[i
];
567 // some integer properties
569 // now the common handling
570 static const CCAFlags nIntegerPropertyAttributeIds
[] =
572 CCAFlags::Size
, CCAFlags::TabIndex
574 static constexpr OUString pIntegerPropertyNames
[] =
576 PROPERTY_LINECOUNT
, PROPERTY_TABINDEX
578 static const sal_Int16 nIntegerPropertyAttrDefaults
[] =
579 { // attribute defaults
583 if ( m_nIncludeCommon
& CCAFlags::MaxLength
)
584 exportedProperty(PROPERTY_MAXTEXTLENGTH
);
586 #if OSL_DEBUG_LEVEL > 0
587 static const sal_Int32 nIdCount
= std::size(nIntegerPropertyAttributeIds
);
588 static const sal_Int32 nNameCount
= std::size(pIntegerPropertyNames
);
589 static const sal_Int32 nDefaultCount
= std::size(nIntegerPropertyAttrDefaults
);
590 OSL_ENSURE((nIdCount
== nNameCount
) && (nNameCount
== nDefaultCount
),
591 "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (3)!");
593 for (i
=0; i
<std::size(nIntegerPropertyAttributeIds
); ++i
)
594 if (nIntegerPropertyAttributeIds
[i
] & m_nIncludeCommon
)
596 exportInt16PropertyAttribute(
597 OAttributeMetaData::getCommonControlAttributeNamespace(nIntegerPropertyAttributeIds
[i
]),
598 OAttributeMetaData::getCommonControlAttributeName(nIntegerPropertyAttributeIds
[i
]),
599 pIntegerPropertyNames
[i
],
600 nIntegerPropertyAttrDefaults
[i
]);
601 #if OSL_DEBUG_LEVEL > 0
602 // reset the bit for later checking
603 m_nIncludeCommon
= m_nIncludeCommon
& ~nIntegerPropertyAttributeIds
[i
];
609 // some enum properties
611 if (m_nIncludeCommon
& CCAFlags::ButtonType
)
613 exportEnumPropertyAttribute(
614 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::ButtonType
),
615 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::ButtonType
),
618 FormButtonType_PUSH
);
619 #if OSL_DEBUG_LEVEL > 0
620 // reset the bit for later checking
621 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::ButtonType
;
624 if ( m_nIncludeCommon
& CCAFlags::Orientation
)
626 exportEnumPropertyAttribute(
627 OAttributeMetaData::getCommonControlAttributeNamespace( CCAFlags::Orientation
),
628 OAttributeMetaData::getCommonControlAttributeName( CCAFlags::Orientation
),
629 PROPERTY_ORIENTATION
,
631 ScrollBarOrientation::HORIZONTAL
633 #if OSL_DEBUG_LEVEL > 0
634 // reset the bit for later checking
635 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::Orientation
;
639 if ( m_nIncludeCommon
& CCAFlags::VisualEffect
)
641 exportEnumPropertyAttribute(
642 OAttributeMetaData::getCommonControlAttributeNamespace( CCAFlags::VisualEffect
),
643 OAttributeMetaData::getCommonControlAttributeName( CCAFlags::VisualEffect
),
644 PROPERTY_VISUAL_EFFECT
,
648 #if OSL_DEBUG_LEVEL > 0
649 // reset the bit for later checking
650 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::VisualEffect
;
655 // some properties which require a special handling
658 if (m_nIncludeCommon
& CCAFlags::TargetFrame
)
660 exportTargetFrameAttribute();
661 #if OSL_DEBUG_LEVEL > 0
662 // reset the bit for later checking
663 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::TargetFrame
;
668 if ( m_nIncludeCommon
& CCAFlags::MaxLength
)
670 // normally, the respective property would be "MaxTextLen"
671 // However, if the model has a property "PersistenceMaxTextLength", then we prefer this
673 // determine the name of the property to export
674 OUString
sTextLenPropertyName( PROPERTY_MAXTEXTLENGTH
);
675 if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_PERSISTENCE_MAXTEXTLENGTH
) )
676 sTextLenPropertyName
= PROPERTY_PERSISTENCE_MAXTEXTLENGTH
;
679 exportInt16PropertyAttribute(
680 OAttributeMetaData::getCommonControlAttributeNamespace( CCAFlags::MaxLength
),
681 OAttributeMetaData::getCommonControlAttributeName( CCAFlags::MaxLength
),
682 sTextLenPropertyName
,
686 // in either way, both properties count as "exported"
687 exportedProperty( PROPERTY_MAXTEXTLENGTH
);
688 exportedProperty( PROPERTY_PERSISTENCE_MAXTEXTLENGTH
);
690 #if OSL_DEBUG_LEVEL > 0
691 // reset the bit for later checking
692 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::MaxLength
;
696 if (m_nIncludeCommon
& CCAFlags::TargetLocation
)
698 exportTargetLocationAttribute(false);
699 #if OSL_DEBUG_LEVEL > 0
700 // reset the bit for later checking
701 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::TargetLocation
;
706 if (m_nIncludeCommon
& CCAFlags::ImageData
)
708 exportImageDataAttribute();
709 #if OSL_DEBUG_LEVEL > 0
710 // reset the bit for later checking
711 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::ImageData
;
717 if (m_nIncludeCommon
& CCAFlags::For
)
719 if (!m_sReferringControls
.isEmpty())
720 { // there is at least one control referring to the one we're handling currently
722 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::For
),
723 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::For
),
724 m_sReferringControls
);
726 #if OSL_DEBUG_LEVEL > 0
727 // reset the bit for later checking
728 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::For
;
732 if ((CCAFlags::CurrentValue
| CCAFlags::Value
) & m_nIncludeCommon
)
734 OUString pCurrentValuePropertyName
;
735 OUString pValuePropertyName
;
737 // get the property names
738 getValuePropertyNames(m_eType
, m_nClassId
, pCurrentValuePropertyName
, pValuePropertyName
);
740 // add the attributes if necessary and possible
741 if (!pCurrentValuePropertyName
.isEmpty() && (CCAFlags::CurrentValue
& m_nIncludeCommon
))
743 static const OUString pCurrentValueAttributeName
= OAttributeMetaData::getCommonControlAttributeName(CCAFlags::CurrentValue
);
744 // don't export the current-value if this value originates from a data binding
746 if ( controlHasActiveDataBinding() )
747 exportedProperty( pCurrentValuePropertyName
);
750 static const sal_uInt16 nCurrentValueAttributeNamespaceKey
= OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::CurrentValue
);
751 exportGenericPropertyAttribute(
752 nCurrentValueAttributeNamespaceKey
,
753 pCurrentValueAttributeName
,
754 pCurrentValuePropertyName
759 if (!pValuePropertyName
.isEmpty() && (CCAFlags::Value
& m_nIncludeCommon
))
761 static const OUString pValueAttributeName
= OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Value
);
762 static const sal_uInt16 nValueAttributeNamespaceKey
= OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Value
);
763 exportGenericPropertyAttribute(
764 nValueAttributeNamespaceKey
,
769 OSL_ENSURE((pValuePropertyName
.isEmpty()) == (CCAFlags::NONE
== (CCAFlags::Value
& m_nIncludeCommon
)),
770 "OControlExport::exportCommonControlAttributes: no property found for the value attribute!");
771 OSL_ENSURE((pCurrentValuePropertyName
.isEmpty()) == (CCAFlags::NONE
== (CCAFlags::CurrentValue
& m_nIncludeCommon
)),
772 "OControlExport::exportCommonControlAttributes: no property found for the current-value attribute!");
774 #if OSL_DEBUG_LEVEL > 0
775 // reset the bit for later checking
776 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags(CCAFlags::CurrentValue
| CCAFlags::Value
);
780 OSL_ENSURE(CCAFlags::NONE
== m_nIncludeCommon
,
781 "OControlExport::exportCommonControlAttributes: forgot some flags!");
782 // in the dbg_util version, we should have removed every bit we handled from the mask, so it should
786 void OControlExport::exportDatabaseAttributes()
788 #if OSL_DEBUG_LEVEL > 0
789 DAFlags nIncludeDatabase
= m_nIncludeDatabase
;
791 // the only string property: DataField
792 if (DAFlags::DataField
& m_nIncludeDatabase
)
794 exportStringPropertyAttribute(
795 OAttributeMetaData::getDatabaseAttributeNamespace(),
796 OAttributeMetaData::getDatabaseAttributeName(DAFlags::DataField
),
798 RESET_BIT( nIncludeDatabase
, DAFlags::DataField
);
802 if ( DAFlags::InputRequired
& m_nIncludeDatabase
)
804 exportBooleanPropertyAttribute(
805 OAttributeMetaData::getDatabaseAttributeNamespace(),
806 OAttributeMetaData::getDatabaseAttributeName( DAFlags::InputRequired
),
807 PROPERTY_INPUT_REQUIRED
,
808 BoolAttrFlags::DefaultFalse
| BoolAttrFlags::DefaultVoid
810 RESET_BIT( nIncludeDatabase
, DAFlags::InputRequired
);
813 // the only int16 property: BoundColumn
814 if (DAFlags::BoundColumn
& m_nIncludeDatabase
)
816 exportInt16PropertyAttribute(
817 OAttributeMetaData::getDatabaseAttributeNamespace(),
818 OAttributeMetaData::getDatabaseAttributeName(DAFlags::BoundColumn
),
819 PROPERTY_BOUNDCOLUMN
,
822 RESET_BIT( nIncludeDatabase
, DAFlags::BoundColumn
);
825 // ConvertEmptyToNull
826 if (DAFlags::ConvertEmpty
& m_nIncludeDatabase
)
828 exportBooleanPropertyAttribute(
829 OAttributeMetaData::getDatabaseAttributeNamespace(),
830 OAttributeMetaData::getDatabaseAttributeName(DAFlags::ConvertEmpty
),
831 PROPERTY_EMPTY_IS_NULL
,
832 BoolAttrFlags::DefaultFalse
834 RESET_BIT( nIncludeDatabase
, DAFlags::ConvertEmpty
);
837 // the only enum property: ListSourceType
838 if (DAFlags::ListSource_TYPE
& m_nIncludeDatabase
)
840 exportEnumPropertyAttribute(
841 OAttributeMetaData::getDatabaseAttributeNamespace(),
842 OAttributeMetaData::getDatabaseAttributeName(DAFlags::ListSource_TYPE
),
843 PROPERTY_LISTSOURCETYPE
,
845 ListSourceType_VALUELIST
847 RESET_BIT( nIncludeDatabase
, DAFlags::ListSource_TYPE
);
850 if (m_nIncludeDatabase
& DAFlags::ListSource
)
852 exportListSourceAsAttribute();
853 RESET_BIT( nIncludeDatabase
, DAFlags::ListSource
);
856 #if OSL_DEBUG_LEVEL > 0
857 OSL_ENSURE(DAFlags::NONE
== nIncludeDatabase
,
858 "OControlExport::exportDatabaseAttributes: forgot some flags!");
859 // in the dbg_util version, we should have removed every bit we handled from the mask, so it should
864 void OControlExport::exportBindingAttributes()
866 #if OSL_DEBUG_LEVEL > 0
867 BAFlags nIncludeBinding
= m_nIncludeBindings
;
870 if ( m_nIncludeBindings
& BAFlags::LinkedCell
)
872 exportCellBindingAttributes( bool(m_nIncludeBindings
& BAFlags::ListLinkingType
) );
873 #if OSL_DEBUG_LEVEL > 0
874 // reset the bit for later checking
875 nIncludeBinding
= nIncludeBinding
& ~BAFlags( BAFlags::LinkedCell
| BAFlags::ListLinkingType
);
879 if ( m_nIncludeBindings
& BAFlags::ListCellRange
)
881 exportCellListSourceRange();
882 #if OSL_DEBUG_LEVEL > 0
883 // reset the bit for later checking
884 nIncludeBinding
= nIncludeBinding
& ~BAFlags::ListCellRange
;
888 if ( m_nIncludeBindings
& BAFlags::XFormsBind
)
890 exportXFormsBindAttributes();
891 #if OSL_DEBUG_LEVEL > 0
892 // reset the bit for later checking
893 nIncludeBinding
= nIncludeBinding
& ~BAFlags::XFormsBind
;
897 if ( m_nIncludeBindings
& BAFlags::XFormsListBind
)
899 exportXFormsListAttributes();
900 #if OSL_DEBUG_LEVEL > 0
901 // reset the bit for later checking
902 nIncludeBinding
= nIncludeBinding
& ~BAFlags::XFormsListBind
;
906 if ( m_nIncludeBindings
& BAFlags::XFormsSubmission
)
908 exportXFormsSubmissionAttributes();
909 #if OSL_DEBUG_LEVEL > 0
910 // reset the bit for later checking
911 nIncludeBinding
= nIncludeBinding
& ~BAFlags::XFormsSubmission
;
915 #if OSL_DEBUG_LEVEL > 0
916 OSL_ENSURE( BAFlags::NONE
== nIncludeBinding
,
917 "OControlExport::exportBindingAttributes: forgot some flags!");
918 // in the debug version, we should have removed every bit we handled from the mask, so it should
923 void OControlExport::exportSpecialAttributes()
927 // the boolean properties
929 static const SCAFlags nBooleanPropertyAttributeIds
[] =
931 SCAFlags::Validation
, SCAFlags::MultiLine
, SCAFlags::AutoCompletion
, SCAFlags::Multiple
, SCAFlags::DefaultButton
, SCAFlags::IsTristate
,
932 SCAFlags::Toggle
, SCAFlags::FocusOnClick
934 static constexpr OUString pBooleanPropertyNames
[] =
936 PROPERTY_STRICTFORMAT
, PROPERTY_MULTILINE
,
937 PROPERTY_AUTOCOMPLETE
,
938 PROPERTY_MULTISELECTION
,
939 PROPERTY_DEFAULTBUTTON
, PROPERTY_TRISTATE
,
940 PROPERTY_TOGGLE
, PROPERTY_FOCUS_ON_CLICK
942 static const sal_Int32 nIdCount
= std::size(nBooleanPropertyAttributeIds
);
943 #if OSL_DEBUG_LEVEL > 0
944 static const sal_Int32 nNameCount
= std::size(pBooleanPropertyNames
);
945 OSL_ENSURE((nIdCount
== nNameCount
),
946 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (1)!");
948 const SCAFlags
* pAttributeId
= nBooleanPropertyAttributeIds
;
949 for ( i
= 0; i
< nIdCount
; ++i
, ++pAttributeId
)
951 if ( *pAttributeId
& m_nIncludeSpecial
)
953 exportBooleanPropertyAttribute(
954 OAttributeMetaData::getSpecialAttributeNamespace( *pAttributeId
),
955 OAttributeMetaData::getSpecialAttributeName( *pAttributeId
),
956 pBooleanPropertyNames
[i
],
957 ( *pAttributeId
== SCAFlags::FocusOnClick
) ? BoolAttrFlags::DefaultTrue
: BoolAttrFlags::DefaultFalse
959 #if OSL_DEBUG_LEVEL > 0
960 // reset the bit for later checking
961 m_nIncludeSpecial
= m_nIncludeSpecial
& ~*pAttributeId
;
967 // the integer properties
969 static const SCAFlags nIntegerPropertyAttributeIds
[] =
971 SCAFlags::PageStepSize
973 static constexpr OUString pIntegerPropertyNames
[] =
975 PROPERTY_BLOCK_INCREMENT
977 static const sal_Int32 nIntegerPropertyAttrDefaults
[] =
978 { // attribute defaults (XML defaults, not runtime defaults!)
982 static const sal_Int32 nIdCount
= std::size( nIntegerPropertyAttributeIds
);
983 #if OSL_DEBUG_LEVEL > 0
984 static const sal_Int32 nNameCount
= std::size( pIntegerPropertyNames
);
985 OSL_ENSURE( ( nIdCount
== nNameCount
),
986 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (2)!" );
987 static const sal_Int32 nDefaultCount
= std::size( nIntegerPropertyAttrDefaults
);
988 OSL_ENSURE( ( nIdCount
== nDefaultCount
),
989 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (3)!" );
991 for ( i
= 0; i
< nIdCount
; ++i
)
992 if ( nIntegerPropertyAttributeIds
[i
] & m_nIncludeSpecial
)
994 exportInt32PropertyAttribute(
995 OAttributeMetaData::getSpecialAttributeNamespace( nIntegerPropertyAttributeIds
[i
] ),
996 OAttributeMetaData::getSpecialAttributeName( nIntegerPropertyAttributeIds
[i
] ),
997 pIntegerPropertyNames
[i
],
998 nIntegerPropertyAttrDefaults
[i
]
1000 #if OSL_DEBUG_LEVEL > 0
1001 // reset the bit for later checking
1002 m_nIncludeSpecial
= m_nIncludeSpecial
& ~nIntegerPropertyAttributeIds
[i
];
1006 if ( SCAFlags::StepSize
& m_nIncludeSpecial
)
1008 OUString sPropertyName
;
1009 if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_LINE_INCREMENT
) )
1010 sPropertyName
= PROPERTY_LINE_INCREMENT
;
1011 else if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_SPIN_INCREMENT
) )
1012 sPropertyName
= PROPERTY_SPIN_INCREMENT
;
1014 OSL_FAIL( "OControlExport::exportSpecialAttributes: not property which can be mapped to step-size attribute!" );
1016 if ( !sPropertyName
.isEmpty() )
1017 exportInt32PropertyAttribute(
1018 OAttributeMetaData::getSpecialAttributeNamespace( SCAFlags::StepSize
),
1019 OAttributeMetaData::getSpecialAttributeName( SCAFlags::StepSize
),
1024 #if OSL_DEBUG_LEVEL > 0
1025 // reset the bit for later checking
1026 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags::StepSize
;
1032 // the enum properties
1034 if (SCAFlags::State
& m_nIncludeSpecial
)
1036 exportEnumPropertyAttribute(
1037 OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::State
),
1038 OAttributeMetaData::getSpecialAttributeName(SCAFlags::State
),
1039 PROPERTY_DEFAULT_STATE
,
1042 #if OSL_DEBUG_LEVEL > 0
1043 // reset the bit for later checking
1044 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags::State
;
1048 if (SCAFlags::CurrentState
& m_nIncludeSpecial
)
1050 exportEnumPropertyAttribute(
1051 OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::CurrentState
),
1052 OAttributeMetaData::getSpecialAttributeName(SCAFlags::CurrentState
),
1056 #if OSL_DEBUG_LEVEL > 0
1057 // reset the bit for later checking
1058 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags::CurrentState
;
1063 // some properties which require a special handling
1066 if ( m_nIncludeSpecial
& SCAFlags::RepeatDelay
)
1068 DBG_CHECK_PROPERTY( PROPERTY_REPEAT_DELAY
, sal_Int32
);
1070 sal_Int32 nRepeatDelay
= 0;
1071 m_xProps
->getPropertyValue( PROPERTY_REPEAT_DELAY
) >>= nRepeatDelay
;
1072 tools::Time
aTime(tools::Time::EMPTY
);
1073 aTime
.MakeTimeFromMS( nRepeatDelay
);
1074 util::Duration aDuration
;
1075 aDuration
.Hours
= aTime
.GetHour();
1076 aDuration
.Minutes
= aTime
.GetMin();
1077 aDuration
.Seconds
= aTime
.GetSec();
1078 aDuration
.NanoSeconds
= (nRepeatDelay
% 1000) * 1000000;
1081 ::sax::Converter::convertDuration(buf
, aDuration
);
1082 AddAttribute(OAttributeMetaData::getSpecialAttributeNamespace( SCAFlags::RepeatDelay
)
1083 ,OAttributeMetaData::getSpecialAttributeName( SCAFlags::RepeatDelay
)
1084 ,buf
.makeStringAndClear());
1086 exportedProperty( PROPERTY_REPEAT_DELAY
);
1088 #if OSL_DEBUG_LEVEL > 0
1089 // reset the bit for later checking
1090 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags::RepeatDelay
;
1095 // the EchoChar property needs special handling, cause it's a Int16, but must be stored as one-character-string
1097 if (SCAFlags::EchoChar
& m_nIncludeSpecial
)
1099 DBG_CHECK_PROPERTY( PROPERTY_ECHO_CHAR
, sal_Int16
);
1100 sal_Int16
nValue(0);
1101 m_xProps
->getPropertyValue(PROPERTY_ECHO_CHAR
) >>= nValue
;
1104 OUString
sCharacter(reinterpret_cast<const sal_Unicode
*>(&nValue
), 1);
1106 OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::EchoChar
),
1107 OAttributeMetaData::getSpecialAttributeName(SCAFlags::EchoChar
),
1110 exportedProperty(PROPERTY_ECHO_CHAR
);
1111 #if OSL_DEBUG_LEVEL > 0
1112 // reset the bit for later checking
1113 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags::EchoChar
;
1118 // the string properties
1120 static const SCAFlags nStringPropertyAttributeIds
[] =
1121 { // attribute flags
1124 static constexpr OUString pStringPropertyNames
[] =
1129 static const sal_Int32 nIdCount
= std::size( nStringPropertyAttributeIds
);
1130 #if OSL_DEBUG_LEVEL > 0
1131 static const sal_Int32 nNameCount
= std::size( pStringPropertyNames
);
1132 OSL_ENSURE( ( nIdCount
== nNameCount
),
1133 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (2)!" );
1135 for ( i
= 0; i
< nIdCount
; ++i
)
1136 if ( nStringPropertyAttributeIds
[i
] & m_nIncludeSpecial
)
1138 exportStringPropertyAttribute(
1139 OAttributeMetaData::getSpecialAttributeNamespace( nStringPropertyAttributeIds
[i
] ),
1140 OAttributeMetaData::getSpecialAttributeName( nStringPropertyAttributeIds
[i
] ),
1141 pStringPropertyNames
[i
]
1143 #if OSL_DEBUG_LEVEL > 0
1144 // reset the bit for later checking
1145 m_nIncludeSpecial
= m_nIncludeSpecial
& ~nStringPropertyAttributeIds
[i
];
1150 if ((SCAFlags::MinValue
| SCAFlags::MaxValue
) & m_nIncludeSpecial
)
1152 // need to export the min value and the max value as attributes
1153 // It depends on the real type (FormComponentType) of the control, which properties hold these
1155 OUString pMinValuePropertyName
;
1156 OUString pMaxValuePropertyName
;
1157 getValueLimitPropertyNames(m_nClassId
, pMinValuePropertyName
, pMaxValuePropertyName
);
1159 OSL_ENSURE((pMinValuePropertyName
.isEmpty()) == (SCAFlags::NONE
== (SCAFlags::MinValue
& m_nIncludeSpecial
)),
1160 "OControlExport::exportCommonControlAttributes: no property found for the min value attribute!");
1161 OSL_ENSURE((pMaxValuePropertyName
.isEmpty()) == (SCAFlags::NONE
== (SCAFlags::MaxValue
& m_nIncludeSpecial
)),
1162 "OControlExport::exportCommonControlAttributes: no property found for the max value attribute!");
1164 // add the two attributes
1165 static const OUString pMinValueAttributeName
= OAttributeMetaData::getSpecialAttributeName(SCAFlags::MinValue
);
1166 static const OUString pMaxValueAttributeName
= OAttributeMetaData::getSpecialAttributeName(SCAFlags::MaxValue
);
1167 static const sal_uInt16 nMinValueNamespaceKey
= OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::MinValue
);
1168 static const sal_uInt16 nMaxValueNamespaceKey
= OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::MaxValue
);
1170 if (!pMinValuePropertyName
.isEmpty() && (SCAFlags::MinValue
& m_nIncludeSpecial
))
1171 exportGenericPropertyAttribute(
1172 nMinValueNamespaceKey
,
1173 pMinValueAttributeName
,
1174 pMinValuePropertyName
);
1176 if (!pMaxValuePropertyName
.isEmpty() && (SCAFlags::MaxValue
& m_nIncludeSpecial
))
1177 exportGenericPropertyAttribute(
1178 nMaxValueNamespaceKey
,
1179 pMaxValueAttributeName
,
1180 pMaxValuePropertyName
);
1181 #if OSL_DEBUG_LEVEL > 0
1182 // reset the bit for later checking
1183 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags(SCAFlags::MinValue
| SCAFlags::MaxValue
);
1187 if ( SCAFlags::ImagePosition
& m_nIncludeSpecial
)
1189 exportImagePositionAttributes();
1190 RESET_BIT( m_nIncludeSpecial
, SCAFlags::ImagePosition
);
1193 OSL_ENSURE(SCAFlags::NONE
== m_nIncludeSpecial
,
1194 "OControlExport::exportSpecialAttributes: forgot some flags!");
1195 // in the dbg_util version, we should have removed every bit we handled from the mask, so it should
1199 OUString
OControlExport::getScalarListSourceValue() const
1201 OUString sListSource
;
1202 Any aListSource
= m_xProps
->getPropertyValue( PROPERTY_LISTSOURCE
);
1203 if ( !( aListSource
>>= sListSource
) )
1205 Sequence
< OUString
> aListSourceSequence
;
1206 aListSource
>>= aListSourceSequence
;
1207 if ( aListSourceSequence
.hasElements() )
1208 sListSource
= aListSourceSequence
[ 0 ];
1213 void OControlExport::exportListSourceAsAttribute()
1215 // DAFlags::ListSource needs some special handling
1216 DBG_CHECK_PROPERTY_NO_TYPE( PROPERTY_LISTSOURCE
);
1218 OUString sListSource
= getScalarListSourceValue();
1219 if ( !sListSource
.isEmpty() )
1220 { // the ListSource property needs to be exported as attribute, and it is not empty
1222 OAttributeMetaData::getDatabaseAttributeNamespace(),
1223 OAttributeMetaData::getDatabaseAttributeName(DAFlags::ListSource
),
1227 exportedProperty( PROPERTY_LISTSOURCE
);
1230 void OControlExport::getSequenceInt16PropertyAsSet(const OUString
& _rPropertyName
, Int16Set
& _rOut
)
1232 Sequence
< sal_Int16
> aValueSequence
;
1233 DBG_CHECK_PROPERTY(_rPropertyName
, Sequence
< sal_Int16
>);
1234 m_xProps
->getPropertyValue(_rPropertyName
) >>= aValueSequence
;
1236 for (const auto& rValue
: aValueSequence
)
1237 _rOut
.insert(rValue
);
1240 void OControlExport::exportListSourceAsElements()
1243 Sequence
< OUString
> aItems
, aValues
;
1244 DBG_CHECK_PROPERTY( PROPERTY_STRING_ITEM_LIST
, Sequence
< OUString
> );
1245 m_xProps
->getPropertyValue(PROPERTY_STRING_ITEM_LIST
) >>= aItems
;
1247 DBG_CHECK_PROPERTY( PROPERTY_LISTSOURCE
, Sequence
< OUString
> );
1248 if ( DAFlags::NONE
== ( m_nIncludeDatabase
& DAFlags::ListSource
) )
1249 m_xProps
->getPropertyValue(PROPERTY_LISTSOURCE
) >>= aValues
;
1250 // if we exported the list source as attribute, we do not repeat it as sub elements
1252 // the selection lists
1253 Int16Set aSelection
, aDefaultSelection
;
1254 getSequenceInt16PropertyAsSet(PROPERTY_SELECT_SEQ
, aSelection
);
1255 getSequenceInt16PropertyAsSet(PROPERTY_DEFAULT_SELECT_SEQ
, aDefaultSelection
);
1257 // the string for "true"
1259 OUStringBuffer sBuffer
;
1260 ::sax::Converter::convertBool(sBuffer
, true);
1261 sTrue
= sBuffer
.makeStringAndClear();
1263 // loop through both lists ('til the maximum of both lengths)
1264 const OUString
* pItems
= aItems
.getConstArray();
1265 const OUString
* pValues
= aValues
.getConstArray();
1267 sal_Int32 nItems
= aItems
.getLength();
1268 sal_Int32 nValues
= aValues
.getLength();
1270 sal_Int16 nMaxLen
= static_cast<sal_Int16
>(std::max(nItems
, nValues
));
1272 for (sal_Int16 i
=0; i
<nMaxLen
; ++i
)
1274 m_rContext
.getGlobalContext().ClearAttrList();
1277 // there is an item at this position
1279 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Label
),
1280 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Label
),
1286 // there is a value at this position
1288 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Value
),
1289 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Value
),
1294 Int16Set::const_iterator aSelectedPos
= aSelection
.find(i
);
1295 if (aSelection
.end() != aSelectedPos
)
1296 { // the item at this position is selected
1298 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::CurrentSelected
),
1299 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::CurrentSelected
),
1302 aSelection
.erase(aSelectedPos
);
1305 Int16Set::const_iterator aDefaultSelectedPos
= aDefaultSelection
.find(i
);
1306 if (aDefaultSelection
.end() != aDefaultSelectedPos
)
1307 { // the item at this position is selected as default
1309 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Selected
),
1310 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Selected
),
1313 aDefaultSelection
.erase(aDefaultSelectedPos
);
1315 SvXMLElementExport
aFormElement(m_rContext
.getGlobalContext(), XML_NAMESPACE_FORM
, u
"option"_ustr
, true, true);
1318 // There may be more "selected" or "default-selected" items than there are in the lists in real,
1319 // so we need to store some additional "form:option" items which have no name and no label, but
1320 // one or both of the selected flags.
1321 // 21.05.2001 - 85388 - frank.schoenheit@germany.sun.com
1323 if (aSelection
.empty() && aDefaultSelection
.empty())
1326 sal_Int16 nLastSelected
= -1;
1327 if ( !aSelection
.empty() )
1328 nLastSelected
= *(--aSelection
.end());
1330 sal_Int16 nLastDefaultSelected
= -1;
1331 if ( !aDefaultSelection
.empty() )
1332 nLastDefaultSelected
= *(--aDefaultSelection
.end());
1334 // the maximum element in both sets
1335 sal_Int16 nLastReferredEntry
= std::max(nLastSelected
, nLastDefaultSelected
);
1336 OSL_ENSURE(nLastReferredEntry
>= nMaxLen
, "OControlExport::exportListSourceAsElements: inconsistence!");
1337 // if the maximum (selected or default selected) entry number is less than the maximum item count
1338 // in both lists, the entry number should have been removed from the set
1340 for (sal_Int16 i
=nMaxLen
; i
<=nLastReferredEntry
; ++i
)
1342 if (aSelection
.end() != aSelection
.find(i
))
1343 { // the (not existent) item at this position is selected
1345 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::CurrentSelected
),
1346 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::CurrentSelected
),
1351 if (aDefaultSelection
.end() != aDefaultSelection
.find(i
))
1352 { // the (not existent) item at this position is selected as default
1354 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Selected
),
1355 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Selected
),
1359 SvXMLElementExport
aFormElement(m_rContext
.getGlobalContext(), XML_NAMESPACE_FORM
, u
"option"_ustr
, true, true);
1363 void OControlExport::implStartElement(const OUString
& _pName
)
1365 // before we let the base class start it's outer element, we add a wrapper element
1366 OUString pOuterElementName
= getOuterXMLElementName();
1367 if (!pOuterElementName
.isEmpty())
1368 m_pOuterElement
= std::make_unique
<SvXMLElementExport
>(
1369 m_rContext
.getGlobalContext(),
1371 pOuterElementName
, true,
1374 // add the attributes for the inner element
1375 exportInnerAttributes();
1377 // and start the inner element
1378 OElementExport::implStartElement(_pName
);
1381 void OControlExport::implEndElement()
1383 // end the inner element
1384 OElementExport::implEndElement();
1386 // end the outer element if it exists
1387 m_pOuterElement
.reset();
1390 OUString
OControlExport::getOuterXMLElementName() const
1395 OUString
OControlExport::getXMLElementName() const
1397 return getElementName(m_eType
);
1400 void OControlExport::examine()
1402 OSL_ENSURE( ( m_nIncludeCommon
== CCAFlags::NONE
) && ( m_nIncludeSpecial
== SCAFlags::NONE
) && ( m_nIncludeDatabase
== DAFlags::NONE
)
1403 && ( m_nIncludeEvents
== EAFlags::NONE
) && ( m_nIncludeBindings
== BAFlags::NONE
),
1404 "OControlExport::examine: called me twice? Not initialized?" );
1406 // get the class id to decide which kind of element we need in the XML stream
1407 m_nClassId
= FormComponentType::CONTROL
;
1408 DBG_CHECK_PROPERTY( PROPERTY_CLASSID
, sal_Int16
);
1409 m_xProps
->getPropertyValue(PROPERTY_CLASSID
) >>= m_nClassId
;
1410 bool knownType
= false;
1413 case FormComponentType::DATEFIELD
:
1417 case FormComponentType::TIMEFIELD
:
1423 m_nIncludeSpecial
|= SCAFlags::Validation
;
1425 case FormComponentType::NUMERICFIELD
:
1426 case FormComponentType::CURRENCYFIELD
:
1427 case FormComponentType::PATTERNFIELD
:
1430 m_eType
= FORMATTED_TEXT
;
1434 case FormComponentType::TEXTFIELD
:
1435 { // it's some kind of edit. To know which type we need further investigation
1439 // check if it's a formatted field
1440 if (m_xPropertyInfo
->hasPropertyByName(PROPERTY_FORMATKEY
))
1442 m_eType
= FORMATTED_TEXT
;
1446 // all other controls are represented by an ordinary edit control, but which XML control type
1447 // it is depends on the current values of some properties
1449 // if the EchoChar string is not empty, it is a password field
1450 sal_Int16 nEchoChar
= 0;
1451 if (m_xPropertyInfo
->hasPropertyByName(PROPERTY_ECHOCHAR
))
1452 // grid columns do not have this property...
1453 m_xProps
->getPropertyValue(PROPERTY_ECHOCHAR
) >>= nEchoChar
;
1457 m_nIncludeSpecial
|= SCAFlags::EchoChar
;
1461 // if the MultiLine property is sal_True, it is a TextArea
1462 bool bMultiLine
= false;
1463 if (m_xPropertyInfo
->hasPropertyByName(PROPERTY_MULTILINE
))
1464 // grid columns do not have this property...
1465 bMultiLine
= ::cppu::any2bool(m_xProps
->getPropertyValue(PROPERTY_MULTILINE
));
1468 m_eType
= TEXT_AREA
;
1470 // the only case left is represented by a Text element
1476 // attributes which are common to all the types:
1477 // common attributes
1479 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
|
1480 CCAFlags::Printable
| CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
;
1482 if ( ( m_nClassId
!= FormComponentType::DATEFIELD
)
1483 && ( m_nClassId
!= FormComponentType::TIMEFIELD
)
1485 // date and time field values are handled differently nowadays
1486 m_nIncludeCommon
|= CCAFlags::Value
;
1488 // database attributes
1489 m_nIncludeDatabase
= DAFlags::DataField
| DAFlags::InputRequired
;
1492 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnChange
| EAFlags::OnSelect
;
1494 // only text and pattern fields have a ConvertEmptyToNull property
1495 if ( ( m_nClassId
== FormComponentType::TEXTFIELD
)
1496 || ( m_nClassId
== FormComponentType::PATTERNFIELD
)
1498 m_nIncludeDatabase
|= DAFlags::ConvertEmpty
;
1500 // all controls but the file control fields have a readonly property
1501 if ( m_nClassId
!= FormComponentType::FILECONTROL
)
1502 m_nIncludeCommon
|= CCAFlags::ReadOnly
;
1504 // a text field has a max text len
1505 if ( m_nClassId
== FormComponentType::TEXTFIELD
)
1506 m_nIncludeCommon
|= CCAFlags::MaxLength
;
1508 // max and min values and validation:
1509 if (FORMATTED_TEXT
== m_eType
)
1510 { // in general all controls represented as formatted-text have these props
1511 if ( FormComponentType::PATTERNFIELD
!= m_nClassId
) // except the PatternField
1512 m_nIncludeSpecial
|= SCAFlags::MaxValue
| SCAFlags::MinValue
;
1514 if (FormComponentType::TEXTFIELD
!= m_nClassId
)
1515 // and the FormattedField does not have a validation flag
1516 m_nIncludeSpecial
|= SCAFlags::Validation
;
1519 // if it's not a password field or rich text control, the CurrentValue needs to be stored, too
1520 if ( ( PASSWORD
!= m_eType
)
1521 && ( DATE
!= m_eType
)
1522 && ( TIME
!= m_eType
)
1525 m_nIncludeCommon
|= CCAFlags::CurrentValue
;
1530 case FormComponentType::FILECONTROL
:
1533 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::CurrentValue
| CCAFlags::Disabled
|
1534 CCAFlags::Printable
| CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
|
1536 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnChange
| EAFlags::OnSelect
;
1539 case FormComponentType::FIXEDTEXT
:
1540 m_eType
= FIXED_TEXT
;
1542 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Label
|
1543 CCAFlags::Printable
| CCAFlags::Title
| CCAFlags::For
;
1544 m_nIncludeSpecial
= SCAFlags::MultiLine
;
1545 m_nIncludeEvents
= EAFlags::ControlEvents
;
1548 case FormComponentType::COMBOBOX
:
1551 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::CurrentValue
|
1552 CCAFlags::Disabled
| CCAFlags::Dropdown
| CCAFlags::MaxLength
| CCAFlags::Printable
| CCAFlags::ReadOnly
| CCAFlags::Size
|
1553 CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
| CCAFlags::Value
;
1554 m_nIncludeSpecial
= SCAFlags::AutoCompletion
;
1555 m_nIncludeDatabase
= DAFlags::ConvertEmpty
| DAFlags::DataField
| DAFlags::InputRequired
| DAFlags::ListSource
| DAFlags::ListSource_TYPE
;
1556 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnChange
| EAFlags::OnSelect
;
1559 case FormComponentType::LISTBOX
:
1562 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Dropdown
|
1563 CCAFlags::Printable
| CCAFlags::Size
| CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
;
1564 m_nIncludeSpecial
= SCAFlags::Multiple
;
1565 m_nIncludeDatabase
= DAFlags::BoundColumn
| DAFlags::DataField
| DAFlags::InputRequired
| DAFlags::ListSource_TYPE
;
1566 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnChange
| EAFlags::OnClick
| EAFlags::OnDoubleClick
;
1567 // check if we need to export the ListSource as attribute
1569 // for a list box, if the ListSourceType is VALUE_LIST, no ListSource is stored, but instead
1570 // a sequence of pairs which is build from the StringItemList and the ValueList
1571 ListSourceType eListSourceType
= ListSourceType_VALUELIST
;
1573 m_xProps
->getPropertyValue(PROPERTY_LISTSOURCETYPE
) >>= eListSourceType
;
1574 OSL_ENSURE(bSuccess
, "OControlExport::examineControl: could not retrieve the ListSourceType!");
1575 if (ListSourceType_VALUELIST
!= eListSourceType
)
1577 m_nIncludeDatabase
|= DAFlags::ListSource
;
1583 case FormComponentType::COMMANDBUTTON
:
1585 m_nIncludeCommon
|= CCAFlags::TabStop
| CCAFlags::Label
;
1586 m_nIncludeSpecial
= SCAFlags::DefaultButton
| SCAFlags::Toggle
| SCAFlags::FocusOnClick
| SCAFlags::ImagePosition
| SCAFlags::RepeatDelay
;
1588 case FormComponentType::IMAGEBUTTON
:
1589 if (BUTTON
!= m_eType
)
1591 // not coming from the previous case
1595 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::ButtonType
| CCAFlags::Disabled
|
1596 CCAFlags::ImageData
| CCAFlags::Printable
| CCAFlags::TabIndex
| CCAFlags::TargetFrame
|
1597 CCAFlags::TargetLocation
| CCAFlags::Title
;
1598 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnClick
| EAFlags::OnDoubleClick
;
1601 case FormComponentType::CHECKBOX
:
1603 m_nIncludeSpecial
= SCAFlags::CurrentState
| SCAFlags::IsTristate
| SCAFlags::State
;
1605 case FormComponentType::RADIOBUTTON
:
1607 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Label
| CCAFlags::Printable
|
1608 CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
| CCAFlags::Value
| CCAFlags::VisualEffect
;
1609 if (CHECKBOX
!= m_eType
)
1610 { // not coming from the previous case
1612 m_nIncludeCommon
|= CCAFlags::CurrentSelected
| CCAFlags::Selected
;
1614 if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_IMAGE_POSITION
) )
1615 m_nIncludeSpecial
|= SCAFlags::ImagePosition
;
1616 if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_GROUP_NAME
) )
1617 m_nIncludeSpecial
|= SCAFlags::GroupName
;
1618 m_nIncludeDatabase
= DAFlags::DataField
| DAFlags::InputRequired
;
1619 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnChange
;
1622 case FormComponentType::GROUPBOX
:
1625 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Label
|
1626 CCAFlags::Printable
| CCAFlags::Title
| CCAFlags::For
;
1627 m_nIncludeEvents
= EAFlags::ControlEvents
;
1630 case FormComponentType::IMAGECONTROL
:
1631 m_eType
= IMAGE_FRAME
;
1633 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::ImageData
|
1634 CCAFlags::Printable
| CCAFlags::ReadOnly
| CCAFlags::Title
;
1635 m_nIncludeDatabase
= DAFlags::DataField
| DAFlags::InputRequired
;
1636 m_nIncludeEvents
= EAFlags::ControlEvents
;
1639 case FormComponentType::HIDDENCONTROL
:
1642 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Value
;
1645 case FormComponentType::GRIDCONTROL
:
1648 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Printable
|
1649 CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
;
1650 m_nIncludeEvents
= EAFlags::ControlEvents
;
1653 case FormComponentType::SCROLLBAR
:
1654 case FormComponentType::SPINBUTTON
:
1655 m_eType
= VALUERANGE
;
1657 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Printable
|
1658 CCAFlags::Title
| CCAFlags::CurrentValue
| CCAFlags::Value
| CCAFlags::Orientation
;
1659 m_nIncludeSpecial
= SCAFlags::MaxValue
| SCAFlags::StepSize
| SCAFlags::MinValue
| SCAFlags::RepeatDelay
;
1661 if ( m_nClassId
== FormComponentType::SCROLLBAR
)
1662 m_nIncludeSpecial
|= SCAFlags::PageStepSize
;
1664 m_nIncludeEvents
= EAFlags::ControlEvents
;
1668 OSL_FAIL("OControlExport::examineControl: unknown control type (class id)!");
1671 case FormComponentType::NAVIGATIONBAR
:
1672 // TODO: should we have an own file format for this?
1675 case FormComponentType::CONTROL
:
1676 m_eType
= GENERIC_CONTROL
;
1677 // unknown control type
1678 m_nIncludeCommon
= CCAFlags::Name
| CCAFlags::ServiceName
;
1679 // at least a name should be there, 'cause without a name the control could never have been
1680 // inserted into its parent container
1681 // In addition, the service name is absolutely necessary to create the control upon reading.
1682 m_nIncludeEvents
= EAFlags::ControlEvents
;
1683 // we always should be able to export events - this is not control type dependent
1687 // in general, all control types need to export the control id
1688 m_nIncludeCommon
|= CCAFlags::ControlId
;
1690 // is it a control bound to a calc cell?
1691 if ( FormCellBindingHelper::livesInSpreadsheetDocument( m_xProps
) )
1693 FormCellBindingHelper
aHelper( m_xProps
, nullptr );
1695 if ( FormCellBindingHelper::isCellBinding( aHelper
.getCurrentBinding( ) ) )
1697 m_nIncludeBindings
|= BAFlags::LinkedCell
;
1698 if ( m_nClassId
== FormComponentType::LISTBOX
)
1699 m_nIncludeBindings
|= BAFlags::ListLinkingType
;
1703 // is it a list-like control which uses a calc cell range as list source?
1705 if ( FormCellBindingHelper::isCellRangeListSource( aHelper
.getCurrentListSource( ) ) )
1706 m_nIncludeBindings
|= BAFlags::ListCellRange
;
1710 // is control bound to XForms?
1711 if( !getXFormsBindName( m_xProps
).isEmpty() )
1713 m_nIncludeBindings
|= BAFlags::XFormsBind
;
1716 // is (list-)control bound to XForms list?
1717 if( !getXFormsListBindName( m_xProps
).isEmpty() )
1719 m_nIncludeBindings
|= BAFlags::XFormsListBind
;
1722 // does the control have an XForms submission?
1723 if( !getXFormsSubmissionName( m_xProps
).isEmpty() )
1725 m_nIncludeBindings
|= BAFlags::XFormsSubmission
;
1729 void OControlExport::exportCellBindingAttributes( bool _bIncludeListLinkageType
)
1733 FormCellBindingHelper
aHelper( m_xProps
, nullptr );
1734 Reference
< XValueBinding
> xBinding( aHelper
.getCurrentBinding() );
1735 OSL_ENSURE( xBinding
.is(), "OControlExport::exportCellBindingAttributes: invalid bindable or invalid binding!" );
1736 if ( xBinding
.is() )
1739 OAttributeMetaData::getBindingAttributeNamespace(),
1740 OAttributeMetaData::getBindingAttributeName( BAFlags::LinkedCell
),
1741 aHelper
.getStringAddressFromCellBinding( xBinding
)
1744 if ( _bIncludeListLinkageType
)
1746 sal_Int16 nLinkageType
= FormCellBindingHelper::isCellIntegerBinding( xBinding
) ? 1 : 0;
1748 OUStringBuffer sBuffer
;
1749 SvXMLUnitConverter::convertEnum(
1756 OAttributeMetaData::getBindingAttributeNamespace(),
1757 OAttributeMetaData::getBindingAttributeName( BAFlags::ListLinkingType
),
1758 sBuffer
.makeStringAndClear()
1764 catch( const Exception
& )
1766 TOOLS_WARN_EXCEPTION( "xmloff.forms", "OControlExport::exportCellBindingAttributes" );
1770 void OControlExport::exportXFormsBindAttributes()
1772 OUString sBindName
= getXFormsBindName( m_xProps
);
1773 AddAttribute( XML_NAMESPACE_XFORMS
, XML_BIND
, sBindName
);
1775 void OControlExport::exportXFormsListAttributes()
1777 OUString sBindName
= getXFormsListBindName( m_xProps
);
1778 AddAttribute( XML_NAMESPACE_FORM
, XML_XFORMS_LIST_SOURCE
, sBindName
);
1780 void OControlExport::exportXFormsSubmissionAttributes()
1782 OUString sSubmission
= getXFormsSubmissionName( m_xProps
);
1783 AddAttribute( XML_NAMESPACE_FORM
, XML_XFORMS_SUBMISSION
, sSubmission
);
1785 void OControlExport::exportCellListSourceRange( )
1789 Reference
< XListEntrySink
> xSink( m_xProps
, UNO_QUERY
);
1790 Reference
< XListEntrySource
> xSource
;
1792 xSource
= xSink
->getListEntrySource();
1793 OSL_ENSURE( xSource
.is(), "OControlExport::exportCellListSourceRange: list source or sink!" );
1796 FormCellBindingHelper
aHelper( m_xProps
, nullptr );
1799 OAttributeMetaData::getBindingAttributeNamespace(),
1800 OAttributeMetaData::getBindingAttributeName( BAFlags::ListCellRange
),
1801 aHelper
.getStringAddressFromCellListSource( xSource
)
1805 catch( const Exception
& )
1807 TOOLS_WARN_EXCEPTION( "xmloff.forms", "OControlExport::exportCellListSourceRange" );
1811 void OControlExport::exportImagePositionAttributes()
1815 sal_Int16 nImagePosition
= ImagePosition::Centered
;
1816 OSL_VERIFY( m_xProps
->getPropertyValue( PROPERTY_IMAGE_POSITION
) >>= nImagePosition
);
1817 OSL_ENSURE( ( nImagePosition
>= ImagePosition::LeftTop
) && ( nImagePosition
<= ImagePosition::Centered
),
1818 "OControlExport::exportImagePositionAttributes: don't know this image position!" );
1820 if ( ( nImagePosition
< ImagePosition::LeftTop
) || ( nImagePosition
> ImagePosition::Centered
) )
1821 // this is important to prevent potential buffer overflows below, so don't optimize
1822 nImagePosition
= ImagePosition::Centered
;
1824 if ( nImagePosition
== ImagePosition::Centered
)
1826 AddAttribute( XML_NAMESPACE_FORM
, GetXMLToken( XML_IMAGE_POSITION
), GetXMLToken( XML_CENTER
) );
1830 const XMLTokenEnum eXmlImagePositions
[] =
1832 XML_START
, XML_END
, XML_TOP
, XML_BOTTOM
1834 const XMLTokenEnum eXmlImageAligns
[] =
1836 XML_START
, XML_CENTER
, XML_END
1839 XMLTokenEnum eXmlImagePosition
= eXmlImagePositions
[ nImagePosition
/ 3 ];
1840 XMLTokenEnum eXmlImageAlign
= eXmlImageAligns
[ nImagePosition
% 3 ];
1842 AddAttribute( XML_NAMESPACE_FORM
, GetXMLToken( XML_IMAGE_POSITION
), GetXMLToken( eXmlImagePosition
) );
1843 AddAttribute( XML_NAMESPACE_FORM
, GetXMLToken( XML_IMAGE_ALIGN
), GetXMLToken( eXmlImageAlign
) );
1846 exportedProperty( PROPERTY_IMAGE_POSITION
);
1847 // some of the controls which have an ImagePosition also have an ImageAlign for compatibility
1848 // reasons. Since the ImageAlign values simply represent a sub set of the ImagePosition values,
1849 // we don't need to export ImageAlign anymore
1850 exportedProperty( PROPERTY_IMAGE_ALIGN
);
1852 catch( const Exception
& )
1854 DBG_UNHANDLED_EXCEPTION("xmloff.forms");
1858 bool OControlExport::controlHasActiveDataBinding() const
1862 // currently exchanging the data with a database column?
1863 OUString
sBoundFieldPropertyName( u
"BoundField"_ustr
);
1864 if ( m_xPropertyInfo
.is() && m_xPropertyInfo
->hasPropertyByName( sBoundFieldPropertyName
) )
1866 Reference
< XPropertySet
> xBoundField
;
1867 m_xProps
->getPropertyValue( sBoundFieldPropertyName
) >>= xBoundField
;
1868 if ( xBoundField
.is() )
1872 // currently exchanging data with an external binding?
1873 Reference
< XBindableValue
> xBindable( m_xProps
, UNO_QUERY
);
1874 if ( xBindable
.is() && xBindable
->getValueBinding().is() )
1877 catch( const Exception
& )
1879 TOOLS_WARN_EXCEPTION( "xmloff.forms", "OColumnExport::controlHasActiveDataBinding" );
1885 bool OControlExport::controlHasUserSuppliedListEntries() const
1889 // an external list source?
1890 Reference
< XListEntrySink
> xEntrySink( m_xProps
, UNO_QUERY
);
1891 if ( xEntrySink
.is() && xEntrySink
->getListEntrySource().is() )
1894 if ( m_xPropertyInfo
.is() && m_xPropertyInfo
->hasPropertyByName( PROPERTY_LISTSOURCETYPE
) )
1896 ListSourceType eListSourceType
= ListSourceType_VALUELIST
;
1897 OSL_VERIFY( m_xProps
->getPropertyValue( PROPERTY_LISTSOURCETYPE
) >>= eListSourceType
);
1898 if ( eListSourceType
== ListSourceType_VALUELIST
)
1899 // for value lists, the list entries as entered by the user are used
1902 // for every other type, the list entries are filled with some data obtained
1903 // from a database - if and only if the ListSource property is not empty
1904 return getScalarListSourceValue().isEmpty();
1907 catch( const Exception
& )
1909 DBG_UNHANDLED_EXCEPTION("xmloff.forms");
1912 OSL_FAIL( "OControlExport::controlHasUserSuppliedListEntries: unreachable code!" );
1913 // this method should be called for list and combo boxes only
1918 OColumnExport::OColumnExport(IFormsExportContext
& _rContext
, const Reference
< XPropertySet
>& _rxControl
, const OUString
& _rControlId
,
1919 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
1920 :OControlExport(_rContext
, _rxControl
, _rControlId
, OUString(), _rEvents
)
1924 OColumnExport::~OColumnExport()
1928 void OColumnExport::exportServiceNameAttribute()
1930 // the attribute "service name" (which has a slightly different meaning for columns
1931 DBG_CHECK_PROPERTY( PROPERTY_COLUMNSERVICENAME
, OUString
);
1932 OUString sColumnServiceName
;
1933 m_xProps
->getPropertyValue(PROPERTY_COLUMNSERVICENAME
) >>= sColumnServiceName
;
1934 // the service name is a full qualified one (i.e. com.sun.star.form.TextField), but the
1935 // real service name for the column (for use with the XGridColumnFactory) is only the last
1936 // token of this complete name.
1937 sal_Int32 nLastSep
= sColumnServiceName
.lastIndexOf('.');
1938 OSL_ENSURE(-1 != nLastSep
, "OColumnExport::startExportElement: invalid service name!");
1939 sColumnServiceName
= sColumnServiceName
.copy(nLastSep
+ 1);
1940 sColumnServiceName
=
1941 m_rContext
.getGlobalContext().GetNamespaceMap().GetQNameByKey(
1942 XML_NAMESPACE_OOO
, sColumnServiceName
);
1943 // add the attribute
1944 AddAttribute( OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::ServiceName
)
1945 , OAttributeMetaData::getCommonControlAttributeName(CCAFlags::ServiceName
)
1946 , sColumnServiceName
);
1947 // flag the property as "handled"
1948 exportedProperty(PROPERTY_COLUMNSERVICENAME
);
1952 OUString
OColumnExport::getOuterXMLElementName() const
1954 return u
"column"_ustr
;
1957 void OColumnExport::exportAttributes()
1959 OControlExport::exportAttributes();
1961 // the attribute "label"
1962 exportStringPropertyAttribute(
1963 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Label
),
1964 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Label
),
1967 // the style attribute
1968 OUString sStyleName
= m_rContext
.getObjectStyleName( m_xProps
);
1969 if ( !sStyleName
.isEmpty() )
1972 OAttributeMetaData::getSpecialAttributeNamespace( SCAFlags::ColumnStyleName
),
1973 OAttributeMetaData::getSpecialAttributeName( SCAFlags::ColumnStyleName
),
1979 void OColumnExport::examine()
1981 OControlExport::examine();
1983 // grid columns miss some properties of the controls they're representing
1984 m_nIncludeCommon
&= ~CCAFlags(CCAFlags::For
| CCAFlags::Printable
| CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Label
);
1985 m_nIncludeSpecial
&= ~SCAFlags(SCAFlags::EchoChar
| SCAFlags::AutoCompletion
| SCAFlags::Multiple
| SCAFlags::MultiLine
);
1987 if (FormComponentType::DATEFIELD
!= m_nClassId
)
1988 // except date fields, no column has the DropDown property
1989 m_nIncludeCommon
&= ~CCAFlags::Dropdown
;
1993 OFormExport::OFormExport(IFormsExportContext
& _rContext
, const Reference
< XPropertySet
>& _rxForm
,
1994 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
1995 :OElementExport(_rContext
, _rxForm
, _rEvents
)
1996 ,m_bCreateConnectionResourceElement(false)
1998 OSL_ENSURE(m_xProps
.is(), "OFormExport::OFormExport: invalid arguments!");
2001 OUString
OFormExport::getXMLElementName() const
2003 return u
"form"_ustr
;
2006 void OFormExport::exportSubTags()
2008 if ( m_bCreateConnectionResourceElement
&& m_xProps
.is() )
2010 m_rContext
.getGlobalContext().ClearAttrList();
2011 OUString sPropValue
;
2012 m_xProps
->getPropertyValue( PROPERTY_DATASOURCENAME
) >>= sPropValue
; // if set it is a file url
2013 if ( sPropValue
.isEmpty() )
2014 m_xProps
->getPropertyValue( PROPERTY_URL
) >>= sPropValue
;
2015 if ( !sPropValue
.isEmpty() )
2017 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::TargetLocation
),
2018 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::TargetLocation
),
2019 m_rContext
.getGlobalContext().GetRelativeReference(sPropValue
));
2020 if ( m_rContext
.getGlobalContext().GetAttrList().getLength() )
2022 SvXMLElementExport
aFormElement(m_rContext
.getGlobalContext(), XML_NAMESPACE_FORM
, xmloff::token::XML_CONNECTION_RESOURCE
, true, true);
2026 // let the base class export the remaining properties and the events
2027 OElementExport::exportSubTags();
2028 // loop through all children
2029 Reference
< XIndexAccess
> xCollection(m_xProps
, UNO_QUERY
);
2030 OSL_ENSURE(xCollection
.is(), "OFormLayerXMLExport::implExportForm: a form which is not an index access? Suspicious!");
2032 if (xCollection
.is())
2033 m_rContext
.exportCollectionElements(xCollection
);
2036 void OFormExport::exportAttributes()
2040 // the string properties
2042 static const FormAttributes eStringPropertyIds
[] =
2044 faName
, /*faAction,*/ faCommand
, faFilter
, faOrder
2046 static constexpr OUString aStringPropertyNames
[] =
2048 PROPERTY_NAME
, /*PROPERTY_TARGETURL,*/ PROPERTY_COMMAND
, PROPERTY_FILTER
, PROPERTY_ORDER
2050 static const sal_Int32 nIdCount
= std::size(eStringPropertyIds
);
2051 #if OSL_DEBUG_LEVEL > 0
2052 static const sal_Int32 nNameCount
= std::size(aStringPropertyNames
);
2053 OSL_ENSURE((nIdCount
== nNameCount
),
2054 "OFormExport::exportAttributes: somebody tampered with the maps (1)!");
2056 for (i
=0; i
<nIdCount
; ++i
)
2057 exportStringPropertyAttribute(
2058 OAttributeMetaData::getFormAttributeNamespace(eStringPropertyIds
[i
]),
2059 OAttributeMetaData::getFormAttributeName(eStringPropertyIds
[i
]),
2060 aStringPropertyNames
[i
]);
2062 // #i112082# xlink:type is added as part of exportTargetLocationAttribute
2064 // now export the data source name or databaselocation or connection resource
2065 OUString sPropValue
;
2066 m_xProps
->getPropertyValue( PROPERTY_DATASOURCENAME
) >>= sPropValue
;
2067 m_bCreateConnectionResourceElement
= sPropValue
.isEmpty();
2068 if ( !m_bCreateConnectionResourceElement
)
2070 INetURLObject
aURL(sPropValue
);
2071 m_bCreateConnectionResourceElement
= ( aURL
.GetProtocol() == INetProtocol::File
);
2072 if ( !m_bCreateConnectionResourceElement
)
2073 exportStringPropertyAttribute(
2074 OAttributeMetaData::getFormAttributeNamespace(faDatasource
),
2075 OAttributeMetaData::getFormAttributeName(faDatasource
),
2076 PROPERTY_DATASOURCENAME
);
2079 exportedProperty(PROPERTY_URL
);
2080 if ( m_bCreateConnectionResourceElement
)
2081 exportedProperty(PROPERTY_DATASOURCENAME
);
2084 // the boolean properties
2086 static const FormAttributes eBooleanPropertyIds
[] =
2088 faAllowDeletes
, faAllowInserts
, faAllowUpdates
, faApplyFilter
, faEscapeProcessing
, faIgnoreResult
2090 static constexpr OUString pBooleanPropertyNames
[] =
2092 PROPERTY_ALLOWDELETES
,
2093 PROPERTY_ALLOWINSERTS
,
2094 PROPERTY_ALLOWUPDATES
,
2095 PROPERTY_APPLYFILTER
,
2096 PROPERTY_ESCAPEPROCESSING
,
2097 PROPERTY_IGNORERESULT
2099 static const BoolAttrFlags nBooleanPropertyAttrFlags
[] =
2101 BoolAttrFlags::DefaultTrue
, BoolAttrFlags::DefaultTrue
, BoolAttrFlags::DefaultTrue
, BoolAttrFlags::DefaultFalse
, BoolAttrFlags::DefaultTrue
, BoolAttrFlags::DefaultFalse
2103 static const sal_Int32 nIdCount
= std::size(eBooleanPropertyIds
);
2104 #if OSL_DEBUG_LEVEL > 0
2105 static const sal_Int32 nNameCount
= std::size(pBooleanPropertyNames
);
2106 static const sal_Int32 nFlagsCount
= std::size(nBooleanPropertyAttrFlags
);
2107 OSL_ENSURE((nIdCount
== nNameCount
) && (nNameCount
== nFlagsCount
),
2108 "OFormExport::exportAttributes: somebody tampered with the maps (2)!");
2110 for (i
=0; i
<nIdCount
; ++i
)
2111 exportBooleanPropertyAttribute(
2112 OAttributeMetaData::getFormAttributeNamespace(eBooleanPropertyIds
[i
]),
2113 OAttributeMetaData::getFormAttributeName(eBooleanPropertyIds
[i
]),
2114 pBooleanPropertyNames
[i
],
2115 nBooleanPropertyAttrFlags
[i
]
2119 // the enum properties
2121 exportEnumPropertyAttribute(
2122 OAttributeMetaData::getFormAttributeNamespace(faEnctype
),
2123 OAttributeMetaData::getFormAttributeName(faEnctype
),
2124 PROPERTY_SUBMIT_ENCODING
,
2126 FormSubmitEncoding_URL
,
2129 exportEnumPropertyAttribute(
2130 OAttributeMetaData::getFormAttributeNamespace(faMethod
),
2131 OAttributeMetaData::getFormAttributeName(faMethod
),
2132 PROPERTY_SUBMIT_METHOD
,
2134 FormSubmitMethod_GET
,
2137 exportEnumPropertyAttribute(
2138 OAttributeMetaData::getFormAttributeNamespace(faCommandType
),
2139 OAttributeMetaData::getFormAttributeName(faCommandType
),
2140 PROPERTY_COMMAND_TYPE
,
2142 CommandType::COMMAND
,
2145 exportEnumPropertyAttribute(
2146 OAttributeMetaData::getFormAttributeNamespace(faNavigationMode
),
2147 OAttributeMetaData::getFormAttributeName(faNavigationMode
),
2148 PROPERTY_NAVIGATION
,
2150 NavigationBarMode_CURRENT
,
2153 exportEnumPropertyAttribute(
2154 OAttributeMetaData::getFormAttributeNamespace(faTabbingCycle
),
2155 OAttributeMetaData::getFormAttributeName(faTabbingCycle
),
2158 TabulatorCycle_RECORDS
,
2164 exportServiceNameAttribute();
2166 exportTargetFrameAttribute();
2168 exportTargetLocationAttribute(true); // #i110911# add type attribute (for form, but not for control)
2171 exportStringSequenceAttribute(
2172 OAttributeMetaData::getFormAttributeNamespace(faMasterFields
),
2173 OAttributeMetaData::getFormAttributeName(faMasterFields
),
2174 PROPERTY_MASTERFIELDS
);
2176 exportStringSequenceAttribute(
2177 OAttributeMetaData::getFormAttributeNamespace(faDetailFields
),
2178 OAttributeMetaData::getFormAttributeName(faDetailFields
),
2179 PROPERTY_DETAILFIELDS
);
2181 } // namespace xmloff
2183 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */