bump product version to 5.0.4.1
[LibreOffice.git] / xmloff / source / forms / elementexport.cxx
blob091e2e73e38e4915ec92a13ce6c9e3a9d98926e9
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(NULL)
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 = NULL;
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(CCA_SERVICE_NAME),
214 OAttributeMetaData::getCommonControlAttributeName(CCA_SERVICE_NAME),
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(0)
238 ,m_nIncludeDatabase(0)
239 ,m_nIncludeSpecial(0)
240 ,m_nIncludeEvents(0)
241 ,m_nIncludeBindings(0)
242 ,m_pOuterElement(NULL)
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 (CCA_NAME & m_nIncludeCommon)
257 exportStringPropertyAttribute(
258 OAttributeMetaData::getCommonControlAttributeNamespace(CCA_NAME),
259 OAttributeMetaData::getCommonControlAttributeName(CCA_NAME),
260 PROPERTY_NAME
262 #if OSL_DEBUG_LEVEL > 0
263 // reset the bit for later checking
264 m_nIncludeCommon = m_nIncludeCommon & ~CCA_NAME;
265 #endif
268 // the service name
269 if (m_nIncludeCommon & CCA_SERVICE_NAME)
271 exportServiceNameAttribute();
272 #if OSL_DEBUG_LEVEL > 0
273 // reset the bit for later checking
274 m_nIncludeCommon = m_nIncludeCommon & ~CCA_SERVICE_NAME;
275 #endif
279 void OControlExport::exportInnerAttributes()
281 // the control id
282 if (CCA_CONTROL_ID & 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 & ~CCA_CONTROL_ID;
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)
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( OUString( "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(CCA_LABEL),
416 OAttributeMetaData::getCommonControlAttributeName(CCA_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 == NULL )
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 sal_Int32 nStringPropertyAttributeIds[] =
543 CCA_LABEL, CCA_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( sizeof(aStringPropertyNames)/sizeof(aStringPropertyNames[0]) ==
551 sizeof(nStringPropertyAttributeIds)/sizeof(nStringPropertyAttributeIds[0]),
552 "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (1)!");
554 for (i=0; i<sizeof(nStringPropertyAttributeIds)/sizeof(nStringPropertyAttributeIds[0]); ++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 sal_Int32 nBooleanPropertyAttributeIds[] =
572 { // attribute flags
573 CCA_CURRENT_SELECTED, CCA_DISABLED, CCA_DROPDOWN, CCA_PRINTABLE, CCA_READONLY, CCA_SELECTED, CCA_TAB_STOP, CCA_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 sal_Int8 nBooleanPropertyAttrFlags[] =
583 { // attribute defaults
584 BOOLATTR_DEFAULT_FALSE, BOOLATTR_DEFAULT_FALSE | BOOLATTR_INVERSE_SEMANTICS, BOOLATTR_DEFAULT_FALSE, BOOLATTR_DEFAULT_TRUE, BOOLATTR_DEFAULT_FALSE, BOOLATTR_DEFAULT_FALSE, BOOLATTR_DEFAULT_VOID, BOOLATTR_DEFAULT_FALSE
586 #if OSL_DEBUG_LEVEL > 0
587 static const sal_Int32 nIdCount = sizeof(nBooleanPropertyAttributeIds) / sizeof(nBooleanPropertyAttributeIds[0]);
588 static const sal_Int32 nNameCount = sizeof(pBooleanPropertyNames) / sizeof(pBooleanPropertyNames[0]);
589 static const sal_Int32 nFlagsCount = sizeof(nBooleanPropertyAttrFlags) / sizeof(nBooleanPropertyAttrFlags[0]);
590 OSL_ENSURE((nIdCount == nNameCount) && (nNameCount == nFlagsCount),
591 "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (2)!");
592 #endif
593 for (i=0; i<sizeof(nBooleanPropertyAttributeIds)/sizeof(nBooleanPropertyAttributeIds[0]); ++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 sal_Int32 nIntegerPropertyAttributeIds[] =
612 { // attribute flags
613 CCA_SIZE, CCA_TAB_INDEX
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 & CCA_MAX_LENGTH )
625 exportedProperty(PROPERTY_MAXTEXTLENGTH);
627 #if OSL_DEBUG_LEVEL > 0
628 static const sal_Int32 nIdCount = sizeof(nIntegerPropertyAttributeIds) / sizeof(nIntegerPropertyAttributeIds[0]);
629 static const sal_Int32 nNameCount = sizeof(pIntegerPropertyNames) / sizeof(pIntegerPropertyNames[0]);
630 static const sal_Int32 nDefaultCount = sizeof(nIntegerPropertyAttrDefaults) / sizeof(nIntegerPropertyAttrDefaults[0]);
631 OSL_ENSURE((nIdCount == nNameCount) && (nNameCount == nDefaultCount),
632 "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (3)!");
633 #endif
634 for (i=0; i<sizeof(nIntegerPropertyAttributeIds)/sizeof(nIntegerPropertyAttributeIds[0]); ++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 & CCA_BUTTON_TYPE)
654 exportEnumPropertyAttribute(
655 OAttributeMetaData::getCommonControlAttributeNamespace(CCA_BUTTON_TYPE),
656 OAttributeMetaData::getCommonControlAttributeName(CCA_BUTTON_TYPE),
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 & ~CCA_BUTTON_TYPE;
663 #endif
665 if ( m_nIncludeCommon & CCA_ORIENTATION )
667 exportEnumPropertyAttribute(
668 OAttributeMetaData::getCommonControlAttributeNamespace( CCA_ORIENTATION ),
669 OAttributeMetaData::getCommonControlAttributeName( CCA_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 & ~CCA_ORIENTATION;
677 #endif
680 if ( m_nIncludeCommon & CCA_VISUAL_EFFECT )
682 exportEnumPropertyAttribute(
683 OAttributeMetaData::getCommonControlAttributeNamespace( CCA_VISUAL_EFFECT ),
684 OAttributeMetaData::getCommonControlAttributeName( CCA_VISUAL_EFFECT ),
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 & ~CCA_VISUAL_EFFECT;
692 #endif
696 // some properties which require a special handling
698 // the target frame
699 if (m_nIncludeCommon & CCA_TARGET_FRAME)
701 exportTargetFrameAttribute();
702 #if OSL_DEBUG_LEVEL > 0
703 // reset the bit for later checking
704 m_nIncludeCommon = m_nIncludeCommon & ~CCA_TARGET_FRAME;
705 #endif
708 // max text length
709 if ( m_nIncludeCommon & CCA_MAX_LENGTH )
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( CCA_MAX_LENGTH ),
722 OAttributeMetaData::getCommonControlAttributeName( CCA_MAX_LENGTH ),
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 & ~CCA_MAX_LENGTH;
734 #endif
737 if (m_nIncludeCommon & CCA_TARGET_LOCATION)
739 exportTargetLocationAttribute(false);
740 #if OSL_DEBUG_LEVEL > 0
741 // reset the bit for later checking
742 m_nIncludeCommon = m_nIncludeCommon & ~CCA_TARGET_LOCATION;
743 #endif
746 // OJ #99721#
747 if (m_nIncludeCommon & CCA_IMAGE_DATA)
749 exportImageDataAttribute();
750 #if OSL_DEBUG_LEVEL > 0
751 // reset the bit for later checking
752 m_nIncludeCommon = m_nIncludeCommon & ~CCA_IMAGE_DATA;
753 #endif
756 // the for attribute
757 // the target frame
758 if (m_nIncludeCommon & CCA_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(CCA_FOR),
764 OAttributeMetaData::getCommonControlAttributeName(CCA_FOR),
765 m_sReferringControls);
767 #if OSL_DEBUG_LEVEL > 0
768 // reset the bit for later checking
769 m_nIncludeCommon = m_nIncludeCommon & ~CCA_FOR;
770 #endif
773 if ((CCA_CURRENT_VALUE | CCA_VALUE) & m_nIncludeCommon)
775 const sal_Char* pCurrentValuePropertyName = NULL;
776 const sal_Char* pValuePropertyName = NULL;
778 // get the property names
779 getValuePropertyNames(m_eType, m_nClassId, pCurrentValuePropertyName, pValuePropertyName);
781 static const sal_Char* pCurrentValueAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_VALUE);
782 static const sal_Char* pValueAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_VALUE);
783 static const sal_uInt16 nCurrentValueAttributeNamespaceKey = OAttributeMetaData::getCommonControlAttributeNamespace(CCA_CURRENT_VALUE);
784 static const sal_uInt16 nValueAttributeNamespaceKey = OAttributeMetaData::getCommonControlAttributeNamespace(CCA_VALUE);
786 // add the atrtributes if necessary and possible
787 if (pCurrentValuePropertyName && (CCA_CURRENT_VALUE & 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 && (CCA_VALUE & m_nIncludeCommon))
802 exportGenericPropertyAttribute(
803 nValueAttributeNamespaceKey,
804 pValueAttributeName,
805 pValuePropertyName);
807 OSL_ENSURE((NULL == pValuePropertyName) == (0 == (CCA_VALUE & m_nIncludeCommon)),
808 "OControlExport::exportCommonControlAttributes: no property found for the value attribute!");
809 OSL_ENSURE((NULL == pCurrentValuePropertyName ) == (0 == (CCA_CURRENT_VALUE & 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 & ~(CCA_CURRENT_VALUE | CCA_VALUE);
815 #endif
818 OSL_ENSURE(0 == 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 sal_Int32 nIncludeDatabase = m_nIncludeDatabase;
828 #endif
829 // the only string property: DataField
830 if (DA_DATA_FIELD & m_nIncludeDatabase)
832 exportStringPropertyAttribute(
833 OAttributeMetaData::getDatabaseAttributeNamespace(DA_DATA_FIELD),
834 OAttributeMetaData::getDatabaseAttributeName(DA_DATA_FIELD),
835 PROPERTY_DATAFIELD);
836 RESET_BIT( nIncludeDatabase, DA_DATA_FIELD );
839 // InputRequired
840 if ( DA_INPUT_REQUIRED & m_nIncludeDatabase )
842 exportBooleanPropertyAttribute(
843 OAttributeMetaData::getDatabaseAttributeNamespace( DA_INPUT_REQUIRED ),
844 OAttributeMetaData::getDatabaseAttributeName( DA_INPUT_REQUIRED ),
845 PROPERTY_INPUT_REQUIRED,
846 BOOLATTR_DEFAULT_TRUE
848 RESET_BIT( nIncludeDatabase, DA_INPUT_REQUIRED );
851 // the only int16 property: BoundColumn
852 if (DA_BOUND_COLUMN & m_nIncludeDatabase)
854 exportInt16PropertyAttribute(
855 OAttributeMetaData::getDatabaseAttributeNamespace(DA_BOUND_COLUMN),
856 OAttributeMetaData::getDatabaseAttributeName(DA_BOUND_COLUMN),
857 PROPERTY_BOUNDCOLUMN,
859 true);
860 RESET_BIT( nIncludeDatabase, DA_BOUND_COLUMN );
863 // ConvertEmptyToNull
864 if (DA_CONVERT_EMPTY & m_nIncludeDatabase)
866 exportBooleanPropertyAttribute(
867 OAttributeMetaData::getDatabaseAttributeNamespace(DA_CONVERT_EMPTY),
868 OAttributeMetaData::getDatabaseAttributeName(DA_CONVERT_EMPTY),
869 PROPERTY_EMPTY_IS_NULL,
870 BOOLATTR_DEFAULT_FALSE
872 RESET_BIT( nIncludeDatabase, DA_CONVERT_EMPTY );
875 // the only enum property: ListSourceType
876 if (DA_LIST_SOURCE_TYPE & m_nIncludeDatabase)
878 exportEnumPropertyAttribute(
879 OAttributeMetaData::getDatabaseAttributeNamespace(DA_LIST_SOURCE_TYPE),
880 OAttributeMetaData::getDatabaseAttributeName(DA_LIST_SOURCE_TYPE),
881 PROPERTY_LISTSOURCETYPE,
882 OEnumMapper::getEnumMap(OEnumMapper::epListSourceType),
883 ListSourceType_VALUELIST
885 RESET_BIT( nIncludeDatabase, DA_LIST_SOURCE_TYPE );
888 if (m_nIncludeDatabase & DA_LIST_SOURCE)
890 exportListSourceAsAttribute();
891 RESET_BIT( nIncludeDatabase, DA_LIST_SOURCE );
894 #if OSL_DEBUG_LEVEL > 0
895 OSL_ENSURE(0 == 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 sal_Int32 nIncludeBinding = m_nIncludeBindings;
906 #endif
908 if ( m_nIncludeBindings & BA_LINKED_CELL )
910 exportCellBindingAttributes( ( m_nIncludeBindings & BA_LIST_LINKING_TYPE ) != 0 );
911 #if OSL_DEBUG_LEVEL > 0
912 // reset the bit for later checking
913 nIncludeBinding = nIncludeBinding & ~( BA_LINKED_CELL | BA_LIST_LINKING_TYPE );
914 #endif
917 if ( m_nIncludeBindings & BA_LIST_CELL_RANGE )
919 exportCellListSourceRange();
920 #if OSL_DEBUG_LEVEL > 0
921 // reset the bit for later checking
922 nIncludeBinding = nIncludeBinding & ~BA_LIST_CELL_RANGE;
923 #endif
926 if ( m_nIncludeBindings & BA_XFORMS_BIND )
928 exportXFormsBindAttributes();
929 #if OSL_DEBUG_LEVEL > 0
930 // reset the bit for later checking
931 nIncludeBinding = nIncludeBinding & ~BA_XFORMS_BIND;
932 #endif
935 if ( m_nIncludeBindings & BA_XFORMS_LISTBIND )
937 exportXFormsListAttributes();
938 #if OSL_DEBUG_LEVEL > 0
939 // reset the bit for later checking
940 nIncludeBinding = nIncludeBinding & ~BA_XFORMS_LISTBIND;
941 #endif
944 if ( m_nIncludeBindings & BA_XFORMS_SUBMISSION )
946 exportXFormsSubmissionAttributes();
947 #if OSL_DEBUG_LEVEL > 0
948 // reset the bit for later checking
949 nIncludeBinding = nIncludeBinding & ~BA_XFORMS_SUBMISSION;
950 #endif
953 OSL_ENSURE( 0 == nIncludeBinding,
954 "OControlExport::exportBindingAtributes: forgot some flags!");
955 // in the debug version, we should have removed every bit we handled from the mask, so it should
956 // be 0 now ...
959 void OControlExport::exportSpecialAttributes()
961 sal_Int32 i=0;
963 // the boolean properties
965 static const sal_Int32 nBooleanPropertyAttributeIds[] =
966 { // attribute flags
967 SCA_VALIDATION, SCA_MULTI_LINE, SCA_AUTOMATIC_COMPLETION, SCA_MULTIPLE, SCA_DEFAULT_BUTTON, SCA_IS_TRISTATE,
968 SCA_TOGGLE, SCA_FOCUS_ON_CLICK
970 static const char * pBooleanPropertyNames[] =
971 { // property names
972 PROPERTY_STRICTFORMAT, PROPERTY_MULTILINE,
973 PROPERTY_AUTOCOMPLETE,
974 PROPERTY_MULTISELECTION,
975 PROPERTY_DEFAULTBUTTON, PROPERTY_TRISTATE,
976 PROPERTY_TOGGLE, PROPERTY_FOCUS_ON_CLICK
978 static const sal_Int32 nIdCount = sizeof(nBooleanPropertyAttributeIds) / sizeof(nBooleanPropertyAttributeIds[0]);
979 #if OSL_DEBUG_LEVEL > 0
980 static const sal_Int32 nNameCount = sizeof(pBooleanPropertyNames) / sizeof(pBooleanPropertyNames[0]);
981 OSL_ENSURE((nIdCount == nNameCount),
982 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (1)!");
983 #endif
984 const sal_Int32* pAttributeId = nBooleanPropertyAttributeIds;
985 for ( i = 0; i < nIdCount; ++i, ++pAttributeId )
987 if ( *pAttributeId & m_nIncludeSpecial)
989 exportBooleanPropertyAttribute(
990 OAttributeMetaData::getSpecialAttributeNamespace( *pAttributeId ),
991 OAttributeMetaData::getSpecialAttributeName( *pAttributeId ),
992 OUString::createFromAscii(pBooleanPropertyNames[i]),
993 ( *pAttributeId == SCA_FOCUS_ON_CLICK ) ? BOOLATTR_DEFAULT_TRUE : BOOLATTR_DEFAULT_FALSE
995 #if OSL_DEBUG_LEVEL > 0
996 // reset the bit for later checking
997 m_nIncludeSpecial = m_nIncludeSpecial & ~*pAttributeId;
998 #endif
1003 // the integer properties
1005 static sal_Int32 nIntegerPropertyAttributeIds[] =
1006 { // attribute flags
1007 SCA_PAGE_STEP_SIZE
1009 static const char * pIntegerPropertyNames[] =
1010 { // property names
1011 PROPERTY_BLOCK_INCREMENT
1013 static const sal_Int32 nIntegerPropertyAttrDefaults[] =
1014 { // attribute defaults (XML defaults, not runtime defaults!)
1018 static const sal_Int32 nIdCount = sizeof( nIntegerPropertyAttributeIds ) / sizeof( nIntegerPropertyAttributeIds[0] );
1019 #if OSL_DEBUG_LEVEL > 0
1020 static const sal_Int32 nNameCount = sizeof( pIntegerPropertyNames ) / sizeof( pIntegerPropertyNames[0] );
1021 OSL_ENSURE( ( nIdCount == nNameCount ),
1022 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (2)!" );
1023 static const sal_Int32 nDefaultCount = sizeof( nIntegerPropertyAttrDefaults ) / sizeof( nIntegerPropertyAttrDefaults[0] );
1024 OSL_ENSURE( ( nIdCount == nDefaultCount ),
1025 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (3)!" );
1026 #endif
1027 for ( i = 0; i < nIdCount; ++i )
1028 if ( nIntegerPropertyAttributeIds[i] & m_nIncludeSpecial )
1030 exportInt32PropertyAttribute(
1031 OAttributeMetaData::getSpecialAttributeNamespace( nIntegerPropertyAttributeIds[i] ),
1032 OAttributeMetaData::getSpecialAttributeName( nIntegerPropertyAttributeIds[i] ),
1033 OUString::createFromAscii(pIntegerPropertyNames[i]),
1034 nIntegerPropertyAttrDefaults[i]
1036 #if OSL_DEBUG_LEVEL > 0
1037 // reset the bit for later checking
1038 m_nIncludeSpecial = m_nIncludeSpecial & ~nIntegerPropertyAttributeIds[i];
1039 #endif
1042 if ( SCA_STEP_SIZE & m_nIncludeSpecial )
1044 OUString sPropertyName;
1045 if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_LINE_INCREMENT ) )
1046 sPropertyName = PROPERTY_LINE_INCREMENT;
1047 else if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_SPIN_INCREMENT ) )
1048 sPropertyName = PROPERTY_SPIN_INCREMENT;
1049 else
1050 OSL_FAIL( "OControlExport::exportSpecialAttributes: not property which can be mapped to step-size attribute!" );
1052 if ( !sPropertyName.isEmpty() )
1053 exportInt32PropertyAttribute(
1054 OAttributeMetaData::getSpecialAttributeNamespace( SCA_STEP_SIZE ),
1055 OAttributeMetaData::getSpecialAttributeName( SCA_STEP_SIZE ),
1056 sPropertyName,
1060 #if OSL_DEBUG_LEVEL > 0
1061 // reset the bit for later checking
1062 m_nIncludeSpecial = m_nIncludeSpecial & ~SCA_STEP_SIZE;
1063 #endif
1068 // the enum properties
1070 if (SCA_STATE & m_nIncludeSpecial)
1072 exportEnumPropertyAttribute(
1073 OAttributeMetaData::getSpecialAttributeNamespace(SCA_STATE),
1074 OAttributeMetaData::getSpecialAttributeName(SCA_STATE),
1075 PROPERTY_DEFAULT_STATE,
1076 OEnumMapper::getEnumMap(OEnumMapper::epCheckState),
1077 TRISTATE_FALSE);
1078 #if OSL_DEBUG_LEVEL > 0
1079 // reset the bit for later checking
1080 m_nIncludeSpecial = m_nIncludeSpecial & ~SCA_STATE;
1081 #endif
1084 if (SCA_CURRENT_STATE & m_nIncludeSpecial)
1086 exportEnumPropertyAttribute(
1087 OAttributeMetaData::getSpecialAttributeNamespace(SCA_CURRENT_STATE),
1088 OAttributeMetaData::getSpecialAttributeName(SCA_CURRENT_STATE),
1089 PROPERTY_STATE,
1090 OEnumMapper::getEnumMap(OEnumMapper::epCheckState),
1091 TRISTATE_FALSE);
1092 #if OSL_DEBUG_LEVEL > 0
1093 // reset the bit for later checking
1094 m_nIncludeSpecial = m_nIncludeSpecial & ~SCA_CURRENT_STATE;
1095 #endif
1099 // some properties which require a special handling
1100 // the repeat delay
1102 if ( m_nIncludeSpecial & SCA_REPEAT_DELAY )
1104 DBG_CHECK_PROPERTY( PROPERTY_REPEAT_DELAY, sal_Int32 );
1106 sal_Int32 nRepeatDelay = 0;
1107 m_xProps->getPropertyValue( PROPERTY_REPEAT_DELAY ) >>= nRepeatDelay;
1108 tools::Time aTime( tools::Time::SYSTEM );
1109 aTime.MakeTimeFromMS( nRepeatDelay );
1110 util::Duration aDuration;
1111 aDuration.Hours = aTime.GetHour();
1112 aDuration.Minutes = aTime.GetMin();
1113 aDuration.Seconds = aTime.GetSec();
1114 aDuration.NanoSeconds = (nRepeatDelay % 1000) * 1000000;
1116 OUStringBuffer buf;
1117 ::sax::Converter::convertDuration(buf, aDuration);
1118 AddAttribute(OAttributeMetaData::getSpecialAttributeNamespace( SCA_REPEAT_DELAY )
1119 ,OAttributeMetaData::getSpecialAttributeName( SCA_REPEAT_DELAY )
1120 ,buf.makeStringAndClear());
1122 exportedProperty( PROPERTY_REPEAT_DELAY );
1124 #if OSL_DEBUG_LEVEL > 0
1125 // reset the bit for later checking
1126 m_nIncludeSpecial = m_nIncludeSpecial & ~SCA_REPEAT_DELAY;
1127 #endif
1131 // the EchoChar property needs special handling, cause it's a Int16, but must be stored as one-character-string
1133 if (SCA_ECHO_CHAR & m_nIncludeSpecial)
1135 DBG_CHECK_PROPERTY( PROPERTY_ECHO_CHAR, sal_Int16 );
1136 sal_Int16 nValue(0);
1137 m_xProps->getPropertyValue(PROPERTY_ECHO_CHAR) >>= nValue;
1138 if (nValue)
1140 OUString sCharacter(reinterpret_cast<const sal_Unicode*>(&nValue), 1);
1141 AddAttribute(
1142 OAttributeMetaData::getSpecialAttributeNamespace(SCA_ECHO_CHAR),
1143 OAttributeMetaData::getSpecialAttributeName(SCA_ECHO_CHAR),
1144 sCharacter);
1146 exportedProperty(PROPERTY_ECHO_CHAR);
1147 #if OSL_DEBUG_LEVEL > 0
1148 // reset the bit for later checking
1149 m_nIncludeSpecial = m_nIncludeSpecial & ~SCA_ECHO_CHAR;
1150 #endif
1154 // the string properties
1156 static const sal_Int32 nStringPropertyAttributeIds[] =
1157 { // attribute flags
1158 SCA_GROUP_NAME
1160 static const OUString pStringPropertyNames[] =
1161 { // property names
1162 OUString(PROPERTY_GROUP_NAME)
1165 static const sal_Int32 nIdCount = sizeof( nStringPropertyAttributeIds ) / sizeof( nStringPropertyAttributeIds[0] );
1166 #if OSL_DEBUG_LEVEL > 0
1167 static const sal_Int32 nNameCount = sizeof( pStringPropertyNames ) / sizeof( pStringPropertyNames[0] );
1168 OSL_ENSURE( ( nIdCount == nNameCount ),
1169 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (2)!" );
1170 #endif
1171 for ( i = 0; i < nIdCount; ++i )
1172 if ( nStringPropertyAttributeIds[i] & m_nIncludeSpecial )
1174 exportStringPropertyAttribute(
1175 OAttributeMetaData::getSpecialAttributeNamespace( nStringPropertyAttributeIds[i] ),
1176 OAttributeMetaData::getSpecialAttributeName( nStringPropertyAttributeIds[i] ),
1177 pStringPropertyNames[i]
1179 #if OSL_DEBUG_LEVEL > 0
1180 // reset the bit for later checking
1181 m_nIncludeSpecial = m_nIncludeSpecial & ~nStringPropertyAttributeIds[i];
1182 #endif
1186 if ((SCA_MIN_VALUE | SCA_MAX_VALUE) & m_nIncludeSpecial)
1188 // need to export the min value and the max value as attributes
1189 // It depends on the real type (FormComponentType) of the control, which properties hold these
1190 // values
1191 const sal_Char* pMinValuePropertyName = NULL;
1192 const sal_Char* pMaxValuePropertyName = NULL;
1193 getValueLimitPropertyNames(m_nClassId, pMinValuePropertyName, pMaxValuePropertyName);
1195 OSL_ENSURE((NULL == pMinValuePropertyName) == (0 == (SCA_MIN_VALUE & m_nIncludeSpecial)),
1196 "OControlExport::exportCommonControlAttributes: no property found for the min value attribute!");
1197 OSL_ENSURE((NULL == pMaxValuePropertyName) == (0 == (SCA_MAX_VALUE & m_nIncludeSpecial)),
1198 "OControlExport::exportCommonControlAttributes: no property found for the max value attribute!");
1200 // add the two attributes
1201 static const sal_Char* pMinValueAttributeName = OAttributeMetaData::getSpecialAttributeName(SCA_MIN_VALUE);
1202 static const sal_Char* pMaxValueAttributeName = OAttributeMetaData::getSpecialAttributeName(SCA_MAX_VALUE);
1203 static const sal_uInt16 nMinValueNamespaceKey = OAttributeMetaData::getSpecialAttributeNamespace(SCA_MIN_VALUE);
1204 static const sal_uInt16 nMaxValueNamespaceKey = OAttributeMetaData::getSpecialAttributeNamespace(SCA_MAX_VALUE);
1206 if (pMinValuePropertyName && (SCA_MIN_VALUE & m_nIncludeSpecial))
1207 exportGenericPropertyAttribute(
1208 nMinValueNamespaceKey,
1209 pMinValueAttributeName,
1210 pMinValuePropertyName);
1212 if (pMaxValuePropertyName && (SCA_MAX_VALUE & m_nIncludeSpecial))
1213 exportGenericPropertyAttribute(
1214 nMaxValueNamespaceKey,
1215 pMaxValueAttributeName,
1216 pMaxValuePropertyName);
1217 #if OSL_DEBUG_LEVEL > 0
1218 // reset the bit for later checking
1219 m_nIncludeSpecial = m_nIncludeSpecial & ~(SCA_MIN_VALUE | SCA_MAX_VALUE);
1220 #endif
1223 if ( SCA_IMAGE_POSITION & m_nIncludeSpecial )
1225 exportImagePositionAttributes();
1226 RESET_BIT( m_nIncludeSpecial, SCA_IMAGE_POSITION );
1229 OSL_ENSURE(0 == m_nIncludeSpecial,
1230 "OControlExport::exportSpecialAttributes: forgot some flags!");
1231 // in the dbg_util version, we should have removed every bit we handled from the mask, so it should
1232 // be 0 now ...
1235 OUString OControlExport::getScalarListSourceValue() const
1237 OUString sListSource;
1238 Any aListSource = m_xProps->getPropertyValue( PROPERTY_LISTSOURCE );
1239 if ( !( aListSource >>= sListSource ) )
1241 Sequence< OUString > aListSourceSequence;
1242 aListSource >>= aListSourceSequence;
1243 if ( aListSourceSequence.getLength() )
1244 sListSource = aListSourceSequence[ 0 ];
1246 return sListSource;
1249 void OControlExport::exportListSourceAsAttribute()
1251 // DA_LIST_SOURCE needs some special handling
1252 DBG_CHECK_PROPERTY_NO_TYPE( PROPERTY_LISTSOURCE );
1254 OUString sListSource = getScalarListSourceValue();
1255 if ( !sListSource.isEmpty() )
1256 { // the ListSource property needs to be exported as attribute, and it is not empty
1257 AddAttribute(
1258 OAttributeMetaData::getDatabaseAttributeNamespace(DA_LIST_SOURCE),
1259 OAttributeMetaData::getDatabaseAttributeName(DA_LIST_SOURCE),
1260 sListSource);
1263 exportedProperty( PROPERTY_LISTSOURCE );
1266 void OControlExport::getSequenceInt16PropertyAsSet(const OUString& _rPropertyName, Int16Set& _rOut)
1268 Sequence< sal_Int16 > aValueSequence;
1269 DBG_CHECK_PROPERTY(_rPropertyName, Sequence< sal_Int16 >);
1270 m_xProps->getPropertyValue(_rPropertyName) >>= aValueSequence;
1272 const sal_Int16* pValues = aValueSequence.getConstArray();
1273 for (sal_Int32 i=0; i<aValueSequence.getLength(); ++i, ++pValues)
1274 _rOut.insert(*pValues);
1277 void OControlExport::exportListSourceAsElements()
1279 // the string lists
1280 Sequence< OUString > aItems, aValues;
1281 DBG_CHECK_PROPERTY( PROPERTY_STRING_ITEM_LIST, Sequence< OUString > );
1282 m_xProps->getPropertyValue(PROPERTY_STRING_ITEM_LIST) >>= aItems;
1284 DBG_CHECK_PROPERTY( PROPERTY_LISTSOURCE, Sequence< OUString > );
1285 if ( 0 == ( m_nIncludeDatabase & DA_LIST_SOURCE ) )
1286 m_xProps->getPropertyValue(PROPERTY_LISTSOURCE) >>= aValues;
1287 // if we exported the list source as attribute, we do not repeat it as sub elements
1289 // the selection lists
1290 Int16Set aSelection, aDefaultSelection;
1291 getSequenceInt16PropertyAsSet(PROPERTY_SELECT_SEQ, aSelection);
1292 getSequenceInt16PropertyAsSet(PROPERTY_DEFAULT_SELECT_SEQ, aDefaultSelection);
1294 // the string for "true"
1295 OUString sTrue;
1296 OUStringBuffer sBuffer;
1297 ::sax::Converter::convertBool(sBuffer, true);
1298 sTrue = sBuffer.makeStringAndClear();
1300 // loop through both lists ('til the maximum of both lengths)
1301 const OUString* pItems = aItems.getConstArray();
1302 const OUString* pValues = aValues.getConstArray();
1304 sal_Int32 nItems = aItems.getLength();
1305 sal_Int32 nValues = aValues.getLength();
1307 sal_Int16 nMaxLen = (sal_Int16)std::max(nItems, nValues);
1309 for (sal_Int16 i=0; i<nMaxLen; ++i )
1311 m_rContext.getGlobalContext().ClearAttrList();
1312 if (i < nItems)
1314 // there is an item at this position
1315 AddAttribute(
1316 OAttributeMetaData::getCommonControlAttributeNamespace(CCA_LABEL),
1317 OAttributeMetaData::getCommonControlAttributeName(CCA_LABEL),
1318 *pItems);
1319 ++pItems;
1321 if (i < nValues)
1323 // there is an value at this position
1324 AddAttribute(
1325 OAttributeMetaData::getCommonControlAttributeNamespace(CCA_VALUE),
1326 OAttributeMetaData::getCommonControlAttributeName(CCA_VALUE),
1327 *pValues);
1328 ++pValues;
1331 Int16Set::iterator aSelectedPos = aSelection.find(i);
1332 if (aSelection.end() != aSelectedPos)
1333 { // the item at this position is selected
1334 AddAttribute(
1335 OAttributeMetaData::getCommonControlAttributeNamespace(CCA_CURRENT_SELECTED),
1336 OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_SELECTED),
1337 sTrue
1339 aSelection.erase(aSelectedPos);
1342 Int16Set::iterator aDefaultSelectedPos = aDefaultSelection.find(i);
1343 if (aDefaultSelection.end() != aDefaultSelectedPos)
1344 { // the item at this position is selected as default
1345 AddAttribute(
1346 OAttributeMetaData::getCommonControlAttributeNamespace(CCA_SELECTED),
1347 OAttributeMetaData::getCommonControlAttributeName(CCA_SELECTED),
1348 sTrue
1350 aDefaultSelection.erase(aDefaultSelectedPos);
1352 SvXMLElementExport aFormElement(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, "option", true, true);
1355 // There may be more "selected" or "default-selected" items than there are in the lists in real,
1356 // so we need to store some additional "form:option" items which have no name and no label, but
1357 // one or both of the selected flags.
1358 // 21.05.2001 - 85388 - frank.schoenheit@germany.sun.com
1360 if ( !aSelection.empty() || !aDefaultSelection.empty() )
1362 sal_Int16 nLastSelected = -1;
1363 if ( !aSelection.empty() )
1364 nLastSelected = *(--aSelection.end());
1366 sal_Int16 nLastDefaultSelected = -1;
1367 if ( !aDefaultSelection.empty() )
1368 nLastDefaultSelected = *(--aDefaultSelection.end());
1370 // the maximum element in both sets
1371 sal_Int16 nLastReferredEntry = std::max(nLastSelected, nLastDefaultSelected);
1372 OSL_ENSURE(nLastReferredEntry >= nMaxLen, "OControlExport::exportListSourceAsElements: inconsistence!");
1373 // if the maximum (selected or default selected) entry number is less than the maximum item count
1374 // in both lists, the entry number should have been removed from the set
1376 for (sal_Int16 i=nMaxLen; i<=nLastReferredEntry; ++i)
1378 if (aSelection.end() != aSelection.find(i))
1379 { // the (not existent) item at this position is selected
1380 AddAttribute(
1381 OAttributeMetaData::getCommonControlAttributeNamespace(CCA_CURRENT_SELECTED),
1382 OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_SELECTED),
1383 sTrue
1387 if (aDefaultSelection.end() != aDefaultSelection.find(i))
1388 { // the (not existent) item at this position is selected as default
1389 AddAttribute(
1390 OAttributeMetaData::getCommonControlAttributeNamespace(CCA_SELECTED),
1391 OAttributeMetaData::getCommonControlAttributeName(CCA_SELECTED),
1392 sTrue
1395 SvXMLElementExport aFormElement(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, "option", true, true);
1400 void OControlExport::implStartElement(const sal_Char* _pName)
1402 // before we let the base class start it's outer element, we add a wrapper element
1403 const sal_Char *pOuterElementName = getOuterXMLElementName();
1404 m_pOuterElement = pOuterElementName
1405 ? new SvXMLElementExport(
1406 m_rContext.getGlobalContext(),
1407 XML_NAMESPACE_FORM,
1408 pOuterElementName, true,
1409 true)
1410 : 0;
1412 // add the attributes for the inner element
1413 exportInnerAttributes();
1415 // and start the inner element
1416 OElementExport::implStartElement(_pName);
1419 void OControlExport::implEndElement()
1421 // end the inner element
1422 OElementExport::implEndElement();
1424 // end the outer element if it exists
1425 delete m_pOuterElement;
1426 m_pOuterElement = NULL;
1429 const sal_Char* OControlExport::getOuterXMLElementName() const
1431 return 0;
1434 const sal_Char* OControlExport::getXMLElementName() const
1436 return getElementName(m_eType);
1439 void OControlExport::examine()
1441 OSL_ENSURE( ( m_nIncludeCommon == 0 ) && ( m_nIncludeSpecial == 0 ) && ( m_nIncludeDatabase == 0 )
1442 && ( m_nIncludeEvents == 0 ) && ( m_nIncludeBindings == 0),
1443 "OControlExport::examine: called me twice? Not initialized?" );
1445 // get the class id to decide which kind of element we need in the XML stream
1446 m_nClassId = FormComponentType::CONTROL;
1447 DBG_CHECK_PROPERTY( PROPERTY_CLASSID, sal_Int16 );
1448 m_xProps->getPropertyValue(PROPERTY_CLASSID) >>= m_nClassId;
1449 bool knownType = false;
1450 switch (m_nClassId)
1452 case FormComponentType::DATEFIELD:
1453 m_eType = DATE;
1454 knownType = true;
1455 // NO BREAK
1456 case FormComponentType::TIMEFIELD:
1457 if ( !knownType )
1459 m_eType = TIME;
1460 knownType = true;
1462 m_nIncludeSpecial |= SCA_VALIDATION;
1463 // NO BREAK
1464 case FormComponentType::NUMERICFIELD:
1465 case FormComponentType::CURRENCYFIELD:
1466 case FormComponentType::PATTERNFIELD:
1467 if ( !knownType )
1469 m_eType = FORMATTED_TEXT;
1470 knownType = true;
1472 // NO BREAK
1473 case FormComponentType::TEXTFIELD:
1474 { // it's some kind of edit. To know which type we need further investigation
1476 if ( !knownType )
1478 // check if it's a formatted field
1479 if (m_xPropertyInfo->hasPropertyByName(PROPERTY_FORMATKEY))
1481 m_eType = FORMATTED_TEXT;
1483 else
1485 // all other controls are represented by an ordinary edit control, but which XML control type
1486 // it is depends on the current values of some properties
1488 // if the EchoChar string is not empty, it is a password field
1489 sal_Int16 nEchoChar = 0;
1490 if (m_xPropertyInfo->hasPropertyByName(PROPERTY_ECHOCHAR))
1491 // grid columns do not have this property ....
1492 m_xProps->getPropertyValue(PROPERTY_ECHOCHAR) >>= nEchoChar;
1493 if (nEchoChar)
1495 m_eType = PASSWORD;
1496 m_nIncludeSpecial |= SCA_ECHO_CHAR;
1498 else
1500 // if the MultiLine property is sal_True, it is a TextArea
1501 bool bMultiLine = false;
1502 if (m_xPropertyInfo->hasPropertyByName(PROPERTY_MULTILINE))
1503 // grid columns do not have this property ....
1504 bMultiLine = ::cppu::any2bool(m_xProps->getPropertyValue(PROPERTY_MULTILINE));
1506 if ( bMultiLine )
1507 m_eType = TEXT_AREA;
1508 else
1509 // the only case left is represented by a Text element
1510 m_eType = TEXT;
1513 knownType = true;
1516 // attributes which are common to all the types:
1517 // common attributes
1518 m_nIncludeCommon =
1519 CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED |
1520 CCA_PRINTABLE | CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE;
1522 if ( ( m_nClassId != FormComponentType::DATEFIELD )
1523 && ( m_nClassId != FormComponentType::TIMEFIELD )
1525 // date and time field values are handled differently nowadays
1526 m_nIncludeCommon |= CCA_VALUE;
1528 // database attributes
1529 m_nIncludeDatabase = DA_DATA_FIELD | DA_INPUT_REQUIRED;
1531 // event attributes
1532 m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE | EA_ON_SELECT;
1534 // only text and pattern fields have a ConvertEmptyToNull property
1535 if ( ( m_nClassId == FormComponentType::TEXTFIELD )
1536 || ( m_nClassId == FormComponentType::PATTERNFIELD )
1538 m_nIncludeDatabase |= DA_CONVERT_EMPTY;
1540 // all controls but the file control fields have a readonly property
1541 if ( m_nClassId != FormComponentType::FILECONTROL )
1542 m_nIncludeCommon |= CCA_READONLY;
1544 // a text field has a max text len
1545 if ( m_nClassId == FormComponentType::TEXTFIELD )
1546 m_nIncludeCommon |= CCA_MAX_LENGTH;
1548 // max and min values and validation:
1549 if (FORMATTED_TEXT == m_eType)
1550 { // in general all controls represented as formatted-text have these props
1551 if ( FormComponentType::PATTERNFIELD != m_nClassId ) // except the PatternField
1552 m_nIncludeSpecial |= SCA_MAX_VALUE | SCA_MIN_VALUE;
1554 if (FormComponentType::TEXTFIELD != m_nClassId)
1555 // and the FormattedField does not have a validation flag
1556 m_nIncludeSpecial |= SCA_VALIDATION;
1559 // if it's not a password field or rich text control, the CurrentValue needs to be stored, too
1560 if ( ( PASSWORD != m_eType )
1561 && ( DATE != m_eType )
1562 && ( TIME != m_eType )
1565 m_nIncludeCommon |= CCA_CURRENT_VALUE;
1568 break;
1570 case FormComponentType::FILECONTROL:
1571 m_eType = FILE;
1572 m_nIncludeCommon =
1573 CCA_NAME | CCA_SERVICE_NAME | CCA_CURRENT_VALUE | CCA_DISABLED |
1574 CCA_PRINTABLE | CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE |
1575 CCA_VALUE;
1576 m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE | EA_ON_SELECT;
1577 break;
1579 case FormComponentType::FIXEDTEXT:
1580 m_eType = FIXED_TEXT;
1581 m_nIncludeCommon =
1582 CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_LABEL |
1583 CCA_PRINTABLE | CCA_TITLE | CCA_FOR;
1584 m_nIncludeSpecial = SCA_MULTI_LINE;
1585 m_nIncludeEvents = EA_CONTROL_EVENTS;
1586 break;
1588 case FormComponentType::COMBOBOX:
1589 m_eType = COMBOBOX;
1590 m_nIncludeCommon =
1591 CCA_NAME | CCA_SERVICE_NAME | CCA_CURRENT_VALUE |
1592 CCA_DISABLED | CCA_DROPDOWN | CCA_MAX_LENGTH | CCA_PRINTABLE | CCA_READONLY | CCA_SIZE |
1593 CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE | CCA_VALUE;
1594 m_nIncludeSpecial = SCA_AUTOMATIC_COMPLETION;
1595 m_nIncludeDatabase = DA_CONVERT_EMPTY | DA_DATA_FIELD | DA_INPUT_REQUIRED | DA_LIST_SOURCE | DA_LIST_SOURCE_TYPE;
1596 m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE | EA_ON_SELECT;
1597 break;
1599 case FormComponentType::LISTBOX:
1600 m_eType = LISTBOX;
1601 m_nIncludeCommon =
1602 CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_DROPDOWN |
1603 CCA_PRINTABLE | CCA_SIZE | CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE;
1604 m_nIncludeSpecial = SCA_MULTIPLE;
1605 m_nIncludeDatabase = DA_BOUND_COLUMN | DA_DATA_FIELD | DA_INPUT_REQUIRED | DA_LIST_SOURCE_TYPE;
1606 m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE | EA_ON_CLICK | EA_ON_DBLCLICK;
1607 // check if we need to export the ListSource as attribute
1609 // for a list box, if the ListSourceType is VALUE_LIST, no ListSource is stored, but instead
1610 // a sequence of pairs which is build from the StringItemList and the ValueList
1611 ListSourceType eListSourceType = ListSourceType_VALUELIST;
1612 #if OSL_DEBUG_LEVEL > 0
1613 bool bSuccess =
1614 #endif
1615 m_xProps->getPropertyValue(PROPERTY_LISTSOURCETYPE) >>= eListSourceType;
1616 OSL_ENSURE(bSuccess, "OControlExport::examineControl: could not retrieve the ListSourceType!");
1617 if (ListSourceType_VALUELIST != eListSourceType)
1619 m_nIncludeDatabase |= DA_LIST_SOURCE;
1623 break;
1625 case FormComponentType::COMMANDBUTTON:
1626 m_eType = BUTTON;
1627 m_nIncludeCommon |= CCA_TAB_STOP | CCA_LABEL;
1628 m_nIncludeSpecial = SCA_DEFAULT_BUTTON | SCA_TOGGLE | SCA_FOCUS_ON_CLICK | SCA_IMAGE_POSITION | SCA_REPEAT_DELAY;
1629 // NO BREAK !
1630 case FormComponentType::IMAGEBUTTON:
1631 if (BUTTON != m_eType)
1633 // not coming from the previous case
1634 m_eType = IMAGE;
1636 m_nIncludeCommon |=
1637 CCA_NAME | CCA_SERVICE_NAME | CCA_BUTTON_TYPE | CCA_DISABLED |
1638 CCA_IMAGE_DATA | CCA_PRINTABLE | CCA_TAB_INDEX | CCA_TARGET_FRAME |
1639 CCA_TARGET_LOCATION | CCA_TITLE;
1640 m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CLICK | EA_ON_DBLCLICK;
1641 break;
1643 case FormComponentType::CHECKBOX:
1644 m_eType = CHECKBOX;
1645 m_nIncludeSpecial = SCA_CURRENT_STATE | SCA_IS_TRISTATE | SCA_STATE;
1646 // NO BREAK !
1647 case FormComponentType::RADIOBUTTON:
1648 m_nIncludeCommon =
1649 CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_LABEL | CCA_PRINTABLE |
1650 CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE | CCA_VALUE | CCA_VISUAL_EFFECT;
1651 if (CHECKBOX != m_eType)
1652 { // not coming from the previous case
1653 m_eType = RADIO;
1654 m_nIncludeCommon |= CCA_CURRENT_SELECTED | CCA_SELECTED;
1656 if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_IMAGE_POSITION ) )
1657 m_nIncludeSpecial |= SCA_IMAGE_POSITION;
1658 if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_GROUP_NAME ) )
1659 m_nIncludeSpecial |= SCA_GROUP_NAME;
1660 m_nIncludeDatabase = DA_DATA_FIELD | DA_INPUT_REQUIRED;
1661 m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE;
1662 break;
1664 case FormComponentType::GROUPBOX:
1665 m_eType = FRAME;
1666 m_nIncludeCommon =
1667 CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_LABEL |
1668 CCA_PRINTABLE | CCA_TITLE | CCA_FOR;
1669 m_nIncludeEvents = EA_CONTROL_EVENTS;
1670 break;
1672 case FormComponentType::IMAGECONTROL:
1673 m_eType = IMAGE_FRAME;
1674 m_nIncludeCommon =
1675 CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_IMAGE_DATA |
1676 CCA_PRINTABLE | CCA_READONLY | CCA_TITLE;
1677 m_nIncludeDatabase = DA_DATA_FIELD | DA_INPUT_REQUIRED;
1678 m_nIncludeEvents = EA_CONTROL_EVENTS;
1679 break;
1681 case FormComponentType::HIDDENCONTROL:
1682 m_eType = HIDDEN;
1683 m_nIncludeCommon =
1684 CCA_NAME | CCA_SERVICE_NAME | CCA_VALUE;
1685 break;
1687 case FormComponentType::GRIDCONTROL:
1688 m_eType = GRID;
1689 m_nIncludeCommon =
1690 CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_PRINTABLE |
1691 CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE;
1692 m_nIncludeEvents = EA_CONTROL_EVENTS;
1693 break;
1695 case FormComponentType::SCROLLBAR:
1696 case FormComponentType::SPINBUTTON:
1697 m_eType = VALUERANGE;
1698 m_nIncludeCommon =
1699 CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_PRINTABLE |
1700 CCA_TITLE | CCA_CURRENT_VALUE | CCA_VALUE | CCA_ORIENTATION;
1701 m_nIncludeSpecial = SCA_MAX_VALUE | SCA_STEP_SIZE | SCA_MIN_VALUE | SCA_REPEAT_DELAY;
1703 if ( m_nClassId == FormComponentType::SCROLLBAR )
1704 m_nIncludeSpecial |= SCA_PAGE_STEP_SIZE ;
1706 m_nIncludeEvents = EA_CONTROL_EVENTS;
1707 break;
1709 default:
1710 OSL_FAIL("OControlExport::examineControl: unknown control type (class id)!");
1711 // NO break!
1713 case FormComponentType::NAVIGATIONBAR:
1714 // TODO: should we have an own file format for this?
1715 // NO break
1717 case FormComponentType::CONTROL:
1718 m_eType = GENERIC_CONTROL;
1719 // unknown control type
1720 m_nIncludeCommon = CCA_NAME | CCA_SERVICE_NAME;
1721 // at least a name should be there, 'cause without a name the control could never have been
1722 // inserted into its parent container
1723 // In addition, the service name is absolutely necessary to create the control upon reading.
1724 m_nIncludeEvents = EA_CONTROL_EVENTS;
1725 // we always should be able to export events - this is not control type dependent
1726 break;
1729 // in general, all control types need to export the control id
1730 m_nIncludeCommon |= CCA_CONTROL_ID;
1732 // is it a control bound to a calc cell?
1733 if ( FormCellBindingHelper::livesInSpreadsheetDocument( m_xProps ) )
1735 FormCellBindingHelper aHelper( m_xProps, NULL );
1737 if ( FormCellBindingHelper::isCellBinding( aHelper.getCurrentBinding( ) ) )
1739 m_nIncludeBindings |= BA_LINKED_CELL;
1740 if ( m_nClassId == FormComponentType::LISTBOX )
1741 m_nIncludeBindings |= BA_LIST_LINKING_TYPE;
1745 // is it a list-like control which uses a calc cell range as list source?
1747 if ( FormCellBindingHelper::isCellRangeListSource( aHelper.getCurrentListSource( ) ) )
1748 m_nIncludeBindings |= BA_LIST_CELL_RANGE;
1752 // is control bound to XForms?
1753 if( !getXFormsBindName( m_xProps ).isEmpty() )
1755 m_nIncludeBindings |= BA_XFORMS_BIND;
1758 // is (list-)control bound to XForms list?
1759 if( !getXFormsListBindName( m_xProps ).isEmpty() )
1761 m_nIncludeBindings |= BA_XFORMS_LISTBIND;
1764 // does the control have an XForms submission?
1765 if( !getXFormsSubmissionName( m_xProps ).isEmpty() )
1767 m_nIncludeBindings |= BA_XFORMS_SUBMISSION;
1771 void OControlExport::exportCellBindingAttributes( bool _bIncludeListLinkageType )
1775 FormCellBindingHelper aHelper( m_xProps, NULL );
1776 Reference< XValueBinding > xBinding( aHelper.getCurrentBinding() );
1777 OSL_ENSURE( xBinding.is(), "OControlExport::exportCellBindingAttributes: invalid bindable or invalid binding!" );
1778 if ( xBinding.is() )
1780 AddAttribute(
1781 OAttributeMetaData::getBindingAttributeNamespace( BA_LINKED_CELL ),
1782 OAttributeMetaData::getBindingAttributeName( BA_LINKED_CELL ),
1783 aHelper.getStringAddressFromCellBinding( xBinding )
1786 if ( _bIncludeListLinkageType )
1788 sal_Int16 nLinkageType = FormCellBindingHelper::isCellIntegerBinding( xBinding ) ? 1 : 0;
1790 OUStringBuffer sBuffer;
1791 SvXMLUnitConverter::convertEnum(
1792 sBuffer,
1793 (sal_uInt16)nLinkageType,
1794 OEnumMapper::getEnumMap( OEnumMapper::epListLinkageType )
1797 AddAttribute(
1798 OAttributeMetaData::getBindingAttributeNamespace( BA_LIST_LINKING_TYPE ),
1799 OAttributeMetaData::getBindingAttributeName( BA_LIST_LINKING_TYPE ),
1800 sBuffer.makeStringAndClear()
1806 catch( const Exception& )
1808 OSL_FAIL( "OControlExport::exportCellBindingAttributes: caught an exception!" );
1809 DBG_UNHANDLED_EXCEPTION();
1813 void OControlExport::exportXFormsBindAttributes()
1815 OUString sBindName = getXFormsBindName( m_xProps );
1816 AddAttribute( XML_NAMESPACE_XFORMS, XML_BIND, sBindName );
1818 void OControlExport::exportXFormsListAttributes()
1820 OUString sBindName = getXFormsListBindName( m_xProps );
1821 AddAttribute( XML_NAMESPACE_FORM, XML_XFORMS_LIST_SOURCE, sBindName );
1823 void OControlExport::exportXFormsSubmissionAttributes()
1825 OUString sSubmission = getXFormsSubmissionName( m_xProps );
1826 AddAttribute( XML_NAMESPACE_FORM, XML_XFORMS_SUBMISSION, sSubmission );
1828 void OControlExport::exportCellListSourceRange( )
1832 Reference< XListEntrySink > xSink( m_xProps, UNO_QUERY );
1833 Reference< XListEntrySource > xSource;
1834 if ( xSink.is() )
1835 xSource.set(xSink->getListEntrySource(), css::uno::UNO_QUERY);
1836 OSL_ENSURE( xSource.is(), "OControlExport::exportCellListSourceRange: list source or sink!" );
1837 if ( xSource.is() )
1839 FormCellBindingHelper aHelper( m_xProps, NULL );
1841 AddAttribute(
1842 OAttributeMetaData::getBindingAttributeNamespace( BA_LIST_CELL_RANGE ),
1843 OAttributeMetaData::getBindingAttributeName( BA_LIST_CELL_RANGE ),
1844 aHelper.getStringAddressFromCellListSource( xSource )
1848 catch( const Exception& )
1850 OSL_FAIL( "OControlExport::exportCellListSourceRange: caught an exception!" );
1851 DBG_UNHANDLED_EXCEPTION();
1855 void OControlExport::exportImagePositionAttributes()
1859 sal_Int16 nImagePosition = ImagePosition::Centered;
1860 OSL_VERIFY( m_xProps->getPropertyValue( PROPERTY_IMAGE_POSITION ) >>= nImagePosition );
1861 OSL_ENSURE( ( nImagePosition >= ImagePosition::LeftTop ) && ( nImagePosition <= ImagePosition::Centered ),
1862 "OControlExport::exportImagePositionAttributes: don't know this image position!" );
1864 if ( ( nImagePosition < ImagePosition::LeftTop ) || ( nImagePosition > ImagePosition::Centered ) )
1865 // this is important to prevent potential buffer overflows below, so don't optimize
1866 nImagePosition = ImagePosition::Centered;
1868 if ( nImagePosition == ImagePosition::Centered )
1870 AddAttribute( XML_NAMESPACE_FORM, GetXMLToken( XML_IMAGE_POSITION ), GetXMLToken( XML_CENTER ) );
1872 else
1874 XMLTokenEnum eXmlImagePositions[] =
1876 XML_START, XML_END, XML_TOP, XML_BOTTOM
1878 XMLTokenEnum eXmlImageAligns[] =
1880 XML_START, XML_CENTER, XML_END
1883 XMLTokenEnum eXmlImagePosition = eXmlImagePositions[ nImagePosition / 3 ];
1884 XMLTokenEnum eXmlImageAlign = eXmlImageAligns [ nImagePosition % 3 ];
1886 AddAttribute( XML_NAMESPACE_FORM, GetXMLToken( XML_IMAGE_POSITION ), GetXMLToken( eXmlImagePosition ) );
1887 AddAttribute( XML_NAMESPACE_FORM, GetXMLToken( XML_IMAGE_ALIGN ), GetXMLToken( eXmlImageAlign ) );
1890 exportedProperty( PROPERTY_IMAGE_POSITION );
1891 // some of the controls which have an ImagePosition also have an ImageAlign for compatibility
1892 // reasons. Since the ImageAlign values simply represent a sub set of the ImagePosition values,
1893 // we don't need to export ImageAlign anymore
1894 exportedProperty( PROPERTY_IMAGE_ALIGN );
1896 catch( const Exception& )
1898 DBG_UNHANDLED_EXCEPTION();
1902 bool OControlExport::controlHasActiveDataBinding() const
1906 // currently exchanging the data with a database column?
1907 OUString sBoundFieldPropertyName( "BoundField" );
1908 if ( m_xPropertyInfo.is() && m_xPropertyInfo->hasPropertyByName( sBoundFieldPropertyName ) )
1910 Reference< XPropertySet > xBoundField;
1911 m_xProps->getPropertyValue( sBoundFieldPropertyName ) >>= xBoundField;
1912 if ( xBoundField.is() )
1913 return true;
1916 // currently exchanging data with an external binding?
1917 Reference< XBindableValue > xBindable( m_xProps, UNO_QUERY );
1918 if ( xBindable.is() && xBindable->getValueBinding().is() )
1919 return true;
1921 catch( const Exception& )
1923 OSL_FAIL( "OColumnExport::controlHasActiveDataBinding: caught an exception!" );
1924 DBG_UNHANDLED_EXCEPTION();
1927 return false;
1930 bool OControlExport::controlHasUserSuppliedListEntries() const
1934 // an external list source?
1935 Reference< XListEntrySink > xEntrySink( m_xProps, UNO_QUERY );
1936 if ( xEntrySink.is() && xEntrySink->getListEntrySource().is() )
1937 return false;
1939 if ( m_xPropertyInfo.is() && m_xPropertyInfo->hasPropertyByName( PROPERTY_LISTSOURCETYPE ) )
1941 ListSourceType eListSourceType = ListSourceType_VALUELIST;
1942 OSL_VERIFY( m_xProps->getPropertyValue( PROPERTY_LISTSOURCETYPE ) >>= eListSourceType );
1943 if ( eListSourceType == ListSourceType_VALUELIST )
1944 // for value lists, the list entries as entered by the user are used
1945 return true;
1947 // for every other type, the list entries are filled with some data obtained
1948 // from a database - if and only if the ListSource property is not empty
1949 return getScalarListSourceValue().isEmpty();
1952 catch( const Exception& )
1954 OSL_FAIL( "OControlExport::controlHasUserSuppliedListEntries: caught an exception!" );
1955 DBG_UNHANDLED_EXCEPTION();
1958 OSL_FAIL( "OControlExport::controlHasUserSuppliedListEntries: unreachable code!" );
1959 // this method should be called for list and combo boxes only
1960 return true;
1963 //= OColumnExport
1964 OColumnExport::OColumnExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxControl, const OUString& _rControlId,
1965 const Sequence< ScriptEventDescriptor >& _rEvents)
1966 :OControlExport(_rContext, _rxControl, _rControlId, OUString(), _rEvents)
1970 OColumnExport::~OColumnExport()
1972 implEndElement();
1975 void OColumnExport::exportServiceNameAttribute()
1977 // the attribute "service name" (which has a slightly different meaning for columns
1978 DBG_CHECK_PROPERTY( PROPERTY_COLUMNSERVICENAME, OUString );
1979 OUString sColumnServiceName;
1980 m_xProps->getPropertyValue(PROPERTY_COLUMNSERVICENAME) >>= sColumnServiceName;
1981 // the service name is a full qualified one (i.e. com.sun.star.form.TextField), but the
1982 // real service name for the column (for use with the XGridColumnFactory) is only the last
1983 // token of this complete name.
1984 sal_Int32 nLastSep = sColumnServiceName.lastIndexOf('.');
1985 OSL_ENSURE(-1 != nLastSep, "OColumnExport::startExportElement: invalid service name!");
1986 sColumnServiceName = sColumnServiceName.copy(nLastSep + 1);
1987 sColumnServiceName =
1988 m_rContext.getGlobalContext().GetNamespaceMap().GetQNameByKey(
1989 XML_NAMESPACE_OOO, sColumnServiceName );
1990 // add the attribute
1991 AddAttribute( OAttributeMetaData::getCommonControlAttributeNamespace(CCA_SERVICE_NAME)
1992 , OAttributeMetaData::getCommonControlAttributeName(CCA_SERVICE_NAME)
1993 , sColumnServiceName);
1994 // flag the property as "handled"
1995 exportedProperty(PROPERTY_COLUMNSERVICENAME);
1999 const sal_Char* OColumnExport::getOuterXMLElementName() const
2001 return "column";
2004 void OColumnExport::exportAttributes()
2006 OControlExport::exportAttributes();
2008 // the attribute "label"
2009 exportStringPropertyAttribute(
2010 OAttributeMetaData::getCommonControlAttributeNamespace(CCA_LABEL),
2011 OAttributeMetaData::getCommonControlAttributeName(CCA_LABEL),
2012 PROPERTY_LABEL);
2014 // the style attribute
2015 OUString sStyleName = m_rContext.getObjectStyleName( m_xProps );
2016 if ( !sStyleName.isEmpty() )
2018 AddAttribute(
2019 OAttributeMetaData::getSpecialAttributeNamespace( SCA_COLUMN_STYLE_NAME ),
2020 OAttributeMetaData::getSpecialAttributeName( SCA_COLUMN_STYLE_NAME ),
2021 sStyleName
2026 void OColumnExport::examine()
2028 OControlExport::examine();
2030 // grid columns miss some properties of the controls they're representing
2031 m_nIncludeCommon &= ~(CCA_FOR | CCA_PRINTABLE | CCA_TAB_INDEX | CCA_TAB_STOP | CCA_LABEL);
2032 m_nIncludeSpecial &= ~(SCA_ECHO_CHAR | SCA_AUTOMATIC_COMPLETION | SCA_MULTIPLE | SCA_MULTI_LINE);
2034 if (FormComponentType::DATEFIELD != m_nClassId)
2035 // except date fields, no column has the DropDown property
2036 m_nIncludeCommon &= ~CCA_DROPDOWN;
2039 //= OFormExport
2040 OFormExport::OFormExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxForm,
2041 const Sequence< ScriptEventDescriptor >& _rEvents)
2042 :OElementExport(_rContext, _rxForm, _rEvents)
2043 ,m_bCreateConnectionResourceElement(false)
2045 OSL_ENSURE(m_xProps.is(), "OFormExport::OFormExport: invalid arguments!");
2048 const sal_Char* OFormExport::getXMLElementName() const
2050 return "form";
2053 void OFormExport::exportSubTags()
2055 if ( m_bCreateConnectionResourceElement && m_xProps.is() )
2057 m_rContext.getGlobalContext().ClearAttrList();
2058 OUString sPropValue;
2059 m_xProps->getPropertyValue( PROPERTY_DATASOURCENAME ) >>= sPropValue; // if set it is a file url
2060 if ( sPropValue.isEmpty() )
2061 m_xProps->getPropertyValue( PROPERTY_URL ) >>= sPropValue;
2062 if ( !sPropValue.isEmpty() )
2063 AddAttribute(
2064 OAttributeMetaData::getCommonControlAttributeNamespace(CCA_TARGET_LOCATION),
2065 OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_LOCATION),
2066 sPropValue);
2067 if ( m_rContext.getGlobalContext().GetAttrList().getLength() )
2069 SvXMLElementExport aFormElement(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, xmloff::token::XML_CONNECTION_RESOURCE, true, true);
2073 // let the base class export the remaining properties and the events
2074 OElementExport::exportSubTags();
2075 // loop through all children
2076 Reference< XIndexAccess > xCollection(m_xProps, UNO_QUERY);
2077 OSL_ENSURE(xCollection.is(), "OFormLayerXMLExport::implExportForm: a form which is not an index access? Suspicious!");
2079 if (xCollection.is())
2080 m_rContext.exportCollectionElements(xCollection);
2083 void OFormExport::exportAttributes()
2085 sal_Int32 i=0;
2087 // the string properties
2089 static const FormAttributes eStringPropertyIds[] =
2091 faName, /*faAction,*/ faCommand, faFilter, faOrder
2093 static const char * aStringPropertyNames[] =
2095 PROPERTY_NAME, /*PROPERTY_TARGETURL,*/ PROPERTY_COMMAND, PROPERTY_FILTER, PROPERTY_ORDER
2097 static const sal_Int32 nIdCount = sizeof(eStringPropertyIds) / sizeof(eStringPropertyIds[0]);
2098 #if OSL_DEBUG_LEVEL > 0
2099 static const sal_Int32 nNameCount = sizeof(aStringPropertyNames) / sizeof(aStringPropertyNames[0]);
2100 OSL_ENSURE((nIdCount == nNameCount),
2101 "OFormExport::exportAttributes: somebody tampered with the maps (1)!");
2102 #endif
2103 for (i=0; i<nIdCount; ++i)
2104 exportStringPropertyAttribute(
2105 OAttributeMetaData::getFormAttributeNamespace(eStringPropertyIds[i]),
2106 OAttributeMetaData::getFormAttributeName(eStringPropertyIds[i]),
2107 OUString::createFromAscii(aStringPropertyNames[i]));
2109 // #i112082# xlink:type is added as part of exportTargetLocationAttribute
2111 // now export the data source name or databaselocation or connection resource
2112 OUString sPropValue;
2113 m_xProps->getPropertyValue( PROPERTY_DATASOURCENAME ) >>= sPropValue;
2114 m_bCreateConnectionResourceElement = sPropValue.isEmpty();
2115 if ( !m_bCreateConnectionResourceElement )
2117 INetURLObject aURL(sPropValue);
2118 m_bCreateConnectionResourceElement = ( aURL.GetProtocol() == INetProtocol::File );
2119 if ( !m_bCreateConnectionResourceElement )
2120 exportStringPropertyAttribute(
2121 OAttributeMetaData::getFormAttributeNamespace(faDatasource),
2122 OAttributeMetaData::getFormAttributeName(faDatasource),
2123 PROPERTY_DATASOURCENAME);
2125 else
2126 exportedProperty(PROPERTY_URL);
2127 if ( m_bCreateConnectionResourceElement )
2128 exportedProperty(PROPERTY_DATASOURCENAME);
2131 // the boolean properties
2133 static const FormAttributes eBooleanPropertyIds[] =
2135 faAllowDeletes, faAllowInserts, faAllowUpdates, faApplyFilter, faEscapeProcessing, faIgnoreResult
2137 static const char * pBooleanPropertyNames[] =
2139 PROPERTY_ALLOWDELETES,
2140 PROPERTY_ALLOWINSERTS,
2141 PROPERTY_ALLOWUPDATES,
2142 PROPERTY_APPLYFILTER,
2143 PROPERTY_ESCAPEPROCESSING,
2144 PROPERTY_IGNORERESULT
2146 static const sal_Int8 nBooleanPropertyAttrFlags[] =
2148 BOOLATTR_DEFAULT_TRUE, BOOLATTR_DEFAULT_TRUE, BOOLATTR_DEFAULT_TRUE, BOOLATTR_DEFAULT_FALSE, BOOLATTR_DEFAULT_TRUE, BOOLATTR_DEFAULT_FALSE
2150 static const sal_Int32 nIdCount = sizeof(eBooleanPropertyIds) / sizeof(eBooleanPropertyIds[0]);
2151 #if OSL_DEBUG_LEVEL > 0
2152 static const sal_Int32 nNameCount = sizeof(pBooleanPropertyNames) / sizeof(pBooleanPropertyNames[0]);
2153 static const sal_Int32 nFlagsCount = sizeof(nBooleanPropertyAttrFlags) / sizeof(nBooleanPropertyAttrFlags[0]);
2154 OSL_ENSURE((nIdCount == nNameCount) && (nNameCount == nFlagsCount),
2155 "OFormExport::exportAttributes: somebody tampered with the maps (2)!");
2156 #endif
2157 for (i=0; i<nIdCount; ++i)
2158 exportBooleanPropertyAttribute(
2159 OAttributeMetaData::getFormAttributeNamespace(eBooleanPropertyIds[i]),
2160 OAttributeMetaData::getFormAttributeName(eBooleanPropertyIds[i]),
2161 OUString::createFromAscii(pBooleanPropertyNames[i]),
2162 nBooleanPropertyAttrFlags[i]
2166 // the enum properties
2168 static const FormAttributes eEnumPropertyIds[] =
2170 faEnctype, faMethod, faCommandType, faNavigationMode, faTabbingCycle
2172 static const char * pEnumPropertyNames[] =
2174 PROPERTY_SUBMIT_ENCODING, PROPERTY_SUBMIT_METHOD, PROPERTY_COMMAND_TYPE, PROPERTY_NAVIGATION, PROPERTY_CYCLE
2176 static const OEnumMapper::EnumProperties eEnumPropertyMaps[] =
2178 OEnumMapper::epSubmitEncoding, OEnumMapper::epSubmitMethod, OEnumMapper::epCommandType, OEnumMapper::epNavigationType, OEnumMapper::epTabCyle
2180 static const sal_Int32 nEnumPropertyAttrDefaults[] =
2182 FormSubmitEncoding_URL, FormSubmitMethod_GET, CommandType::COMMAND, NavigationBarMode_CURRENT, TabulatorCycle_RECORDS
2184 static const sal_Bool nEnumPropertyAttrDefaultFlags[] =
2186 sal_False, sal_False, sal_False, sal_False, sal_True
2188 static const sal_Int32 nIdCount = sizeof(eEnumPropertyIds) / sizeof(eEnumPropertyIds[0]);
2189 #if OSL_DEBUG_LEVEL > 0
2190 static const sal_Int32 nNameCount = sizeof(pEnumPropertyNames) / sizeof(pEnumPropertyNames[0]);
2191 static const sal_Int32 nDefaultCount = sizeof(nEnumPropertyAttrDefaults) / sizeof(nEnumPropertyAttrDefaults[0]);
2192 static const sal_Int32 nDefaultFlagCount = sizeof(nEnumPropertyAttrDefaultFlags) / sizeof(nEnumPropertyAttrDefaultFlags[0]);
2193 static const sal_Int32 nMapCount = sizeof(eEnumPropertyMaps) / sizeof(eEnumPropertyMaps[0]);
2194 OSL_ENSURE((nIdCount == nNameCount) && (nNameCount == nDefaultCount) && (nDefaultCount == nDefaultFlagCount) && (nDefaultFlagCount == nMapCount),
2195 "OFormExport::exportAttributes: somebody tampered with the maps (3)!");
2196 #endif
2197 for (i=0; i<nIdCount; ++i)
2198 exportEnumPropertyAttribute(
2199 OAttributeMetaData::getFormAttributeNamespace(eEnumPropertyIds[i]),
2200 OAttributeMetaData::getFormAttributeName(eEnumPropertyIds[i]),
2201 OUString::createFromAscii(pEnumPropertyNames[i]),
2202 OEnumMapper::getEnumMap(eEnumPropertyMaps[i]),
2203 nEnumPropertyAttrDefaults[i],
2204 nEnumPropertyAttrDefaultFlags[i]
2208 // the service name
2209 exportServiceNameAttribute();
2210 // the target frame
2211 exportTargetFrameAttribute();
2212 // the target URL
2213 exportTargetLocationAttribute(true); // #i110911# add type attribute (for form, but not for control)
2215 // master fields
2216 exportStringSequenceAttribute(
2217 OAttributeMetaData::getFormAttributeNamespace(faMasterFields),
2218 OAttributeMetaData::getFormAttributeName(faMasterFields),
2219 PROPERTY_MASTERFIELDS);
2220 // detail fields
2221 exportStringSequenceAttribute(
2222 OAttributeMetaData::getFormAttributeNamespace(faDetailFiels),
2223 OAttributeMetaData::getFormAttributeName(faDetailFiels),
2224 PROPERTY_DETAILFIELDS);
2226 } // namespace xmloff
2228 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */