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"
21 #include "strings.hxx"
22 #include <xmloff/xmlnmspe.hxx>
23 #include "eventexport.hxx"
24 #include "formenums.hxx"
25 #include "formcellbinding.hxx"
26 #include <xmloff/xformsexport.hxx>
27 #include "property_meta_data.hxx"
29 #include <com/sun/star/text/XText.hpp>
30 #include <com/sun/star/lang/XServiceInfo.hpp>
31 #include <com/sun/star/io/XPersistObject.hpp>
32 #include <com/sun/star/util/Duration.hpp>
33 #include <com/sun/star/form/FormComponentType.hpp>
34 #include <com/sun/star/beans/PropertyAttribute.hpp>
35 #include <com/sun/star/form/FormSubmitEncoding.hpp>
36 #include <com/sun/star/form/FormSubmitMethod.hpp>
37 #include <com/sun/star/sdb/CommandType.hpp>
38 #include <com/sun/star/form/NavigationBarMode.hpp>
39 #include <com/sun/star/form/TabulatorCycle.hpp>
40 #include <com/sun/star/form/FormButtonType.hpp>
41 #include <com/sun/star/awt/ScrollBarOrientation.hpp>
42 #include <com/sun/star/awt/VisualEffect.hpp>
43 #include <com/sun/star/form/ListSourceType.hpp>
44 #include <com/sun/star/awt/ImagePosition.hpp>
46 #include <sax/tools/converter.hxx>
47 #include <tools/gen.hxx>
48 #include <xmloff/txtprmap.hxx>
49 #include <com/sun/star/form/binding/XBindableValue.hpp>
50 #include <com/sun/star/form/binding/XListEntrySink.hpp>
51 #include <tools/urlobj.hxx>
52 #include <xmloff/xmlexp.hxx>
53 #include <xmloff/nmspmap.hxx>
54 #include <xmloff/XMLEventExport.hxx>
55 #include <xmloff/xmluconv.hxx>
56 #include <xmloff/xmltoken.hxx>
57 #include <xmloff/maptype.hxx>
58 #include <tools/time.hxx>
59 #include <tools/diagnose_ex.h>
60 #include <comphelper/extract.hxx>
61 #include <sal/macros.h>
68 #if OSL_DEBUG_LEVEL > 0
69 #define RESET_BIT( bitfield, bit ) \
70 bitfield = bitfield & ~bit
72 #define RESET_BIT( bitfield, bit )
75 using namespace ::xmloff::token
;
76 using namespace ::com::sun::star
;
77 using namespace ::com::sun::star::uno
;
78 using namespace ::com::sun::star::sdb
;
79 using namespace ::com::sun::star::awt
;
80 using namespace ::com::sun::star::form
;
81 using namespace ::com::sun::star::lang
;
82 using namespace ::com::sun::star::beans
;
83 using namespace ::com::sun::star::container
;
84 using namespace ::com::sun::star::script
;
85 using namespace ::com::sun::star::io
;
86 using namespace ::com::sun::star::table
;
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
)
95 ,m_pXMLElement(nullptr)
99 OElementExport::~OElementExport()
104 void OElementExport::doExport()
106 // collect some general information about the element
109 // first add the attributes necessary for the element
110 m_rContext
.getGlobalContext().ClearAttrList();
112 // add the attributes
115 // start the XML element
116 implStartElement(getXMLElementName());
118 // the sub elements (mostly control type dependent)
124 void OElementExport::examine()
126 // nothing to do here
129 void OElementExport::exportAttributes()
131 // nothing to do here
134 void OElementExport::exportSubTags()
136 // the properties which where not exported 'til now
137 exportRemainingProperties();
139 // the script:events sub tags
143 void OElementExport::implStartElement(const sal_Char
* _pName
)
145 m_pXMLElement
= new SvXMLElementExport(m_rContext
.getGlobalContext(), XML_NAMESPACE_FORM
, _pName
, true, true);
148 void OElementExport::implEndElement()
150 delete m_pXMLElement
;
151 m_pXMLElement
= nullptr;
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
.getLength())
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 const OUString
& _rControlId
, const OUString
& _rReferringControls
,
231 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
232 :OElementExport(_rContext
, _rxControl
, _rEvents
)
233 ,m_sControlId(_rControlId
)
234 ,m_sReferringControls(_rReferringControls
)
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
)
242 ,m_pOuterElement(nullptr)
244 OSL_ENSURE(m_xProps
.is(), "OControlExport::OControlExport: invalid arguments!");
247 OControlExport::~OControlExport()
252 void OControlExport::exportOuterAttributes()
255 if (CCAFlags::Name
& m_nIncludeCommon
)
257 exportStringPropertyAttribute(
258 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Name
),
259 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Name
),
262 #if OSL_DEBUG_LEVEL > 0
263 // reset the bit for later checking
264 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::Name
;
269 if (m_nIncludeCommon
& CCAFlags::ServiceName
)
271 exportServiceNameAttribute();
272 #if OSL_DEBUG_LEVEL > 0
273 // reset the bit for later checking
274 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::ServiceName
;
279 void OControlExport::exportInnerAttributes()
282 if (CCAFlags::ControlId
& m_nIncludeCommon
)
284 OSL_ENSURE(!m_sControlId
.isEmpty(), "OControlExport::exportInnerAttributes: have no control id for the control!");
285 m_rContext
.getGlobalContext().AddAttributeIdLegacy(
286 XML_NAMESPACE_FORM
, m_sControlId
);
287 #if OSL_DEBUG_LEVEL > 0
288 // reset the bit for later checking
289 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::ControlId
;
293 // "new-style" properties ...
294 exportGenericHandlerAttributes();
296 // common control attributes
297 exportCommonControlAttributes();
299 // common database attributes
300 exportDatabaseAttributes();
302 // attributes related to external bindings
303 exportBindingAtributes();
305 // attributes special to the respective control type
306 exportSpecialAttributes();
308 // add the style references to the attributes
309 flagStyleProperties();
312 void OControlExport::exportAttributes()
314 exportOuterAttributes();
317 void OControlExport::exportSubTags() throw (Exception
, std::exception
)
319 // for the upcoming exportRemainingProperties:
320 // if a control has the LabelControl property, this is not stored with the control itself, but instead with
321 // the control which is referenced by this property. As the base class' exportRemainingProperties doesn't
322 // know anything about this, we need to prevent that it tries to export this property
323 exportedProperty(PROPERTY_CONTROLLABEL
);
325 // if it's a control supporting XText, then we need to declare all text-related properties
326 // as "already exported". This prevents them from being exported as generic "form:property"-tags.
327 // *If* we would export them this way, they would be completely superfluous, and sometimes even
328 // disastrous, since they may, at import time, override paragraph properties which already have
330 Reference
< XText
> xControlText( m_xProps
, UNO_QUERY
);
331 if ( xControlText
.is() )
333 const XMLPropertyMapEntry
* pCharAttributeProperties
= XMLTextPropertySetMapper::getPropertyMapForType( TextPropMap::TEXT
);
334 while ( pCharAttributeProperties
->msApiName
)
336 exportedProperty( OUString::createFromAscii( pCharAttributeProperties
->msApiName
) );
337 ++pCharAttributeProperties
;
340 const XMLPropertyMapEntry
* pParaAttributeProperties
= XMLTextPropertySetMapper::getPropertyMapForType( TextPropMap::SHAPE_PARA
);
341 while ( pParaAttributeProperties
->msApiName
)
343 exportedProperty( OUString::createFromAscii( pParaAttributeProperties
->msApiName
) );
344 ++pParaAttributeProperties
;
347 // the RichText property is not exported. The presence of the text:p element
348 // will be used - upon reading - as indicator for the value of the RichText property
349 exportedProperty( PROPERTY_RICH_TEXT
);
351 // strange thing: paragraphs support both a CharStrikeout and a CharCrossedOut property
352 // The former is a short/enum value, the latter a boolean. The former has a real meaning
353 // (the strikeout type), the latter hasn't. But, when the CharCrossedOut is exported and
354 // later on imported, it overwrites anything which has previously been imported for
357 exportedProperty( "CharCrossedOut" );
360 if ( m_eType
== LISTBOX
)
362 // will be exported in exportListSourceAsElements:
363 if ( controlHasUserSuppliedListEntries() )
364 exportedProperty( PROPERTY_DEFAULT_SELECT_SEQ
);
366 // will not be exported in a generic way. Either exportListSourceAsElements cares
367 // for them, or we don't need them
368 exportedProperty( PROPERTY_STRING_ITEM_LIST
);
369 exportedProperty( PROPERTY_VALUE_SEQ
);
370 exportedProperty( PROPERTY_SELECT_SEQ
);
371 exportedProperty( PROPERTY_LISTSOURCE
);
373 if ( m_eType
== COMBOBOX
)
374 exportedProperty( PROPERTY_STRING_ITEM_LIST
);
376 // let the base class export the remaining properties and the events
377 OElementExport::exportSubTags();
379 // special sub tags for some controls
383 // don't export the list entries if the are not provided by the user, but obtained implicitly
384 // from other sources
386 if ( controlHasUserSuppliedListEntries() )
387 exportListSourceAsElements();
390 { // a grid control requires us to store all columns as sub elements
391 Reference
< XIndexAccess
> xColumnContainer(m_xProps
, UNO_QUERY
);
392 OSL_ENSURE(xColumnContainer
.is(), "OControlExport::exportSubTags: a grid control which is no IndexAccess?!!");
393 if (xColumnContainer
.is())
394 m_rContext
.exportCollectionElements(xColumnContainer
);
398 { // a combox box description has sub elements: the items
399 DBG_CHECK_PROPERTY( PROPERTY_STRING_ITEM_LIST
, Sequence
< OUString
> );
401 // don't export the list entries if the are not provided by the user, but obtained implicitly
402 // from other sources
404 if ( controlHasUserSuppliedListEntries() )
407 Sequence
< OUString
> aListItems
;
408 m_xProps
->getPropertyValue(PROPERTY_STRING_ITEM_LIST
) >>= aListItems
;
409 // loop through it and write the sub elements
410 const OUString
* pListItems
= aListItems
.getConstArray();
411 for (sal_Int32 i
=0; i
<aListItems
.getLength(); ++i
, ++pListItems
)
413 m_rContext
.getGlobalContext().ClearAttrList();
415 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Label
),
416 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Label
),
418 SvXMLElementExport
aFormElement(m_rContext
.getGlobalContext(), XML_NAMESPACE_FORM
, "item", true, true);
426 // if we act as rich text control, we need to export some text:p elements
427 if ( xControlText
.is() )
429 bool bActingAsRichText
= false;
430 if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_RICH_TEXT
) )
432 OSL_VERIFY(m_xProps
->getPropertyValue( PROPERTY_RICH_TEXT
) >>= bActingAsRichText
);
435 if ( bActingAsRichText
)
436 m_rContext
.getGlobalContext().GetTextParagraphExport()->exportText( xControlText
);
446 void OControlExport::exportGenericHandlerAttributes()
448 const Sequence
< Property
> aProperties
= m_xPropertyInfo
->getProperties();
449 for ( const Property
* prop
= aProperties
.getConstArray();
450 prop
!= aProperties
.getConstArray() + aProperties
.getLength();
456 // see if this property can already be handled with an IPropertyHandler (which, on the long
457 // term, should be the case for most, if not all, properties)
458 const PropertyDescription
* propDescription
= metadata::getPropertyDescription( prop
->Name
);
459 if ( propDescription
== nullptr )
462 // let the factory provide the concrete handler. Note that caching, if desired, is the task
464 PPropertyHandler handler
= (*propDescription
->factory
)( propDescription
->propertyId
);
465 if ( !handler
.get() )
467 SAL_WARN( "xmloff.forms", "OControlExport::exportGenericHandlerAttributes: invalid property handler provided by the factory!" );
471 OUString attributeValue
;
472 if ( propDescription
->propertyGroup
== NO_GROUP
)
474 // that's a property which has a direct mapping to an attribute
475 if ( !shouldExportProperty( prop
->Name
) )
476 // TODO: in the future, we surely need a more sophisticated approach to this, involving the property
477 // handler, or the property description
479 exportedProperty( prop
->Name
);
483 const Any propValue
= m_xProps
->getPropertyValue( prop
->Name
);
484 attributeValue
= handler
->getAttributeValue( propValue
);
488 // that's a property which is part of a group of properties, whose values, in their entity, comprise
489 // a single attribute value
491 // retrieve the descriptions of all other properties which add to the attribute value
492 PropertyDescriptionList descriptions
;
493 metadata::getPropertyGroup( propDescription
->propertyGroup
, descriptions
);
495 // retrieve the values for all those properties
496 PropertyValues aValues
;
497 for ( PropertyDescriptionList::iterator desc
= descriptions
.begin();
498 desc
!= descriptions
.end();
502 // TODO: XMultiPropertySet?
503 const Any propValue
= m_xProps
->getPropertyValue( (*desc
)->propertyName
);
504 aValues
[ (*desc
)->propertyId
] = propValue
;
507 // let the handler translate into an XML attribute value
508 attributeValue
= handler
->getAttributeValue( aValues
);
512 propDescription
->attribute
.namespacePrefix
,
513 token::GetXMLToken( propDescription
->attribute
.attributeToken
),
517 exportedProperty( prop
->Name
);
519 catch( const Exception
& )
521 DBG_UNHANDLED_EXCEPTION();
526 void OControlExport::exportCommonControlAttributes()
530 // I decided to handle all the properties here with some static arrays describing the property-attribute
531 // relations. This leads to somewhat ugly code :), but the only alternative I can think of right now
532 // would require maps and O(log n) searches, which seems somewhat expensive as this code is used
535 // the extra indents for the respective blocks are to ensure that there is no copy'n'paste error, using
536 // map identifiers from the wrong block
538 // some string properties
540 // the attribute ids of all properties which are expected to be of type string
541 static const CCAFlags nStringPropertyAttributeIds
[] =
543 CCAFlags::Label
, CCAFlags::Title
545 // the names of all properties which are expected to be of type string
546 static const char * aStringPropertyNames
[] =
548 PROPERTY_LABEL
, PROPERTY_TITLE
550 OSL_ENSURE( SAL_N_ELEMENTS(aStringPropertyNames
) ==
551 SAL_N_ELEMENTS(nStringPropertyAttributeIds
),
552 "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (1)!");
554 for (i
=0; i
<SAL_N_ELEMENTS(nStringPropertyAttributeIds
); ++i
)
555 if (nStringPropertyAttributeIds
[i
] & m_nIncludeCommon
)
557 exportStringPropertyAttribute(
558 OAttributeMetaData::getCommonControlAttributeNamespace(nStringPropertyAttributeIds
[i
]),
559 OAttributeMetaData::getCommonControlAttributeName(nStringPropertyAttributeIds
[i
]),
560 OUString::createFromAscii(aStringPropertyNames
[i
])
562 #if OSL_DEBUG_LEVEL > 0
563 // reset the bit for later checking
564 m_nIncludeCommon
= m_nIncludeCommon
& ~nStringPropertyAttributeIds
[i
];
569 // some boolean properties
571 static const CCAFlags nBooleanPropertyAttributeIds
[] =
573 CCAFlags::CurrentSelected
, CCAFlags::Disabled
, CCAFlags::Dropdown
, CCAFlags::Printable
, CCAFlags::ReadOnly
, CCAFlags::Selected
, CCAFlags::TabStop
, CCAFlags::EnableVisible
575 static const char * pBooleanPropertyNames
[] =
577 PROPERTY_STATE
, PROPERTY_ENABLED
,
578 PROPERTY_DROPDOWN
, PROPERTY_PRINTABLE
,
579 PROPERTY_READONLY
, PROPERTY_DEFAULT_STATE
,
580 PROPERTY_TABSTOP
, PROPERTY_ENABLEVISIBLE
582 static const BoolAttrFlags nBooleanPropertyAttrFlags
[] =
583 { // attribute defaults
584 BoolAttrFlags::DefaultFalse
, BoolAttrFlags::DefaultFalse
| BoolAttrFlags::InverseSemantics
, BoolAttrFlags::DefaultFalse
, BoolAttrFlags::DefaultTrue
, BoolAttrFlags::DefaultFalse
, BoolAttrFlags::DefaultFalse
, BoolAttrFlags::DefaultVoid
, BoolAttrFlags::DefaultFalse
586 #if OSL_DEBUG_LEVEL > 0
587 static const sal_Int32 nIdCount
= SAL_N_ELEMENTS(nBooleanPropertyAttributeIds
);
588 static const sal_Int32 nNameCount
= SAL_N_ELEMENTS(pBooleanPropertyNames
);
589 static const sal_Int32 nFlagsCount
= SAL_N_ELEMENTS(nBooleanPropertyAttrFlags
);
590 OSL_ENSURE((nIdCount
== nNameCount
) && (nNameCount
== nFlagsCount
),
591 "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (2)!");
593 for (i
=0; i
<SAL_N_ELEMENTS(nBooleanPropertyAttributeIds
); ++i
)
594 if (nBooleanPropertyAttributeIds
[i
] & m_nIncludeCommon
)
596 exportBooleanPropertyAttribute(
597 OAttributeMetaData::getCommonControlAttributeNamespace(nBooleanPropertyAttributeIds
[i
]),
598 OAttributeMetaData::getCommonControlAttributeName(nBooleanPropertyAttributeIds
[i
]),
599 OUString::createFromAscii(pBooleanPropertyNames
[i
]),
600 nBooleanPropertyAttrFlags
[i
]);
601 #if OSL_DEBUG_LEVEL > 0
602 // reset the bit for later checking
603 m_nIncludeCommon
= m_nIncludeCommon
& ~nBooleanPropertyAttributeIds
[i
];
608 // some integer properties
610 // now the common handling
611 static CCAFlags nIntegerPropertyAttributeIds
[] =
613 CCAFlags::Size
, CCAFlags::TabIndex
615 static const char * pIntegerPropertyNames
[] =
617 PROPERTY_LINECOUNT
, PROPERTY_TABINDEX
619 static const sal_Int16 nIntegerPropertyAttrDefaults
[] =
620 { // attribute defaults
624 if ( m_nIncludeCommon
& CCAFlags::MaxLength
)
625 exportedProperty(PROPERTY_MAXTEXTLENGTH
);
627 #if OSL_DEBUG_LEVEL > 0
628 static const sal_Int32 nIdCount
= SAL_N_ELEMENTS(nIntegerPropertyAttributeIds
);
629 static const sal_Int32 nNameCount
= SAL_N_ELEMENTS(pIntegerPropertyNames
);
630 static const sal_Int32 nDefaultCount
= SAL_N_ELEMENTS(nIntegerPropertyAttrDefaults
);
631 OSL_ENSURE((nIdCount
== nNameCount
) && (nNameCount
== nDefaultCount
),
632 "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (3)!");
634 for (i
=0; i
<SAL_N_ELEMENTS(nIntegerPropertyAttributeIds
); ++i
)
635 if (nIntegerPropertyAttributeIds
[i
] & m_nIncludeCommon
)
637 exportInt16PropertyAttribute(
638 OAttributeMetaData::getCommonControlAttributeNamespace(nIntegerPropertyAttributeIds
[i
]),
639 OAttributeMetaData::getCommonControlAttributeName(nIntegerPropertyAttributeIds
[i
]),
640 OUString::createFromAscii(pIntegerPropertyNames
[i
]),
641 nIntegerPropertyAttrDefaults
[i
]);
642 #if OSL_DEBUG_LEVEL > 0
643 // reset the bit for later checking
644 m_nIncludeCommon
= m_nIncludeCommon
& ~nIntegerPropertyAttributeIds
[i
];
650 // some enum properties
652 if (m_nIncludeCommon
& CCAFlags::ButtonType
)
654 exportEnumPropertyAttribute(
655 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::ButtonType
),
656 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::ButtonType
),
658 OEnumMapper::getEnumMap(OEnumMapper::epButtonType
),
659 FormButtonType_PUSH
);
660 #if OSL_DEBUG_LEVEL > 0
661 // reset the bit for later checking
662 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::ButtonType
;
665 if ( m_nIncludeCommon
& CCAFlags::Orientation
)
667 exportEnumPropertyAttribute(
668 OAttributeMetaData::getCommonControlAttributeNamespace( CCAFlags::Orientation
),
669 OAttributeMetaData::getCommonControlAttributeName( CCAFlags::Orientation
),
670 PROPERTY_ORIENTATION
,
671 OEnumMapper::getEnumMap( OEnumMapper::epOrientation
),
672 ScrollBarOrientation::HORIZONTAL
674 #if OSL_DEBUG_LEVEL > 0
675 // reset the bit for later checking
676 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::Orientation
;
680 if ( m_nIncludeCommon
& CCAFlags::VisualEffect
)
682 exportEnumPropertyAttribute(
683 OAttributeMetaData::getCommonControlAttributeNamespace( CCAFlags::VisualEffect
),
684 OAttributeMetaData::getCommonControlAttributeName( CCAFlags::VisualEffect
),
685 PROPERTY_VISUAL_EFFECT
,
686 OEnumMapper::getEnumMap( OEnumMapper::epVisualEffect
),
689 #if OSL_DEBUG_LEVEL > 0
690 // reset the bit for later checking
691 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::VisualEffect
;
696 // some properties which require a special handling
699 if (m_nIncludeCommon
& CCAFlags::TargetFrame
)
701 exportTargetFrameAttribute();
702 #if OSL_DEBUG_LEVEL > 0
703 // reset the bit for later checking
704 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::TargetFrame
;
709 if ( m_nIncludeCommon
& CCAFlags::MaxLength
)
711 // normally, the respective property would be "MaxTextLen"
712 // However, if the model has a property "PersistenceMaxTextLength", then we prefer this
714 // determine the name of the property to export
715 OUString
sTextLenPropertyName( PROPERTY_MAXTEXTLENGTH
);
716 if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_PERSISTENCE_MAXTEXTLENGTH
) )
717 sTextLenPropertyName
= PROPERTY_PERSISTENCE_MAXTEXTLENGTH
;
720 exportInt16PropertyAttribute(
721 OAttributeMetaData::getCommonControlAttributeNamespace( CCAFlags::MaxLength
),
722 OAttributeMetaData::getCommonControlAttributeName( CCAFlags::MaxLength
),
723 sTextLenPropertyName
,
727 // in either way, both properties count as "exported"
728 exportedProperty( PROPERTY_MAXTEXTLENGTH
);
729 exportedProperty( PROPERTY_PERSISTENCE_MAXTEXTLENGTH
);
731 #if OSL_DEBUG_LEVEL > 0
732 // reset the bit for later checking
733 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::MaxLength
;
737 if (m_nIncludeCommon
& CCAFlags::TargetLocation
)
739 exportTargetLocationAttribute(false);
740 #if OSL_DEBUG_LEVEL > 0
741 // reset the bit for later checking
742 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::TargetLocation
;
747 if (m_nIncludeCommon
& CCAFlags::ImageData
)
749 exportImageDataAttribute();
750 #if OSL_DEBUG_LEVEL > 0
751 // reset the bit for later checking
752 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::ImageData
;
758 if (m_nIncludeCommon
& CCAFlags::For
)
760 if (!m_sReferringControls
.isEmpty())
761 { // there is at least one control referring to the one we're handling currently
763 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::For
),
764 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::For
),
765 m_sReferringControls
);
767 #if OSL_DEBUG_LEVEL > 0
768 // reset the bit for later checking
769 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags::For
;
773 if ((CCAFlags::CurrentValue
| CCAFlags::Value
) & m_nIncludeCommon
)
775 const sal_Char
* pCurrentValuePropertyName
= nullptr;
776 const sal_Char
* pValuePropertyName
= nullptr;
778 // get the property names
779 getValuePropertyNames(m_eType
, m_nClassId
, pCurrentValuePropertyName
, pValuePropertyName
);
781 static const sal_Char
* pCurrentValueAttributeName
= OAttributeMetaData::getCommonControlAttributeName(CCAFlags::CurrentValue
);
782 static const sal_Char
* pValueAttributeName
= OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Value
);
783 static const sal_uInt16 nCurrentValueAttributeNamespaceKey
= OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::CurrentValue
);
784 static const sal_uInt16 nValueAttributeNamespaceKey
= OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Value
);
786 // add the attributes if necessary and possible
787 if (pCurrentValuePropertyName
&& (CCAFlags::CurrentValue
& m_nIncludeCommon
))
789 // don't export the current-value if this value originates from a data binding
791 if ( controlHasActiveDataBinding() )
792 exportedProperty( OUString::createFromAscii( pCurrentValuePropertyName
) );
794 exportGenericPropertyAttribute(
795 nCurrentValueAttributeNamespaceKey
,
796 pCurrentValueAttributeName
,
797 pCurrentValuePropertyName
801 if (pValuePropertyName
&& (CCAFlags::Value
& m_nIncludeCommon
))
802 exportGenericPropertyAttribute(
803 nValueAttributeNamespaceKey
,
807 OSL_ENSURE((nullptr == pValuePropertyName
) == (CCAFlags::NONE
== (CCAFlags::Value
& m_nIncludeCommon
)),
808 "OControlExport::exportCommonControlAttributes: no property found for the value attribute!");
809 OSL_ENSURE((nullptr == pCurrentValuePropertyName
) == (CCAFlags::NONE
== (CCAFlags::CurrentValue
& m_nIncludeCommon
)),
810 "OControlExport::exportCommonControlAttributes: no property found for the current-value attribute!");
812 #if OSL_DEBUG_LEVEL > 0
813 // reset the bit for later checking
814 m_nIncludeCommon
= m_nIncludeCommon
& ~CCAFlags(CCAFlags::CurrentValue
| CCAFlags::Value
);
818 OSL_ENSURE(CCAFlags::NONE
== m_nIncludeCommon
,
819 "OControlExport::exportCommonControlAttributes: forgot some flags!");
820 // in the dbg_util version, we should have removed every bit we handled from the mask, so it should
824 void OControlExport::exportDatabaseAttributes()
826 #if OSL_DEBUG_LEVEL > 0
827 DAFlags nIncludeDatabase
= m_nIncludeDatabase
;
829 // the only string property: DataField
830 if (DAFlags::DataField
& m_nIncludeDatabase
)
832 exportStringPropertyAttribute(
833 OAttributeMetaData::getDatabaseAttributeNamespace(DAFlags::DataField
),
834 OAttributeMetaData::getDatabaseAttributeName(DAFlags::DataField
),
836 RESET_BIT( nIncludeDatabase
, DAFlags::DataField
);
840 if ( DAFlags::InputRequired
& m_nIncludeDatabase
)
842 exportBooleanPropertyAttribute(
843 OAttributeMetaData::getDatabaseAttributeNamespace( DAFlags::InputRequired
),
844 OAttributeMetaData::getDatabaseAttributeName( DAFlags::InputRequired
),
845 PROPERTY_INPUT_REQUIRED
,
846 BoolAttrFlags::DefaultTrue
848 RESET_BIT( nIncludeDatabase
, DAFlags::InputRequired
);
851 // the only int16 property: BoundColumn
852 if (DAFlags::BoundColumn
& m_nIncludeDatabase
)
854 exportInt16PropertyAttribute(
855 OAttributeMetaData::getDatabaseAttributeNamespace(DAFlags::BoundColumn
),
856 OAttributeMetaData::getDatabaseAttributeName(DAFlags::BoundColumn
),
857 PROPERTY_BOUNDCOLUMN
,
860 RESET_BIT( nIncludeDatabase
, DAFlags::BoundColumn
);
863 // ConvertEmptyToNull
864 if (DAFlags::ConvertEmpty
& m_nIncludeDatabase
)
866 exportBooleanPropertyAttribute(
867 OAttributeMetaData::getDatabaseAttributeNamespace(DAFlags::ConvertEmpty
),
868 OAttributeMetaData::getDatabaseAttributeName(DAFlags::ConvertEmpty
),
869 PROPERTY_EMPTY_IS_NULL
,
870 BoolAttrFlags::DefaultFalse
872 RESET_BIT( nIncludeDatabase
, DAFlags::ConvertEmpty
);
875 // the only enum property: ListSourceType
876 if (DAFlags::ListSource_TYPE
& m_nIncludeDatabase
)
878 exportEnumPropertyAttribute(
879 OAttributeMetaData::getDatabaseAttributeNamespace(DAFlags::ListSource_TYPE
),
880 OAttributeMetaData::getDatabaseAttributeName(DAFlags::ListSource_TYPE
),
881 PROPERTY_LISTSOURCETYPE
,
882 OEnumMapper::getEnumMap(OEnumMapper::epListSourceType
),
883 ListSourceType_VALUELIST
885 RESET_BIT( nIncludeDatabase
, DAFlags::ListSource_TYPE
);
888 if (m_nIncludeDatabase
& DAFlags::ListSource
)
890 exportListSourceAsAttribute();
891 RESET_BIT( nIncludeDatabase
, DAFlags::ListSource
);
894 #if OSL_DEBUG_LEVEL > 0
895 OSL_ENSURE(DAFlags::NONE
== nIncludeDatabase
,
896 "OControlExport::exportDatabaseAttributes: forgot some flags!");
897 // in the dbg_util version, we should have removed every bit we handled from the mask, so it should
902 void OControlExport::exportBindingAtributes()
904 #if OSL_DEBUG_LEVEL > 0
905 BAFlags nIncludeBinding
= m_nIncludeBindings
;
908 if ( m_nIncludeBindings
& BAFlags::LinkedCell
)
910 exportCellBindingAttributes( bool(m_nIncludeBindings
& BAFlags::ListLinkingType
) );
911 #if OSL_DEBUG_LEVEL > 0
912 // reset the bit for later checking
913 nIncludeBinding
= nIncludeBinding
& ~BAFlags( BAFlags::LinkedCell
| BAFlags::ListLinkingType
);
917 if ( m_nIncludeBindings
& BAFlags::ListCellRange
)
919 exportCellListSourceRange();
920 #if OSL_DEBUG_LEVEL > 0
921 // reset the bit for later checking
922 nIncludeBinding
= nIncludeBinding
& ~BAFlags::ListCellRange
;
926 if ( m_nIncludeBindings
& BAFlags::XFormsBind
)
928 exportXFormsBindAttributes();
929 #if OSL_DEBUG_LEVEL > 0
930 // reset the bit for later checking
931 nIncludeBinding
= nIncludeBinding
& ~BAFlags::XFormsBind
;
935 if ( m_nIncludeBindings
& BAFlags::XFormsListBind
)
937 exportXFormsListAttributes();
938 #if OSL_DEBUG_LEVEL > 0
939 // reset the bit for later checking
940 nIncludeBinding
= nIncludeBinding
& ~BAFlags::XFormsListBind
;
944 if ( m_nIncludeBindings
& BAFlags::XFormsSubmission
)
946 exportXFormsSubmissionAttributes();
947 #if OSL_DEBUG_LEVEL > 0
948 // reset the bit for later checking
949 nIncludeBinding
= nIncludeBinding
& ~BAFlags::XFormsSubmission
;
953 #if OSL_DEBUG_LEVEL > 0
954 OSL_ENSURE( BAFlags::NONE
== nIncludeBinding
,
955 "OControlExport::exportBindingAtributes: forgot some flags!");
956 // in the debug version, we should have removed every bit we handled from the mask, so it should
961 void OControlExport::exportSpecialAttributes()
965 // the boolean properties
967 static const SCAFlags nBooleanPropertyAttributeIds
[] =
969 SCAFlags::Validation
, SCAFlags::MultiLine
, SCAFlags::AutoCompletion
, SCAFlags::Multiple
, SCAFlags::DefaultButton
, SCAFlags::IsTristate
,
970 SCAFlags::Toggle
, SCAFlags::FocusOnClick
972 static const char * pBooleanPropertyNames
[] =
974 PROPERTY_STRICTFORMAT
, PROPERTY_MULTILINE
,
975 PROPERTY_AUTOCOMPLETE
,
976 PROPERTY_MULTISELECTION
,
977 PROPERTY_DEFAULTBUTTON
, PROPERTY_TRISTATE
,
978 PROPERTY_TOGGLE
, PROPERTY_FOCUS_ON_CLICK
980 static const sal_Int32 nIdCount
= SAL_N_ELEMENTS(nBooleanPropertyAttributeIds
);
981 #if OSL_DEBUG_LEVEL > 0
982 static const sal_Int32 nNameCount
= SAL_N_ELEMENTS(pBooleanPropertyNames
);
983 OSL_ENSURE((nIdCount
== nNameCount
),
984 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (1)!");
986 const SCAFlags
* pAttributeId
= nBooleanPropertyAttributeIds
;
987 for ( i
= 0; i
< nIdCount
; ++i
, ++pAttributeId
)
989 if ( *pAttributeId
& m_nIncludeSpecial
)
991 exportBooleanPropertyAttribute(
992 OAttributeMetaData::getSpecialAttributeNamespace( *pAttributeId
),
993 OAttributeMetaData::getSpecialAttributeName( *pAttributeId
),
994 OUString::createFromAscii(pBooleanPropertyNames
[i
]),
995 ( *pAttributeId
== SCAFlags::FocusOnClick
) ? BoolAttrFlags::DefaultTrue
: BoolAttrFlags::DefaultFalse
997 #if OSL_DEBUG_LEVEL > 0
998 // reset the bit for later checking
999 m_nIncludeSpecial
= m_nIncludeSpecial
& ~*pAttributeId
;
1005 // the integer properties
1007 static SCAFlags nIntegerPropertyAttributeIds
[] =
1008 { // attribute flags
1009 SCAFlags::PageStepSize
1011 static const char * pIntegerPropertyNames
[] =
1013 PROPERTY_BLOCK_INCREMENT
1015 static const sal_Int32 nIntegerPropertyAttrDefaults
[] =
1016 { // attribute defaults (XML defaults, not runtime defaults!)
1020 static const sal_Int32 nIdCount
= SAL_N_ELEMENTS( nIntegerPropertyAttributeIds
);
1021 #if OSL_DEBUG_LEVEL > 0
1022 static const sal_Int32 nNameCount
= SAL_N_ELEMENTS( pIntegerPropertyNames
);
1023 OSL_ENSURE( ( nIdCount
== nNameCount
),
1024 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (2)!" );
1025 static const sal_Int32 nDefaultCount
= SAL_N_ELEMENTS( nIntegerPropertyAttrDefaults
);
1026 OSL_ENSURE( ( nIdCount
== nDefaultCount
),
1027 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (3)!" );
1029 for ( i
= 0; i
< nIdCount
; ++i
)
1030 if ( nIntegerPropertyAttributeIds
[i
] & m_nIncludeSpecial
)
1032 exportInt32PropertyAttribute(
1033 OAttributeMetaData::getSpecialAttributeNamespace( nIntegerPropertyAttributeIds
[i
] ),
1034 OAttributeMetaData::getSpecialAttributeName( nIntegerPropertyAttributeIds
[i
] ),
1035 OUString::createFromAscii(pIntegerPropertyNames
[i
]),
1036 nIntegerPropertyAttrDefaults
[i
]
1038 #if OSL_DEBUG_LEVEL > 0
1039 // reset the bit for later checking
1040 m_nIncludeSpecial
= m_nIncludeSpecial
& ~nIntegerPropertyAttributeIds
[i
];
1044 if ( SCAFlags::StepSize
& m_nIncludeSpecial
)
1046 OUString sPropertyName
;
1047 if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_LINE_INCREMENT
) )
1048 sPropertyName
= PROPERTY_LINE_INCREMENT
;
1049 else if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_SPIN_INCREMENT
) )
1050 sPropertyName
= PROPERTY_SPIN_INCREMENT
;
1052 OSL_FAIL( "OControlExport::exportSpecialAttributes: not property which can be mapped to step-size attribute!" );
1054 if ( !sPropertyName
.isEmpty() )
1055 exportInt32PropertyAttribute(
1056 OAttributeMetaData::getSpecialAttributeNamespace( SCAFlags::StepSize
),
1057 OAttributeMetaData::getSpecialAttributeName( SCAFlags::StepSize
),
1062 #if OSL_DEBUG_LEVEL > 0
1063 // reset the bit for later checking
1064 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags::StepSize
;
1070 // the enum properties
1072 if (SCAFlags::State
& m_nIncludeSpecial
)
1074 exportEnumPropertyAttribute(
1075 OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::State
),
1076 OAttributeMetaData::getSpecialAttributeName(SCAFlags::State
),
1077 PROPERTY_DEFAULT_STATE
,
1078 OEnumMapper::getEnumMap(OEnumMapper::epCheckState
),
1080 #if OSL_DEBUG_LEVEL > 0
1081 // reset the bit for later checking
1082 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags::State
;
1086 if (SCAFlags::CurrentState
& m_nIncludeSpecial
)
1088 exportEnumPropertyAttribute(
1089 OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::CurrentState
),
1090 OAttributeMetaData::getSpecialAttributeName(SCAFlags::CurrentState
),
1092 OEnumMapper::getEnumMap(OEnumMapper::epCheckState
),
1094 #if OSL_DEBUG_LEVEL > 0
1095 // reset the bit for later checking
1096 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags::CurrentState
;
1101 // some properties which require a special handling
1104 if ( m_nIncludeSpecial
& SCAFlags::RepeatDelay
)
1106 DBG_CHECK_PROPERTY( PROPERTY_REPEAT_DELAY
, sal_Int32
);
1108 sal_Int32 nRepeatDelay
= 0;
1109 m_xProps
->getPropertyValue( PROPERTY_REPEAT_DELAY
) >>= nRepeatDelay
;
1110 tools::Time
aTime( tools::Time::SYSTEM
);
1111 aTime
.MakeTimeFromMS( nRepeatDelay
);
1112 util::Duration aDuration
;
1113 aDuration
.Hours
= aTime
.GetHour();
1114 aDuration
.Minutes
= aTime
.GetMin();
1115 aDuration
.Seconds
= aTime
.GetSec();
1116 aDuration
.NanoSeconds
= (nRepeatDelay
% 1000) * 1000000;
1119 ::sax::Converter::convertDuration(buf
, aDuration
);
1120 AddAttribute(OAttributeMetaData::getSpecialAttributeNamespace( SCAFlags::RepeatDelay
)
1121 ,OAttributeMetaData::getSpecialAttributeName( SCAFlags::RepeatDelay
)
1122 ,buf
.makeStringAndClear());
1124 exportedProperty( PROPERTY_REPEAT_DELAY
);
1126 #if OSL_DEBUG_LEVEL > 0
1127 // reset the bit for later checking
1128 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags::RepeatDelay
;
1133 // the EchoChar property needs special handling, cause it's a Int16, but must be stored as one-character-string
1135 if (SCAFlags::EchoChar
& m_nIncludeSpecial
)
1137 DBG_CHECK_PROPERTY( PROPERTY_ECHO_CHAR
, sal_Int16
);
1138 sal_Int16
nValue(0);
1139 m_xProps
->getPropertyValue(PROPERTY_ECHO_CHAR
) >>= nValue
;
1142 OUString
sCharacter(reinterpret_cast<const sal_Unicode
*>(&nValue
), 1);
1144 OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::EchoChar
),
1145 OAttributeMetaData::getSpecialAttributeName(SCAFlags::EchoChar
),
1148 exportedProperty(PROPERTY_ECHO_CHAR
);
1149 #if OSL_DEBUG_LEVEL > 0
1150 // reset the bit for later checking
1151 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags::EchoChar
;
1156 // the string properties
1158 static const SCAFlags nStringPropertyAttributeIds
[] =
1159 { // attribute flags
1162 static const OUString pStringPropertyNames
[] =
1164 OUString(PROPERTY_GROUP_NAME
)
1167 static const sal_Int32 nIdCount
= SAL_N_ELEMENTS( nStringPropertyAttributeIds
);
1168 #if OSL_DEBUG_LEVEL > 0
1169 static const sal_Int32 nNameCount
= SAL_N_ELEMENTS( pStringPropertyNames
);
1170 OSL_ENSURE( ( nIdCount
== nNameCount
),
1171 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (2)!" );
1173 for ( i
= 0; i
< nIdCount
; ++i
)
1174 if ( nStringPropertyAttributeIds
[i
] & m_nIncludeSpecial
)
1176 exportStringPropertyAttribute(
1177 OAttributeMetaData::getSpecialAttributeNamespace( nStringPropertyAttributeIds
[i
] ),
1178 OAttributeMetaData::getSpecialAttributeName( nStringPropertyAttributeIds
[i
] ),
1179 pStringPropertyNames
[i
]
1181 #if OSL_DEBUG_LEVEL > 0
1182 // reset the bit for later checking
1183 m_nIncludeSpecial
= m_nIncludeSpecial
& ~nStringPropertyAttributeIds
[i
];
1188 if ((SCAFlags::MinValue
| SCAFlags::MaxValue
) & m_nIncludeSpecial
)
1190 // need to export the min value and the max value as attributes
1191 // It depends on the real type (FormComponentType) of the control, which properties hold these
1193 const sal_Char
* pMinValuePropertyName
= nullptr;
1194 const sal_Char
* pMaxValuePropertyName
= nullptr;
1195 getValueLimitPropertyNames(m_nClassId
, pMinValuePropertyName
, pMaxValuePropertyName
);
1197 OSL_ENSURE((nullptr == pMinValuePropertyName
) == (SCAFlags::NONE
== (SCAFlags::MinValue
& m_nIncludeSpecial
)),
1198 "OControlExport::exportCommonControlAttributes: no property found for the min value attribute!");
1199 OSL_ENSURE((nullptr == pMaxValuePropertyName
) == (SCAFlags::NONE
== (SCAFlags::MaxValue
& m_nIncludeSpecial
)),
1200 "OControlExport::exportCommonControlAttributes: no property found for the max value attribute!");
1202 // add the two attributes
1203 static const sal_Char
* pMinValueAttributeName
= OAttributeMetaData::getSpecialAttributeName(SCAFlags::MinValue
);
1204 static const sal_Char
* pMaxValueAttributeName
= OAttributeMetaData::getSpecialAttributeName(SCAFlags::MaxValue
);
1205 static const sal_uInt16 nMinValueNamespaceKey
= OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::MinValue
);
1206 static const sal_uInt16 nMaxValueNamespaceKey
= OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::MaxValue
);
1208 if (pMinValuePropertyName
&& (SCAFlags::MinValue
& m_nIncludeSpecial
))
1209 exportGenericPropertyAttribute(
1210 nMinValueNamespaceKey
,
1211 pMinValueAttributeName
,
1212 pMinValuePropertyName
);
1214 if (pMaxValuePropertyName
&& (SCAFlags::MaxValue
& m_nIncludeSpecial
))
1215 exportGenericPropertyAttribute(
1216 nMaxValueNamespaceKey
,
1217 pMaxValueAttributeName
,
1218 pMaxValuePropertyName
);
1219 #if OSL_DEBUG_LEVEL > 0
1220 // reset the bit for later checking
1221 m_nIncludeSpecial
= m_nIncludeSpecial
& ~SCAFlags(SCAFlags::MinValue
| SCAFlags::MaxValue
);
1225 if ( SCAFlags::ImagePosition
& m_nIncludeSpecial
)
1227 exportImagePositionAttributes();
1228 RESET_BIT( m_nIncludeSpecial
, SCAFlags::ImagePosition
);
1231 OSL_ENSURE(SCAFlags::NONE
== m_nIncludeSpecial
,
1232 "OControlExport::exportSpecialAttributes: forgot some flags!");
1233 // in the dbg_util version, we should have removed every bit we handled from the mask, so it should
1237 OUString
OControlExport::getScalarListSourceValue() const
1239 OUString sListSource
;
1240 Any aListSource
= m_xProps
->getPropertyValue( PROPERTY_LISTSOURCE
);
1241 if ( !( aListSource
>>= sListSource
) )
1243 Sequence
< OUString
> aListSourceSequence
;
1244 aListSource
>>= aListSourceSequence
;
1245 if ( aListSourceSequence
.getLength() )
1246 sListSource
= aListSourceSequence
[ 0 ];
1251 void OControlExport::exportListSourceAsAttribute()
1253 // DAFlags::ListSource needs some special handling
1254 DBG_CHECK_PROPERTY_NO_TYPE( PROPERTY_LISTSOURCE
);
1256 OUString sListSource
= getScalarListSourceValue();
1257 if ( !sListSource
.isEmpty() )
1258 { // the ListSource property needs to be exported as attribute, and it is not empty
1260 OAttributeMetaData::getDatabaseAttributeNamespace(DAFlags::ListSource
),
1261 OAttributeMetaData::getDatabaseAttributeName(DAFlags::ListSource
),
1265 exportedProperty( PROPERTY_LISTSOURCE
);
1268 void OControlExport::getSequenceInt16PropertyAsSet(const OUString
& _rPropertyName
, Int16Set
& _rOut
)
1270 Sequence
< sal_Int16
> aValueSequence
;
1271 DBG_CHECK_PROPERTY(_rPropertyName
, Sequence
< sal_Int16
>);
1272 m_xProps
->getPropertyValue(_rPropertyName
) >>= aValueSequence
;
1274 const sal_Int16
* pValues
= aValueSequence
.getConstArray();
1275 for (sal_Int32 i
=0; i
<aValueSequence
.getLength(); ++i
, ++pValues
)
1276 _rOut
.insert(*pValues
);
1279 void OControlExport::exportListSourceAsElements()
1282 Sequence
< OUString
> aItems
, aValues
;
1283 DBG_CHECK_PROPERTY( PROPERTY_STRING_ITEM_LIST
, Sequence
< OUString
> );
1284 m_xProps
->getPropertyValue(PROPERTY_STRING_ITEM_LIST
) >>= aItems
;
1286 DBG_CHECK_PROPERTY( PROPERTY_LISTSOURCE
, Sequence
< OUString
> );
1287 if ( DAFlags::NONE
== ( m_nIncludeDatabase
& DAFlags::ListSource
) )
1288 m_xProps
->getPropertyValue(PROPERTY_LISTSOURCE
) >>= aValues
;
1289 // if we exported the list source as attribute, we do not repeat it as sub elements
1291 // the selection lists
1292 Int16Set aSelection
, aDefaultSelection
;
1293 getSequenceInt16PropertyAsSet(PROPERTY_SELECT_SEQ
, aSelection
);
1294 getSequenceInt16PropertyAsSet(PROPERTY_DEFAULT_SELECT_SEQ
, aDefaultSelection
);
1296 // the string for "true"
1298 OUStringBuffer sBuffer
;
1299 ::sax::Converter::convertBool(sBuffer
, true);
1300 sTrue
= sBuffer
.makeStringAndClear();
1302 // loop through both lists ('til the maximum of both lengths)
1303 const OUString
* pItems
= aItems
.getConstArray();
1304 const OUString
* pValues
= aValues
.getConstArray();
1306 sal_Int32 nItems
= aItems
.getLength();
1307 sal_Int32 nValues
= aValues
.getLength();
1309 sal_Int16 nMaxLen
= (sal_Int16
)std::max(nItems
, nValues
);
1311 for (sal_Int16 i
=0; i
<nMaxLen
; ++i
)
1313 m_rContext
.getGlobalContext().ClearAttrList();
1316 // there is an item at this position
1318 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Label
),
1319 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Label
),
1325 // there is an value at this position
1327 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Value
),
1328 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Value
),
1333 Int16Set::iterator aSelectedPos
= aSelection
.find(i
);
1334 if (aSelection
.end() != aSelectedPos
)
1335 { // the item at this position is selected
1337 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::CurrentSelected
),
1338 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::CurrentSelected
),
1341 aSelection
.erase(aSelectedPos
);
1344 Int16Set::iterator aDefaultSelectedPos
= aDefaultSelection
.find(i
);
1345 if (aDefaultSelection
.end() != aDefaultSelectedPos
)
1346 { // the item at this position is selected as default
1348 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Selected
),
1349 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Selected
),
1352 aDefaultSelection
.erase(aDefaultSelectedPos
);
1354 SvXMLElementExport
aFormElement(m_rContext
.getGlobalContext(), XML_NAMESPACE_FORM
, "option", true, true);
1357 // There may be more "selected" or "default-selected" items than there are in the lists in real,
1358 // so we need to store some additional "form:option" items which have no name and no label, but
1359 // one or both of the selected flags.
1360 // 21.05.2001 - 85388 - frank.schoenheit@germany.sun.com
1362 if ( !aSelection
.empty() || !aDefaultSelection
.empty() )
1364 sal_Int16 nLastSelected
= -1;
1365 if ( !aSelection
.empty() )
1366 nLastSelected
= *(--aSelection
.end());
1368 sal_Int16 nLastDefaultSelected
= -1;
1369 if ( !aDefaultSelection
.empty() )
1370 nLastDefaultSelected
= *(--aDefaultSelection
.end());
1372 // the maximum element in both sets
1373 sal_Int16 nLastReferredEntry
= std::max(nLastSelected
, nLastDefaultSelected
);
1374 OSL_ENSURE(nLastReferredEntry
>= nMaxLen
, "OControlExport::exportListSourceAsElements: inconsistence!");
1375 // if the maximum (selected or default selected) entry number is less than the maximum item count
1376 // in both lists, the entry number should have been removed from the set
1378 for (sal_Int16 i
=nMaxLen
; i
<=nLastReferredEntry
; ++i
)
1380 if (aSelection
.end() != aSelection
.find(i
))
1381 { // the (not existent) item at this position is selected
1383 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::CurrentSelected
),
1384 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::CurrentSelected
),
1389 if (aDefaultSelection
.end() != aDefaultSelection
.find(i
))
1390 { // the (not existent) item at this position is selected as default
1392 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Selected
),
1393 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Selected
),
1397 SvXMLElementExport
aFormElement(m_rContext
.getGlobalContext(), XML_NAMESPACE_FORM
, "option", true, true);
1402 void OControlExport::implStartElement(const sal_Char
* _pName
)
1404 // before we let the base class start it's outer element, we add a wrapper element
1405 const sal_Char
*pOuterElementName
= getOuterXMLElementName();
1406 m_pOuterElement
= pOuterElementName
1407 ? new SvXMLElementExport(
1408 m_rContext
.getGlobalContext(),
1410 pOuterElementName
, true,
1414 // add the attributes for the inner element
1415 exportInnerAttributes();
1417 // and start the inner element
1418 OElementExport::implStartElement(_pName
);
1421 void OControlExport::implEndElement()
1423 // end the inner element
1424 OElementExport::implEndElement();
1426 // end the outer element if it exists
1427 delete m_pOuterElement
;
1428 m_pOuterElement
= nullptr;
1431 const sal_Char
* OControlExport::getOuterXMLElementName() const
1436 const sal_Char
* OControlExport::getXMLElementName() const
1438 return getElementName(m_eType
);
1441 void OControlExport::examine()
1443 OSL_ENSURE( ( m_nIncludeCommon
== CCAFlags::NONE
) && ( m_nIncludeSpecial
== SCAFlags::NONE
) && ( m_nIncludeDatabase
== DAFlags::NONE
)
1444 && ( m_nIncludeEvents
== EAFlags::NONE
) && ( m_nIncludeBindings
== BAFlags::NONE
),
1445 "OControlExport::examine: called me twice? Not initialized?" );
1447 // get the class id to decide which kind of element we need in the XML stream
1448 m_nClassId
= FormComponentType::CONTROL
;
1449 DBG_CHECK_PROPERTY( PROPERTY_CLASSID
, sal_Int16
);
1450 m_xProps
->getPropertyValue(PROPERTY_CLASSID
) >>= m_nClassId
;
1451 bool knownType
= false;
1454 case FormComponentType::DATEFIELD
:
1458 case FormComponentType::TIMEFIELD
:
1464 m_nIncludeSpecial
|= SCAFlags::Validation
;
1466 case FormComponentType::NUMERICFIELD
:
1467 case FormComponentType::CURRENCYFIELD
:
1468 case FormComponentType::PATTERNFIELD
:
1471 m_eType
= FORMATTED_TEXT
;
1475 case FormComponentType::TEXTFIELD
:
1476 { // it's some kind of edit. To know which type we need further investigation
1480 // check if it's a formatted field
1481 if (m_xPropertyInfo
->hasPropertyByName(PROPERTY_FORMATKEY
))
1483 m_eType
= FORMATTED_TEXT
;
1487 // all other controls are represented by an ordinary edit control, but which XML control type
1488 // it is depends on the current values of some properties
1490 // if the EchoChar string is not empty, it is a password field
1491 sal_Int16 nEchoChar
= 0;
1492 if (m_xPropertyInfo
->hasPropertyByName(PROPERTY_ECHOCHAR
))
1493 // grid columns do not have this property ....
1494 m_xProps
->getPropertyValue(PROPERTY_ECHOCHAR
) >>= nEchoChar
;
1498 m_nIncludeSpecial
|= SCAFlags::EchoChar
;
1502 // if the MultiLine property is sal_True, it is a TextArea
1503 bool bMultiLine
= false;
1504 if (m_xPropertyInfo
->hasPropertyByName(PROPERTY_MULTILINE
))
1505 // grid columns do not have this property ....
1506 bMultiLine
= ::cppu::any2bool(m_xProps
->getPropertyValue(PROPERTY_MULTILINE
));
1509 m_eType
= TEXT_AREA
;
1511 // the only case left is represented by a Text element
1517 // attributes which are common to all the types:
1518 // common attributes
1520 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
|
1521 CCAFlags::Printable
| CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
;
1523 if ( ( m_nClassId
!= FormComponentType::DATEFIELD
)
1524 && ( m_nClassId
!= FormComponentType::TIMEFIELD
)
1526 // date and time field values are handled differently nowadays
1527 m_nIncludeCommon
|= CCAFlags::Value
;
1529 // database attributes
1530 m_nIncludeDatabase
= DAFlags::DataField
| DAFlags::InputRequired
;
1533 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnChange
| EAFlags::OnSelect
;
1535 // only text and pattern fields have a ConvertEmptyToNull property
1536 if ( ( m_nClassId
== FormComponentType::TEXTFIELD
)
1537 || ( m_nClassId
== FormComponentType::PATTERNFIELD
)
1539 m_nIncludeDatabase
|= DAFlags::ConvertEmpty
;
1541 // all controls but the file control fields have a readonly property
1542 if ( m_nClassId
!= FormComponentType::FILECONTROL
)
1543 m_nIncludeCommon
|= CCAFlags::ReadOnly
;
1545 // a text field has a max text len
1546 if ( m_nClassId
== FormComponentType::TEXTFIELD
)
1547 m_nIncludeCommon
|= CCAFlags::MaxLength
;
1549 // max and min values and validation:
1550 if (FORMATTED_TEXT
== m_eType
)
1551 { // in general all controls represented as formatted-text have these props
1552 if ( FormComponentType::PATTERNFIELD
!= m_nClassId
) // except the PatternField
1553 m_nIncludeSpecial
|= SCAFlags::MaxValue
| SCAFlags::MinValue
;
1555 if (FormComponentType::TEXTFIELD
!= m_nClassId
)
1556 // and the FormattedField does not have a validation flag
1557 m_nIncludeSpecial
|= SCAFlags::Validation
;
1560 // if it's not a password field or rich text control, the CurrentValue needs to be stored, too
1561 if ( ( PASSWORD
!= m_eType
)
1562 && ( DATE
!= m_eType
)
1563 && ( TIME
!= m_eType
)
1566 m_nIncludeCommon
|= CCAFlags::CurrentValue
;
1571 case FormComponentType::FILECONTROL
:
1574 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::CurrentValue
| CCAFlags::Disabled
|
1575 CCAFlags::Printable
| CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
|
1577 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnChange
| EAFlags::OnSelect
;
1580 case FormComponentType::FIXEDTEXT
:
1581 m_eType
= FIXED_TEXT
;
1583 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Label
|
1584 CCAFlags::Printable
| CCAFlags::Title
| CCAFlags::For
;
1585 m_nIncludeSpecial
= SCAFlags::MultiLine
;
1586 m_nIncludeEvents
= EAFlags::ControlEvents
;
1589 case FormComponentType::COMBOBOX
:
1592 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::CurrentValue
|
1593 CCAFlags::Disabled
| CCAFlags::Dropdown
| CCAFlags::MaxLength
| CCAFlags::Printable
| CCAFlags::ReadOnly
| CCAFlags::Size
|
1594 CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
| CCAFlags::Value
;
1595 m_nIncludeSpecial
= SCAFlags::AutoCompletion
;
1596 m_nIncludeDatabase
= DAFlags::ConvertEmpty
| DAFlags::DataField
| DAFlags::InputRequired
| DAFlags::ListSource
| DAFlags::ListSource_TYPE
;
1597 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnChange
| EAFlags::OnSelect
;
1600 case FormComponentType::LISTBOX
:
1603 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Dropdown
|
1604 CCAFlags::Printable
| CCAFlags::Size
| CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
;
1605 m_nIncludeSpecial
= SCAFlags::Multiple
;
1606 m_nIncludeDatabase
= DAFlags::BoundColumn
| DAFlags::DataField
| DAFlags::InputRequired
| DAFlags::ListSource_TYPE
;
1607 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnChange
| EAFlags::OnClick
| EAFlags::OnDoubleClick
;
1608 // check if we need to export the ListSource as attribute
1610 // for a list box, if the ListSourceType is VALUE_LIST, no ListSource is stored, but instead
1611 // a sequence of pairs which is build from the StringItemList and the ValueList
1612 ListSourceType eListSourceType
= ListSourceType_VALUELIST
;
1614 m_xProps
->getPropertyValue(PROPERTY_LISTSOURCETYPE
) >>= eListSourceType
;
1615 OSL_ENSURE(bSuccess
, "OControlExport::examineControl: could not retrieve the ListSourceType!");
1616 if (ListSourceType_VALUELIST
!= eListSourceType
)
1618 m_nIncludeDatabase
|= DAFlags::ListSource
;
1624 case FormComponentType::COMMANDBUTTON
:
1626 m_nIncludeCommon
|= CCAFlags::TabStop
| CCAFlags::Label
;
1627 m_nIncludeSpecial
= SCAFlags::DefaultButton
| SCAFlags::Toggle
| SCAFlags::FocusOnClick
| SCAFlags::ImagePosition
| SCAFlags::RepeatDelay
;
1629 case FormComponentType::IMAGEBUTTON
:
1630 if (BUTTON
!= m_eType
)
1632 // not coming from the previous case
1636 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::ButtonType
| CCAFlags::Disabled
|
1637 CCAFlags::ImageData
| CCAFlags::Printable
| CCAFlags::TabIndex
| CCAFlags::TargetFrame
|
1638 CCAFlags::TargetLocation
| CCAFlags::Title
;
1639 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnClick
| EAFlags::OnDoubleClick
;
1642 case FormComponentType::CHECKBOX
:
1644 m_nIncludeSpecial
= SCAFlags::CurrentState
| SCAFlags::IsTristate
| SCAFlags::State
;
1646 case FormComponentType::RADIOBUTTON
:
1648 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Label
| CCAFlags::Printable
|
1649 CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
| CCAFlags::Value
| CCAFlags::VisualEffect
;
1650 if (CHECKBOX
!= m_eType
)
1651 { // not coming from the previous case
1653 m_nIncludeCommon
|= CCAFlags::CurrentSelected
| CCAFlags::Selected
;
1655 if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_IMAGE_POSITION
) )
1656 m_nIncludeSpecial
|= SCAFlags::ImagePosition
;
1657 if ( m_xPropertyInfo
->hasPropertyByName( PROPERTY_GROUP_NAME
) )
1658 m_nIncludeSpecial
|= SCAFlags::GroupName
;
1659 m_nIncludeDatabase
= DAFlags::DataField
| DAFlags::InputRequired
;
1660 m_nIncludeEvents
= EAFlags::ControlEvents
| EAFlags::OnChange
;
1663 case FormComponentType::GROUPBOX
:
1666 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Label
|
1667 CCAFlags::Printable
| CCAFlags::Title
| CCAFlags::For
;
1668 m_nIncludeEvents
= EAFlags::ControlEvents
;
1671 case FormComponentType::IMAGECONTROL
:
1672 m_eType
= IMAGE_FRAME
;
1674 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::ImageData
|
1675 CCAFlags::Printable
| CCAFlags::ReadOnly
| CCAFlags::Title
;
1676 m_nIncludeDatabase
= DAFlags::DataField
| DAFlags::InputRequired
;
1677 m_nIncludeEvents
= EAFlags::ControlEvents
;
1680 case FormComponentType::HIDDENCONTROL
:
1683 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Value
;
1686 case FormComponentType::GRIDCONTROL
:
1689 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Printable
|
1690 CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Title
;
1691 m_nIncludeEvents
= EAFlags::ControlEvents
;
1694 case FormComponentType::SCROLLBAR
:
1695 case FormComponentType::SPINBUTTON
:
1696 m_eType
= VALUERANGE
;
1698 CCAFlags::Name
| CCAFlags::ServiceName
| CCAFlags::Disabled
| CCAFlags::Printable
|
1699 CCAFlags::Title
| CCAFlags::CurrentValue
| CCAFlags::Value
| CCAFlags::Orientation
;
1700 m_nIncludeSpecial
= SCAFlags::MaxValue
| SCAFlags::StepSize
| SCAFlags::MinValue
| SCAFlags::RepeatDelay
;
1702 if ( m_nClassId
== FormComponentType::SCROLLBAR
)
1703 m_nIncludeSpecial
|= SCAFlags::PageStepSize
;
1705 m_nIncludeEvents
= EAFlags::ControlEvents
;
1709 OSL_FAIL("OControlExport::examineControl: unknown control type (class id)!");
1712 case FormComponentType::NAVIGATIONBAR
:
1713 // TODO: should we have an own file format for this?
1716 case FormComponentType::CONTROL
:
1717 m_eType
= GENERIC_CONTROL
;
1718 // unknown control type
1719 m_nIncludeCommon
= CCAFlags::Name
| CCAFlags::ServiceName
;
1720 // at least a name should be there, 'cause without a name the control could never have been
1721 // inserted into its parent container
1722 // In addition, the service name is absolutely necessary to create the control upon reading.
1723 m_nIncludeEvents
= EAFlags::ControlEvents
;
1724 // we always should be able to export events - this is not control type dependent
1728 // in general, all control types need to export the control id
1729 m_nIncludeCommon
|= CCAFlags::ControlId
;
1731 // is it a control bound to a calc cell?
1732 if ( FormCellBindingHelper::livesInSpreadsheetDocument( m_xProps
) )
1734 FormCellBindingHelper
aHelper( m_xProps
, nullptr );
1736 if ( FormCellBindingHelper::isCellBinding( aHelper
.getCurrentBinding( ) ) )
1738 m_nIncludeBindings
|= BAFlags::LinkedCell
;
1739 if ( m_nClassId
== FormComponentType::LISTBOX
)
1740 m_nIncludeBindings
|= BAFlags::ListLinkingType
;
1744 // is it a list-like control which uses a calc cell range as list source?
1746 if ( FormCellBindingHelper::isCellRangeListSource( aHelper
.getCurrentListSource( ) ) )
1747 m_nIncludeBindings
|= BAFlags::ListCellRange
;
1751 // is control bound to XForms?
1752 if( !getXFormsBindName( m_xProps
).isEmpty() )
1754 m_nIncludeBindings
|= BAFlags::XFormsBind
;
1757 // is (list-)control bound to XForms list?
1758 if( !getXFormsListBindName( m_xProps
).isEmpty() )
1760 m_nIncludeBindings
|= BAFlags::XFormsListBind
;
1763 // does the control have an XForms submission?
1764 if( !getXFormsSubmissionName( m_xProps
).isEmpty() )
1766 m_nIncludeBindings
|= BAFlags::XFormsSubmission
;
1770 void OControlExport::exportCellBindingAttributes( bool _bIncludeListLinkageType
)
1774 FormCellBindingHelper
aHelper( m_xProps
, nullptr );
1775 Reference
< XValueBinding
> xBinding( aHelper
.getCurrentBinding() );
1776 OSL_ENSURE( xBinding
.is(), "OControlExport::exportCellBindingAttributes: invalid bindable or invalid binding!" );
1777 if ( xBinding
.is() )
1780 OAttributeMetaData::getBindingAttributeNamespace( BAFlags::LinkedCell
),
1781 OAttributeMetaData::getBindingAttributeName( BAFlags::LinkedCell
),
1782 aHelper
.getStringAddressFromCellBinding( xBinding
)
1785 if ( _bIncludeListLinkageType
)
1787 sal_Int16 nLinkageType
= FormCellBindingHelper::isCellIntegerBinding( xBinding
) ? 1 : 0;
1789 OUStringBuffer sBuffer
;
1790 SvXMLUnitConverter::convertEnum(
1792 (sal_uInt16
)nLinkageType
,
1793 OEnumMapper::getEnumMap( OEnumMapper::epListLinkageType
)
1797 OAttributeMetaData::getBindingAttributeNamespace( BAFlags::ListLinkingType
),
1798 OAttributeMetaData::getBindingAttributeName( BAFlags::ListLinkingType
),
1799 sBuffer
.makeStringAndClear()
1805 catch( const Exception
& )
1807 OSL_FAIL( "OControlExport::exportCellBindingAttributes: caught an exception!" );
1808 DBG_UNHANDLED_EXCEPTION();
1812 void OControlExport::exportXFormsBindAttributes()
1814 OUString sBindName
= getXFormsBindName( m_xProps
);
1815 AddAttribute( XML_NAMESPACE_XFORMS
, XML_BIND
, sBindName
);
1817 void OControlExport::exportXFormsListAttributes()
1819 OUString sBindName
= getXFormsListBindName( m_xProps
);
1820 AddAttribute( XML_NAMESPACE_FORM
, XML_XFORMS_LIST_SOURCE
, sBindName
);
1822 void OControlExport::exportXFormsSubmissionAttributes()
1824 OUString sSubmission
= getXFormsSubmissionName( m_xProps
);
1825 AddAttribute( XML_NAMESPACE_FORM
, XML_XFORMS_SUBMISSION
, sSubmission
);
1827 void OControlExport::exportCellListSourceRange( )
1831 Reference
< XListEntrySink
> xSink( m_xProps
, UNO_QUERY
);
1832 Reference
< XListEntrySource
> xSource
;
1834 xSource
.set(xSink
->getListEntrySource(), css::uno::UNO_QUERY
);
1835 OSL_ENSURE( xSource
.is(), "OControlExport::exportCellListSourceRange: list source or sink!" );
1838 FormCellBindingHelper
aHelper( m_xProps
, nullptr );
1841 OAttributeMetaData::getBindingAttributeNamespace( BAFlags::ListCellRange
),
1842 OAttributeMetaData::getBindingAttributeName( BAFlags::ListCellRange
),
1843 aHelper
.getStringAddressFromCellListSource( xSource
)
1847 catch( const Exception
& )
1849 OSL_FAIL( "OControlExport::exportCellListSourceRange: caught an exception!" );
1850 DBG_UNHANDLED_EXCEPTION();
1854 void OControlExport::exportImagePositionAttributes()
1858 sal_Int16 nImagePosition
= ImagePosition::Centered
;
1859 OSL_VERIFY( m_xProps
->getPropertyValue( PROPERTY_IMAGE_POSITION
) >>= nImagePosition
);
1860 OSL_ENSURE( ( nImagePosition
>= ImagePosition::LeftTop
) && ( nImagePosition
<= ImagePosition::Centered
),
1861 "OControlExport::exportImagePositionAttributes: don't know this image position!" );
1863 if ( ( nImagePosition
< ImagePosition::LeftTop
) || ( nImagePosition
> ImagePosition::Centered
) )
1864 // this is important to prevent potential buffer overflows below, so don't optimize
1865 nImagePosition
= ImagePosition::Centered
;
1867 if ( nImagePosition
== ImagePosition::Centered
)
1869 AddAttribute( XML_NAMESPACE_FORM
, GetXMLToken( XML_IMAGE_POSITION
), GetXMLToken( XML_CENTER
) );
1873 XMLTokenEnum eXmlImagePositions
[] =
1875 XML_START
, XML_END
, XML_TOP
, XML_BOTTOM
1877 XMLTokenEnum eXmlImageAligns
[] =
1879 XML_START
, XML_CENTER
, XML_END
1882 XMLTokenEnum eXmlImagePosition
= eXmlImagePositions
[ nImagePosition
/ 3 ];
1883 XMLTokenEnum eXmlImageAlign
= eXmlImageAligns
[ nImagePosition
% 3 ];
1885 AddAttribute( XML_NAMESPACE_FORM
, GetXMLToken( XML_IMAGE_POSITION
), GetXMLToken( eXmlImagePosition
) );
1886 AddAttribute( XML_NAMESPACE_FORM
, GetXMLToken( XML_IMAGE_ALIGN
), GetXMLToken( eXmlImageAlign
) );
1889 exportedProperty( PROPERTY_IMAGE_POSITION
);
1890 // some of the controls which have an ImagePosition also have an ImageAlign for compatibility
1891 // reasons. Since the ImageAlign values simply represent a sub set of the ImagePosition values,
1892 // we don't need to export ImageAlign anymore
1893 exportedProperty( PROPERTY_IMAGE_ALIGN
);
1895 catch( const Exception
& )
1897 DBG_UNHANDLED_EXCEPTION();
1901 bool OControlExport::controlHasActiveDataBinding() const
1905 // currently exchanging the data with a database column?
1906 OUString
sBoundFieldPropertyName( "BoundField" );
1907 if ( m_xPropertyInfo
.is() && m_xPropertyInfo
->hasPropertyByName( sBoundFieldPropertyName
) )
1909 Reference
< XPropertySet
> xBoundField
;
1910 m_xProps
->getPropertyValue( sBoundFieldPropertyName
) >>= xBoundField
;
1911 if ( xBoundField
.is() )
1915 // currently exchanging data with an external binding?
1916 Reference
< XBindableValue
> xBindable( m_xProps
, UNO_QUERY
);
1917 if ( xBindable
.is() && xBindable
->getValueBinding().is() )
1920 catch( const Exception
& )
1922 OSL_FAIL( "OColumnExport::controlHasActiveDataBinding: caught an exception!" );
1923 DBG_UNHANDLED_EXCEPTION();
1929 bool OControlExport::controlHasUserSuppliedListEntries() const
1933 // an external list source?
1934 Reference
< XListEntrySink
> xEntrySink( m_xProps
, UNO_QUERY
);
1935 if ( xEntrySink
.is() && xEntrySink
->getListEntrySource().is() )
1938 if ( m_xPropertyInfo
.is() && m_xPropertyInfo
->hasPropertyByName( PROPERTY_LISTSOURCETYPE
) )
1940 ListSourceType eListSourceType
= ListSourceType_VALUELIST
;
1941 OSL_VERIFY( m_xProps
->getPropertyValue( PROPERTY_LISTSOURCETYPE
) >>= eListSourceType
);
1942 if ( eListSourceType
== ListSourceType_VALUELIST
)
1943 // for value lists, the list entries as entered by the user are used
1946 // for every other type, the list entries are filled with some data obtained
1947 // from a database - if and only if the ListSource property is not empty
1948 return getScalarListSourceValue().isEmpty();
1951 catch( const Exception
& )
1953 OSL_FAIL( "OControlExport::controlHasUserSuppliedListEntries: caught an exception!" );
1954 DBG_UNHANDLED_EXCEPTION();
1957 OSL_FAIL( "OControlExport::controlHasUserSuppliedListEntries: unreachable code!" );
1958 // this method should be called for list and combo boxes only
1963 OColumnExport::OColumnExport(IFormsExportContext
& _rContext
, const Reference
< XPropertySet
>& _rxControl
, const OUString
& _rControlId
,
1964 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
1965 :OControlExport(_rContext
, _rxControl
, _rControlId
, OUString(), _rEvents
)
1969 OColumnExport::~OColumnExport()
1974 void OColumnExport::exportServiceNameAttribute()
1976 // the attribute "service name" (which has a slightly different meaning for columns
1977 DBG_CHECK_PROPERTY( PROPERTY_COLUMNSERVICENAME
, OUString
);
1978 OUString sColumnServiceName
;
1979 m_xProps
->getPropertyValue(PROPERTY_COLUMNSERVICENAME
) >>= sColumnServiceName
;
1980 // the service name is a full qualified one (i.e. com.sun.star.form.TextField), but the
1981 // real service name for the column (for use with the XGridColumnFactory) is only the last
1982 // token of this complete name.
1983 sal_Int32 nLastSep
= sColumnServiceName
.lastIndexOf('.');
1984 OSL_ENSURE(-1 != nLastSep
, "OColumnExport::startExportElement: invalid service name!");
1985 sColumnServiceName
= sColumnServiceName
.copy(nLastSep
+ 1);
1986 sColumnServiceName
=
1987 m_rContext
.getGlobalContext().GetNamespaceMap().GetQNameByKey(
1988 XML_NAMESPACE_OOO
, sColumnServiceName
);
1989 // add the attribute
1990 AddAttribute( OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::ServiceName
)
1991 , OAttributeMetaData::getCommonControlAttributeName(CCAFlags::ServiceName
)
1992 , sColumnServiceName
);
1993 // flag the property as "handled"
1994 exportedProperty(PROPERTY_COLUMNSERVICENAME
);
1998 const sal_Char
* OColumnExport::getOuterXMLElementName() const
2003 void OColumnExport::exportAttributes()
2005 OControlExport::exportAttributes();
2007 // the attribute "label"
2008 exportStringPropertyAttribute(
2009 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Label
),
2010 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Label
),
2013 // the style attribute
2014 OUString sStyleName
= m_rContext
.getObjectStyleName( m_xProps
);
2015 if ( !sStyleName
.isEmpty() )
2018 OAttributeMetaData::getSpecialAttributeNamespace( SCAFlags::ColumnStyleName
),
2019 OAttributeMetaData::getSpecialAttributeName( SCAFlags::ColumnStyleName
),
2025 void OColumnExport::examine()
2027 OControlExport::examine();
2029 // grid columns miss some properties of the controls they're representing
2030 m_nIncludeCommon
&= ~CCAFlags(CCAFlags::For
| CCAFlags::Printable
| CCAFlags::TabIndex
| CCAFlags::TabStop
| CCAFlags::Label
);
2031 m_nIncludeSpecial
&= ~SCAFlags(SCAFlags::EchoChar
| SCAFlags::AutoCompletion
| SCAFlags::Multiple
| SCAFlags::MultiLine
);
2033 if (FormComponentType::DATEFIELD
!= m_nClassId
)
2034 // except date fields, no column has the DropDown property
2035 m_nIncludeCommon
&= ~CCAFlags::Dropdown
;
2039 OFormExport::OFormExport(IFormsExportContext
& _rContext
, const Reference
< XPropertySet
>& _rxForm
,
2040 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
2041 :OElementExport(_rContext
, _rxForm
, _rEvents
)
2042 ,m_bCreateConnectionResourceElement(false)
2044 OSL_ENSURE(m_xProps
.is(), "OFormExport::OFormExport: invalid arguments!");
2047 const sal_Char
* OFormExport::getXMLElementName() const
2052 void OFormExport::exportSubTags()
2054 if ( m_bCreateConnectionResourceElement
&& m_xProps
.is() )
2056 m_rContext
.getGlobalContext().ClearAttrList();
2057 OUString sPropValue
;
2058 m_xProps
->getPropertyValue( PROPERTY_DATASOURCENAME
) >>= sPropValue
; // if set it is a file url
2059 if ( sPropValue
.isEmpty() )
2060 m_xProps
->getPropertyValue( PROPERTY_URL
) >>= sPropValue
;
2061 if ( !sPropValue
.isEmpty() )
2063 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::TargetLocation
),
2064 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::TargetLocation
),
2066 if ( m_rContext
.getGlobalContext().GetAttrList().getLength() )
2068 SvXMLElementExport
aFormElement(m_rContext
.getGlobalContext(), XML_NAMESPACE_FORM
, xmloff::token::XML_CONNECTION_RESOURCE
, true, true);
2072 // let the base class export the remaining properties and the events
2073 OElementExport::exportSubTags();
2074 // loop through all children
2075 Reference
< XIndexAccess
> xCollection(m_xProps
, UNO_QUERY
);
2076 OSL_ENSURE(xCollection
.is(), "OFormLayerXMLExport::implExportForm: a form which is not an index access? Suspicious!");
2078 if (xCollection
.is())
2079 m_rContext
.exportCollectionElements(xCollection
);
2082 void OFormExport::exportAttributes()
2086 // the string properties
2088 static const FormAttributes eStringPropertyIds
[] =
2090 faName
, /*faAction,*/ faCommand
, faFilter
, faOrder
2092 static const char * aStringPropertyNames
[] =
2094 PROPERTY_NAME
, /*PROPERTY_TARGETURL,*/ PROPERTY_COMMAND
, PROPERTY_FILTER
, PROPERTY_ORDER
2096 static const sal_Int32 nIdCount
= SAL_N_ELEMENTS(eStringPropertyIds
);
2097 #if OSL_DEBUG_LEVEL > 0
2098 static const sal_Int32 nNameCount
= SAL_N_ELEMENTS(aStringPropertyNames
);
2099 OSL_ENSURE((nIdCount
== nNameCount
),
2100 "OFormExport::exportAttributes: somebody tampered with the maps (1)!");
2102 for (i
=0; i
<nIdCount
; ++i
)
2103 exportStringPropertyAttribute(
2104 OAttributeMetaData::getFormAttributeNamespace(eStringPropertyIds
[i
]),
2105 OAttributeMetaData::getFormAttributeName(eStringPropertyIds
[i
]),
2106 OUString::createFromAscii(aStringPropertyNames
[i
]));
2108 // #i112082# xlink:type is added as part of exportTargetLocationAttribute
2110 // now export the data source name or databaselocation or connection resource
2111 OUString sPropValue
;
2112 m_xProps
->getPropertyValue( PROPERTY_DATASOURCENAME
) >>= sPropValue
;
2113 m_bCreateConnectionResourceElement
= sPropValue
.isEmpty();
2114 if ( !m_bCreateConnectionResourceElement
)
2116 INetURLObject
aURL(sPropValue
);
2117 m_bCreateConnectionResourceElement
= ( aURL
.GetProtocol() == INetProtocol::File
);
2118 if ( !m_bCreateConnectionResourceElement
)
2119 exportStringPropertyAttribute(
2120 OAttributeMetaData::getFormAttributeNamespace(faDatasource
),
2121 OAttributeMetaData::getFormAttributeName(faDatasource
),
2122 PROPERTY_DATASOURCENAME
);
2125 exportedProperty(PROPERTY_URL
);
2126 if ( m_bCreateConnectionResourceElement
)
2127 exportedProperty(PROPERTY_DATASOURCENAME
);
2130 // the boolean properties
2132 static const FormAttributes eBooleanPropertyIds
[] =
2134 faAllowDeletes
, faAllowInserts
, faAllowUpdates
, faApplyFilter
, faEscapeProcessing
, faIgnoreResult
2136 static const char * pBooleanPropertyNames
[] =
2138 PROPERTY_ALLOWDELETES
,
2139 PROPERTY_ALLOWINSERTS
,
2140 PROPERTY_ALLOWUPDATES
,
2141 PROPERTY_APPLYFILTER
,
2142 PROPERTY_ESCAPEPROCESSING
,
2143 PROPERTY_IGNORERESULT
2145 static const BoolAttrFlags nBooleanPropertyAttrFlags
[] =
2147 BoolAttrFlags::DefaultTrue
, BoolAttrFlags::DefaultTrue
, BoolAttrFlags::DefaultTrue
, BoolAttrFlags::DefaultFalse
, BoolAttrFlags::DefaultTrue
, BoolAttrFlags::DefaultFalse
2149 static const sal_Int32 nIdCount
= SAL_N_ELEMENTS(eBooleanPropertyIds
);
2150 #if OSL_DEBUG_LEVEL > 0
2151 static const sal_Int32 nNameCount
= SAL_N_ELEMENTS(pBooleanPropertyNames
);
2152 static const sal_Int32 nFlagsCount
= SAL_N_ELEMENTS(nBooleanPropertyAttrFlags
);
2153 OSL_ENSURE((nIdCount
== nNameCount
) && (nNameCount
== nFlagsCount
),
2154 "OFormExport::exportAttributes: somebody tampered with the maps (2)!");
2156 for (i
=0; i
<nIdCount
; ++i
)
2157 exportBooleanPropertyAttribute(
2158 OAttributeMetaData::getFormAttributeNamespace(eBooleanPropertyIds
[i
]),
2159 OAttributeMetaData::getFormAttributeName(eBooleanPropertyIds
[i
]),
2160 OUString::createFromAscii(pBooleanPropertyNames
[i
]),
2161 nBooleanPropertyAttrFlags
[i
]
2165 // the enum properties
2167 static const FormAttributes eEnumPropertyIds
[] =
2169 faEnctype
, faMethod
, faCommandType
, faNavigationMode
, faTabbingCycle
2171 static const char * pEnumPropertyNames
[] =
2173 PROPERTY_SUBMIT_ENCODING
, PROPERTY_SUBMIT_METHOD
, PROPERTY_COMMAND_TYPE
, PROPERTY_NAVIGATION
, PROPERTY_CYCLE
2175 static const OEnumMapper::EnumProperties eEnumPropertyMaps
[] =
2177 OEnumMapper::epSubmitEncoding
, OEnumMapper::epSubmitMethod
, OEnumMapper::epCommandType
, OEnumMapper::epNavigationType
, OEnumMapper::epTabCyle
2179 static const sal_Int32 nEnumPropertyAttrDefaults
[] =
2181 FormSubmitEncoding_URL
, FormSubmitMethod_GET
, CommandType::COMMAND
, NavigationBarMode_CURRENT
, TabulatorCycle_RECORDS
2183 static const bool nEnumPropertyAttrDefaultFlags
[] =
2185 false, false, false, false, true
2187 static const sal_Int32 nIdCount
= SAL_N_ELEMENTS(eEnumPropertyIds
);
2188 #if OSL_DEBUG_LEVEL > 0
2189 static const sal_Int32 nNameCount
= SAL_N_ELEMENTS(pEnumPropertyNames
);
2190 static const sal_Int32 nDefaultCount
= SAL_N_ELEMENTS(nEnumPropertyAttrDefaults
);
2191 static const sal_Int32 nDefaultFlagCount
= SAL_N_ELEMENTS(nEnumPropertyAttrDefaultFlags
);
2192 static const sal_Int32 nMapCount
= SAL_N_ELEMENTS(eEnumPropertyMaps
);
2193 OSL_ENSURE((nIdCount
== nNameCount
) && (nNameCount
== nDefaultCount
) && (nDefaultCount
== nDefaultFlagCount
) && (nDefaultFlagCount
== nMapCount
),
2194 "OFormExport::exportAttributes: somebody tampered with the maps (3)!");
2196 for (i
=0; i
<nIdCount
; ++i
)
2197 exportEnumPropertyAttribute(
2198 OAttributeMetaData::getFormAttributeNamespace(eEnumPropertyIds
[i
]),
2199 OAttributeMetaData::getFormAttributeName(eEnumPropertyIds
[i
]),
2200 OUString::createFromAscii(pEnumPropertyNames
[i
]),
2201 OEnumMapper::getEnumMap(eEnumPropertyMaps
[i
]),
2202 nEnumPropertyAttrDefaults
[i
],
2203 nEnumPropertyAttrDefaultFlags
[i
]
2208 exportServiceNameAttribute();
2210 exportTargetFrameAttribute();
2212 exportTargetLocationAttribute(true); // #i110911# add type attribute (for form, but not for control)
2215 exportStringSequenceAttribute(
2216 OAttributeMetaData::getFormAttributeNamespace(faMasterFields
),
2217 OAttributeMetaData::getFormAttributeName(faMasterFields
),
2218 PROPERTY_MASTERFIELDS
);
2220 exportStringSequenceAttribute(
2221 OAttributeMetaData::getFormAttributeNamespace(faDetailFiels
),
2222 OAttributeMetaData::getFormAttributeName(faDetailFiels
),
2223 PROPERTY_DETAILFIELDS
);
2225 } // namespace xmloff
2227 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */