Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / xmloff / source / forms / elementexport.cxx
blobb80d7b0bb2c62d995c435f0829c795b6bf45fd0e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
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>
63 #include <algorithm>
65 namespace xmloff
68 #if OSL_DEBUG_LEVEL > 0
69 #define RESET_BIT( bitfield, bit ) \
70 bitfield = bitfield & ~bit
71 #else
72 #define RESET_BIT( bitfield, bit )
73 #endif
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;
90 //= OElementExport
91 OElementExport::OElementExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxProps,
92 const Sequence< ScriptEventDescriptor >& _rEvents)
93 :OPropertyExport(_rContext, _rxProps)
94 ,m_aEvents(_rEvents)
95 ,m_pXMLElement(nullptr)
99 OElementExport::~OElementExport()
101 implEndElement();
104 void OElementExport::doExport()
106 // collect some general information about the element
107 examine();
109 // first add the attributes necessary for the element
110 m_rContext.getGlobalContext().ClearAttrList();
112 // add the attributes
113 exportAttributes();
115 // start the XML element
116 implStartElement(getXMLElementName());
118 // the sub elements (mostly control type dependent)
119 exportSubTags();
121 implEndElement();
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
140 exportEvents();
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!");
160 return;
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
166 // compatibility ...
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!");
206 #endif
207 sToWriteServiceName =
208 m_rContext.getGlobalContext().GetNamespaceMap().GetQNameByKey(
209 XML_NAMESPACE_OOO, sToWriteServiceName );
211 // now write this
212 AddAttribute(
213 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::ServiceName),
214 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::ServiceName),
215 sToWriteServiceName);
218 void OElementExport::exportEvents()
220 if (!m_aEvents.getLength())
221 // nothing to do
222 return;
224 Reference< XNameReplace > xWrapper = new OEventDescriptorMapper(m_aEvents);
225 m_rContext.getGlobalContext().GetEventExport().Export(xWrapper);
228 //= OControlExport
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)
236 ,m_eType( UNKNOWN )
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()
249 implEndElement();
252 void OControlExport::exportOuterAttributes()
254 // the control id
255 if (CCAFlags::Name & m_nIncludeCommon)
257 exportStringPropertyAttribute(
258 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Name),
259 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Name),
260 PROPERTY_NAME
262 #if OSL_DEBUG_LEVEL > 0
263 // reset the bit for later checking
264 m_nIncludeCommon = m_nIncludeCommon & ~CCAFlags::Name;
265 #endif
268 // the service 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;
275 #endif
279 void OControlExport::exportInnerAttributes()
281 // the control id
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;
290 #endif
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
329 // been set before
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
355 // CharStrikeout.
356 // #i27729#
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
380 switch (m_eType)
382 case LISTBOX:
383 // don't export the list entries if the are not provided by the user, but obtained implicitly
384 // from other sources
385 // #i26944#
386 if ( controlHasUserSuppliedListEntries() )
387 exportListSourceAsElements();
388 break;
389 case GRID:
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);
396 break;
397 case COMBOBOX:
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
403 // #i26944#
404 if ( controlHasUserSuppliedListEntries() )
406 // get the item list
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();
414 AddAttribute(
415 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Label),
416 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Label),
417 *pListItems);
418 SvXMLElementExport aFormElement(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, "item", true, true);
422 break;
424 case TEXT_AREA:
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 );
439 break;
440 default:
441 // nothing do to
442 break;
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();
451 ++prop
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 )
460 continue;
462 // let the factory provide the concrete handler. Note that caching, if desired, is the task
463 // of the factory
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!" );
468 continue;
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 );
480 continue;
483 const Any propValue = m_xProps->getPropertyValue( prop->Name );
484 attributeValue = handler->getAttributeValue( propValue );
486 else
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();
499 ++desc
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 );
511 AddAttribute(
512 propDescription->attribute.namespacePrefix,
513 token::GetXMLToken( propDescription->attribute.attributeToken ),
514 attributeValue
517 exportedProperty( prop->Name );
519 catch( const Exception& )
521 DBG_UNHANDLED_EXCEPTION();
526 void OControlExport::exportCommonControlAttributes()
528 size_t i=0;
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
533 // very frequently.
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];
565 #endif
569 // some boolean properties
571 static const CCAFlags nBooleanPropertyAttributeIds[] =
572 { // attribute flags
573 CCAFlags::CurrentSelected, CCAFlags::Disabled, CCAFlags::Dropdown, CCAFlags::Printable, CCAFlags::ReadOnly, CCAFlags::Selected, CCAFlags::TabStop, CCAFlags::EnableVisible
575 static const char * pBooleanPropertyNames[] =
576 { // property names
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)!");
592 #endif
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];
604 #endif
608 // some integer properties
610 // now the common handling
611 static CCAFlags nIntegerPropertyAttributeIds[] =
612 { // attribute flags
613 CCAFlags::Size, CCAFlags::TabIndex
615 static const char * pIntegerPropertyNames[] =
616 { // property names
617 PROPERTY_LINECOUNT, PROPERTY_TABINDEX
619 static const sal_Int16 nIntegerPropertyAttrDefaults[] =
620 { // attribute defaults
621 5, 0
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)!");
633 #endif
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];
645 #endif
650 // some enum properties
652 if (m_nIncludeCommon & CCAFlags::ButtonType)
654 exportEnumPropertyAttribute(
655 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::ButtonType),
656 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::ButtonType),
657 PROPERTY_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;
663 #endif
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;
677 #endif
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 ),
687 VisualEffect::LOOK3D
689 #if OSL_DEBUG_LEVEL > 0
690 // reset the bit for later checking
691 m_nIncludeCommon = m_nIncludeCommon & ~CCAFlags::VisualEffect;
692 #endif
696 // some properties which require a special handling
698 // the target frame
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;
705 #endif
708 // max text length
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;
719 // export it
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;
734 #endif
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;
743 #endif
746 // OJ #99721#
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;
753 #endif
756 // the for attribute
757 // the target frame
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
762 AddAttribute(
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;
770 #endif
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
790 // #i26944#
791 if ( controlHasActiveDataBinding() )
792 exportedProperty( OUString::createFromAscii( pCurrentValuePropertyName ) );
793 else
794 exportGenericPropertyAttribute(
795 nCurrentValueAttributeNamespaceKey,
796 pCurrentValueAttributeName,
797 pCurrentValuePropertyName
801 if (pValuePropertyName && (CCAFlags::Value & m_nIncludeCommon))
802 exportGenericPropertyAttribute(
803 nValueAttributeNamespaceKey,
804 pValueAttributeName,
805 pValuePropertyName);
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);
815 #endif
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
821 // be 0 now ...
824 void OControlExport::exportDatabaseAttributes()
826 #if OSL_DEBUG_LEVEL > 0
827 DAFlags nIncludeDatabase = m_nIncludeDatabase;
828 #endif
829 // the only string property: DataField
830 if (DAFlags::DataField & m_nIncludeDatabase)
832 exportStringPropertyAttribute(
833 OAttributeMetaData::getDatabaseAttributeNamespace(DAFlags::DataField),
834 OAttributeMetaData::getDatabaseAttributeName(DAFlags::DataField),
835 PROPERTY_DATAFIELD);
836 RESET_BIT( nIncludeDatabase, DAFlags::DataField );
839 // InputRequired
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,
859 true);
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
898 // be 0 now ...
899 #endif
902 void OControlExport::exportBindingAtributes()
904 #if OSL_DEBUG_LEVEL > 0
905 BAFlags nIncludeBinding = m_nIncludeBindings;
906 #endif
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 );
914 #endif
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;
923 #endif
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;
932 #endif
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;
941 #endif
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;
950 #endif
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
957 // be 0 now ...
958 #endif
961 void OControlExport::exportSpecialAttributes()
963 sal_Int32 i=0;
965 // the boolean properties
967 static const SCAFlags nBooleanPropertyAttributeIds[] =
968 { // attribute flags
969 SCAFlags::Validation, SCAFlags::MultiLine, SCAFlags::AutoCompletion, SCAFlags::Multiple, SCAFlags::DefaultButton, SCAFlags::IsTristate,
970 SCAFlags::Toggle, SCAFlags::FocusOnClick
972 static const char * pBooleanPropertyNames[] =
973 { // property names
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)!");
985 #endif
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;
1000 #endif
1005 // the integer properties
1007 static SCAFlags nIntegerPropertyAttributeIds[] =
1008 { // attribute flags
1009 SCAFlags::PageStepSize
1011 static const char * pIntegerPropertyNames[] =
1012 { // property names
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)!" );
1028 #endif
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];
1041 #endif
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;
1051 else
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 ),
1058 sPropertyName,
1062 #if OSL_DEBUG_LEVEL > 0
1063 // reset the bit for later checking
1064 m_nIncludeSpecial = m_nIncludeSpecial & ~SCAFlags::StepSize;
1065 #endif
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),
1079 TRISTATE_FALSE);
1080 #if OSL_DEBUG_LEVEL > 0
1081 // reset the bit for later checking
1082 m_nIncludeSpecial = m_nIncludeSpecial & ~SCAFlags::State;
1083 #endif
1086 if (SCAFlags::CurrentState & m_nIncludeSpecial)
1088 exportEnumPropertyAttribute(
1089 OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::CurrentState),
1090 OAttributeMetaData::getSpecialAttributeName(SCAFlags::CurrentState),
1091 PROPERTY_STATE,
1092 OEnumMapper::getEnumMap(OEnumMapper::epCheckState),
1093 TRISTATE_FALSE);
1094 #if OSL_DEBUG_LEVEL > 0
1095 // reset the bit for later checking
1096 m_nIncludeSpecial = m_nIncludeSpecial & ~SCAFlags::CurrentState;
1097 #endif
1101 // some properties which require a special handling
1102 // the repeat delay
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;
1118 OUStringBuffer buf;
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;
1129 #endif
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;
1140 if (nValue)
1142 OUString sCharacter(reinterpret_cast<const sal_Unicode*>(&nValue), 1);
1143 AddAttribute(
1144 OAttributeMetaData::getSpecialAttributeNamespace(SCAFlags::EchoChar),
1145 OAttributeMetaData::getSpecialAttributeName(SCAFlags::EchoChar),
1146 sCharacter);
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;
1152 #endif
1156 // the string properties
1158 static const SCAFlags nStringPropertyAttributeIds[] =
1159 { // attribute flags
1160 SCAFlags::GroupName
1162 static const OUString pStringPropertyNames[] =
1163 { // property names
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)!" );
1172 #endif
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];
1184 #endif
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
1192 // values
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);
1222 #endif
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
1234 // be 0 now ...
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 ];
1248 return sListSource;
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
1259 AddAttribute(
1260 OAttributeMetaData::getDatabaseAttributeNamespace(DAFlags::ListSource),
1261 OAttributeMetaData::getDatabaseAttributeName(DAFlags::ListSource),
1262 sListSource);
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()
1281 // the string lists
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"
1297 OUString sTrue;
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();
1314 if (i < nItems)
1316 // there is an item at this position
1317 AddAttribute(
1318 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Label),
1319 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Label),
1320 *pItems);
1321 ++pItems;
1323 if (i < nValues)
1325 // there is an value at this position
1326 AddAttribute(
1327 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Value),
1328 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Value),
1329 *pValues);
1330 ++pValues;
1333 Int16Set::iterator aSelectedPos = aSelection.find(i);
1334 if (aSelection.end() != aSelectedPos)
1335 { // the item at this position is selected
1336 AddAttribute(
1337 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::CurrentSelected),
1338 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::CurrentSelected),
1339 sTrue
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
1347 AddAttribute(
1348 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Selected),
1349 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Selected),
1350 sTrue
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
1382 AddAttribute(
1383 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::CurrentSelected),
1384 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::CurrentSelected),
1385 sTrue
1389 if (aDefaultSelection.end() != aDefaultSelection.find(i))
1390 { // the (not existent) item at this position is selected as default
1391 AddAttribute(
1392 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Selected),
1393 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Selected),
1394 sTrue
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(),
1409 XML_NAMESPACE_FORM,
1410 pOuterElementName, true,
1411 true)
1412 : nullptr;
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
1433 return nullptr;
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;
1452 switch (m_nClassId)
1454 case FormComponentType::DATEFIELD:
1455 m_eType = DATE;
1456 knownType = true;
1457 SAL_FALLTHROUGH;
1458 case FormComponentType::TIMEFIELD:
1459 if ( !knownType )
1461 m_eType = TIME;
1462 knownType = true;
1464 m_nIncludeSpecial |= SCAFlags::Validation;
1465 SAL_FALLTHROUGH;
1466 case FormComponentType::NUMERICFIELD:
1467 case FormComponentType::CURRENCYFIELD:
1468 case FormComponentType::PATTERNFIELD:
1469 if ( !knownType )
1471 m_eType = FORMATTED_TEXT;
1472 knownType = true;
1474 SAL_FALLTHROUGH;
1475 case FormComponentType::TEXTFIELD:
1476 { // it's some kind of edit. To know which type we need further investigation
1478 if ( !knownType )
1480 // check if it's a formatted field
1481 if (m_xPropertyInfo->hasPropertyByName(PROPERTY_FORMATKEY))
1483 m_eType = FORMATTED_TEXT;
1485 else
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;
1495 if (nEchoChar)
1497 m_eType = PASSWORD;
1498 m_nIncludeSpecial |= SCAFlags::EchoChar;
1500 else
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));
1508 if ( bMultiLine )
1509 m_eType = TEXT_AREA;
1510 else
1511 // the only case left is represented by a Text element
1512 m_eType = TEXT;
1517 // attributes which are common to all the types:
1518 // common attributes
1519 m_nIncludeCommon =
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;
1532 // event attributes
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;
1569 break;
1571 case FormComponentType::FILECONTROL:
1572 m_eType = FILE;
1573 m_nIncludeCommon =
1574 CCAFlags::Name | CCAFlags::ServiceName | CCAFlags::CurrentValue | CCAFlags::Disabled |
1575 CCAFlags::Printable | CCAFlags::TabIndex | CCAFlags::TabStop | CCAFlags::Title |
1576 CCAFlags::Value;
1577 m_nIncludeEvents = EAFlags::ControlEvents | EAFlags::OnChange | EAFlags::OnSelect;
1578 break;
1580 case FormComponentType::FIXEDTEXT:
1581 m_eType = FIXED_TEXT;
1582 m_nIncludeCommon =
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;
1587 break;
1589 case FormComponentType::COMBOBOX:
1590 m_eType = COMBOBOX;
1591 m_nIncludeCommon =
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;
1598 break;
1600 case FormComponentType::LISTBOX:
1601 m_eType = LISTBOX;
1602 m_nIncludeCommon =
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;
1613 bool bSuccess =
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;
1622 break;
1624 case FormComponentType::COMMANDBUTTON:
1625 m_eType = BUTTON;
1626 m_nIncludeCommon |= CCAFlags::TabStop | CCAFlags::Label;
1627 m_nIncludeSpecial = SCAFlags::DefaultButton | SCAFlags::Toggle | SCAFlags::FocusOnClick | SCAFlags::ImagePosition | SCAFlags::RepeatDelay;
1628 SAL_FALLTHROUGH;
1629 case FormComponentType::IMAGEBUTTON:
1630 if (BUTTON != m_eType)
1632 // not coming from the previous case
1633 m_eType = IMAGE;
1635 m_nIncludeCommon |=
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;
1640 break;
1642 case FormComponentType::CHECKBOX:
1643 m_eType = CHECKBOX;
1644 m_nIncludeSpecial = SCAFlags::CurrentState | SCAFlags::IsTristate | SCAFlags::State;
1645 SAL_FALLTHROUGH;
1646 case FormComponentType::RADIOBUTTON:
1647 m_nIncludeCommon =
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
1652 m_eType = RADIO;
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;
1661 break;
1663 case FormComponentType::GROUPBOX:
1664 m_eType = FRAME;
1665 m_nIncludeCommon =
1666 CCAFlags::Name | CCAFlags::ServiceName | CCAFlags::Disabled | CCAFlags::Label |
1667 CCAFlags::Printable | CCAFlags::Title | CCAFlags::For;
1668 m_nIncludeEvents = EAFlags::ControlEvents;
1669 break;
1671 case FormComponentType::IMAGECONTROL:
1672 m_eType = IMAGE_FRAME;
1673 m_nIncludeCommon =
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;
1678 break;
1680 case FormComponentType::HIDDENCONTROL:
1681 m_eType = HIDDEN;
1682 m_nIncludeCommon =
1683 CCAFlags::Name | CCAFlags::ServiceName | CCAFlags::Value;
1684 break;
1686 case FormComponentType::GRIDCONTROL:
1687 m_eType = GRID;
1688 m_nIncludeCommon =
1689 CCAFlags::Name | CCAFlags::ServiceName | CCAFlags::Disabled | CCAFlags::Printable |
1690 CCAFlags::TabIndex | CCAFlags::TabStop | CCAFlags::Title;
1691 m_nIncludeEvents = EAFlags::ControlEvents;
1692 break;
1694 case FormComponentType::SCROLLBAR:
1695 case FormComponentType::SPINBUTTON:
1696 m_eType = VALUERANGE;
1697 m_nIncludeCommon =
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;
1706 break;
1708 default:
1709 OSL_FAIL("OControlExport::examineControl: unknown control type (class id)!");
1710 SAL_FALLTHROUGH;
1712 case FormComponentType::NAVIGATIONBAR:
1713 // TODO: should we have an own file format for this?
1714 // NO break
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
1725 break;
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() )
1779 AddAttribute(
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(
1791 sBuffer,
1792 (sal_uInt16)nLinkageType,
1793 OEnumMapper::getEnumMap( OEnumMapper::epListLinkageType )
1796 AddAttribute(
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;
1833 if ( xSink.is() )
1834 xSource.set(xSink->getListEntrySource(), css::uno::UNO_QUERY);
1835 OSL_ENSURE( xSource.is(), "OControlExport::exportCellListSourceRange: list source or sink!" );
1836 if ( xSource.is() )
1838 FormCellBindingHelper aHelper( m_xProps, nullptr );
1840 AddAttribute(
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 ) );
1871 else
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() )
1912 return true;
1915 // currently exchanging data with an external binding?
1916 Reference< XBindableValue > xBindable( m_xProps, UNO_QUERY );
1917 if ( xBindable.is() && xBindable->getValueBinding().is() )
1918 return true;
1920 catch( const Exception& )
1922 OSL_FAIL( "OColumnExport::controlHasActiveDataBinding: caught an exception!" );
1923 DBG_UNHANDLED_EXCEPTION();
1926 return false;
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() )
1936 return false;
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
1944 return true;
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
1959 return true;
1962 //= OColumnExport
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()
1971 implEndElement();
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
2000 return "column";
2003 void OColumnExport::exportAttributes()
2005 OControlExport::exportAttributes();
2007 // the attribute "label"
2008 exportStringPropertyAttribute(
2009 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::Label),
2010 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::Label),
2011 PROPERTY_LABEL);
2013 // the style attribute
2014 OUString sStyleName = m_rContext.getObjectStyleName( m_xProps );
2015 if ( !sStyleName.isEmpty() )
2017 AddAttribute(
2018 OAttributeMetaData::getSpecialAttributeNamespace( SCAFlags::ColumnStyleName ),
2019 OAttributeMetaData::getSpecialAttributeName( SCAFlags::ColumnStyleName ),
2020 sStyleName
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;
2038 //= OFormExport
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
2049 return "form";
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() )
2062 AddAttribute(
2063 OAttributeMetaData::getCommonControlAttributeNamespace(CCAFlags::TargetLocation),
2064 OAttributeMetaData::getCommonControlAttributeName(CCAFlags::TargetLocation),
2065 sPropValue);
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()
2084 sal_Int32 i=0;
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)!");
2101 #endif
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);
2124 else
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)!");
2155 #endif
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)!");
2195 #endif
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]
2207 // the service name
2208 exportServiceNameAttribute();
2209 // the target frame
2210 exportTargetFrameAttribute();
2211 // the target URL
2212 exportTargetLocationAttribute(true); // #i110911# add type attribute (for form, but not for control)
2214 // master fields
2215 exportStringSequenceAttribute(
2216 OAttributeMetaData::getFormAttributeNamespace(faMasterFields),
2217 OAttributeMetaData::getFormAttributeName(faMasterFields),
2218 PROPERTY_MASTERFIELDS);
2219 // detail fields
2220 exportStringSequenceAttribute(
2221 OAttributeMetaData::getFormAttributeNamespace(faDetailFiels),
2222 OAttributeMetaData::getFormAttributeName(faDetailFiels),
2223 PROPERTY_DETAILFIELDS);
2225 } // namespace xmloff
2227 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */