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/macros.h>
63 #include <sal/log.hxx>
66 #include <string_view>
71 #if OSL_DEBUG_LEVEL > 0
72 #define RESET_BIT( bitfield, bit ) \
73 bitfield = bitfield & ~bit
75 #define RESET_BIT( bitfield, bit )
78 using namespace ::xmloff::token
;
79 using namespace ::com::sun::star
;
80 using namespace ::com::sun::star::uno
;
81 using namespace ::com::sun::star::sdb
;
82 using namespace ::com::sun::star::awt
;
83 using namespace ::com::sun::star::form
;
84 using namespace ::com::sun::star::lang
;
85 using namespace ::com::sun::star::beans
;
86 using namespace ::com::sun::star::container
;
87 using namespace ::com::sun::star::script
;
88 using namespace ::com::sun::star::io
;
89 using namespace ::com::sun::star::table
;
90 using namespace ::com::sun::star::text
;
91 using namespace ::com::sun::star::form::binding
;
94 OElementExport::OElementExport(IFormsExportContext
& _rContext
, const Reference
< XPropertySet
>& _rxProps
,
95 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
96 :OPropertyExport(_rContext
, _rxProps
)
101 OElementExport::~OElementExport()
105 void OElementExport::doExport()
107 // collect some general information about the element
110 // first add the attributes necessary for the element
111 m_rContext
.getGlobalContext().ClearAttrList();
113 // add the attributes
116 // start the XML element
117 implStartElement(getXMLElementName());
119 // the sub elements (mostly control type dependent)
125 void OElementExport::examine()
127 // nothing to do here
130 void OElementExport::exportAttributes()
132 // nothing to do here
135 void OElementExport::exportSubTags()
137 // the properties which where not exported 'til now
138 exportRemainingProperties();
140 // the script:events sub tags
144 void OElementExport::implStartElement(const char* _pName
)
146 m_pXMLElement
= std::make_unique
<SvXMLElementExport
>(m_rContext
.getGlobalContext(), XML_NAMESPACE_FORM
, _pName
, true, true);
149 void OElementExport::implEndElement()
151 m_pXMLElement
.reset();
154 void OElementExport::exportServiceNameAttribute()
156 Reference
< XPersistObject
> xPersistence(m_xProps
, UNO_QUERY
);
157 if (!xPersistence
.is())
159 OSL_FAIL("OElementExport::exportServiceNameAttribute: no XPersistObject!");
163 OUString sServiceName
= xPersistence
->getServiceName();
164 // we don't want to write the old service name directly: it's a name used for compatibility reasons, but
165 // as we start some kind of new file format here (with this xml export), we don't care about
167 // So we translate the old persistence service name into new ones, if possible
169 OUString sToWriteServiceName
= sServiceName
;
170 #define CHECK_N_TRANSLATE( name ) \
171 else if (sServiceName == SERVICE_PERSISTENT_COMPONENT_##name) \
172 sToWriteServiceName = SERVICE_##name
174 if (sServiceName
== SERVICE_PERSISTENT_COMPONENT_EDIT
)
176 // special handling for the edit field: we have two controls using this as persistence service name
177 sToWriteServiceName
= SERVICE_EDIT
;
178 Reference
< XServiceInfo
> xSI(m_xProps
, UNO_QUERY
);
179 if (xSI
.is() && xSI
->supportsService(SERVICE_FORMATTEDFIELD
))
180 sToWriteServiceName
= SERVICE_FORMATTEDFIELD
;
182 CHECK_N_TRANSLATE( FORM
);
183 CHECK_N_TRANSLATE( LISTBOX
);
184 CHECK_N_TRANSLATE( COMBOBOX
);
185 CHECK_N_TRANSLATE( RADIOBUTTON
);
186 CHECK_N_TRANSLATE( GROUPBOX
);
187 CHECK_N_TRANSLATE( FIXEDTEXT
);
188 CHECK_N_TRANSLATE( COMMANDBUTTON
);
189 CHECK_N_TRANSLATE( CHECKBOX
);
190 CHECK_N_TRANSLATE( GRID
);
191 CHECK_N_TRANSLATE( IMAGEBUTTON
);
192 CHECK_N_TRANSLATE( FILECONTROL
);
193 CHECK_N_TRANSLATE( TIMEFIELD
);
194 CHECK_N_TRANSLATE( DATEFIELD
);
195 CHECK_N_TRANSLATE( NUMERICFIELD
);
196 CHECK_N_TRANSLATE( CURRENCYFIELD
);
197 CHECK_N_TRANSLATE( PATTERNFIELD
);
198 CHECK_N_TRANSLATE( HIDDENCONTROL
);
199 CHECK_N_TRANSLATE( IMAGECONTROL
);
200 CHECK_N_TRANSLATE( FORMATTEDFIELD
);
201 #if OSL_DEBUG_LEVEL > 0
202 Reference
< XServiceInfo
> xSI(m_xProps
, UNO_QUERY
);
203 OSL_ENSURE(xSI
.is() && xSI
->supportsService(sToWriteServiceName
),
204 "OElementExport::exportServiceNameAttribute: wrong service name translation!");
207 sToWriteServiceName
=
208 m_rContext
.getGlobalContext().GetNamespaceMap().GetQNameByKey(
209 XML_NAMESPACE_OOO
, sToWriteServiceName
);
213 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::ServiceName
),
214 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::ServiceName
),
215 sToWriteServiceName
);
218 void OElementExport::exportEvents()
220 if (!m_aEvents
.hasElements())
224 Reference
< XNameReplace
> xWrapper
= new OEventDescriptorMapper(m_aEvents
);
225 m_rContext
.getGlobalContext().GetEventExport().Export(xWrapper
);
229 OControlExport::OControlExport(IFormsExportContext
& _rContext
, const Reference
< XPropertySet
>& _rxControl
,
230 OUString _sControlId
, OUString _sReferringControls
,
231 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
232 :OElementExport(_rContext
, _rxControl
, _rEvents
)
233 ,m_sControlId(std::move(_sControlId
))
234 ,m_sReferringControls(std::move(_sReferringControls
))
235 ,m_nClassId(FormComponentType::CONTROL
)
237 ,m_nIncludeCommon(CCAFlags::NONE
)
238 ,m_nIncludeDatabase(DAFlags::NONE
)
239 ,m_nIncludeSpecial(SCAFlags::NONE
)
240 ,m_nIncludeEvents(EAFlags::NONE
)
241 ,m_nIncludeBindings(BAFlags::NONE
)
243 OSL_ENSURE(m_xProps
.is(), "OControlExport::OControlExport: invalid arguments!");
246 void OControlExport::exportOuterAttributes()
249 if (CCAFlags::Name
& m_nIncludeCommon
)
251 exportStringPropertyAttribute(
252 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Name
),
253 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Name
),
256 #if OSL_DEBUG_LEVEL > 0
257 // reset the bit for later checking
258 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::Name
;
263 if (m_nIncludeCommon
& CCAFlags::ServiceName
)
265 exportServiceNameAttribute();
266 #if OSL_DEBUG_LEVEL > 0
267 // reset the bit for later checking
268 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::ServiceName
;
273 void OControlExport::exportInnerAttributes()
276 if (CCAFlags::ControlId
& m_nIncludeCommon
)
278 OSL_ENSURE(!m_sControlId
.isEmpty(), "OControlExport::exportInnerAttributes: have no control id for the control!");
279 m_rContext
.getGlobalContext().AddAttributeIdLegacy(
280 XML_NAMESPACE_FORM
, m_sControlId
);
281 #if OSL_DEBUG_LEVEL > 0
282 // reset the bit for later checking
283 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::ControlId
;
287 // "new-style" properties ...
288 exportGenericHandlerAttributes();
290 // common control attributes
291 exportCommonControlAttributes();
293 // common database attributes
294 exportDatabaseAttributes();
296 // attributes related to external bindings
297 exportBindingAttributes();
299 // attributes special to the respective control type
300 exportSpecialAttributes();
302 // add the style references to the attributes
303 flagStyleProperties();
306 void OControlExport::exportAttributes()
308 exportOuterAttributes();
311 void OControlExport::exportSubTags()
313 // for the upcoming exportRemainingProperties:
314 // if a control has the LabelControl property, this is not stored with the control itself, but instead with
315 // the control which is referenced by this property. As the base class' exportRemainingProperties doesn't
316 // know anything about this, we need to prevent that it tries to export this property
317 exportedProperty(PROPERTY_CONTROLLABEL
);
319 // if it's a control supporting XText, then we need to declare all text-related properties
320 // as "already exported". This prevents them from being exported as generic "form:property"-tags.
321 // *If* we would export them this way, they would be completely superfluous, and sometimes even
322 // disastrous, since they may, at import time, override paragraph properties which already have
324 Reference
< XText
> xControlText( m_xProps
, UNO_QUERY
);
325 if ( xControlText
.is() )
327 const XMLPropertyMapEntry
* pCharAttributeProperties
= XMLTextPropertySetMapper::getPropertyMapForType( TextPropMap::TEXT
);
328 while ( !pCharAttributeProperties
->IsEnd() )
330 exportedProperty( pCharAttributeProperties
->getApiName() );
331 ++pCharAttributeProperties
;
334 const XMLPropertyMapEntry
* pParaAttributeProperties
= XMLTextPropertySetMapper::getPropertyMapForType( TextPropMap::SHAPE_PARA
);
335 while ( !pParaAttributeProperties
->IsEnd() )
337 exportedProperty( pParaAttributeProperties
->getApiName() );
338 ++pParaAttributeProperties
;
341 // the RichText property is not exported. The presence of the text:p element
342 // will be used - upon reading - as indicator for the value of the RichText property
343 exportedProperty( PROPERTY_RICH_TEXT
);
345 // strange thing: paragraphs support both a CharStrikeout and a CharCrossedOut property
346 // The former is a short/enum value, the latter a boolean. The former has a real meaning
347 // (the strikeout type), the latter hasn't. But, when the CharCrossedOut is exported and
348 // later on imported, it overwrites anything which has previously been imported for
351 exportedProperty( "CharCrossedOut" );
354 if ( m_eType
== LISTBOX
)
356 // will be exported in exportListSourceAsElements:
357 if ( controlHasUserSuppliedListEntries() )
358 exportedProperty( PROPERTY_DEFAULT_SELECT_SEQ
);
360 // will not be exported in a generic way. Either exportListSourceAsElements cares
361 // for them, or we don't need them
362 exportedProperty( PROPERTY_STRING_ITEM_LIST
);
363 exportedProperty( PROPERTY_VALUE_SEQ
);
364 exportedProperty( PROPERTY_SELECT_SEQ
);
365 exportedProperty( PROPERTY_LISTSOURCE
);
367 if ( m_eType
== COMBOBOX
)
368 exportedProperty( PROPERTY_STRING_ITEM_LIST
);
370 // let the base class export the remaining properties and the events
371 OElementExport::exportSubTags();
373 // special sub tags for some controls
377 // don't export the list entries if the are not provided by the user, but obtained implicitly
378 // from other sources
380 if ( controlHasUserSuppliedListEntries() )
381 exportListSourceAsElements();
384 { // a grid control requires us to store all columns as sub elements
385 Reference
< XIndexAccess
> xColumnContainer(m_xProps
, UNO_QUERY
);
386 OSL_ENSURE(xColumnContainer
.is(), "OControlExport::exportSubTags: a grid control which is no IndexAccess?!!");
387 if (xColumnContainer
.is())
388 m_rContext
.exportCollectionElements(xColumnContainer
);
392 { // a combox box description has sub elements: the items
393 DBG_CHECK_PROPERTY( PROPERTY_STRING_ITEM_LIST
, Sequence
< OUString
> );
395 // don't export the list entries if the are not provided by the user, but obtained implicitly
396 // from other sources
398 if ( controlHasUserSuppliedListEntries() )
401 Sequence
< OUString
> aListItems
;
402 m_xProps
->getPropertyValue(PROPERTY_STRING_ITEM_LIST
) >>= aListItems
;
403 // loop through it and write the sub elements
404 for (const auto& rListItem
: std::as_const(aListItems
))
406 m_rContext
.getGlobalContext().ClearAttrList();
408 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Label
),
409 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Label
),
411 SvXMLElementExport
aFormElement(m_rContext
.getGlobalContext(), XML_NAMESPACE_FORM
, "item", true, true);
419 // if we act as rich text control, we need to export some text:p elements
420 if ( xControlText
.is() )
422 bool bActingAsRichText
= false;
423 if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_RICH_TEXT
) )
425 OSL_VERIFY(m_xProps
->getPropertyValue( PROPERTY_RICH_TEXT
) >>= bActingAsRichText
);
428 if ( bActingAsRichText
)
429 m_rContext
.getGlobalContext().GetTextParagraphExport()->exportText( xControlText
);
439 void OControlExport::exportGenericHandlerAttributes()
441 const Sequence
< Property
> aProperties
= m_xPropertyInfo
->getProperties();
442 for ( auto const & prop
: aProperties
)
446 // see if this property can already be handled with an IPropertyHandler (which, on the long
447 // term, should be the case for most, if not all, properties)
448 const PropertyDescription
* propDescription
= metadata::getPropertyDescription( prop
.Name
);
449 if ( propDescription
== nullptr )
452 // let the factory provide the concrete handler. Note that caching, if desired, is the task
454 PPropertyHandler handler
= (*propDescription
->factory
)( propDescription
->propertyId
);
457 SAL_WARN( "xmloff.forms", "OControlExport::exportGenericHandlerAttributes: invalid property handler provided by the factory!" );
461 // that's a property which has a direct mapping to an attribute
462 if ( !shouldExportProperty( prop
.Name
) )
463 // TODO: in the future, we surely need a more sophisticated approach to this, involving the property
464 // handler, or the property description
466 exportedProperty( prop
.Name
);
470 const Any propValue
= m_xProps
->getPropertyValue( prop
.Name
);
471 OUString attributeValue
= handler
->getAttributeValue( propValue
);
474 propDescription
->attribute
.namespacePrefix
,
475 token::GetXMLToken( propDescription
->attribute
.attributeToken
),
479 exportedProperty( prop
.Name
);
481 catch( const Exception
& )
483 DBG_UNHANDLED_EXCEPTION("xmloff.forms");
488 void OControlExport::exportCommonControlAttributes()
492 // I decided to handle all the properties here with some static arrays describing the property-attribute
493 // relations. This leads to somewhat ugly code :), but the only alternative I can think of right now
494 // would require maps and O(log n) searches, which seems somewhat expensive as this code is used
497 // the extra indents for the respective blocks are to ensure that there is no copy'n'paste error, using
498 // map identifiers from the wrong block
500 // some string properties
502 // the attribute ids of all properties which are expected to be of type string
503 static const CCAFlags nStringPropertyAttributeIds
[] =
505 CCAFlags::Label
, CCAFlags::Title
507 // the names of all properties which are expected to be of type string
508 static const rtl::OUStringConstExpr aStringPropertyNames
[] =
510 PROPERTY_LABEL
, PROPERTY_TITLE
512 OSL_ENSURE( std::size(aStringPropertyNames
) ==
513 std::size(nStringPropertyAttributeIds
),
514 "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (1)!");
516 for (i
=0; i
<std::size(nStringPropertyAttributeIds
); ++i
)
517 if (nStringPropertyAttributeIds
[i
] & m_nIncludeCommon
)
519 exportStringPropertyAttribute(
520 OAttributeMetaData::getCommonControlAttributeNamespace(nStringPropertyAttributeIds
[i
]),
521 OAttributeMetaData::getCommonControlAttributeName(nStringPropertyAttributeIds
[i
]),
522 aStringPropertyNames
[i
]
524 #if OSL_DEBUG_LEVEL > 0
525 // reset the bit for later checking
526 m_nIncludeCommon
= m_nIncludeCommon
& ~nStringPropertyAttributeIds
[i
];
531 // some boolean properties
533 static const CCAFlags nBooleanPropertyAttributeIds
[] =
535 CCAFlags::CurrentSelected
, CCAFlags::Disabled
, CCAFlags::Dropdown
, CCAFlags::Printable
, CCAFlags::ReadOnly
, CCAFlags::Selected
, CCAFlags::TabStop
, CCAFlags::EnableVisible
537 static const rtl::OUStringConstExpr pBooleanPropertyNames
[] =
539 PROPERTY_STATE
, PROPERTY_ENABLED
,
540 PROPERTY_DROPDOWN
, PROPERTY_PRINTABLE
,
541 PROPERTY_READONLY
, PROPERTY_DEFAULT_STATE
,
542 PROPERTY_TABSTOP
, PROPERTY_ENABLEVISIBLE
544 static const BoolAttrFlags nBooleanPropertyAttrFlags
[] =
545 { // attribute defaults
546 BoolAttrFlags::DefaultFalse
, BoolAttrFlags::DefaultFalse
| BoolAttrFlags::InverseSemantics
, BoolAttrFlags::DefaultFalse
, BoolAttrFlags::DefaultTrue
, BoolAttrFlags::DefaultFalse
, BoolAttrFlags::DefaultFalse
, BoolAttrFlags::DefaultVoid
, BoolAttrFlags::DefaultFalse
548 #if OSL_DEBUG_LEVEL > 0
549 static const sal_Int32 nIdCount
= std::size(nBooleanPropertyAttributeIds
);
550 static const sal_Int32 nNameCount
= std::size(pBooleanPropertyNames
);
551 static const sal_Int32 nFlagsCount
= std::size(nBooleanPropertyAttrFlags
);
552 OSL_ENSURE((nIdCount
== nNameCount
) && (nNameCount
== nFlagsCount
),
553 "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (2)!");
555 for (i
=0; i
<std::size(nBooleanPropertyAttributeIds
); ++i
)
556 if (nBooleanPropertyAttributeIds
[i
] & m_nIncludeCommon
)
558 exportBooleanPropertyAttribute(
559 OAttributeMetaData::getCommonControlAttributeNamespace(nBooleanPropertyAttributeIds
[i
]),
560 OAttributeMetaData::getCommonControlAttributeName(nBooleanPropertyAttributeIds
[i
]),
561 pBooleanPropertyNames
[i
],
562 nBooleanPropertyAttrFlags
[i
]);
563 #if OSL_DEBUG_LEVEL > 0
564 // reset the bit for later checking
565 m_nIncludeCommon
= m_nIncludeCommon
& ~nBooleanPropertyAttributeIds
[i
];
570 // some integer properties
572 // now the common handling
573 static const CCAFlags nIntegerPropertyAttributeIds
[] =
575 CCAFlags::Size
, CCAFlags::TabIndex
577 static const rtl::OUStringConstExpr pIntegerPropertyNames
[] =
579 PROPERTY_LINECOUNT
, PROPERTY_TABINDEX
581 static const sal_Int16 nIntegerPropertyAttrDefaults
[] =
582 { // attribute defaults
586 if ( m_nIncludeCommon
& CCAFlags::MaxLength
)
587 exportedProperty(PROPERTY_MAXTEXTLENGTH
);
589 #if OSL_DEBUG_LEVEL > 0
590 static const sal_Int32 nIdCount
= std::size(nIntegerPropertyAttributeIds
);
591 static const sal_Int32 nNameCount
= std::size(pIntegerPropertyNames
);
592 static const sal_Int32 nDefaultCount
= std::size(nIntegerPropertyAttrDefaults
);
593 OSL_ENSURE((nIdCount
== nNameCount
) && (nNameCount
== nDefaultCount
),
594 "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (3)!");
596 for (i
=0; i
<std::size(nIntegerPropertyAttributeIds
); ++i
)
597 if (nIntegerPropertyAttributeIds
[i
] & m_nIncludeCommon
)
599 exportInt16PropertyAttribute(
600 OAttributeMetaData::getCommonControlAttributeNamespace(nIntegerPropertyAttributeIds
[i
]),
601 OAttributeMetaData::getCommonControlAttributeName(nIntegerPropertyAttributeIds
[i
]),
602 pIntegerPropertyNames
[i
],
603 nIntegerPropertyAttrDefaults
[i
]);
604 #if OSL_DEBUG_LEVEL > 0
605 // reset the bit for later checking
606 m_nIncludeCommon
= m_nIncludeCommon
& ~nIntegerPropertyAttributeIds
[i
];
612 // some enum properties
614 if (m_nIncludeCommon
& CCAFlags::ButtonType
)
616 exportEnumPropertyAttribute(
617 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::ButtonType
),
618 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::ButtonType
),
621 FormButtonType_PUSH
);
622 #if OSL_DEBUG_LEVEL > 0
623 // reset the bit for later checking
624 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::ButtonType
;
627 if ( m_nIncludeCommon
& CCAFlags::Orientation
)
629 exportEnumPropertyAttribute(
630 OAttributeMetaData::getCommonControlAttributeNamespace( CCAFlags::Orientation
),
631 OAttributeMetaData::getCommonControlAttributeName( CCAFlags::Orientation
),
632 PROPERTY_ORIENTATION
,
634 ScrollBarOrientation::HORIZONTAL
636 #if OSL_DEBUG_LEVEL > 0
637 // reset the bit for later checking
638 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::Orientation
;
642 if ( m_nIncludeCommon
& CCAFlags::VisualEffect
)
644 exportEnumPropertyAttribute(
645 OAttributeMetaData::getCommonControlAttributeNamespace( CCAFlags::VisualEffect
),
646 OAttributeMetaData::getCommonControlAttributeName( CCAFlags::VisualEffect
),
647 PROPERTY_VISUAL_EFFECT
,
651 #if OSL_DEBUG_LEVEL > 0
652 // reset the bit for later checking
653 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::VisualEffect
;
658 // some properties which require a special handling
661 if (m_nIncludeCommon
& CCAFlags::TargetFrame
)
663 exportTargetFrameAttribute();
664 #if OSL_DEBUG_LEVEL > 0
665 // reset the bit for later checking
666 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::TargetFrame
;
671 if ( m_nIncludeCommon
& CCAFlags::MaxLength
)
673 // normally, the respective property would be "MaxTextLen"
674 // However, if the model has a property "PersistenceMaxTextLength", then we prefer this
676 // determine the name of the property to export
677 OUString
sTextLenPropertyName( PROPERTY_MAXTEXTLENGTH
);
678 if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_PERSISTENCE_MAXTEXTLENGTH
) )
679 sTextLenPropertyName
= PROPERTY_PERSISTENCE_MAXTEXTLENGTH
;
682 exportInt16PropertyAttribute(
683 OAttributeMetaData::getCommonControlAttributeNamespace( CCAFlags::MaxLength
),
684 OAttributeMetaData::getCommonControlAttributeName( CCAFlags::MaxLength
),
685 sTextLenPropertyName
,
689 // in either way, both properties count as "exported"
690 exportedProperty( PROPERTY_MAXTEXTLENGTH
);
691 exportedProperty( PROPERTY_PERSISTENCE_MAXTEXTLENGTH
);
693 #if OSL_DEBUG_LEVEL > 0
694 // reset the bit for later checking
695 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::MaxLength
;
699 if (m_nIncludeCommon
& CCAFlags::TargetLocation
)
701 exportTargetLocationAttribute(false);
702 #if OSL_DEBUG_LEVEL > 0
703 // reset the bit for later checking
704 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::TargetLocation
;
709 if (m_nIncludeCommon
& CCAFlags::ImageData
)
711 exportImageDataAttribute();
712 #if OSL_DEBUG_LEVEL > 0
713 // reset the bit for later checking
714 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::ImageData
;
720 if (m_nIncludeCommon
& CCAFlags::For
)
722 if (!m_sReferringControls
.isEmpty())
723 { // there is at least one control referring to the one we're handling currently
725 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::For
),
726 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::For
),
727 m_sReferringControls
);
729 #if OSL_DEBUG_LEVEL > 0
730 // reset the bit for later checking
731 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::For
;
735 if ((CCAFlags::CurrentValue
| CCAFlags::Value
) & m_nIncludeCommon
)
737 OUString pCurrentValuePropertyName
;
738 OUString pValuePropertyName
;
740 // get the property names
741 getValuePropertyNames(m_eType
, m_nClassId
, pCurrentValuePropertyName
, pValuePropertyName
);
743 // add the attributes if necessary and possible
744 if (!pCurrentValuePropertyName
.isEmpty() && (CCAFlags::CurrentValue
& m_nIncludeCommon
))
746 static const OUString pCurrentValueAttributeName
= OAttributeMetaData::getCommonControlAttributeName(CCAFlags::CurrentValue
);
747 // don't export the current-value if this value originates from a data binding
749 if ( controlHasActiveDataBinding() )
750 exportedProperty( pCurrentValuePropertyName
);
753 static const sal_uInt16 nCurrentValueAttributeNamespaceKey
= OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::CurrentValue
);
754 exportGenericPropertyAttribute(
755 nCurrentValueAttributeNamespaceKey
,
756 pCurrentValueAttributeName
,
757 pCurrentValuePropertyName
762 if (!pValuePropertyName
.isEmpty() && (CCAFlags::Value
& m_nIncludeCommon
))
764 static const OUString pValueAttributeName
= OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Value
);
765 static const sal_uInt16 nValueAttributeNamespaceKey
= OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Value
);
766 exportGenericPropertyAttribute(
767 nValueAttributeNamespaceKey
,
772 OSL_ENSURE((pValuePropertyName
.isEmpty()) == (CCAFlags::NONE
== (CCAFlags::Value
& m_nIncludeCommon
)),
773 "OControlExport::exportCommonControlAttributes: no property found for the value attribute!");
774 OSL_ENSURE((pCurrentValuePropertyName
.isEmpty()) == (CCAFlags::NONE
== (CCAFlags::CurrentValue
& m_nIncludeCommon
)),
775 "OControlExport::exportCommonControlAttributes: no property found for the current-value attribute!");
777 #if OSL_DEBUG_LEVEL > 0
778 // reset the bit for later checking
779 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags(CCAFlags::CurrentValue
| CCAFlags::Value
);
783 OSL_ENSURE(CCAFlags::NONE
== m_nIncludeCommon
,
784 "OControlExport::exportCommonControlAttributes: forgot some flags!");
785 // in the dbg_util version, we should have removed every bit we handled from the mask, so it should
789 void OControlExport::exportDatabaseAttributes()
791 #if OSL_DEBUG_LEVEL > 0
792 DAFlags nIncludeDatabase
= m_nIncludeDatabase
;
794 // the only string property: DataField
795 if (DAFlags::DataField
& m_nIncludeDatabase
)
797 exportStringPropertyAttribute(
798 OAttributeMetaData::getDatabaseAttributeNamespace(),
799 OAttributeMetaData::getDatabaseAttributeName(DAFlags::DataField
),
801 RESET_BIT( nIncludeDatabase
, DAFlags::DataField
);
805 if ( DAFlags::InputRequired
& m_nIncludeDatabase
)
807 exportBooleanPropertyAttribute(
808 OAttributeMetaData::getDatabaseAttributeNamespace(),
809 OAttributeMetaData::getDatabaseAttributeName( DAFlags::InputRequired
),
810 PROPERTY_INPUT_REQUIRED
,
811 BoolAttrFlags::DefaultFalse
| BoolAttrFlags::DefaultVoid
813 RESET_BIT( nIncludeDatabase
, DAFlags::InputRequired
);
816 // the only int16 property: BoundColumn
817 if (DAFlags::BoundColumn
& m_nIncludeDatabase
)
819 exportInt16PropertyAttribute(
820 OAttributeMetaData::getDatabaseAttributeNamespace(),
821 OAttributeMetaData::getDatabaseAttributeName(DAFlags::BoundColumn
),
822 PROPERTY_BOUNDCOLUMN
,
825 RESET_BIT( nIncludeDatabase
, DAFlags::BoundColumn
);
828 // ConvertEmptyToNull
829 if (DAFlags::ConvertEmpty
& m_nIncludeDatabase
)
831 exportBooleanPropertyAttribute(
832 OAttributeMetaData::getDatabaseAttributeNamespace(),
833 OAttributeMetaData::getDatabaseAttributeName(DAFlags::ConvertEmpty
),
834 PROPERTY_EMPTY_IS_NULL
,
835 BoolAttrFlags::DefaultFalse
837 RESET_BIT( nIncludeDatabase
, DAFlags::ConvertEmpty
);
840 // the only enum property: ListSourceType
841 if (DAFlags::ListSource_TYPE
& m_nIncludeDatabase
)
843 exportEnumPropertyAttribute(
844 OAttributeMetaData::getDatabaseAttributeNamespace(),
845 OAttributeMetaData::getDatabaseAttributeName(DAFlags::ListSource_TYPE
),
846 PROPERTY_LISTSOURCETYPE
,
848 ListSourceType_VALUELIST
850 RESET_BIT( nIncludeDatabase
, DAFlags::ListSource_TYPE
);
853 if (m_nIncludeDatabase
& DAFlags::ListSource
)
855 exportListSourceAsAttribute();
856 RESET_BIT( nIncludeDatabase
, DAFlags::ListSource
);
859 #if OSL_DEBUG_LEVEL > 0
860 OSL_ENSURE(DAFlags::NONE
== nIncludeDatabase
,
861 "OControlExport::exportDatabaseAttributes: forgot some flags!");
862 // in the dbg_util version, we should have removed every bit we handled from the mask, so it should
867 void OControlExport::exportBindingAttributes()
869 #if OSL_DEBUG_LEVEL > 0
870 BAFlags nIncludeBinding
= m_nIncludeBindings
;
873 if ( m_nIncludeBindings
& BAFlags::LinkedCell
)
875 exportCellBindingAttributes( bool(m_nIncludeBindings
& BAFlags::ListLinkingType
) );
876 #if OSL_DEBUG_LEVEL > 0
877 // reset the bit for later checking
878 nIncludeBinding
= nIncludeBinding
& ~BAFlags( BAFlags::LinkedCell
| BAFlags::ListLinkingType
);
882 if ( m_nIncludeBindings
& BAFlags::ListCellRange
)
884 exportCellListSourceRange();
885 #if OSL_DEBUG_LEVEL > 0
886 // reset the bit for later checking
887 nIncludeBinding
= nIncludeBinding
& ~BAFlags::ListCellRange
;
891 if ( m_nIncludeBindings
& BAFlags::XFormsBind
)
893 exportXFormsBindAttributes();
894 #if OSL_DEBUG_LEVEL > 0
895 // reset the bit for later checking
896 nIncludeBinding
= nIncludeBinding
& ~BAFlags::XFormsBind
;
900 if ( m_nIncludeBindings
& BAFlags::XFormsListBind
)
902 exportXFormsListAttributes();
903 #if OSL_DEBUG_LEVEL > 0
904 // reset the bit for later checking
905 nIncludeBinding
= nIncludeBinding
& ~BAFlags::XFormsListBind
;
909 if ( m_nIncludeBindings
& BAFlags::XFormsSubmission
)
911 exportXFormsSubmissionAttributes();
912 #if OSL_DEBUG_LEVEL > 0
913 // reset the bit for later checking
914 nIncludeBinding
= nIncludeBinding
& ~BAFlags::XFormsSubmission
;
918 #if OSL_DEBUG_LEVEL > 0
919 OSL_ENSURE( BAFlags::NONE
== nIncludeBinding
,
920 "OControlExport::exportBindingAttributes: forgot some flags!");
921 // in the debug version, we should have removed every bit we handled from the mask, so it should
926 void OControlExport::exportSpecialAttributes()
930 // the boolean properties
932 static const SCAFlags nBooleanPropertyAttributeIds
[] =
934 SCAFlags::Validation
, SCAFlags::MultiLine
, SCAFlags::AutoCompletion
, SCAFlags::Multiple
, SCAFlags::DefaultButton
, SCAFlags::IsTristate
,
935 SCAFlags::Toggle
, SCAFlags::FocusOnClick
937 static const rtl::OUStringConstExpr pBooleanPropertyNames
[] =
939 PROPERTY_STRICTFORMAT
, PROPERTY_MULTILINE
,
940 PROPERTY_AUTOCOMPLETE
,
941 PROPERTY_MULTISELECTION
,
942 PROPERTY_DEFAULTBUTTON
, PROPERTY_TRISTATE
,
943 PROPERTY_TOGGLE
, PROPERTY_FOCUS_ON_CLICK
945 static const sal_Int32 nIdCount
= std::size(nBooleanPropertyAttributeIds
);
946 #if OSL_DEBUG_LEVEL > 0
947 static const sal_Int32 nNameCount
= std::size(pBooleanPropertyNames
);
948 OSL_ENSURE((nIdCount
== nNameCount
),
949 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (1)!");
951 const SCAFlags
* pAttributeId
= nBooleanPropertyAttributeIds
;
952 for ( i
= 0; i
< nIdCount
; ++i
, ++pAttributeId
)
954 if ( *pAttributeId
& m_nIncludeSpecial
)
956 exportBooleanPropertyAttribute(
957 OAttributeMetaData::getSpecialAttributeNamespace( *pAttributeId
),
958 OAttributeMetaData::getSpecialAttributeName( *pAttributeId
),
959 pBooleanPropertyNames
[i
],
960 ( *pAttributeId
== SCAFlags::FocusOnClick
) ? BoolAttrFlags::DefaultTrue
: BoolAttrFlags::DefaultFalse
962 #if OSL_DEBUG_LEVEL > 0
963 // reset the bit for later checking
964 m_nIncludeSpecial
= m_nIncludeSpecial
& ~*pAttributeId
;
970 // the integer properties
972 static const SCAFlags nIntegerPropertyAttributeIds
[] =
974 SCAFlags::PageStepSize
976 static const rtl::OUStringConstExpr pIntegerPropertyNames
[] =
978 PROPERTY_BLOCK_INCREMENT
980 static const sal_Int32 nIntegerPropertyAttrDefaults
[] =
981 { // attribute defaults (XML defaults, not runtime defaults!)
985 static const sal_Int32 nIdCount
= std::size( nIntegerPropertyAttributeIds
);
986 #if OSL_DEBUG_LEVEL > 0
987 static const sal_Int32 nNameCount
= std::size( pIntegerPropertyNames
);
988 OSL_ENSURE( ( nIdCount
== nNameCount
),
989 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (2)!" );
990 static const sal_Int32 nDefaultCount
= std::size( nIntegerPropertyAttrDefaults
);
991 OSL_ENSURE( ( nIdCount
== nDefaultCount
),
992 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (3)!" );
994 for ( i
= 0; i
< nIdCount
; ++i
)
995 if ( nIntegerPropertyAttributeIds
[i
] & m_nIncludeSpecial
)
997 exportInt32PropertyAttribute(
998 OAttributeMetaData::getSpecialAttributeNamespace( nIntegerPropertyAttributeIds
[i
] ),
999 OAttributeMetaData::getSpecialAttributeName( nIntegerPropertyAttributeIds
[i
] ),
1000 pIntegerPropertyNames
[i
],
1001 nIntegerPropertyAttrDefaults
[i
]
1003 #if OSL_DEBUG_LEVEL > 0
1004 // reset the bit for later checking
1005 m_nIncludeSpecial
= m_nIncludeSpecial
& ~nIntegerPropertyAttributeIds
[i
];
1009 if ( SCAFlags::StepSize
& m_nIncludeSpecial
)
1011 OUString sPropertyName
;
1012 if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_LINE_INCREMENT
) )
1013 sPropertyName
= PROPERTY_LINE_INCREMENT
;
1014 else if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_SPIN_INCREMENT
) )
1015 sPropertyName
= PROPERTY_SPIN_INCREMENT
;
1017 OSL_FAIL( "OControlExport::exportSpecialAttributes: not property which can be mapped to step-size attribute!" );
1019 if ( !sPropertyName
.isEmpty() )
1020 exportInt32PropertyAttribute(
1021 OAttributeMetaData::getSpecialAttributeNamespace( SCAFlags::StepSize
),
1022 OAttributeMetaData::getSpecialAttributeName( SCAFlags::StepSize
),
1027 #if OSL_DEBUG_LEVEL > 0
1028 // reset the bit for later checking
1029 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags::StepSize
;
1035 // the enum properties
1037 if (SCAFlags::State
& m_nIncludeSpecial
)
1039 exportEnumPropertyAttribute(
1040 OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::State
),
1041 OAttributeMetaData::getSpecialAttributeName(SCAFlags::State
),
1042 PROPERTY_DEFAULT_STATE
,
1045 #if OSL_DEBUG_LEVEL > 0
1046 // reset the bit for later checking
1047 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags::State
;
1051 if (SCAFlags::CurrentState
& m_nIncludeSpecial
)
1053 exportEnumPropertyAttribute(
1054 OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::CurrentState
),
1055 OAttributeMetaData::getSpecialAttributeName(SCAFlags::CurrentState
),
1059 #if OSL_DEBUG_LEVEL > 0
1060 // reset the bit for later checking
1061 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags::CurrentState
;
1066 // some properties which require a special handling
1069 if ( m_nIncludeSpecial
& SCAFlags::RepeatDelay
)
1071 DBG_CHECK_PROPERTY( PROPERTY_REPEAT_DELAY
, sal_Int32
);
1073 sal_Int32 nRepeatDelay
= 0;
1074 m_xProps
->getPropertyValue( PROPERTY_REPEAT_DELAY
) >>= nRepeatDelay
;
1075 tools::Time
aTime( tools::Time::SYSTEM
);
1076 aTime
.MakeTimeFromMS( nRepeatDelay
);
1077 util::Duration aDuration
;
1078 aDuration
.Hours
= aTime
.GetHour();
1079 aDuration
.Minutes
= aTime
.GetMin();
1080 aDuration
.Seconds
= aTime
.GetSec();
1081 aDuration
.NanoSeconds
= (nRepeatDelay
% 1000) * 1000000;
1084 ::sax::Converter::convertDuration(buf
, aDuration
);
1085 AddAttribute(OAttributeMetaData::getSpecialAttributeNamespace( SCAFlags::RepeatDelay
)
1086 ,OAttributeMetaData::getSpecialAttributeName( SCAFlags::RepeatDelay
)
1087 ,buf
.makeStringAndClear());
1089 exportedProperty( PROPERTY_REPEAT_DELAY
);
1091 #if OSL_DEBUG_LEVEL > 0
1092 // reset the bit for later checking
1093 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags::RepeatDelay
;
1098 // the EchoChar property needs special handling, cause it's a Int16, but must be stored as one-character-string
1100 if (SCAFlags::EchoChar
& m_nIncludeSpecial
)
1102 DBG_CHECK_PROPERTY( PROPERTY_ECHO_CHAR
, sal_Int16
);
1103 sal_Int16
nValue(0);
1104 m_xProps
->getPropertyValue(PROPERTY_ECHO_CHAR
) >>= nValue
;
1107 OUString
sCharacter(reinterpret_cast<const sal_Unicode
*>(&nValue
), 1);
1109 OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::EchoChar
),
1110 OAttributeMetaData::getSpecialAttributeName(SCAFlags::EchoChar
),
1113 exportedProperty(PROPERTY_ECHO_CHAR
);
1114 #if OSL_DEBUG_LEVEL > 0
1115 // reset the bit for later checking
1116 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags::EchoChar
;
1121 // the string properties
1123 static const SCAFlags nStringPropertyAttributeIds
[] =
1124 { // attribute flags
1127 static const rtl::OUStringConstExpr pStringPropertyNames
[] =
1132 static const sal_Int32 nIdCount
= std::size( nStringPropertyAttributeIds
);
1133 #if OSL_DEBUG_LEVEL > 0
1134 static const sal_Int32 nNameCount
= std::size( pStringPropertyNames
);
1135 OSL_ENSURE( ( nIdCount
== nNameCount
),
1136 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (2)!" );
1138 for ( i
= 0; i
< nIdCount
; ++i
)
1139 if ( nStringPropertyAttributeIds
[i
] & m_nIncludeSpecial
)
1141 exportStringPropertyAttribute(
1142 OAttributeMetaData::getSpecialAttributeNamespace( nStringPropertyAttributeIds
[i
] ),
1143 OAttributeMetaData::getSpecialAttributeName( nStringPropertyAttributeIds
[i
] ),
1144 OUString(pStringPropertyNames
[i
])
1146 #if OSL_DEBUG_LEVEL > 0
1147 // reset the bit for later checking
1148 m_nIncludeSpecial
= m_nIncludeSpecial
& ~nStringPropertyAttributeIds
[i
];
1153 if ((SCAFlags::MinValue
| SCAFlags::MaxValue
) & m_nIncludeSpecial
)
1155 // need to export the min value and the max value as attributes
1156 // It depends on the real type (FormComponentType) of the control, which properties hold these
1158 OUString pMinValuePropertyName
;
1159 OUString pMaxValuePropertyName
;
1160 getValueLimitPropertyNames(m_nClassId
, pMinValuePropertyName
, pMaxValuePropertyName
);
1162 OSL_ENSURE((pMinValuePropertyName
.isEmpty()) == (SCAFlags::NONE
== (SCAFlags::MinValue
& m_nIncludeSpecial
)),
1163 "OControlExport::exportCommonControlAttributes: no property found for the min value attribute!");
1164 OSL_ENSURE((pMaxValuePropertyName
.isEmpty()) == (SCAFlags::NONE
== (SCAFlags::MaxValue
& m_nIncludeSpecial
)),
1165 "OControlExport::exportCommonControlAttributes: no property found for the max value attribute!");
1167 // add the two attributes
1168 static const OUString pMinValueAttributeName
= OAttributeMetaData::getSpecialAttributeName(SCAFlags::MinValue
);
1169 static const OUString pMaxValueAttributeName
= OAttributeMetaData::getSpecialAttributeName(SCAFlags::MaxValue
);
1170 static const sal_uInt16 nMinValueNamespaceKey
= OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::MinValue
);
1171 static const sal_uInt16 nMaxValueNamespaceKey
= OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::MaxValue
);
1173 if (!pMinValuePropertyName
.isEmpty() && (SCAFlags::MinValue
& m_nIncludeSpecial
))
1174 exportGenericPropertyAttribute(
1175 nMinValueNamespaceKey
,
1176 pMinValueAttributeName
,
1177 pMinValuePropertyName
);
1179 if (!pMaxValuePropertyName
.isEmpty() && (SCAFlags::MaxValue
& m_nIncludeSpecial
))
1180 exportGenericPropertyAttribute(
1181 nMaxValueNamespaceKey
,
1182 pMaxValueAttributeName
,
1183 pMaxValuePropertyName
);
1184 #if OSL_DEBUG_LEVEL > 0
1185 // reset the bit for later checking
1186 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags(SCAFlags::MinValue
| SCAFlags::MaxValue
);
1190 if ( SCAFlags::ImagePosition
& m_nIncludeSpecial
)
1192 exportImagePositionAttributes();
1193 RESET_BIT( m_nIncludeSpecial
, SCAFlags::ImagePosition
);
1196 OSL_ENSURE(SCAFlags::NONE
== m_nIncludeSpecial
,
1197 "OControlExport::exportSpecialAttributes: forgot some flags!");
1198 // in the dbg_util version, we should have removed every bit we handled from the mask, so it should
1202 OUString
OControlExport::getScalarListSourceValue() const
1204 OUString sListSource
;
1205 Any aListSource
= m_xProps
->getPropertyValue( PROPERTY_LISTSOURCE
);
1206 if ( !( aListSource
>>= sListSource
) )
1208 Sequence
< OUString
> aListSourceSequence
;
1209 aListSource
>>= aListSourceSequence
;
1210 if ( aListSourceSequence
.hasElements() )
1211 sListSource
= aListSourceSequence
[ 0 ];
1216 void OControlExport::exportListSourceAsAttribute()
1218 // DAFlags::ListSource needs some special handling
1219 DBG_CHECK_PROPERTY_NO_TYPE( PROPERTY_LISTSOURCE
);
1221 OUString sListSource
= getScalarListSourceValue();
1222 if ( !sListSource
.isEmpty() )
1223 { // the ListSource property needs to be exported as attribute, and it is not empty
1225 OAttributeMetaData::getDatabaseAttributeNamespace(),
1226 OAttributeMetaData::getDatabaseAttributeName(DAFlags::ListSource
),
1230 exportedProperty( PROPERTY_LISTSOURCE
);
1233 void OControlExport::getSequenceInt16PropertyAsSet(const OUString
& _rPropertyName
, Int16Set
& _rOut
)
1235 Sequence
< sal_Int16
> aValueSequence
;
1236 DBG_CHECK_PROPERTY(_rPropertyName
, Sequence
< sal_Int16
>);
1237 m_xProps
->getPropertyValue(_rPropertyName
) >>= aValueSequence
;
1239 for (const auto& rValue
: std::as_const(aValueSequence
))
1240 _rOut
.insert(rValue
);
1243 void OControlExport::exportListSourceAsElements()
1246 Sequence
< OUString
> aItems
, aValues
;
1247 DBG_CHECK_PROPERTY( PROPERTY_STRING_ITEM_LIST
, Sequence
< OUString
> );
1248 m_xProps
->getPropertyValue(PROPERTY_STRING_ITEM_LIST
) >>= aItems
;
1250 DBG_CHECK_PROPERTY( PROPERTY_LISTSOURCE
, Sequence
< OUString
> );
1251 if ( DAFlags::NONE
== ( m_nIncludeDatabase
& DAFlags::ListSource
) )
1252 m_xProps
->getPropertyValue(PROPERTY_LISTSOURCE
) >>= aValues
;
1253 // if we exported the list source as attribute, we do not repeat it as sub elements
1255 // the selection lists
1256 Int16Set aSelection
, aDefaultSelection
;
1257 getSequenceInt16PropertyAsSet(PROPERTY_SELECT_SEQ
, aSelection
);
1258 getSequenceInt16PropertyAsSet(PROPERTY_DEFAULT_SELECT_SEQ
, aDefaultSelection
);
1260 // the string for "true"
1262 OUStringBuffer sBuffer
;
1263 ::sax::Converter::convertBool(sBuffer
, true);
1264 sTrue
= sBuffer
.makeStringAndClear();
1266 // loop through both lists ('til the maximum of both lengths)
1267 const OUString
* pItems
= aItems
.getConstArray();
1268 const OUString
* pValues
= aValues
.getConstArray();
1270 sal_Int32 nItems
= aItems
.getLength();
1271 sal_Int32 nValues
= aValues
.getLength();
1273 sal_Int16 nMaxLen
= static_cast<sal_Int16
>(std::max(nItems
, nValues
));
1275 for (sal_Int16 i
=0; i
<nMaxLen
; ++i
)
1277 m_rContext
.getGlobalContext().ClearAttrList();
1280 // there is an item at this position
1282 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Label
),
1283 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Label
),
1289 // there is a value at this position
1291 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Value
),
1292 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Value
),
1297 Int16Set::const_iterator aSelectedPos
= aSelection
.find(i
);
1298 if (aSelection
.end() != aSelectedPos
)
1299 { // the item at this position is selected
1301 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::CurrentSelected
),
1302 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::CurrentSelected
),
1305 aSelection
.erase(aSelectedPos
);
1308 Int16Set::const_iterator aDefaultSelectedPos
= aDefaultSelection
.find(i
);
1309 if (aDefaultSelection
.end() != aDefaultSelectedPos
)
1310 { // the item at this position is selected as default
1312 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Selected
),
1313 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Selected
),
1316 aDefaultSelection
.erase(aDefaultSelectedPos
);
1318 SvXMLElementExport
aFormElement(m_rContext
.getGlobalContext(), XML_NAMESPACE_FORM
, "option", true, true);
1321 // There may be more "selected" or "default-selected" items than there are in the lists in real,
1322 // so we need to store some additional "form:option" items which have no name and no label, but
1323 // one or both of the selected flags.
1324 // 21.05.2001 - 85388 - frank.schoenheit@germany.sun.com
1326 if (aSelection
.empty() && aDefaultSelection
.empty())
1329 sal_Int16 nLastSelected
= -1;
1330 if ( !aSelection
.empty() )
1331 nLastSelected
= *(--aSelection
.end());
1333 sal_Int16 nLastDefaultSelected
= -1;
1334 if ( !aDefaultSelection
.empty() )
1335 nLastDefaultSelected
= *(--aDefaultSelection
.end());
1337 // the maximum element in both sets
1338 sal_Int16 nLastReferredEntry
= std::max(nLastSelected
, nLastDefaultSelected
);
1339 OSL_ENSURE(nLastReferredEntry
>= nMaxLen
, "OControlExport::exportListSourceAsElements: inconsistence!");
1340 // if the maximum (selected or default selected) entry number is less than the maximum item count
1341 // in both lists, the entry number should have been removed from the set
1343 for (sal_Int16 i
=nMaxLen
; i
<=nLastReferredEntry
; ++i
)
1345 if (aSelection
.end() != aSelection
.find(i
))
1346 { // the (not existent) item at this position is selected
1348 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::CurrentSelected
),
1349 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::CurrentSelected
),
1354 if (aDefaultSelection
.end() != aDefaultSelection
.find(i
))
1355 { // the (not existent) item at this position is selected as default
1357 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Selected
),
1358 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Selected
),
1362 SvXMLElementExport
aFormElement(m_rContext
.getGlobalContext(), XML_NAMESPACE_FORM
, "option", true, true);
1366 void OControlExport::implStartElement(const char* _pName
)
1368 // before we let the base class start it's outer element, we add a wrapper element
1369 const char *pOuterElementName
= getOuterXMLElementName();
1370 if (pOuterElementName
)
1371 m_pOuterElement
= std::make_unique
<SvXMLElementExport
>(
1372 m_rContext
.getGlobalContext(),
1374 pOuterElementName
, true,
1377 // add the attributes for the inner element
1378 exportInnerAttributes();
1380 // and start the inner element
1381 OElementExport::implStartElement(_pName
);
1384 void OControlExport::implEndElement()
1386 // end the inner element
1387 OElementExport::implEndElement();
1389 // end the outer element if it exists
1390 m_pOuterElement
.reset();
1393 const char* OControlExport::getOuterXMLElementName() const
1398 const char* OControlExport::getXMLElementName() const
1400 return getElementName(m_eType
);
1403 void OControlExport::examine()
1405 OSL_ENSURE( ( m_nIncludeCommon
== CCAFlags::NONE
) && ( m_nIncludeSpecial
== SCAFlags::NONE
) && ( m_nIncludeDatabase
== DAFlags::NONE
)
1406 && ( m_nIncludeEvents
== EAFlags::NONE
) && ( m_nIncludeBindings
== BAFlags::NONE
),
1407 "OControlExport::examine: called me twice? Not initialized?" );
1409 // get the class id to decide which kind of element we need in the XML stream
1410 m_nClassId
= FormComponentType::CONTROL
;
1411 DBG_CHECK_PROPERTY( PROPERTY_CLASSID
, sal_Int16
);
1412 m_xProps
->getPropertyValue(PROPERTY_CLASSID
) >>= m_nClassId
;
1413 bool knownType
= false;
1416 case FormComponentType::DATEFIELD
:
1420 case FormComponentType::TIMEFIELD
:
1426 m_nIncludeSpecial
|= SCAFlags::Validation
;
1428 case FormComponentType::NUMERICFIELD
:
1429 case FormComponentType::CURRENCYFIELD
:
1430 case FormComponentType::PATTERNFIELD
:
1433 m_eType
= FORMATTED_TEXT
;
1437 case FormComponentType::TEXTFIELD
:
1438 { // it's some kind of edit. To know which type we need further investigation
1442 // check if it's a formatted field
1443 if (m_xPropertyInfo
->hasPropertyByName(PROPERTY_FORMATKEY
))
1445 m_eType
= FORMATTED_TEXT
;
1449 // all other controls are represented by an ordinary edit control, but which XML control type
1450 // it is depends on the current values of some properties
1452 // if the EchoChar string is not empty, it is a password field
1453 sal_Int16 nEchoChar
= 0;
1454 if (m_xPropertyInfo
->hasPropertyByName(PROPERTY_ECHOCHAR
))
1455 // grid columns do not have this property...
1456 m_xProps
->getPropertyValue(PROPERTY_ECHOCHAR
) >>= nEchoChar
;
1460 m_nIncludeSpecial
|= SCAFlags::EchoChar
;
1464 // if the MultiLine property is sal_True, it is a TextArea
1465 bool bMultiLine
= false;
1466 if (m_xPropertyInfo
->hasPropertyByName(PROPERTY_MULTILINE
))
1467 // grid columns do not have this property...
1468 bMultiLine
= ::cppu::any2bool(m_xProps
->getPropertyValue(PROPERTY_MULTILINE
));
1471 m_eType
= TEXT_AREA
;
1473 // the only case left is represented by a Text element
1479 // attributes which are common to all the types:
1480 // common attributes
1482 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
|
1483 CCAFlags::Printable
| CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
;
1485 if ( ( m_nClassId
!= FormComponentType::DATEFIELD
)
1486 && ( m_nClassId
!= FormComponentType::TIMEFIELD
)
1488 // date and time field values are handled differently nowadays
1489 m_nIncludeCommon
|= CCAFlags::Value
;
1491 // database attributes
1492 m_nIncludeDatabase
= DAFlags::DataField
| DAFlags::InputRequired
;
1495 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnChange
| EAFlags::OnSelect
;
1497 // only text and pattern fields have a ConvertEmptyToNull property
1498 if ( ( m_nClassId
== FormComponentType::TEXTFIELD
)
1499 || ( m_nClassId
== FormComponentType::PATTERNFIELD
)
1501 m_nIncludeDatabase
|= DAFlags::ConvertEmpty
;
1503 // all controls but the file control fields have a readonly property
1504 if ( m_nClassId
!= FormComponentType::FILECONTROL
)
1505 m_nIncludeCommon
|= CCAFlags::ReadOnly
;
1507 // a text field has a max text len
1508 if ( m_nClassId
== FormComponentType::TEXTFIELD
)
1509 m_nIncludeCommon
|= CCAFlags::MaxLength
;
1511 // max and min values and validation:
1512 if (FORMATTED_TEXT
== m_eType
)
1513 { // in general all controls represented as formatted-text have these props
1514 if ( FormComponentType::PATTERNFIELD
!= m_nClassId
) // except the PatternField
1515 m_nIncludeSpecial
|= SCAFlags::MaxValue
| SCAFlags::MinValue
;
1517 if (FormComponentType::TEXTFIELD
!= m_nClassId
)
1518 // and the FormattedField does not have a validation flag
1519 m_nIncludeSpecial
|= SCAFlags::Validation
;
1522 // if it's not a password field or rich text control, the CurrentValue needs to be stored, too
1523 if ( ( PASSWORD
!= m_eType
)
1524 && ( DATE
!= m_eType
)
1525 && ( TIME
!= m_eType
)
1528 m_nIncludeCommon
|= CCAFlags::CurrentValue
;
1533 case FormComponentType::FILECONTROL
:
1536 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::CurrentValue
| CCAFlags::Disabled
|
1537 CCAFlags::Printable
| CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
|
1539 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnChange
| EAFlags::OnSelect
;
1542 case FormComponentType::FIXEDTEXT
:
1543 m_eType
= FIXED_TEXT
;
1545 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Label
|
1546 CCAFlags::Printable
| CCAFlags::Title
| CCAFlags::For
;
1547 m_nIncludeSpecial
= SCAFlags::MultiLine
;
1548 m_nIncludeEvents
= EAFlags::ControlEvents
;
1551 case FormComponentType::COMBOBOX
:
1554 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::CurrentValue
|
1555 CCAFlags::Disabled
| CCAFlags::Dropdown
| CCAFlags::MaxLength
| CCAFlags::Printable
| CCAFlags::ReadOnly
| CCAFlags::Size
|
1556 CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
| CCAFlags::Value
;
1557 m_nIncludeSpecial
= SCAFlags::AutoCompletion
;
1558 m_nIncludeDatabase
= DAFlags::ConvertEmpty
| DAFlags::DataField
| DAFlags::InputRequired
| DAFlags::ListSource
| DAFlags::ListSource_TYPE
;
1559 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnChange
| EAFlags::OnSelect
;
1562 case FormComponentType::LISTBOX
:
1565 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Dropdown
|
1566 CCAFlags::Printable
| CCAFlags::Size
| CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
;
1567 m_nIncludeSpecial
= SCAFlags::Multiple
;
1568 m_nIncludeDatabase
= DAFlags::BoundColumn
| DAFlags::DataField
| DAFlags::InputRequired
| DAFlags::ListSource_TYPE
;
1569 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnChange
| EAFlags::OnClick
| EAFlags::OnDoubleClick
;
1570 // check if we need to export the ListSource as attribute
1572 // for a list box, if the ListSourceType is VALUE_LIST, no ListSource is stored, but instead
1573 // a sequence of pairs which is build from the StringItemList and the ValueList
1574 ListSourceType eListSourceType
= ListSourceType_VALUELIST
;
1576 m_xProps
->getPropertyValue(PROPERTY_LISTSOURCETYPE
) >>= eListSourceType
;
1577 OSL_ENSURE(bSuccess
, "OControlExport::examineControl: could not retrieve the ListSourceType!");
1578 if (ListSourceType_VALUELIST
!= eListSourceType
)
1580 m_nIncludeDatabase
|= DAFlags::ListSource
;
1586 case FormComponentType::COMMANDBUTTON
:
1588 m_nIncludeCommon
|= CCAFlags::TabStop
| CCAFlags::Label
;
1589 m_nIncludeSpecial
= SCAFlags::DefaultButton
| SCAFlags::Toggle
| SCAFlags::FocusOnClick
| SCAFlags::ImagePosition
| SCAFlags::RepeatDelay
;
1591 case FormComponentType::IMAGEBUTTON
:
1592 if (BUTTON
!= m_eType
)
1594 // not coming from the previous case
1598 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::ButtonType
| CCAFlags::Disabled
|
1599 CCAFlags::ImageData
| CCAFlags::Printable
| CCAFlags::TabIndex
| CCAFlags::TargetFrame
|
1600 CCAFlags::TargetLocation
| CCAFlags::Title
;
1601 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnClick
| EAFlags::OnDoubleClick
;
1604 case FormComponentType::CHECKBOX
:
1606 m_nIncludeSpecial
= SCAFlags::CurrentState
| SCAFlags::IsTristate
| SCAFlags::State
;
1608 case FormComponentType::RADIOBUTTON
:
1610 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Label
| CCAFlags::Printable
|
1611 CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
| CCAFlags::Value
| CCAFlags::VisualEffect
;
1612 if (CHECKBOX
!= m_eType
)
1613 { // not coming from the previous case
1615 m_nIncludeCommon
|= CCAFlags::CurrentSelected
| CCAFlags::Selected
;
1617 if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_IMAGE_POSITION
) )
1618 m_nIncludeSpecial
|= SCAFlags::ImagePosition
;
1619 if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_GROUP_NAME
) )
1620 m_nIncludeSpecial
|= SCAFlags::GroupName
;
1621 m_nIncludeDatabase
= DAFlags::DataField
| DAFlags::InputRequired
;
1622 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnChange
;
1625 case FormComponentType::GROUPBOX
:
1628 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Label
|
1629 CCAFlags::Printable
| CCAFlags::Title
| CCAFlags::For
;
1630 m_nIncludeEvents
= EAFlags::ControlEvents
;
1633 case FormComponentType::IMAGECONTROL
:
1634 m_eType
= IMAGE_FRAME
;
1636 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::ImageData
|
1637 CCAFlags::Printable
| CCAFlags::ReadOnly
| CCAFlags::Title
;
1638 m_nIncludeDatabase
= DAFlags::DataField
| DAFlags::InputRequired
;
1639 m_nIncludeEvents
= EAFlags::ControlEvents
;
1642 case FormComponentType::HIDDENCONTROL
:
1645 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Value
;
1648 case FormComponentType::GRIDCONTROL
:
1651 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Printable
|
1652 CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
;
1653 m_nIncludeEvents
= EAFlags::ControlEvents
;
1656 case FormComponentType::SCROLLBAR
:
1657 case FormComponentType::SPINBUTTON
:
1658 m_eType
= VALUERANGE
;
1660 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Printable
|
1661 CCAFlags::Title
| CCAFlags::CurrentValue
| CCAFlags::Value
| CCAFlags::Orientation
;
1662 m_nIncludeSpecial
= SCAFlags::MaxValue
| SCAFlags::StepSize
| SCAFlags::MinValue
| SCAFlags::RepeatDelay
;
1664 if ( m_nClassId
== FormComponentType::SCROLLBAR
)
1665 m_nIncludeSpecial
|= SCAFlags::PageStepSize
;
1667 m_nIncludeEvents
= EAFlags::ControlEvents
;
1671 OSL_FAIL("OControlExport::examineControl: unknown control type (class id)!");
1674 case FormComponentType::NAVIGATIONBAR
:
1675 // TODO: should we have an own file format for this?
1678 case FormComponentType::CONTROL
:
1679 m_eType
= GENERIC_CONTROL
;
1680 // unknown control type
1681 m_nIncludeCommon
= CCAFlags::Name
| CCAFlags::ServiceName
;
1682 // at least a name should be there, 'cause without a name the control could never have been
1683 // inserted into its parent container
1684 // In addition, the service name is absolutely necessary to create the control upon reading.
1685 m_nIncludeEvents
= EAFlags::ControlEvents
;
1686 // we always should be able to export events - this is not control type dependent
1690 // in general, all control types need to export the control id
1691 m_nIncludeCommon
|= CCAFlags::ControlId
;
1693 // is it a control bound to a calc cell?
1694 if ( FormCellBindingHelper::livesInSpreadsheetDocument( m_xProps
) )
1696 FormCellBindingHelper
aHelper( m_xProps
, nullptr );
1698 if ( FormCellBindingHelper::isCellBinding( aHelper
.getCurrentBinding( ) ) )
1700 m_nIncludeBindings
|= BAFlags::LinkedCell
;
1701 if ( m_nClassId
== FormComponentType::LISTBOX
)
1702 m_nIncludeBindings
|= BAFlags::ListLinkingType
;
1706 // is it a list-like control which uses a calc cell range as list source?
1708 if ( FormCellBindingHelper::isCellRangeListSource( aHelper
.getCurrentListSource( ) ) )
1709 m_nIncludeBindings
|= BAFlags::ListCellRange
;
1713 // is control bound to XForms?
1714 if( !getXFormsBindName( m_xProps
).isEmpty() )
1716 m_nIncludeBindings
|= BAFlags::XFormsBind
;
1719 // is (list-)control bound to XForms list?
1720 if( !getXFormsListBindName( m_xProps
).isEmpty() )
1722 m_nIncludeBindings
|= BAFlags::XFormsListBind
;
1725 // does the control have an XForms submission?
1726 if( !getXFormsSubmissionName( m_xProps
).isEmpty() )
1728 m_nIncludeBindings
|= BAFlags::XFormsSubmission
;
1732 void OControlExport::exportCellBindingAttributes( bool _bIncludeListLinkageType
)
1736 FormCellBindingHelper
aHelper( m_xProps
, nullptr );
1737 Reference
< XValueBinding
> xBinding( aHelper
.getCurrentBinding() );
1738 OSL_ENSURE( xBinding
.is(), "OControlExport::exportCellBindingAttributes: invalid bindable or invalid binding!" );
1739 if ( xBinding
.is() )
1742 OAttributeMetaData::getBindingAttributeNamespace(),
1743 OAttributeMetaData::getBindingAttributeName( BAFlags::LinkedCell
),
1744 aHelper
.getStringAddressFromCellBinding( xBinding
)
1747 if ( _bIncludeListLinkageType
)
1749 sal_Int16 nLinkageType
= FormCellBindingHelper::isCellIntegerBinding( xBinding
) ? 1 : 0;
1751 OUStringBuffer sBuffer
;
1752 SvXMLUnitConverter::convertEnum(
1759 OAttributeMetaData::getBindingAttributeNamespace(),
1760 OAttributeMetaData::getBindingAttributeName( BAFlags::ListLinkingType
),
1761 sBuffer
.makeStringAndClear()
1767 catch( const Exception
& )
1769 TOOLS_WARN_EXCEPTION( "xmloff.forms", "OControlExport::exportCellBindingAttributes" );
1773 void OControlExport::exportXFormsBindAttributes()
1775 OUString sBindName
= getXFormsBindName( m_xProps
);
1776 AddAttribute( XML_NAMESPACE_XFORMS
, XML_BIND
, sBindName
);
1778 void OControlExport::exportXFormsListAttributes()
1780 OUString sBindName
= getXFormsListBindName( m_xProps
);
1781 AddAttribute( XML_NAMESPACE_FORM
, XML_XFORMS_LIST_SOURCE
, sBindName
);
1783 void OControlExport::exportXFormsSubmissionAttributes()
1785 OUString sSubmission
= getXFormsSubmissionName( m_xProps
);
1786 AddAttribute( XML_NAMESPACE_FORM
, XML_XFORMS_SUBMISSION
, sSubmission
);
1788 void OControlExport::exportCellListSourceRange( )
1792 Reference
< XListEntrySink
> xSink( m_xProps
, UNO_QUERY
);
1793 Reference
< XListEntrySource
> xSource
;
1795 xSource
= xSink
->getListEntrySource();
1796 OSL_ENSURE( xSource
.is(), "OControlExport::exportCellListSourceRange: list source or sink!" );
1799 FormCellBindingHelper
aHelper( m_xProps
, nullptr );
1802 OAttributeMetaData::getBindingAttributeNamespace(),
1803 OAttributeMetaData::getBindingAttributeName( BAFlags::ListCellRange
),
1804 aHelper
.getStringAddressFromCellListSource( xSource
)
1808 catch( const Exception
& )
1810 TOOLS_WARN_EXCEPTION( "xmloff.forms", "OControlExport::exportCellListSourceRange" );
1814 void OControlExport::exportImagePositionAttributes()
1818 sal_Int16 nImagePosition
= ImagePosition::Centered
;
1819 OSL_VERIFY( m_xProps
->getPropertyValue( PROPERTY_IMAGE_POSITION
) >>= nImagePosition
);
1820 OSL_ENSURE( ( nImagePosition
>= ImagePosition::LeftTop
) && ( nImagePosition
<= ImagePosition::Centered
),
1821 "OControlExport::exportImagePositionAttributes: don't know this image position!" );
1823 if ( ( nImagePosition
< ImagePosition::LeftTop
) || ( nImagePosition
> ImagePosition::Centered
) )
1824 // this is important to prevent potential buffer overflows below, so don't optimize
1825 nImagePosition
= ImagePosition::Centered
;
1827 if ( nImagePosition
== ImagePosition::Centered
)
1829 AddAttribute( XML_NAMESPACE_FORM
, GetXMLToken( XML_IMAGE_POSITION
), GetXMLToken( XML_CENTER
) );
1833 const XMLTokenEnum eXmlImagePositions
[] =
1835 XML_START
, XML_END
, XML_TOP
, XML_BOTTOM
1837 const XMLTokenEnum eXmlImageAligns
[] =
1839 XML_START
, XML_CENTER
, XML_END
1842 XMLTokenEnum eXmlImagePosition
= eXmlImagePositions
[ nImagePosition
/ 3 ];
1843 XMLTokenEnum eXmlImageAlign
= eXmlImageAligns
[ nImagePosition
% 3 ];
1845 AddAttribute( XML_NAMESPACE_FORM
, GetXMLToken( XML_IMAGE_POSITION
), GetXMLToken( eXmlImagePosition
) );
1846 AddAttribute( XML_NAMESPACE_FORM
, GetXMLToken( XML_IMAGE_ALIGN
), GetXMLToken( eXmlImageAlign
) );
1849 exportedProperty( PROPERTY_IMAGE_POSITION
);
1850 // some of the controls which have an ImagePosition also have an ImageAlign for compatibility
1851 // reasons. Since the ImageAlign values simply represent a sub set of the ImagePosition values,
1852 // we don't need to export ImageAlign anymore
1853 exportedProperty( PROPERTY_IMAGE_ALIGN
);
1855 catch( const Exception
& )
1857 DBG_UNHANDLED_EXCEPTION("xmloff.forms");
1861 bool OControlExport::controlHasActiveDataBinding() const
1865 // currently exchanging the data with a database column?
1866 OUString
sBoundFieldPropertyName( "BoundField" );
1867 if ( m_xPropertyInfo
.is() && m_xPropertyInfo
->hasPropertyByName( sBoundFieldPropertyName
) )
1869 Reference
< XPropertySet
> xBoundField
;
1870 m_xProps
->getPropertyValue( sBoundFieldPropertyName
) >>= xBoundField
;
1871 if ( xBoundField
.is() )
1875 // currently exchanging data with an external binding?
1876 Reference
< XBindableValue
> xBindable( m_xProps
, UNO_QUERY
);
1877 if ( xBindable
.is() && xBindable
->getValueBinding().is() )
1880 catch( const Exception
& )
1882 TOOLS_WARN_EXCEPTION( "xmloff.forms", "OColumnExport::controlHasActiveDataBinding" );
1888 bool OControlExport::controlHasUserSuppliedListEntries() const
1892 // an external list source?
1893 Reference
< XListEntrySink
> xEntrySink( m_xProps
, UNO_QUERY
);
1894 if ( xEntrySink
.is() && xEntrySink
->getListEntrySource().is() )
1897 if ( m_xPropertyInfo
.is() && m_xPropertyInfo
->hasPropertyByName( PROPERTY_LISTSOURCETYPE
) )
1899 ListSourceType eListSourceType
= ListSourceType_VALUELIST
;
1900 OSL_VERIFY( m_xProps
->getPropertyValue( PROPERTY_LISTSOURCETYPE
) >>= eListSourceType
);
1901 if ( eListSourceType
== ListSourceType_VALUELIST
)
1902 // for value lists, the list entries as entered by the user are used
1905 // for every other type, the list entries are filled with some data obtained
1906 // from a database - if and only if the ListSource property is not empty
1907 return getScalarListSourceValue().isEmpty();
1910 catch( const Exception
& )
1912 DBG_UNHANDLED_EXCEPTION("xmloff.forms");
1915 OSL_FAIL( "OControlExport::controlHasUserSuppliedListEntries: unreachable code!" );
1916 // this method should be called for list and combo boxes only
1921 OColumnExport::OColumnExport(IFormsExportContext
& _rContext
, const Reference
< XPropertySet
>& _rxControl
, const OUString
& _rControlId
,
1922 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
1923 :OControlExport(_rContext
, _rxControl
, _rControlId
, OUString(), _rEvents
)
1927 OColumnExport::~OColumnExport()
1931 void OColumnExport::exportServiceNameAttribute()
1933 // the attribute "service name" (which has a slightly different meaning for columns
1934 DBG_CHECK_PROPERTY( PROPERTY_COLUMNSERVICENAME
, OUString
);
1935 OUString sColumnServiceName
;
1936 m_xProps
->getPropertyValue(PROPERTY_COLUMNSERVICENAME
) >>= sColumnServiceName
;
1937 // the service name is a full qualified one (i.e. com.sun.star.form.TextField), but the
1938 // real service name for the column (for use with the XGridColumnFactory) is only the last
1939 // token of this complete name.
1940 sal_Int32 nLastSep
= sColumnServiceName
.lastIndexOf('.');
1941 OSL_ENSURE(-1 != nLastSep
, "OColumnExport::startExportElement: invalid service name!");
1942 sColumnServiceName
= sColumnServiceName
.copy(nLastSep
+ 1);
1943 sColumnServiceName
=
1944 m_rContext
.getGlobalContext().GetNamespaceMap().GetQNameByKey(
1945 XML_NAMESPACE_OOO
, sColumnServiceName
);
1946 // add the attribute
1947 AddAttribute( OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::ServiceName
)
1948 , OAttributeMetaData::getCommonControlAttributeName(CCAFlags::ServiceName
)
1949 , sColumnServiceName
);
1950 // flag the property as "handled"
1951 exportedProperty(PROPERTY_COLUMNSERVICENAME
);
1955 const char* OColumnExport::getOuterXMLElementName() const
1960 void OColumnExport::exportAttributes()
1962 OControlExport::exportAttributes();
1964 // the attribute "label"
1965 exportStringPropertyAttribute(
1966 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Label
),
1967 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Label
),
1970 // the style attribute
1971 OUString sStyleName
= m_rContext
.getObjectStyleName( m_xProps
);
1972 if ( !sStyleName
.isEmpty() )
1975 OAttributeMetaData::getSpecialAttributeNamespace( SCAFlags::ColumnStyleName
),
1976 OAttributeMetaData::getSpecialAttributeName( SCAFlags::ColumnStyleName
),
1982 void OColumnExport::examine()
1984 OControlExport::examine();
1986 // grid columns miss some properties of the controls they're representing
1987 m_nIncludeCommon
&= ~CCAFlags(CCAFlags::For
| CCAFlags::Printable
| CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Label
);
1988 m_nIncludeSpecial
&= ~SCAFlags(SCAFlags::EchoChar
| SCAFlags::AutoCompletion
| SCAFlags::Multiple
| SCAFlags::MultiLine
);
1990 if (FormComponentType::DATEFIELD
!= m_nClassId
)
1991 // except date fields, no column has the DropDown property
1992 m_nIncludeCommon
&= ~CCAFlags::Dropdown
;
1996 OFormExport::OFormExport(IFormsExportContext
& _rContext
, const Reference
< XPropertySet
>& _rxForm
,
1997 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
1998 :OElementExport(_rContext
, _rxForm
, _rEvents
)
1999 ,m_bCreateConnectionResourceElement(false)
2001 OSL_ENSURE(m_xProps
.is(), "OFormExport::OFormExport: invalid arguments!");
2004 const char* OFormExport::getXMLElementName() const
2009 void OFormExport::exportSubTags()
2011 if ( m_bCreateConnectionResourceElement
&& m_xProps
.is() )
2013 m_rContext
.getGlobalContext().ClearAttrList();
2014 OUString sPropValue
;
2015 m_xProps
->getPropertyValue( PROPERTY_DATASOURCENAME
) >>= sPropValue
; // if set it is a file url
2016 if ( sPropValue
.isEmpty() )
2017 m_xProps
->getPropertyValue( PROPERTY_URL
) >>= sPropValue
;
2018 if ( !sPropValue
.isEmpty() )
2020 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::TargetLocation
),
2021 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::TargetLocation
),
2022 m_rContext
.getGlobalContext().GetRelativeReference(sPropValue
));
2023 if ( m_rContext
.getGlobalContext().GetAttrList().getLength() )
2025 SvXMLElementExport
aFormElement(m_rContext
.getGlobalContext(), XML_NAMESPACE_FORM
, xmloff::token::XML_CONNECTION_RESOURCE
, true, true);
2029 // let the base class export the remaining properties and the events
2030 OElementExport::exportSubTags();
2031 // loop through all children
2032 Reference
< XIndexAccess
> xCollection(m_xProps
, UNO_QUERY
);
2033 OSL_ENSURE(xCollection
.is(), "OFormLayerXMLExport::implExportForm: a form which is not an index access? Suspicious!");
2035 if (xCollection
.is())
2036 m_rContext
.exportCollectionElements(xCollection
);
2039 void OFormExport::exportAttributes()
2043 // the string properties
2045 static const FormAttributes eStringPropertyIds
[] =
2047 faName
, /*faAction,*/ faCommand
, faFilter
, faOrder
2049 static const rtl::OUStringConstExpr aStringPropertyNames
[] =
2051 PROPERTY_NAME
, /*PROPERTY_TARGETURL,*/ PROPERTY_COMMAND
, PROPERTY_FILTER
, PROPERTY_ORDER
2053 static const sal_Int32 nIdCount
= std::size(eStringPropertyIds
);
2054 #if OSL_DEBUG_LEVEL > 0
2055 static const sal_Int32 nNameCount
= std::size(aStringPropertyNames
);
2056 OSL_ENSURE((nIdCount
== nNameCount
),
2057 "OFormExport::exportAttributes: somebody tampered with the maps (1)!");
2059 for (i
=0; i
<nIdCount
; ++i
)
2060 exportStringPropertyAttribute(
2061 OAttributeMetaData::getFormAttributeNamespace(eStringPropertyIds
[i
]),
2062 OAttributeMetaData::getFormAttributeName(eStringPropertyIds
[i
]),
2063 aStringPropertyNames
[i
]);
2065 // #i112082# xlink:type is added as part of exportTargetLocationAttribute
2067 // now export the data source name or databaselocation or connection resource
2068 OUString sPropValue
;
2069 m_xProps
->getPropertyValue( PROPERTY_DATASOURCENAME
) >>= sPropValue
;
2070 m_bCreateConnectionResourceElement
= sPropValue
.isEmpty();
2071 if ( !m_bCreateConnectionResourceElement
)
2073 INetURLObject
aURL(sPropValue
);
2074 m_bCreateConnectionResourceElement
= ( aURL
.GetProtocol() == INetProtocol::File
);
2075 if ( !m_bCreateConnectionResourceElement
)
2076 exportStringPropertyAttribute(
2077 OAttributeMetaData::getFormAttributeNamespace(faDatasource
),
2078 OAttributeMetaData::getFormAttributeName(faDatasource
),
2079 PROPERTY_DATASOURCENAME
);
2082 exportedProperty(PROPERTY_URL
);
2083 if ( m_bCreateConnectionResourceElement
)
2084 exportedProperty(PROPERTY_DATASOURCENAME
);
2087 // the boolean properties
2089 static const FormAttributes eBooleanPropertyIds
[] =
2091 faAllowDeletes
, faAllowInserts
, faAllowUpdates
, faApplyFilter
, faEscapeProcessing
, faIgnoreResult
2093 static const rtl::OUStringConstExpr pBooleanPropertyNames
[] =
2095 PROPERTY_ALLOWDELETES
,
2096 PROPERTY_ALLOWINSERTS
,
2097 PROPERTY_ALLOWUPDATES
,
2098 PROPERTY_APPLYFILTER
,
2099 PROPERTY_ESCAPEPROCESSING
,
2100 PROPERTY_IGNORERESULT
2102 static const BoolAttrFlags nBooleanPropertyAttrFlags
[] =
2104 BoolAttrFlags::DefaultTrue
, BoolAttrFlags::DefaultTrue
, BoolAttrFlags::DefaultTrue
, BoolAttrFlags::DefaultFalse
, BoolAttrFlags::DefaultTrue
, BoolAttrFlags::DefaultFalse
2106 static const sal_Int32 nIdCount
= std::size(eBooleanPropertyIds
);
2107 #if OSL_DEBUG_LEVEL > 0
2108 static const sal_Int32 nNameCount
= std::size(pBooleanPropertyNames
);
2109 static const sal_Int32 nFlagsCount
= std::size(nBooleanPropertyAttrFlags
);
2110 OSL_ENSURE((nIdCount
== nNameCount
) && (nNameCount
== nFlagsCount
),
2111 "OFormExport::exportAttributes: somebody tampered with the maps (2)!");
2113 for (i
=0; i
<nIdCount
; ++i
)
2114 exportBooleanPropertyAttribute(
2115 OAttributeMetaData::getFormAttributeNamespace(eBooleanPropertyIds
[i
]),
2116 OAttributeMetaData::getFormAttributeName(eBooleanPropertyIds
[i
]),
2117 pBooleanPropertyNames
[i
],
2118 nBooleanPropertyAttrFlags
[i
]
2122 // the enum properties
2124 exportEnumPropertyAttribute(
2125 OAttributeMetaData::getFormAttributeNamespace(faEnctype
),
2126 OAttributeMetaData::getFormAttributeName(faEnctype
),
2127 PROPERTY_SUBMIT_ENCODING
,
2129 FormSubmitEncoding_URL
,
2132 exportEnumPropertyAttribute(
2133 OAttributeMetaData::getFormAttributeNamespace(faMethod
),
2134 OAttributeMetaData::getFormAttributeName(faMethod
),
2135 PROPERTY_SUBMIT_METHOD
,
2137 FormSubmitMethod_GET
,
2140 exportEnumPropertyAttribute(
2141 OAttributeMetaData::getFormAttributeNamespace(faCommandType
),
2142 OAttributeMetaData::getFormAttributeName(faCommandType
),
2143 PROPERTY_COMMAND_TYPE
,
2145 CommandType::COMMAND
,
2148 exportEnumPropertyAttribute(
2149 OAttributeMetaData::getFormAttributeNamespace(faNavigationMode
),
2150 OAttributeMetaData::getFormAttributeName(faNavigationMode
),
2151 PROPERTY_NAVIGATION
,
2153 NavigationBarMode_CURRENT
,
2156 exportEnumPropertyAttribute(
2157 OAttributeMetaData::getFormAttributeNamespace(faTabbingCycle
),
2158 OAttributeMetaData::getFormAttributeName(faTabbingCycle
),
2161 TabulatorCycle_RECORDS
,
2167 exportServiceNameAttribute();
2169 exportTargetFrameAttribute();
2171 exportTargetLocationAttribute(true); // #i110911# add type attribute (for form, but not for control)
2174 exportStringSequenceAttribute(
2175 OAttributeMetaData::getFormAttributeNamespace(faMasterFields
),
2176 OAttributeMetaData::getFormAttributeName(faMasterFields
),
2177 PROPERTY_MASTERFIELDS
);
2179 exportStringSequenceAttribute(
2180 OAttributeMetaData::getFormAttributeNamespace(faDetailFields
),
2181 OAttributeMetaData::getFormAttributeName(faDetailFields
),
2182 PROPERTY_DETAILFIELDS
);
2184 } // namespace xmloff
2186 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */