xref: /trunk/main/xmloff/source/forms/elementexport.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmloff.hxx"
30 
31 #include "elementexport.hxx"
32 #include "strings.hxx"
33 #include "xmloff/xmlnmspe.hxx"
34 #include "eventexport.hxx"
35 #include "formenums.hxx"
36 #include "formcellbinding.hxx"
37 #include "formcellbinding.hxx"
38 #include "xmloff/xformsexport.hxx"
39 #include "property_meta_data.hxx"
40 
41 /** === begin UNO includes === **/
42 #include <com/sun/star/text/XText.hpp>
43 #include <com/sun/star/lang/XServiceInfo.hpp>
44 #include <com/sun/star/io/XPersistObject.hpp>
45 #include <com/sun/star/form/FormComponentType.hpp>
46 #include <com/sun/star/beans/PropertyAttribute.hpp>
47 #include <com/sun/star/form/FormSubmitEncoding.hpp>
48 #include <com/sun/star/form/FormSubmitMethod.hpp>
49 #include <com/sun/star/sdb/CommandType.hpp>
50 #include <com/sun/star/form/NavigationBarMode.hpp>
51 #include <com/sun/star/form/TabulatorCycle.hpp>
52 #include <com/sun/star/form/FormButtonType.hpp>
53 #include <com/sun/star/awt/ScrollBarOrientation.hpp>
54 #include <com/sun/star/awt/VisualEffect.hpp>
55 #include <com/sun/star/form/ListSourceType.hpp>
56 #include <com/sun/star/awt/ImagePosition.hpp>
57 /** === end UNO includes === **/
58 
59 #include <tools/wintypes.hxx>       // for check states
60 #include <xmloff/txtprmap.hxx>
61 #include <com/sun/star/form/binding/XBindableValue.hpp>
62 #include <com/sun/star/form/binding/XListEntrySink.hpp>
63 #include <tools/urlobj.hxx>
64 #include <xmloff/xmlexp.hxx>
65 #include <xmloff/nmspmap.hxx>
66 #include <xmloff/XMLEventExport.hxx>
67 #include <xmloff/xmluconv.hxx>
68 #include <xmloff/xmltoken.hxx>
69 #include <tools/time.hxx>
70 #include <tools/diagnose_ex.h>
71 #include <comphelper/extract.hxx>
72 
73 #include <stdio.h>
74 #include <algorithm>
75 
76 //.........................................................................
77 namespace xmloff
78 {
79 //.........................................................................
80 
81     #if OSL_DEBUG_LEVEL > 0
82         #define RESET_BIT( bitfield, bit ) \
83             bitfield = bitfield & ~bit
84     #else
85         #define RESET_BIT( bitfield, bit )
86     #endif
87 
88     using namespace ::xmloff::token;
89     using namespace ::com::sun::star::uno;
90     using namespace ::com::sun::star::sdb;
91     using namespace ::com::sun::star::awt;
92     using namespace ::com::sun::star::form;
93     using namespace ::com::sun::star::lang;
94     using namespace ::com::sun::star::lang;
95     using namespace ::com::sun::star::beans;
96     using namespace ::com::sun::star::container;
97     using namespace ::com::sun::star::script;
98     using namespace ::com::sun::star::io;
99     using namespace ::com::sun::star::table;
100     using namespace ::com::sun::star::text;
101     using namespace ::com::sun::star::form::binding;
102 
103     //=====================================================================
104     //= OElementExport
105     //=====================================================================
106     OElementExport::OElementExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxProps,
107         const Sequence< ScriptEventDescriptor >& _rEvents)
108         :OPropertyExport(_rContext, _rxProps)
109         ,m_aEvents(_rEvents)
110         ,m_pXMLElement(NULL)
111     {
112     }
113 
114     //---------------------------------------------------------------------
115     OElementExport::~OElementExport()
116     {
117         implEndElement();
118     }
119 
120     //---------------------------------------------------------------------
121     void OElementExport::doExport()
122     {
123         // collect some general information about the element
124         examine();
125 
126         // first add the attributes necessary for the element
127         m_rContext.getGlobalContext().ClearAttrList();
128 
129         // add the attributes
130         exportAttributes();
131 
132         // start the XML element
133         implStartElement(getXMLElementName());
134 
135         // the sub elements (mostly control type dependent)
136         exportSubTags();
137 
138         implEndElement();
139     }
140 
141     //---------------------------------------------------------------------
142     void OElementExport::examine()
143     {
144         // nothing to do here
145     }
146 
147     //---------------------------------------------------------------------
148     void OElementExport::exportAttributes()
149     {
150         // nothing to do here
151     }
152 
153     //---------------------------------------------------------------------
154     void OElementExport::exportSubTags()
155     {
156         // the properties which where not exported 'til now
157         exportRemainingProperties();
158 
159         // the script:events sub tags
160         exportEvents();
161     }
162 
163     //---------------------------------------------------------------------
164     void OElementExport::implStartElement(const sal_Char* _pName)
165     {
166         m_pXMLElement = new SvXMLElementExport(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, _pName, sal_True, sal_True);
167     }
168 
169     //---------------------------------------------------------------------
170     void OElementExport::implEndElement()
171     {
172         delete m_pXMLElement;
173         m_pXMLElement = NULL;
174     }
175 
176     //---------------------------------------------------------------------
177     void OElementExport::exportServiceNameAttribute()
178     {
179         Reference< XPersistObject > xPersistence(m_xProps, UNO_QUERY);
180         if (!xPersistence.is())
181         {
182             OSL_ENSURE(sal_False, "OElementExport::exportServiceNameAttribute: no XPersistObject!");
183             return;
184         }
185 
186         ::rtl::OUString sServiceName = xPersistence->getServiceName();
187         // we don't want to write the old service name directly: it's a name used for compatibility reasons, but
188         // as we start some kind of new file format here (with this xml export), we don't care about
189         // compatibility ...
190         // So we translate the old persistence service name into new ones, if possible
191 
192         ::rtl::OUString sToWriteServiceName = sServiceName;
193 #define CHECK_N_TRANSLATE( name )   \
194         else if (0 == sServiceName.compareToAscii(SERVICE_PERSISTENT_COMPONENT_##name)) \
195             sToWriteServiceName = SERVICE_##name
196 
197         if (sal_False)
198             ;
199         CHECK_N_TRANSLATE( FORM );
200         CHECK_N_TRANSLATE( FORM );
201         CHECK_N_TRANSLATE( LISTBOX );
202         CHECK_N_TRANSLATE( COMBOBOX );
203         CHECK_N_TRANSLATE( RADIOBUTTON );
204         CHECK_N_TRANSLATE( GROUPBOX );
205         CHECK_N_TRANSLATE( FIXEDTEXT );
206         CHECK_N_TRANSLATE( COMMANDBUTTON );
207         CHECK_N_TRANSLATE( CHECKBOX );
208         CHECK_N_TRANSLATE( GRID );
209         CHECK_N_TRANSLATE( IMAGEBUTTON );
210         CHECK_N_TRANSLATE( FILECONTROL );
211         CHECK_N_TRANSLATE( TIMEFIELD );
212         CHECK_N_TRANSLATE( DATEFIELD );
213         CHECK_N_TRANSLATE( NUMERICFIELD );
214         CHECK_N_TRANSLATE( CURRENCYFIELD );
215         CHECK_N_TRANSLATE( PATTERNFIELD );
216         CHECK_N_TRANSLATE( HIDDENCONTROL );
217         CHECK_N_TRANSLATE( IMAGECONTROL );
218         CHECK_N_TRANSLATE( FORMATTEDFIELD );
219         else if (0 == sServiceName.compareToAscii(SERVICE_PERSISTENT_COMPONENT_EDIT))
220         {   // special handling for the edit field: we have two controls using this as persistence service name
221             sToWriteServiceName = SERVICE_EDIT;
222             Reference< XServiceInfo > xSI(m_xProps, UNO_QUERY);
223             if (xSI.is() && xSI->supportsService(SERVICE_FORMATTEDFIELD))
224                 sToWriteServiceName = SERVICE_FORMATTEDFIELD;
225         }
226 #if OSL_DEBUG_LEVEL > 0
227         Reference< XServiceInfo > xSI(m_xProps, UNO_QUERY);
228         OSL_ENSURE(xSI.is() && xSI->supportsService(sToWriteServiceName),
229             "OElementExport::exportServiceNameAttribute: wrong service name translation!");
230 
231 #endif
232         sToWriteServiceName =
233             m_rContext.getGlobalContext().GetNamespaceMap().GetQNameByKey(
234                 XML_NAMESPACE_OOO, sToWriteServiceName );
235 
236         // now write this
237         AddAttribute(
238             OAttributeMetaData::getCommonControlAttributeNamespace(CCA_SERVICE_NAME),
239             OAttributeMetaData::getCommonControlAttributeName(CCA_SERVICE_NAME),
240             sToWriteServiceName);
241     }
242 
243     //---------------------------------------------------------------------
244     void OElementExport::exportEvents()
245     {
246         if (!m_aEvents.getLength())
247             // nothing to do
248             return;
249 
250         Reference< XNameReplace > xWrapper = new OEventDescriptorMapper(m_aEvents);
251         m_rContext.getGlobalContext().GetEventExport().Export(xWrapper);
252     }
253 
254     //=====================================================================
255     //= OControlExport
256     //=====================================================================
257     //---------------------------------------------------------------------
258     OControlExport::OControlExport(IFormsExportContext& _rContext,  const Reference< XPropertySet >& _rxControl,
259         const ::rtl::OUString& _rControlId, const ::rtl::OUString& _rReferringControls,
260         const Sequence< ScriptEventDescriptor >& _rEvents)
261         :OElementExport(_rContext, _rxControl, _rEvents)
262         ,m_sControlId(_rControlId)
263         ,m_sReferringControls(_rReferringControls)
264         ,m_nClassId(FormComponentType::CONTROL)
265         ,m_eType( UNKNOWN )
266         ,m_nIncludeCommon(0)
267         ,m_nIncludeDatabase(0)
268         ,m_nIncludeSpecial(0)
269         ,m_nIncludeEvents(0)
270         ,m_nIncludeBindings(0)
271         ,m_pOuterElement(NULL)
272     {
273         OSL_ENSURE(m_xProps.is(), "OControlExport::OControlExport: invalid arguments!");
274     }
275 
276     //---------------------------------------------------------------------
277     OControlExport::~OControlExport()
278     {
279         implEndElement();
280     }
281 
282     //---------------------------------------------------------------------
283     void OControlExport::exportOuterAttributes()
284     {
285         // the control id
286         if (CCA_NAME & m_nIncludeCommon)
287         {
288             exportStringPropertyAttribute(
289                 OAttributeMetaData::getCommonControlAttributeNamespace(CCA_NAME),
290                 OAttributeMetaData::getCommonControlAttributeName(CCA_NAME),
291                 PROPERTY_NAME
292                 );
293         #if OSL_DEBUG_LEVEL > 0
294             //  reset the bit for later checking
295             m_nIncludeCommon = m_nIncludeCommon & ~CCA_NAME;
296         #endif
297         }
298 
299         // the service name
300         if (m_nIncludeCommon & CCA_SERVICE_NAME)
301         {
302             exportServiceNameAttribute();
303         #if OSL_DEBUG_LEVEL > 0
304             //  reset the bit for later checking
305             m_nIncludeCommon = m_nIncludeCommon & ~CCA_SERVICE_NAME;
306         #endif
307         }
308     }
309 
310     //---------------------------------------------------------------------
311     void OControlExport::exportInnerAttributes()
312     {
313         // the control id
314         if (CCA_CONTROL_ID & m_nIncludeCommon)
315         {
316             OSL_ENSURE(m_sControlId.getLength(), "OControlExport::exportInnerAttributes: have no control id for the control!");
317             m_rContext.getGlobalContext().AddAttributeIdLegacy(
318                 XML_NAMESPACE_FORM, m_sControlId);
319         #if OSL_DEBUG_LEVEL > 0
320             //  reset the bit for later checking
321             m_nIncludeCommon = m_nIncludeCommon & ~CCA_CONTROL_ID;
322         #endif
323         }
324 
325         // "new-style" properties ...
326         exportGenericHandlerAttributes();
327 
328         // common control attributes
329         exportCommonControlAttributes();
330 
331         // common database attributes
332         exportDatabaseAttributes();
333 
334         // attributes related to external bindings
335         exportBindingAtributes();
336 
337         // attributes special to the respective control type
338         exportSpecialAttributes();
339 
340         // add the style references to the attributes
341         flagStyleProperties();
342     }
343 
344     //---------------------------------------------------------------------
345     void OControlExport::exportAttributes()
346     {
347         exportOuterAttributes();
348     }
349 
350     //---------------------------------------------------------------------
351     void OControlExport::exportSubTags() throw (Exception)
352     {
353         // for the upcoming exportRemainingProperties:
354         // if a control has the LabelControl property, this is not stored with the control itself, but instead with
355         // the control which is referenced by this property. As the base class' exportRemainingProperties doesn't
356         // know anything about this, we need to prevent that it tries to export this property
357         exportedProperty(PROPERTY_CONTROLLABEL);
358 
359         // if it's a control supporting XText, then we need to declare all text-related properties
360         // as "already exported". This prevents them from being exported as generic "form:property"-tags.
361         // *If* we would export them this way, they would be completely superfluous, and sometimes even
362         // disastrous, since they may, at import time, override paragraph properties which already have
363         // been set before
364         Reference< XText > xControlText( m_xProps, UNO_QUERY );
365         if ( xControlText.is() )
366         {
367             const XMLPropertyMapEntry* pCharAttributeProperties = XMLTextPropertySetMapper::getPropertyMapForType( TEXT_PROP_MAP_TEXT );
368             while ( pCharAttributeProperties->msApiName )
369             {
370                 exportedProperty( ::rtl::OUString::createFromAscii( pCharAttributeProperties->msApiName ) );
371                 ++pCharAttributeProperties;
372             }
373 
374             const XMLPropertyMapEntry* pParaAttributeProperties = XMLTextPropertySetMapper::getPropertyMapForType( TEXT_PROP_MAP_SHAPE_PARA );
375             while ( pParaAttributeProperties->msApiName )
376             {
377                 exportedProperty( ::rtl::OUString::createFromAscii( pParaAttributeProperties->msApiName ) );
378                 ++pParaAttributeProperties;
379             }
380 
381             // the RichText property is not exported. The presence of the text:p element
382             // will be used - upon reading - as indicator for the value of the RichText property
383             exportedProperty( PROPERTY_RICH_TEXT );
384 
385             // strange thing: paragraphs support both a CharStrikeout and a CharCrossedOut property
386             // The former is a short/enum value, the latter a boolean. The former has a real meaning
387             // (the strikeout type), the latter hasn't. But, when the CharCrossedOut is exported and
388             // later on imported, it overwrites anything which has previously been imported for
389             // CharStrikeout.
390             // 2004-04-14 - #i27729# - fs@openoffice.org
391             exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharCrossedOut" ) ) );
392         }
393 
394         if ( m_eType == LISTBOX )
395         {
396             // will be exported in exportListSourceAsElements:
397             if ( controlHasUserSuppliedListEntries() )
398                 exportedProperty( PROPERTY_DEFAULT_SELECT_SEQ );
399 
400             // will not be exported in a generic way. Either exportListSourceAsElements cares
401             // for them, or we don't need them
402             exportedProperty( PROPERTY_STRING_ITEM_LIST );
403             exportedProperty( PROPERTY_VALUE_SEQ );
404             exportedProperty( PROPERTY_SELECT_SEQ );
405             exportedProperty( PROPERTY_LISTSOURCE );
406         }
407         if ( m_eType == COMBOBOX )
408             exportedProperty( PROPERTY_STRING_ITEM_LIST );
409 
410         // let the base class export the remaining properties and the events
411         OElementExport::exportSubTags();
412 
413         // special sub tags for some controls
414         switch (m_eType)
415         {
416             case LISTBOX:
417                 // don't export the list entries if the are not provided by the user, but obtained implicitly
418                 // from other sources
419                 // #i26944# - 2004-05-17 - fs@openoffice.org
420                 if ( controlHasUserSuppliedListEntries() )
421                     exportListSourceAsElements();
422                 break;
423             case GRID:
424             {   // a grid control requires us to store all columns as sub elements
425                 Reference< XIndexAccess > xColumnContainer(m_xProps, UNO_QUERY);
426                 OSL_ENSURE(xColumnContainer.is(), "OControlExport::exportSubTags: a grid control which is no IndexAccess?!!");
427                 if (xColumnContainer.is())
428                     m_rContext.exportCollectionElements(xColumnContainer);
429             }
430             break;
431             case COMBOBOX:
432             {   // a combox box description has sub elements: the items
433                 DBG_CHECK_PROPERTY( PROPERTY_STRING_ITEM_LIST, Sequence< ::rtl::OUString > );
434 
435                 // don't export the list entries if the are not provided by the user, but obtained implicitly
436                 // from other sources
437                 // #i26944# - 2004-05-17 - fs@openoffice.org
438                 if ( controlHasUserSuppliedListEntries() )
439                 {
440                     // get the item list
441                     Sequence< ::rtl::OUString > aListItems;
442                     m_xProps->getPropertyValue(PROPERTY_STRING_ITEM_LIST) >>= aListItems;
443                     // loop through it and write the sub elements
444                     const ::rtl::OUString* pListItems = aListItems.getConstArray();
445                     for (sal_Int32 i=0; i<aListItems.getLength(); ++i, ++pListItems)
446                     {
447                         m_rContext.getGlobalContext().ClearAttrList();
448                         AddAttribute(
449                             OAttributeMetaData::getCommonControlAttributeNamespace(CCA_LABEL),
450                             OAttributeMetaData::getCommonControlAttributeName(CCA_LABEL),
451                             *pListItems);
452                         SvXMLElementExport aFormElement(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, "item", sal_True, sal_True);
453                     }
454                 }
455             }
456             break;
457 
458             case TEXT_AREA:
459             {
460                 // if we act as rich text control, we need to export some text:p elements
461                 if ( xControlText.is() )
462                 {
463                     sal_Bool bActingAsRichText = sal_False;
464                     if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_RICH_TEXT ) )
465                     {
466                         OSL_VERIFY(m_xProps->getPropertyValue( PROPERTY_RICH_TEXT ) >>= bActingAsRichText );
467                     }
468 
469                     if ( bActingAsRichText )
470                         m_rContext.getGlobalContext().GetTextParagraphExport()->exportText( xControlText );
471                 }
472             }
473             break;
474             default:
475                 // nothing do to
476                 break;
477         }
478     }
479 
480     //---------------------------------------------------------------------
481     void OControlExport::exportGenericHandlerAttributes()
482     {
483         const Sequence< Property > aProperties = m_xPropertyInfo->getProperties();
484         for (   const Property* prop = aProperties.getConstArray();
485                 prop != aProperties.getConstArray() + aProperties.getLength();
486                 ++prop
487             )
488         {
489             try
490             {
491                 // see if this property can already be handled with an IPropertyHandler (which, on the long
492                 // term, should be the case for most, if not all, properties)
493                 const PropertyDescription* propDescription = metadata::getPropertyDescription( prop->Name );
494                 if ( propDescription == NULL )
495                     continue;
496 
497                 // let the factory provide the concrete handler. Note that caching, if desired, is the task
498                 // of the factory
499                 PPropertyHandler handler = (*propDescription->factory)( propDescription->propertyId );
500                 ENSURE_OR_CONTINUE( handler.get() != NULL,
501                     "OControlExport::exportGenericHandlerAttributes: invalid property handler provided by the factory!" );
502 
503                 ::rtl::OUString attributeValue;
504                 if ( propDescription->propertyGroup == NO_GROUP )
505                 {
506                     // that's a property which has a direct mapping to an attribute
507                     if ( !shouldExportProperty( prop->Name ) )
508                         // TODO: in the future, we surely need a more sophisticated approach to this, involving the property
509                         // handler, or the property description
510                     {
511                         exportedProperty( prop->Name );
512                         continue;
513                     }
514 
515                     const Any propValue = m_xProps->getPropertyValue( prop->Name );
516                     attributeValue = handler->getAttributeValue( propValue );
517                 }
518                 else
519                 {
520                     // that's a property which is part of a group of properties, whose values, in their entity, comprise
521                     // a single attribute value
522 
523                     // retrieve the descriptions of all other properties which add to the attribute value
524                     PropertyDescriptionList descriptions;
525                     metadata::getPropertyGroup( propDescription->propertyGroup, descriptions );
526 
527                     // retrieve the values for all those properties
528                     PropertyValues aValues;
529                     for (   PropertyDescriptionList::iterator desc = descriptions.begin();
530                             desc != descriptions.end();
531                             ++desc
532                         )
533                     {
534                         // TODO: XMultiPropertySet?
535                         const Any propValue = m_xProps->getPropertyValue( (*desc)->propertyName );
536                         aValues[ (*desc)->propertyId ] = propValue;
537                     }
538 
539                     // let the handler translate into an XML attribute value
540                     attributeValue = handler->getAttributeValue( aValues );
541                 }
542 
543                 AddAttribute(
544                     propDescription->attribute.namespacePrefix,
545                     token::GetXMLToken( propDescription->attribute.attributeToken ),
546                     attributeValue
547                 );
548 
549                 exportedProperty( prop->Name );
550             }
551             catch( const Exception& )
552             {
553                 DBG_UNHANDLED_EXCEPTION();
554             }
555         }
556     }
557 
558     //---------------------------------------------------------------------
559     void OControlExport::exportCommonControlAttributes()
560     {
561         size_t i=0;
562 
563         // I decided to handle all the properties here with some static arrays describing the property-attribute
564         // relations. This leads to somewhat ugly code :), but the only alternative I can think of right now
565         // would require maps and O(log n) searches, which seems somewhat expensive as this code is used
566         // very frequently.
567 
568         // the extra indents for the respective blocks are to ensure that there is no copy'n'paste error, using
569         // map identifiers from the wrong block
570 
571         // --------------------------------------------------------------------
572         // some string properties
573         {
574             // the attribute ids of all properties which are expected to be of type string
575             static sal_Int32 nStringPropertyAttributeIds[] =
576             {
577                 CCA_LABEL, CCA_TITLE
578             };
579             // the names of all properties which are expected to be of type string
580             static ::rtl::OUString aStringPropertyNames[] =
581             {
582                 PROPERTY_LABEL, PROPERTY_TITLE
583             };
584             OSL_ENSURE( sizeof(aStringPropertyNames)/sizeof(aStringPropertyNames[0]) ==
585                         sizeof(nStringPropertyAttributeIds)/sizeof(nStringPropertyAttributeIds[0]),
586                         "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (1)!");
587 
588             for (i=0; i<sizeof(nStringPropertyAttributeIds)/sizeof(nStringPropertyAttributeIds[0]); ++i)
589                 if (nStringPropertyAttributeIds[i] & m_nIncludeCommon)
590                 {
591                     exportStringPropertyAttribute(
592                         OAttributeMetaData::getCommonControlAttributeNamespace(nStringPropertyAttributeIds[i]),
593                         OAttributeMetaData::getCommonControlAttributeName(nStringPropertyAttributeIds[i]),
594                         aStringPropertyNames[i]
595                         );
596                 #if OSL_DEBUG_LEVEL > 0
597                     //  reset the bit for later checking
598                     m_nIncludeCommon = m_nIncludeCommon & ~nStringPropertyAttributeIds[i];
599                 #endif
600                 }
601         }
602 
603         // --------------------------------------------------------------------
604         // some boolean properties
605         {
606             static sal_Int32 nBooleanPropertyAttributeIds[] =
607             {   // attribute flags
608                 CCA_CURRENT_SELECTED, CCA_DISABLED, CCA_DROPDOWN, CCA_PRINTABLE, CCA_READONLY, CCA_SELECTED, CCA_TAB_STOP, CCA_ENABLEVISIBLE
609             };
610             static const ::rtl::OUString* pBooleanPropertyNames[] =
611             {   // property names
612                 &PROPERTY_STATE, &PROPERTY_ENABLED, &PROPERTY_DROPDOWN, &PROPERTY_PRINTABLE, &PROPERTY_READONLY, &PROPERTY_DEFAULT_STATE, &PROPERTY_TABSTOP, &PROPERTY_ENABLEVISIBLE
613             };
614             static sal_Bool nBooleanPropertyAttrFlags[] =
615             {   // attribute defaults
616                 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
617             };
618         #if OSL_DEBUG_LEVEL > 0
619             sal_Int32 nIdCount = sizeof(nBooleanPropertyAttributeIds) / sizeof(nBooleanPropertyAttributeIds[0]);
620             sal_Int32 nNameCount = sizeof(pBooleanPropertyNames) / sizeof(pBooleanPropertyNames[0]);
621             sal_Int32 nFlagsCount = sizeof(nBooleanPropertyAttrFlags) / sizeof(nBooleanPropertyAttrFlags[0]);
622             OSL_ENSURE((nIdCount == nNameCount) && (nNameCount == nFlagsCount),
623                 "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (2)!");
624         #endif
625             for (i=0; i<sizeof(nBooleanPropertyAttributeIds)/sizeof(nBooleanPropertyAttributeIds[0]); ++i)
626                 if (nBooleanPropertyAttributeIds[i] & m_nIncludeCommon)
627                 {
628                     exportBooleanPropertyAttribute(
629                         OAttributeMetaData::getCommonControlAttributeNamespace(nBooleanPropertyAttributeIds[i]),
630                         OAttributeMetaData::getCommonControlAttributeName(nBooleanPropertyAttributeIds[i]),
631                         *(pBooleanPropertyNames[i]),
632                         nBooleanPropertyAttrFlags[i]);
633         #if OSL_DEBUG_LEVEL > 0
634                     //  reset the bit for later checking
635                     m_nIncludeCommon = m_nIncludeCommon & ~nBooleanPropertyAttributeIds[i];
636         #endif
637                 }
638         }
639 
640 
641         // --------------------------------------------------------------------
642         // some integer properties
643         {
644             // now the common handling
645             static sal_Int32 nIntegerPropertyAttributeIds[] =
646             {   // attribute flags
647                 CCA_SIZE, CCA_TAB_INDEX
648             };
649             static const ::rtl::OUString* pIntegerPropertyNames[] =
650             {   // property names
651                 &PROPERTY_LINECOUNT, &PROPERTY_TABINDEX
652             };
653             static const sal_Int16 nIntegerPropertyAttrDefaults[] =
654             {   // attribute defaults
655                 5, 0
656             };
657 
658             if ( m_nIncludeCommon & CCA_MAX_LENGTH )
659                 exportedProperty(PROPERTY_MAXTEXTLENGTH);
660 
661         #if OSL_DEBUG_LEVEL > 0
662             sal_Int32 nIdCount = sizeof(nIntegerPropertyAttributeIds) / sizeof(nIntegerPropertyAttributeIds[0]);
663             sal_Int32 nNameCount = sizeof(pIntegerPropertyNames) / sizeof(pIntegerPropertyNames[0]);
664             sal_Int32 nDefaultCount = sizeof(nIntegerPropertyAttrDefaults) / sizeof(nIntegerPropertyAttrDefaults[0]);
665             OSL_ENSURE((nIdCount == nNameCount) && (nNameCount == nDefaultCount),
666                 "OControlExport::exportCommonControlAttributes: somebody tampered with the maps (3)!");
667         #endif
668             for (i=0; i<sizeof(nIntegerPropertyAttributeIds)/sizeof(nIntegerPropertyAttributeIds[0]); ++i)
669                 if (nIntegerPropertyAttributeIds[i] & m_nIncludeCommon)
670                 {
671                     exportInt16PropertyAttribute(
672                         OAttributeMetaData::getCommonControlAttributeNamespace(nIntegerPropertyAttributeIds[i]),
673                         OAttributeMetaData::getCommonControlAttributeName(nIntegerPropertyAttributeIds[i]),
674                         *(pIntegerPropertyNames[i]),
675                         nIntegerPropertyAttrDefaults[i]);
676         #if OSL_DEBUG_LEVEL > 0
677                     //  reset the bit for later checking
678                     m_nIncludeCommon = m_nIncludeCommon & ~nIntegerPropertyAttributeIds[i];
679         #endif
680                 }
681 
682 
683         }
684 
685         // --------------------------------------------------------------------
686         // some enum properties
687         {
688             if (m_nIncludeCommon & CCA_BUTTON_TYPE)
689             {
690                 exportEnumPropertyAttribute(
691                     OAttributeMetaData::getCommonControlAttributeNamespace(CCA_BUTTON_TYPE),
692                     OAttributeMetaData::getCommonControlAttributeName(CCA_BUTTON_TYPE),
693                     PROPERTY_BUTTONTYPE,
694                     OEnumMapper::getEnumMap(OEnumMapper::epButtonType),
695                     FormButtonType_PUSH);
696         #if OSL_DEBUG_LEVEL > 0
697                 //  reset the bit for later checking
698                 m_nIncludeCommon = m_nIncludeCommon & ~CCA_BUTTON_TYPE;
699         #endif
700             }
701             if ( m_nIncludeCommon & CCA_ORIENTATION )
702             {
703                 exportEnumPropertyAttribute(
704                     OAttributeMetaData::getCommonControlAttributeNamespace( CCA_ORIENTATION ),
705                     OAttributeMetaData::getCommonControlAttributeName( CCA_ORIENTATION ),
706                     PROPERTY_ORIENTATION,
707                     OEnumMapper::getEnumMap( OEnumMapper::epOrientation ),
708                     ScrollBarOrientation::HORIZONTAL
709                 );
710         #if OSL_DEBUG_LEVEL > 0
711                 //  reset the bit for later checking
712                 m_nIncludeCommon = m_nIncludeCommon & ~CCA_ORIENTATION;
713         #endif
714             }
715 
716             if ( m_nIncludeCommon & CCA_VISUAL_EFFECT )
717             {
718                 exportEnumPropertyAttribute(
719                     OAttributeMetaData::getCommonControlAttributeNamespace( CCA_VISUAL_EFFECT ),
720                     OAttributeMetaData::getCommonControlAttributeName( CCA_VISUAL_EFFECT ),
721                     PROPERTY_VISUAL_EFFECT,
722                     OEnumMapper::getEnumMap( OEnumMapper::epVisualEffect ),
723                     VisualEffect::LOOK3D
724                 );
725             #if OSL_DEBUG_LEVEL > 0
726                 //  reset the bit for later checking
727                 m_nIncludeCommon = m_nIncludeCommon & ~CCA_VISUAL_EFFECT;
728             #endif
729             }
730         }
731 
732         // --------------------------------------------------------------------
733         // some properties which require a special handling
734 
735         // the target frame
736         if (m_nIncludeCommon & CCA_TARGET_FRAME)
737         {
738             exportTargetFrameAttribute();
739         #if OSL_DEBUG_LEVEL > 0
740             //  reset the bit for later checking
741             m_nIncludeCommon = m_nIncludeCommon & ~CCA_TARGET_FRAME;
742         #endif
743         }
744 
745         // max text length
746         if ( m_nIncludeCommon & CCA_MAX_LENGTH )
747         {
748             // normally, the respective property would be "MaxTextLen"
749             // However, if the model has a property "PersistenceMaxTextLength", then we prefer this
750 
751             // determine the name of the property to export
752             ::rtl::OUString sTextLenPropertyName( PROPERTY_MAXTEXTLENGTH );
753             if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_PERSISTENCE_MAXTEXTLENGTH ) )
754                 sTextLenPropertyName = PROPERTY_PERSISTENCE_MAXTEXTLENGTH;
755 
756             // export it
757             exportInt16PropertyAttribute(
758                 OAttributeMetaData::getCommonControlAttributeNamespace( CCA_MAX_LENGTH ),
759                 OAttributeMetaData::getCommonControlAttributeName( CCA_MAX_LENGTH ),
760                 sTextLenPropertyName,
761                 0
762             );
763 
764             // in either way, both properties count as "exported"
765             exportedProperty( PROPERTY_MAXTEXTLENGTH );
766             exportedProperty( PROPERTY_PERSISTENCE_MAXTEXTLENGTH );
767 
768         #if OSL_DEBUG_LEVEL > 0
769             //  reset the bit for later checking
770             m_nIncludeCommon = m_nIncludeCommon & ~CCA_MAX_LENGTH;
771         #endif
772         }
773 
774         if (m_nIncludeCommon & CCA_TARGET_LOCATION)
775         {
776             exportTargetLocationAttribute(false);
777         #if OSL_DEBUG_LEVEL > 0
778             //  reset the bit for later checking
779             m_nIncludeCommon = m_nIncludeCommon & ~CCA_TARGET_LOCATION;
780         #endif
781         }
782 
783         // OJ #99721#
784         if (m_nIncludeCommon & CCA_IMAGE_DATA)
785         {
786             exportImageDataAttribute();
787         #if OSL_DEBUG_LEVEL > 0
788             //  reset the bit for later checking
789             m_nIncludeCommon = m_nIncludeCommon & ~CCA_IMAGE_DATA;
790         #endif
791         }
792 
793         // the for attribute
794         // the target frame
795         if (m_nIncludeCommon & CCA_FOR)
796         {
797             if (m_sReferringControls.getLength())
798             {   // there is at least one control referring to the one we're handling currently
799                 AddAttribute(
800                     OAttributeMetaData::getCommonControlAttributeNamespace(CCA_FOR),
801                     OAttributeMetaData::getCommonControlAttributeName(CCA_FOR),
802                     m_sReferringControls);
803             }
804         #if OSL_DEBUG_LEVEL > 0
805             //  reset the bit for later checking
806             m_nIncludeCommon = m_nIncludeCommon & ~CCA_FOR;
807         #endif
808         }
809 
810         if ((CCA_CURRENT_VALUE | CCA_VALUE) & m_nIncludeCommon)
811         {
812             const sal_Char* pCurrentValuePropertyName = NULL;
813             const sal_Char* pValuePropertyName = NULL;
814 
815             // get the property names
816             getValuePropertyNames(m_eType, m_nClassId, pCurrentValuePropertyName, pValuePropertyName);
817 
818             static const sal_Char* pCurrentValueAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_VALUE);
819             static const sal_Char* pValueAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_VALUE);
820             static const sal_uInt16 nCurrentValueAttributeNamespaceKey = OAttributeMetaData::getCommonControlAttributeNamespace(CCA_CURRENT_VALUE);
821             static const sal_uInt16 nValueAttributeNamespaceKey = OAttributeMetaData::getCommonControlAttributeNamespace(CCA_VALUE);
822 
823             // add the atrtributes if necessary and possible
824             if (pCurrentValuePropertyName && (CCA_CURRENT_VALUE & m_nIncludeCommon))
825             {
826                 // don't export the current-value if this value originates from a data binding
827                 // #i26944# - 2004-05-17 - fs@openoffice.org
828                 if ( controlHasActiveDataBinding() )
829                     exportedProperty( ::rtl::OUString::createFromAscii( pCurrentValuePropertyName ) );
830                 else
831                     exportGenericPropertyAttribute(
832                         nCurrentValueAttributeNamespaceKey,
833                         pCurrentValueAttributeName,
834                         pCurrentValuePropertyName
835                     );
836             }
837 
838             if (pValuePropertyName && (CCA_VALUE & m_nIncludeCommon))
839                 exportGenericPropertyAttribute(
840                     nValueAttributeNamespaceKey,
841                     pValueAttributeName,
842                     pValuePropertyName);
843 
844             OSL_ENSURE((NULL == pValuePropertyName) == (0 == (CCA_VALUE & m_nIncludeCommon)),
845                 "OControlExport::exportCommonControlAttributes: no property found for the value attribute!");
846             OSL_ENSURE((NULL == pCurrentValuePropertyName ) == (0 == (CCA_CURRENT_VALUE & m_nIncludeCommon)),
847                 "OControlExport::exportCommonControlAttributes: no property found for the current-value attribute!");
848 
849         #if OSL_DEBUG_LEVEL > 0
850             //  reset the bit for later checking
851             m_nIncludeCommon = m_nIncludeCommon & ~(CCA_CURRENT_VALUE | CCA_VALUE);
852         #endif
853         }
854 
855         OSL_ENSURE(0 == m_nIncludeCommon,
856             "OControlExport::exportCommonControlAttributes: forgot some flags!");
857             // in the dbg_util version, we should have removed every bit we handled from the mask, so it should
858             // be 0 now ...
859     }
860 
861     //---------------------------------------------------------------------
862     void OControlExport::exportDatabaseAttributes()
863     {
864 #if OSL_DEBUG_LEVEL > 0
865         sal_Int32 nIncludeDatabase = m_nIncludeDatabase;
866 #endif
867         // the only string property: DataField
868         if (DA_DATA_FIELD & m_nIncludeDatabase)
869         {
870             exportStringPropertyAttribute(
871                 OAttributeMetaData::getDatabaseAttributeNamespace(DA_DATA_FIELD),
872                 OAttributeMetaData::getDatabaseAttributeName(DA_DATA_FIELD),
873                 PROPERTY_DATAFIELD);
874             RESET_BIT( nIncludeDatabase, DA_DATA_FIELD );
875         }
876 
877         // InputRequired
878         if ( DA_INPUT_REQUIRED & m_nIncludeDatabase )
879         {
880             exportBooleanPropertyAttribute(
881                 OAttributeMetaData::getDatabaseAttributeNamespace( DA_INPUT_REQUIRED ),
882                 OAttributeMetaData::getDatabaseAttributeName( DA_INPUT_REQUIRED ),
883                 PROPERTY_INPUT_REQUIRED,
884                 BOOLATTR_DEFAULT_TRUE
885             );
886             RESET_BIT( nIncludeDatabase, DA_INPUT_REQUIRED );
887         }
888 
889         // the only int16 property: BoundColumn
890         if (DA_BOUND_COLUMN & m_nIncludeDatabase)
891         {
892             exportInt16PropertyAttribute(
893                 OAttributeMetaData::getDatabaseAttributeNamespace(DA_BOUND_COLUMN),
894                 OAttributeMetaData::getDatabaseAttributeName(DA_BOUND_COLUMN),
895                 PROPERTY_BOUNDCOLUMN,
896                 0);
897             RESET_BIT( nIncludeDatabase, DA_BOUND_COLUMN );
898         }
899 
900         // ConvertEmptyToNull
901         if (DA_CONVERT_EMPTY & m_nIncludeDatabase)
902         {
903             exportBooleanPropertyAttribute(
904                 OAttributeMetaData::getDatabaseAttributeNamespace(DA_CONVERT_EMPTY),
905                 OAttributeMetaData::getDatabaseAttributeName(DA_CONVERT_EMPTY),
906                 PROPERTY_EMPTY_IS_NULL,
907                 BOOLATTR_DEFAULT_FALSE
908                 );
909             RESET_BIT( nIncludeDatabase, DA_CONVERT_EMPTY );
910         }
911 
912         // the only enum property: ListSourceType
913         if (DA_LIST_SOURCE_TYPE & m_nIncludeDatabase)
914         {
915             exportEnumPropertyAttribute(
916                 OAttributeMetaData::getDatabaseAttributeNamespace(DA_LIST_SOURCE_TYPE),
917                 OAttributeMetaData::getDatabaseAttributeName(DA_LIST_SOURCE_TYPE),
918                 PROPERTY_LISTSOURCETYPE,
919                 OEnumMapper::getEnumMap(OEnumMapper::epListSourceType),
920                 ListSourceType_VALUELIST
921                 );
922             RESET_BIT( nIncludeDatabase, DA_LIST_SOURCE_TYPE );
923         }
924 
925         if (m_nIncludeDatabase & DA_LIST_SOURCE)
926         {
927             exportListSourceAsAttribute();
928             RESET_BIT( nIncludeDatabase, DA_LIST_SOURCE );
929         }
930 
931 #if OSL_DEBUG_LEVEL > 0
932         OSL_ENSURE(0 == nIncludeDatabase,
933             "OControlExport::exportDatabaseAttributes: forgot some flags!");
934             // in the dbg_util version, we should have removed every bit we handled from the mask, so it should
935             // be 0 now ...
936 #endif
937     }
938 
939     //---------------------------------------------------------------------
940     void OControlExport::exportBindingAtributes()
941     {
942 #if OSL_DEBUG_LEVEL > 0
943         sal_Int32 nIncludeBinding = m_nIncludeBindings;
944 #endif
945 
946         // ....................................................
947         if ( m_nIncludeBindings & BA_LINKED_CELL )
948         {
949             exportCellBindingAttributes( ( m_nIncludeBindings & BA_LIST_LINKING_TYPE ) != 0 );
950         #if OSL_DEBUG_LEVEL > 0
951             //  reset the bit for later checking
952             nIncludeBinding = nIncludeBinding & ~( BA_LINKED_CELL | BA_LIST_LINKING_TYPE );
953         #endif
954         }
955 
956         // ....................................................
957         if ( m_nIncludeBindings & BA_LIST_CELL_RANGE )
958         {
959             exportCellListSourceRange();
960         #if OSL_DEBUG_LEVEL > 0
961             //  reset the bit for later checking
962             nIncludeBinding = nIncludeBinding & ~BA_LIST_CELL_RANGE;
963         #endif
964         }
965 
966         if ( m_nIncludeBindings & BA_XFORMS_BIND )
967         {
968             exportXFormsBindAttributes();
969         #if OSL_DEBUG_LEVEL > 0
970             //  reset the bit for later checking
971             nIncludeBinding = nIncludeBinding & ~BA_XFORMS_BIND;
972         #endif
973         }
974 
975         if ( m_nIncludeBindings & BA_XFORMS_LISTBIND )
976         {
977             exportXFormsListAttributes();
978         #if OSL_DEBUG_LEVEL > 0
979             //  reset the bit for later checking
980             nIncludeBinding = nIncludeBinding & ~BA_XFORMS_LISTBIND;
981         #endif
982         }
983 
984         if ( m_nIncludeBindings & BA_XFORMS_SUBMISSION )
985         {
986             exportXFormsSubmissionAttributes();
987         #if OSL_DEBUG_LEVEL > 0
988             //  reset the bit for later checking
989             nIncludeBinding = nIncludeBinding & ~BA_XFORMS_SUBMISSION;
990         #endif
991         }
992 
993         OSL_ENSURE( 0 == nIncludeBinding,
994             "OControlExport::exportBindingAtributes: forgot some flags!");
995             // in the debug version, we should have removed every bit we handled from the mask, so it should
996             // be 0 now ...
997     }
998 
999     //---------------------------------------------------------------------
1000     void OControlExport::exportSpecialAttributes()
1001     {
1002         sal_Int32 i=0;
1003 
1004         // ----------------------
1005         // the boolean properties
1006         {
1007             static const sal_Int32 nBooleanPropertyAttributeIds[] =
1008             {   // attribute flags
1009                 SCA_VALIDATION, SCA_MULTI_LINE, SCA_AUTOMATIC_COMPLETION, SCA_MULTIPLE, SCA_DEFAULT_BUTTON, SCA_IS_TRISTATE,
1010                 SCA_TOGGLE, SCA_FOCUS_ON_CLICK
1011             };
1012             static const ::rtl::OUString* pBooleanPropertyNames[] =
1013             {   // property names
1014                 &PROPERTY_STRICTFORMAT, &PROPERTY_MULTILINE, &PROPERTY_AUTOCOMPLETE, &PROPERTY_MULTISELECTION, &PROPERTY_DEFAULTBUTTON, &PROPERTY_TRISTATE,
1015                 &PROPERTY_TOGGLE, &PROPERTY_FOCUS_ON_CLICK
1016             };
1017             sal_Int32 nIdCount = sizeof(nBooleanPropertyAttributeIds) / sizeof(nBooleanPropertyAttributeIds[0]);
1018         #if OSL_DEBUG_LEVEL > 0
1019             sal_Int32 nNameCount = sizeof(pBooleanPropertyNames) / sizeof(pBooleanPropertyNames[0]);
1020             OSL_ENSURE((nIdCount == nNameCount),
1021                 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (1)!");
1022         #endif
1023             const sal_Int32* pAttributeId = nBooleanPropertyAttributeIds;
1024             const ::rtl::OUString** pPropertyName = pBooleanPropertyNames;
1025             for ( i = 0; i < nIdCount; ++i, ++pAttributeId, ++pPropertyName )
1026             {
1027                 if ( *pAttributeId& m_nIncludeSpecial)
1028                 {
1029                     exportBooleanPropertyAttribute(
1030                         OAttributeMetaData::getSpecialAttributeNamespace( *pAttributeId ),
1031                         OAttributeMetaData::getSpecialAttributeName( *pAttributeId ),
1032                         *(*pPropertyName),
1033                         ( *pAttributeId == SCA_FOCUS_ON_CLICK ) ? BOOLATTR_DEFAULT_TRUE : BOOLATTR_DEFAULT_FALSE
1034                     );
1035             #if OSL_DEBUG_LEVEL > 0
1036                 //  reset the bit for later checking
1037                 m_nIncludeSpecial = m_nIncludeSpecial & ~*pAttributeId;
1038             #endif
1039                 }
1040             }
1041         }
1042 
1043         // ----------------------
1044         // the integer properties
1045         {
1046             static sal_Int32 nIntegerPropertyAttributeIds[] =
1047             {   // attribute flags
1048                 SCA_PAGE_STEP_SIZE
1049             };
1050             static const ::rtl::OUString* pIntegerPropertyNames[] =
1051             {   // property names
1052                 &PROPERTY_BLOCK_INCREMENT
1053             };
1054             static const sal_Int32 nIntegerPropertyAttrDefaults[] =
1055             {   // attribute defaults (XML defaults, not runtime defaults!)
1056                 10
1057             };
1058 
1059             sal_Int32 nIdCount = sizeof( nIntegerPropertyAttributeIds ) / sizeof( nIntegerPropertyAttributeIds[0] );
1060         #if OSL_DEBUG_LEVEL > 0
1061             sal_Int32 nNameCount = sizeof( pIntegerPropertyNames ) / sizeof( pIntegerPropertyNames[0] );
1062             OSL_ENSURE( ( nIdCount == nNameCount ),
1063                 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (2)!" );
1064             sal_Int32 nDefaultCount = sizeof( nIntegerPropertyAttrDefaults ) / sizeof( nIntegerPropertyAttrDefaults[0] );
1065             OSL_ENSURE( ( nIdCount == nDefaultCount ),
1066                 "OControlExport::exportSpecialAttributes: somebody tampered with the maps (3)!" );
1067         #endif
1068             for ( i = 0; i < nIdCount; ++i )
1069                 if ( nIntegerPropertyAttributeIds[i] & m_nIncludeSpecial )
1070                 {
1071                     exportInt32PropertyAttribute(
1072                         OAttributeMetaData::getSpecialAttributeNamespace( nIntegerPropertyAttributeIds[i] ),
1073                         OAttributeMetaData::getSpecialAttributeName( nIntegerPropertyAttributeIds[i] ),
1074                         *( pIntegerPropertyNames[i] ),
1075                         nIntegerPropertyAttrDefaults[i]
1076                     );
1077             #if OSL_DEBUG_LEVEL > 0
1078                 //  reset the bit for later checking
1079                 m_nIncludeSpecial = m_nIncludeSpecial & ~nIntegerPropertyAttributeIds[i];
1080             #endif
1081                 }
1082 
1083             if ( SCA_STEP_SIZE & m_nIncludeSpecial )
1084             {
1085                 ::rtl::OUString sPropertyName;
1086                 if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_LINE_INCREMENT ) )
1087                     sPropertyName = PROPERTY_LINE_INCREMENT;
1088                 else if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_SPIN_INCREMENT ) )
1089                     sPropertyName = PROPERTY_SPIN_INCREMENT;
1090                 else
1091                     OSL_ENSURE( sal_False, "OControlExport::exportSpecialAttributes: not property which can be mapped to step-size attribute!" );
1092 
1093                 if ( sPropertyName.getLength() )
1094                     exportInt32PropertyAttribute(
1095                         OAttributeMetaData::getSpecialAttributeNamespace( SCA_STEP_SIZE ),
1096                         OAttributeMetaData::getSpecialAttributeName( SCA_STEP_SIZE ),
1097                         sPropertyName,
1098                         1
1099                     );
1100 
1101             #if OSL_DEBUG_LEVEL > 0
1102                 //  reset the bit for later checking
1103                 m_nIncludeSpecial = m_nIncludeSpecial & ~SCA_STEP_SIZE;
1104             #endif
1105             }
1106 
1107         }
1108 
1109         // -------------------
1110         // the enum properties
1111         {
1112             if (SCA_STATE & m_nIncludeSpecial)
1113             {
1114                 exportEnumPropertyAttribute(
1115                     OAttributeMetaData::getSpecialAttributeNamespace(SCA_STATE),
1116                     OAttributeMetaData::getSpecialAttributeName(SCA_STATE),
1117                     PROPERTY_DEFAULT_STATE,
1118                     OEnumMapper::getEnumMap(OEnumMapper::epCheckState),
1119                     STATE_NOCHECK);
1120             #if OSL_DEBUG_LEVEL > 0
1121                 //  reset the bit for later checking
1122                 m_nIncludeSpecial = m_nIncludeSpecial & ~SCA_STATE;
1123             #endif
1124             }
1125 
1126             if (SCA_CURRENT_STATE & m_nIncludeSpecial)
1127             {
1128                 exportEnumPropertyAttribute(
1129                     OAttributeMetaData::getSpecialAttributeNamespace(SCA_CURRENT_STATE),
1130                     OAttributeMetaData::getSpecialAttributeName(SCA_CURRENT_STATE),
1131                     PROPERTY_STATE,
1132                     OEnumMapper::getEnumMap(OEnumMapper::epCheckState),
1133                     STATE_NOCHECK);
1134             #if OSL_DEBUG_LEVEL > 0
1135                 //  reset the bit for later checking
1136                 m_nIncludeSpecial = m_nIncludeSpecial & ~SCA_CURRENT_STATE;
1137             #endif
1138             }
1139         }
1140 
1141         // --------------------------------------------------------------------
1142         // some properties which require a special handling
1143         // the repeat delay
1144         {
1145             if ( m_nIncludeSpecial & SCA_REPEAT_DELAY )
1146             {
1147                 DBG_CHECK_PROPERTY( PROPERTY_REPEAT_DELAY, sal_Int32 );
1148 
1149                 sal_Int32 nRepeatDelay = 0;
1150                 m_xProps->getPropertyValue( PROPERTY_REPEAT_DELAY ) >>= nRepeatDelay;
1151                 Time aTime;
1152                 aTime.MakeTimeFromMS( nRepeatDelay );
1153 
1154                 AddAttribute(OAttributeMetaData::getSpecialAttributeNamespace( SCA_REPEAT_DELAY )
1155                             ,OAttributeMetaData::getSpecialAttributeName( SCA_REPEAT_DELAY )
1156                             ,SvXMLUnitConverter::convertTimeDuration( aTime, nRepeatDelay % 1000 ) );
1157 
1158                 exportedProperty( PROPERTY_REPEAT_DELAY );
1159 
1160             #if OSL_DEBUG_LEVEL > 0
1161                 //  reset the bit for later checking
1162                 m_nIncludeSpecial = m_nIncludeSpecial & ~SCA_REPEAT_DELAY;
1163             #endif
1164             }
1165         }
1166 
1167         // ----------------------------------
1168         // the EchoChar property needs special handling, cause it's a Int16, but must be stored as one-character-string
1169         {
1170             if (SCA_ECHO_CHAR & m_nIncludeSpecial)
1171             {
1172                 DBG_CHECK_PROPERTY( PROPERTY_ECHO_CHAR, sal_Int16 );
1173                 sal_Int16 nValue(0);
1174                 m_xProps->getPropertyValue(PROPERTY_ECHO_CHAR) >>= nValue;
1175                 if (nValue)
1176                 {
1177                     ::rtl::OUString sCharacter(reinterpret_cast<const sal_Unicode*>(&nValue), 1);
1178                     AddAttribute(
1179                         OAttributeMetaData::getSpecialAttributeNamespace(SCA_ECHO_CHAR),
1180                         OAttributeMetaData::getSpecialAttributeName(SCA_ECHO_CHAR),
1181                         sCharacter);
1182                 }
1183                 exportedProperty(PROPERTY_ECHO_CHAR);
1184             #if OSL_DEBUG_LEVEL > 0
1185                 //  reset the bit for later checking
1186                 m_nIncludeSpecial = m_nIncludeSpecial & ~SCA_ECHO_CHAR;
1187             #endif
1188             }
1189         }
1190 
1191         // ----------------------------------
1192         if ((SCA_MIN_VALUE | SCA_MAX_VALUE) & m_nIncludeSpecial)
1193         {
1194             // need to export the min value and the max value as attributes
1195             // It depends on the real type (FormComponentType) of the control, which properties hold these
1196             // values
1197             const sal_Char* pMinValuePropertyName = NULL;
1198             const sal_Char* pMaxValuePropertyName = NULL;
1199             getValueLimitPropertyNames(m_nClassId, pMinValuePropertyName, pMaxValuePropertyName);
1200 
1201             OSL_ENSURE((NULL == pMinValuePropertyName) == (0 == (SCA_MIN_VALUE & m_nIncludeSpecial)),
1202                 "OControlExport::exportCommonControlAttributes: no property found for the min value attribute!");
1203             OSL_ENSURE((NULL == pMaxValuePropertyName) == (0 == (SCA_MAX_VALUE & m_nIncludeSpecial)),
1204                 "OControlExport::exportCommonControlAttributes: no property found for the max value attribute!");
1205 
1206             // add the two attributes
1207             static const sal_Char* pMinValueAttributeName = OAttributeMetaData::getSpecialAttributeName(SCA_MIN_VALUE);
1208             static const sal_Char* pMaxValueAttributeName = OAttributeMetaData::getSpecialAttributeName(SCA_MAX_VALUE);
1209             static const sal_uInt16 nMinValueNamespaceKey = OAttributeMetaData::getSpecialAttributeNamespace(SCA_MIN_VALUE);
1210             static const sal_uInt16 nMaxValueNamespaceKey = OAttributeMetaData::getSpecialAttributeNamespace(SCA_MAX_VALUE);
1211 
1212             if (pMinValuePropertyName && (SCA_MIN_VALUE & m_nIncludeSpecial))
1213                 exportGenericPropertyAttribute(
1214                     nMinValueNamespaceKey,
1215                     pMinValueAttributeName,
1216                     pMinValuePropertyName);
1217 
1218             if (pMaxValuePropertyName && (SCA_MAX_VALUE & m_nIncludeSpecial))
1219                 exportGenericPropertyAttribute(
1220                     nMaxValueNamespaceKey,
1221                     pMaxValueAttributeName,
1222                     pMaxValuePropertyName);
1223         #if OSL_DEBUG_LEVEL > 0
1224             //  reset the bit for later checking
1225             m_nIncludeSpecial = m_nIncludeSpecial & ~(SCA_MIN_VALUE | SCA_MAX_VALUE);
1226         #endif
1227         }
1228 
1229         // ----------------------------------
1230         if ( SCA_IMAGE_POSITION & m_nIncludeSpecial )
1231         {
1232             exportImagePositionAttributes();
1233             RESET_BIT( m_nIncludeSpecial, SCA_IMAGE_POSITION );
1234         }
1235 
1236         OSL_ENSURE(0 == m_nIncludeSpecial,
1237             "OControlExport::exportSpecialAttributes: forgot some flags!");
1238             // in the dbg_util version, we should have removed every bit we handled from the mask, so it should
1239             // be 0 now ...
1240     }
1241 
1242     //---------------------------------------------------------------------
1243     ::rtl::OUString OControlExport::getScalarListSourceValue() const
1244     {
1245         ::rtl::OUString sListSource;
1246         Any aListSource = m_xProps->getPropertyValue( PROPERTY_LISTSOURCE );
1247         if ( !( aListSource >>= sListSource ) )
1248         {
1249             Sequence< ::rtl::OUString > aListSourceSequence;
1250             aListSource >>= aListSourceSequence;
1251             if ( aListSourceSequence.getLength() )
1252                 sListSource = aListSourceSequence[ 0 ];
1253         }
1254         return sListSource;
1255     }
1256 
1257     //---------------------------------------------------------------------
1258     void OControlExport::exportListSourceAsAttribute()
1259     {
1260         // DA_LIST_SOURCE needs some special handling
1261         DBG_CHECK_PROPERTY_NO_TYPE( PROPERTY_LISTSOURCE );
1262 
1263         ::rtl::OUString sListSource = getScalarListSourceValue();
1264         if ( sListSource.getLength() )
1265         {   // the ListSource property needs to be exported as attribute, and it is not empty
1266             AddAttribute(
1267                 OAttributeMetaData::getDatabaseAttributeNamespace(DA_LIST_SOURCE),
1268                 OAttributeMetaData::getDatabaseAttributeName(DA_LIST_SOURCE),
1269                 sListSource);
1270         }
1271 
1272         exportedProperty( PROPERTY_LISTSOURCE );
1273     }
1274 
1275     //---------------------------------------------------------------------
1276     void OControlExport::getSequenceInt16PropertyAsSet(const ::rtl::OUString& _rPropertyName, Int16Set& _rOut)
1277     {
1278         Sequence< sal_Int16 > aValueSequence;
1279         DBG_CHECK_PROPERTY(_rPropertyName, Sequence< sal_Int16 >);
1280         m_xProps->getPropertyValue(_rPropertyName) >>= aValueSequence;
1281 
1282         const sal_Int16* pValues = aValueSequence.getConstArray();
1283         for (sal_Int32 i=0; i<aValueSequence.getLength(); ++i, ++pValues)
1284             _rOut.insert(*pValues);
1285     }
1286 
1287     //---------------------------------------------------------------------
1288     void OControlExport::exportListSourceAsElements()
1289     {
1290         // the string lists
1291         Sequence< ::rtl::OUString > aItems, aValues;
1292         DBG_CHECK_PROPERTY( PROPERTY_STRING_ITEM_LIST, Sequence< ::rtl::OUString > );
1293         m_xProps->getPropertyValue(PROPERTY_STRING_ITEM_LIST) >>= aItems;
1294 
1295         DBG_CHECK_PROPERTY( PROPERTY_LISTSOURCE, Sequence< ::rtl::OUString > );
1296         if ( 0 == ( m_nIncludeDatabase & DA_LIST_SOURCE ) )
1297             m_xProps->getPropertyValue(PROPERTY_LISTSOURCE) >>= aValues;
1298         // if we exported the list source as attribute, we do not repeat it as sub elements
1299 
1300         // the selection lists
1301         Int16Set aSelection, aDefaultSelection;
1302         getSequenceInt16PropertyAsSet(PROPERTY_SELECT_SEQ, aSelection);
1303         getSequenceInt16PropertyAsSet(PROPERTY_DEFAULT_SELECT_SEQ, aDefaultSelection);
1304 
1305         // the string for "true"
1306         ::rtl::OUString sTrue;
1307         ::rtl::OUStringBuffer sBuffer;
1308         m_rContext.getGlobalContext().GetMM100UnitConverter().convertBool(sBuffer, sal_True);
1309         sTrue = sBuffer.makeStringAndClear();
1310 
1311         // loop through both lists ('til the maximum of both lengths)
1312         const ::rtl::OUString* pItems = aItems.getConstArray();
1313         const ::rtl::OUString* pValues = aValues.getConstArray();
1314 
1315         sal_Int32 nItems = aItems.getLength();
1316         sal_Int32 nValues = aValues.getLength();
1317 
1318         sal_Int16 nMaxLen = (sal_Int16)std::max(nItems, nValues);
1319 
1320         for (sal_Int16 i=0; i<nMaxLen; ++i )
1321         {
1322             m_rContext.getGlobalContext().ClearAttrList();
1323             if (i < nItems)
1324             {
1325                 // there is an item at this position
1326                 AddAttribute(
1327                     OAttributeMetaData::getCommonControlAttributeNamespace(CCA_LABEL),
1328                     OAttributeMetaData::getCommonControlAttributeName(CCA_LABEL),
1329                     *pItems);
1330                 ++pItems;
1331             }
1332             if (i < nValues)
1333             {
1334                 // there is an value at this position
1335                 AddAttribute(
1336                     OAttributeMetaData::getCommonControlAttributeNamespace(CCA_VALUE),
1337                     OAttributeMetaData::getCommonControlAttributeName(CCA_VALUE),
1338                     *pValues);
1339                 ++pValues;
1340             }
1341 
1342             Int16SetIterator aSelectedPos = aSelection.find(i);
1343             if (aSelection.end() != aSelectedPos)
1344             {   // the item at this position is selected
1345                 AddAttribute(
1346                     OAttributeMetaData::getCommonControlAttributeNamespace(CCA_CURRENT_SELECTED),
1347                     OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_SELECTED),
1348                     sTrue
1349                     );
1350                 aSelection.erase(aSelectedPos);
1351             }
1352 
1353             Int16SetIterator aDefaultSelectedPos = aDefaultSelection.find(i);
1354             if (aDefaultSelection.end() != aDefaultSelectedPos)
1355             {   // the item at this position is selected as default
1356                 AddAttribute(
1357                     OAttributeMetaData::getCommonControlAttributeNamespace(CCA_SELECTED),
1358                     OAttributeMetaData::getCommonControlAttributeName(CCA_SELECTED),
1359                     sTrue
1360                     );
1361                 aDefaultSelection.erase(aDefaultSelectedPos);
1362             }
1363             SvXMLElementExport aFormElement(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, "option", sal_True, sal_True);
1364         }
1365 
1366         // There may be more "selected" or "default-selected" items than there are in the lists in real,
1367         // so we need to store some additional "form:option" items which have no name and no label, but
1368         // one or both of the selected flags.
1369         // 21.05.2001 - 85388 - frank.schoenheit@germany.sun.com
1370 
1371         if ( !aSelection.empty() || !aDefaultSelection.empty() )
1372         {
1373             sal_Int16 nLastSelected = -1;
1374             if ( !aSelection.empty() )
1375                 nLastSelected = *(--aSelection.end());
1376 
1377             sal_Int16 nLastDefaultSelected = -1;
1378             if ( !aDefaultSelection.empty() )
1379                 nLastDefaultSelected = *(--aDefaultSelection.end());
1380 
1381             // the maximum element in both sets
1382             sal_Int16 nLastReferredEntry = std::max(nLastSelected, nLastDefaultSelected);
1383             OSL_ENSURE(nLastReferredEntry >= nMaxLen, "OControlExport::exportListSourceAsElements: inconsistence!");
1384                 // if the maximum (selected or default selected) entry number is less than the maximum item count
1385                 // in both lists, the entry number should have been removed from the set
1386 
1387             for (sal_Int16 i=nMaxLen; i<=nLastReferredEntry; ++i)
1388             {
1389                 if (aSelection.end() != aSelection.find(i))
1390                 {   // the (not existent) item at this position is selected
1391                     AddAttribute(
1392                         OAttributeMetaData::getCommonControlAttributeNamespace(CCA_CURRENT_SELECTED),
1393                         OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_SELECTED),
1394                         sTrue
1395                         );
1396                 }
1397 
1398                 if (aDefaultSelection.end() != aDefaultSelection.find(i))
1399                 {   // the (not existent) item at this position is selected as default
1400                     AddAttribute(
1401                         OAttributeMetaData::getCommonControlAttributeNamespace(CCA_SELECTED),
1402                         OAttributeMetaData::getCommonControlAttributeName(CCA_SELECTED),
1403                         sTrue
1404                         );
1405                 }
1406                 SvXMLElementExport aFormElement(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, "option", sal_True, sal_True);
1407             }
1408         }
1409     }
1410 
1411     //---------------------------------------------------------------------
1412     void OControlExport::implStartElement(const sal_Char* _pName)
1413     {
1414         // before we let the base class start it's outer element, we add a wrapper element
1415         const sal_Char *pOuterElementName = getOuterXMLElementName();
1416         m_pOuterElement = pOuterElementName
1417                             ? new SvXMLElementExport(
1418                                         m_rContext.getGlobalContext(),
1419                                         XML_NAMESPACE_FORM,
1420                                         pOuterElementName, sal_True,
1421                                         sal_True)
1422                             : 0;
1423 
1424         // add the attributes for the inner element
1425         exportInnerAttributes();
1426 
1427         // and start the inner element
1428         OElementExport::implStartElement(_pName);
1429     }
1430 
1431     //---------------------------------------------------------------------
1432     void OControlExport::implEndElement()
1433     {
1434         // end the inner element
1435         OElementExport::implEndElement();
1436 
1437         // end the outer element if it exists
1438         delete m_pOuterElement;
1439         m_pOuterElement = NULL;
1440     }
1441 
1442     //---------------------------------------------------------------------
1443     const sal_Char* OControlExport::getOuterXMLElementName() const
1444     {
1445         return 0;
1446     }
1447 
1448     //---------------------------------------------------------------------
1449     const sal_Char* OControlExport::getXMLElementName() const
1450     {
1451         return getElementName(m_eType);
1452     }
1453 
1454     //---------------------------------------------------------------------
1455     void OControlExport::examine()
1456     {
1457         OSL_ENSURE( ( m_nIncludeCommon == 0 ) && ( m_nIncludeSpecial == 0 ) && ( m_nIncludeDatabase == 0 )
1458                  && ( m_nIncludeEvents == 0 ) && ( m_nIncludeBindings == 0),
1459                  "OControlExport::examine: called me twice? Not initialized?" );
1460 
1461         // get the class id to decide which kind of element we need in the XML stream
1462         m_nClassId = FormComponentType::CONTROL;
1463         DBG_CHECK_PROPERTY( PROPERTY_CLASSID, sal_Int16 );
1464         m_xProps->getPropertyValue(PROPERTY_CLASSID) >>= m_nClassId;
1465         bool knownType = false;
1466         switch (m_nClassId)
1467         {
1468             case FormComponentType::DATEFIELD:
1469                 m_eType = DATE;
1470                 knownType = true;
1471                 // NO BREAK
1472             case FormComponentType::TIMEFIELD:
1473                 if ( !knownType )
1474                 {
1475                     m_eType = TIME;
1476                     knownType = true;
1477                 }
1478                 m_nIncludeSpecial |= SCA_VALIDATION;
1479                 // NO BREAK
1480             case FormComponentType::NUMERICFIELD:
1481             case FormComponentType::CURRENCYFIELD:
1482             case FormComponentType::PATTERNFIELD:
1483                 if ( !knownType )
1484                 {
1485                     m_eType = FORMATTED_TEXT;
1486                     knownType = true;
1487                 }
1488                 // NO BREAK
1489             case FormComponentType::TEXTFIELD:
1490             {   // it's some kind of edit. To know which type we need further investigation
1491 
1492                 if ( !knownType )
1493                 {
1494                     // check if it's a formatted field
1495                     if (m_xPropertyInfo->hasPropertyByName(PROPERTY_FORMATKEY))
1496                     {
1497                         m_eType = FORMATTED_TEXT;
1498                     }
1499                     else
1500                     {
1501                         // all other controls are represented by an ordinary edit control, but which XML control type
1502                         // it is depends on the current values of some properties
1503 
1504                         // if the EchoChar string is not empty, it is a password field
1505                         sal_Int16 nEchoChar = 0;
1506                         if (m_xPropertyInfo->hasPropertyByName(PROPERTY_ECHOCHAR))
1507                             // grid columns do not have this property ....
1508                             m_xProps->getPropertyValue(PROPERTY_ECHOCHAR) >>= nEchoChar;
1509                         if (nEchoChar)
1510                         {
1511                             m_eType = PASSWORD;
1512                             m_nIncludeSpecial |= SCA_ECHO_CHAR;
1513                         }
1514                         else
1515                         {
1516                             // if the MultiLine property is sal_True, it is a TextArea
1517                             sal_Bool bMultiLine = sal_False;
1518                             if (m_xPropertyInfo->hasPropertyByName(PROPERTY_MULTILINE))
1519                                 // grid columns do not have this property ....
1520                                 bMultiLine = ::cppu::any2bool(m_xProps->getPropertyValue(PROPERTY_MULTILINE));
1521 
1522                             if ( bMultiLine )
1523                                 m_eType = TEXT_AREA;
1524                             else
1525                                 // the only case left is represented by a Text element
1526                                 m_eType = TEXT;
1527                         }
1528                     }
1529                     knownType = true;
1530                 }
1531 
1532                 // attributes which are common to all the types:
1533                 // common attributes
1534                 m_nIncludeCommon =
1535                     CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED |
1536                     CCA_PRINTABLE | CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE;
1537 
1538                 if  (   ( m_nClassId != FormComponentType::DATEFIELD )
1539                     &&  ( m_nClassId != FormComponentType::TIMEFIELD )
1540                     )
1541                     // date and time field values are handled differently nowadays
1542                     m_nIncludeCommon |= CCA_VALUE;
1543 
1544                 // database attributes
1545                 m_nIncludeDatabase = DA_DATA_FIELD | DA_INPUT_REQUIRED;
1546 
1547                 // event attributes
1548                 m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE | EA_ON_SELECT;
1549 
1550                 // only text and pattern fields have a ConvertEmptyToNull property
1551                 if  (   ( m_nClassId == FormComponentType::TEXTFIELD )
1552                     ||  ( m_nClassId == FormComponentType::PATTERNFIELD )
1553                     )
1554                     m_nIncludeDatabase |= DA_CONVERT_EMPTY;
1555 
1556                 // all controls but the file control fields have a readonly property
1557                 if ( m_nClassId != FormComponentType::FILECONTROL )
1558                     m_nIncludeCommon |= CCA_READONLY;
1559 
1560                 // a text field has a max text len
1561                 if ( m_nClassId == FormComponentType::TEXTFIELD )
1562                     m_nIncludeCommon |= CCA_MAX_LENGTH;
1563 
1564                 // max and min values and validation:
1565                 if (FORMATTED_TEXT == m_eType)
1566                 {   // in general all controls represented as formatted-text have these props
1567                     if  ( FormComponentType::PATTERNFIELD != m_nClassId )   // except the PatternField
1568                         m_nIncludeSpecial |= SCA_MAX_VALUE | SCA_MIN_VALUE;
1569 
1570                     if (FormComponentType::TEXTFIELD != m_nClassId)
1571                         // and the FormattedField does not have a validation flag
1572                         m_nIncludeSpecial |= SCA_VALIDATION;
1573                 }
1574 
1575                 // if it's not a password field or rich text control, the CurrentValue needs to be stored, too
1576                 if  (   ( PASSWORD != m_eType )
1577                     &&  ( DATE != m_eType )
1578                     &&  ( TIME != m_eType )
1579                     )
1580                 {
1581                     m_nIncludeCommon |= CCA_CURRENT_VALUE;
1582                 }
1583             }
1584             break;
1585 
1586             case FormComponentType::FILECONTROL:
1587                 m_eType = FILE;
1588                 m_nIncludeCommon =
1589                     CCA_NAME | CCA_SERVICE_NAME | CCA_CURRENT_VALUE | CCA_DISABLED |
1590                     CCA_PRINTABLE | CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE |
1591                     CCA_VALUE;
1592                 m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE | EA_ON_SELECT;
1593                 break;
1594 
1595             case FormComponentType::FIXEDTEXT:
1596                 m_eType = FIXED_TEXT;
1597                 m_nIncludeCommon =
1598                     CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_LABEL |
1599                     CCA_PRINTABLE | CCA_TITLE | CCA_FOR;
1600                 m_nIncludeSpecial = SCA_MULTI_LINE;
1601                 m_nIncludeEvents = EA_CONTROL_EVENTS;
1602                 break;
1603 
1604             case FormComponentType::COMBOBOX:
1605                 m_eType = COMBOBOX;
1606                 m_nIncludeCommon =
1607                     CCA_NAME | CCA_SERVICE_NAME | CCA_CURRENT_VALUE |
1608                     CCA_DISABLED | CCA_DROPDOWN | CCA_MAX_LENGTH | CCA_PRINTABLE | CCA_READONLY | CCA_SIZE |
1609                     CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE | CCA_VALUE;
1610                 m_nIncludeSpecial = SCA_AUTOMATIC_COMPLETION;
1611                 m_nIncludeDatabase = DA_CONVERT_EMPTY | DA_DATA_FIELD | DA_INPUT_REQUIRED | DA_LIST_SOURCE | DA_LIST_SOURCE_TYPE;
1612                 m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE | EA_ON_SELECT;
1613                 break;
1614 
1615             case FormComponentType::LISTBOX:
1616                 m_eType = LISTBOX;
1617                 m_nIncludeCommon =
1618                     CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_DROPDOWN |
1619                     CCA_PRINTABLE | CCA_SIZE | CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE;
1620                 m_nIncludeSpecial = SCA_MULTIPLE;
1621                 m_nIncludeDatabase = DA_BOUND_COLUMN | DA_DATA_FIELD | DA_INPUT_REQUIRED | DA_LIST_SOURCE_TYPE;
1622                 m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE | EA_ON_CLICK | EA_ON_DBLCLICK;
1623                 // check if we need to export the ListSource as attribute
1624                 {
1625                     // for a list box, if the ListSourceType is VALUE_LIST, no ListSource is stored, but instead
1626                     // a sequence of pairs which is build from the StringItemList and the ValueList
1627                     ListSourceType eListSourceType = ListSourceType_VALUELIST;
1628                 #if OSL_DEBUG_LEVEL > 0
1629                     sal_Bool bSuccess =
1630                 #endif
1631                     m_xProps->getPropertyValue(PROPERTY_LISTSOURCETYPE) >>= eListSourceType;
1632                     OSL_ENSURE(bSuccess, "OControlExport::examineControl: could not retrieve the ListSourceType!");
1633                     if (ListSourceType_VALUELIST != eListSourceType)
1634                     {
1635                         m_nIncludeDatabase |= DA_LIST_SOURCE;
1636                     }
1637                 }
1638 
1639                 break;
1640 
1641             case FormComponentType::COMMANDBUTTON:
1642                 m_eType = BUTTON;
1643                 m_nIncludeCommon |= CCA_TAB_STOP | CCA_LABEL;
1644                 m_nIncludeSpecial = SCA_DEFAULT_BUTTON | SCA_TOGGLE | SCA_FOCUS_ON_CLICK | SCA_IMAGE_POSITION | SCA_REPEAT_DELAY;
1645                 // NO BREAK !
1646             case FormComponentType::IMAGEBUTTON:
1647                 if (BUTTON != m_eType)
1648                 {
1649                     // not coming from the previous case
1650                     m_eType = IMAGE;
1651                 }
1652                 m_nIncludeCommon |=
1653                     CCA_NAME | CCA_SERVICE_NAME | CCA_BUTTON_TYPE | CCA_DISABLED |
1654                     CCA_IMAGE_DATA | CCA_PRINTABLE | CCA_TAB_INDEX | CCA_TARGET_FRAME |
1655                     CCA_TARGET_LOCATION | CCA_TITLE;
1656                 m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CLICK  | EA_ON_DBLCLICK;
1657                 break;
1658 
1659             case FormComponentType::CHECKBOX:
1660                 m_eType = CHECKBOX;
1661                 m_nIncludeSpecial = SCA_CURRENT_STATE | SCA_IS_TRISTATE | SCA_STATE;
1662                 // NO BREAK !
1663             case FormComponentType::RADIOBUTTON:
1664                 m_nIncludeCommon =
1665                     CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_LABEL | CCA_PRINTABLE |
1666                     CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE | CCA_VALUE | CCA_VISUAL_EFFECT;
1667                 if (CHECKBOX != m_eType)
1668                 {   // not coming from the previous case
1669                     m_eType = RADIO;
1670                     m_nIncludeCommon |= CCA_CURRENT_SELECTED | CCA_SELECTED;
1671                 }
1672                 if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_IMAGE_POSITION ) )
1673                     m_nIncludeSpecial |= SCA_IMAGE_POSITION;
1674                 m_nIncludeDatabase = DA_DATA_FIELD | DA_INPUT_REQUIRED;
1675                 m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE;
1676                 break;
1677 
1678             case FormComponentType::GROUPBOX:
1679                 m_eType = FRAME;
1680                 m_nIncludeCommon =
1681                     CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_LABEL |
1682                     CCA_PRINTABLE | CCA_TITLE | CCA_FOR;
1683                 m_nIncludeEvents = EA_CONTROL_EVENTS;
1684                 break;
1685 
1686             case FormComponentType::IMAGECONTROL:
1687                 m_eType = IMAGE_FRAME;
1688                 m_nIncludeCommon =
1689                     CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_IMAGE_DATA |
1690                     CCA_PRINTABLE | CCA_READONLY | CCA_TITLE;
1691                 m_nIncludeDatabase = DA_DATA_FIELD | DA_INPUT_REQUIRED;
1692                 m_nIncludeEvents = EA_CONTROL_EVENTS;
1693                 break;
1694 
1695             case FormComponentType::HIDDENCONTROL:
1696                 m_eType = HIDDEN;
1697                 m_nIncludeCommon =
1698                     CCA_NAME | CCA_SERVICE_NAME | CCA_VALUE;
1699                 break;
1700 
1701             case FormComponentType::GRIDCONTROL:
1702                 m_eType = GRID;
1703                 m_nIncludeCommon =
1704                     CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_PRINTABLE |
1705                     CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE;
1706                 m_nIncludeEvents = EA_CONTROL_EVENTS;
1707                 break;
1708 
1709             case FormComponentType::SCROLLBAR:
1710             case FormComponentType::SPINBUTTON:
1711                 m_eType = VALUERANGE;
1712                 m_nIncludeCommon =
1713                     CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_PRINTABLE |
1714                     CCA_TITLE | CCA_CURRENT_VALUE | CCA_VALUE | CCA_ORIENTATION;
1715                 m_nIncludeSpecial = SCA_MAX_VALUE | SCA_STEP_SIZE | SCA_MIN_VALUE | SCA_REPEAT_DELAY;
1716 
1717                 if ( m_nClassId == FormComponentType::SCROLLBAR )
1718                     m_nIncludeSpecial |= SCA_PAGE_STEP_SIZE ;
1719 
1720                 m_nIncludeEvents = EA_CONTROL_EVENTS;
1721                 break;
1722 
1723             default:
1724                 OSL_ENSURE(sal_False, "OControlExport::examineControl: unknown control type (class id)!");
1725                 // NO break!
1726 
1727             case FormComponentType::NAVIGATIONBAR:
1728                 // TODO: should we have an own file format for this?
1729                 // NO break
1730 
1731             case FormComponentType::CONTROL:
1732                 m_eType = GENERIC_CONTROL;
1733                 // unknown control type
1734                 m_nIncludeCommon = CCA_NAME | CCA_SERVICE_NAME;
1735                     // at least a name should be there, 'cause without a name the control could never have been
1736                     // inserted into it's parent container
1737                     // In addition, the service name is absolutely necessary to create the control upon reading.
1738                 m_nIncludeEvents = EA_CONTROL_EVENTS;
1739                     // we always should be able to export events - this is not control type dependent
1740                 break;
1741         }
1742 
1743         // in general, all control types need to export the control id
1744         m_nIncludeCommon |= CCA_CONTROL_ID;
1745 
1746         // is is a control bound to a calc cell?
1747         if ( FormCellBindingHelper::livesInSpreadsheetDocument( m_xProps ) )
1748         {
1749             FormCellBindingHelper aHelper( m_xProps, NULL );
1750             {
1751                 if ( aHelper.isCellBinding( aHelper.getCurrentBinding( ) ) )
1752                 {
1753                     m_nIncludeBindings |= BA_LINKED_CELL;
1754                     if ( m_nClassId == FormComponentType::LISTBOX )
1755                         m_nIncludeBindings |= BA_LIST_LINKING_TYPE;
1756                 }
1757             }
1758 
1759             // is it a list-like control which uses a calc cell range as list source?
1760             {
1761                 if ( aHelper.isCellRangeListSource( aHelper.getCurrentListSource( ) ) )
1762                     m_nIncludeBindings |= BA_LIST_CELL_RANGE;
1763             }
1764         }
1765 
1766         // is control bound to XForms?
1767         if( getXFormsBindName( m_xProps ).getLength() > 0 )
1768         {
1769             m_nIncludeBindings |= BA_XFORMS_BIND;
1770         }
1771 
1772         // is (list-)control bound to XForms list?
1773         if( getXFormsListBindName( m_xProps ).getLength() > 0 )
1774         {
1775             m_nIncludeBindings |= BA_XFORMS_LISTBIND;
1776         }
1777 
1778         // does the control have an XForms submission?
1779         if( getXFormsSubmissionName( m_xProps ).getLength() > 0 )
1780         {
1781             m_nIncludeBindings |= BA_XFORMS_SUBMISSION;
1782         }
1783     }
1784 
1785     //---------------------------------------------------------------------
1786     void OControlExport::exportCellBindingAttributes( bool _bIncludeListLinkageType )
1787     {
1788         try
1789         {
1790             FormCellBindingHelper aHelper( m_xProps, NULL );
1791             Reference< XValueBinding > xBinding( aHelper.getCurrentBinding() );
1792             OSL_ENSURE( xBinding.is(), "OControlExport::exportCellBindingAttributes: invalid bindable or invalid binding!" );
1793             if ( xBinding.is() )
1794             {
1795                 // ....................................................
1796                 AddAttribute(
1797                     OAttributeMetaData::getBindingAttributeNamespace( BA_LINKED_CELL ),
1798                     OAttributeMetaData::getBindingAttributeName( BA_LINKED_CELL ),
1799                     aHelper.getStringAddressFromCellBinding( xBinding )
1800                 );
1801 
1802                 // ....................................................
1803                 if ( _bIncludeListLinkageType )
1804                 {
1805                     sal_Int16 nLinkageType = aHelper.isCellIntegerBinding( xBinding ) ? 1 : 0;
1806 
1807                     ::rtl::OUStringBuffer sBuffer;
1808                     m_rContext.getGlobalContext().GetMM100UnitConverter().convertEnum(
1809                         sBuffer,
1810                         (sal_uInt16)nLinkageType,
1811                         OEnumMapper::getEnumMap( OEnumMapper::epListLinkageType )
1812                     );
1813 
1814                     AddAttribute(
1815                         OAttributeMetaData::getBindingAttributeNamespace( BA_LIST_LINKING_TYPE ),
1816                         OAttributeMetaData::getBindingAttributeName( BA_LIST_LINKING_TYPE ),
1817                         sBuffer.makeStringAndClear()
1818                     );
1819                 }
1820 
1821             }
1822         }
1823         catch( const Exception& )
1824         {
1825             OSL_ENSURE( sal_False, "OControlExport::exportCellBindingAttributes: caught an exception!" );
1826         }
1827     }
1828 
1829     //---------------------------------------------------------------------
1830     void OControlExport::exportXFormsBindAttributes()
1831     {
1832         rtl::OUString sBindName = getXFormsBindName( m_xProps );
1833         AddAttribute( XML_NAMESPACE_XFORMS, XML_BIND, sBindName );
1834     }
1835     //---------------------------------------------------------------------
1836     void OControlExport::exportXFormsListAttributes()
1837     {
1838         rtl::OUString sBindName = getXFormsListBindName( m_xProps );
1839         AddAttribute( XML_NAMESPACE_FORM, XML_XFORMS_LIST_SOURCE, sBindName );
1840     }
1841     //---------------------------------------------------------------------
1842     void OControlExport::exportXFormsSubmissionAttributes()
1843     {
1844         rtl::OUString sSubmission = getXFormsSubmissionName( m_xProps );
1845         AddAttribute( XML_NAMESPACE_FORM, XML_XFORMS_SUBMISSION, sSubmission );
1846     }
1847     //---------------------------------------------------------------------
1848     void OControlExport::exportCellListSourceRange( )
1849     {
1850         try
1851         {
1852             Reference< XListEntrySink > xSink( m_xProps, UNO_QUERY );
1853             Reference< XListEntrySource > xSource;
1854             if ( xSink.is() )
1855                 xSource = xSource.query( xSink->getListEntrySource() );
1856             OSL_ENSURE( xSource.is(), "OControlExport::exportCellListSourceRange: list source or sink!" );
1857             if ( xSource.is() )
1858             {
1859                 FormCellBindingHelper aHelper( m_xProps, NULL );
1860 
1861                 AddAttribute(
1862                     OAttributeMetaData::getBindingAttributeNamespace( BA_LIST_CELL_RANGE ),
1863                     OAttributeMetaData::getBindingAttributeName( BA_LIST_CELL_RANGE ),
1864                     aHelper.getStringAddressFromCellListSource( xSource )
1865                 );
1866             }
1867         }
1868         catch( const Exception& )
1869         {
1870             OSL_ENSURE( sal_False, "OControlExport::exportCellListSourceRange: caught an exception!" );
1871         }
1872     }
1873 
1874     //---------------------------------------------------------------------
1875     void OControlExport::exportImagePositionAttributes()
1876     {
1877         try
1878         {
1879             sal_Int16 nImagePosition = ImagePosition::Centered;
1880             OSL_VERIFY( m_xProps->getPropertyValue( PROPERTY_IMAGE_POSITION ) >>= nImagePosition );
1881             OSL_ENSURE( ( nImagePosition >= ImagePosition::LeftTop ) && ( nImagePosition <= ImagePosition::Centered ),
1882                 "OControlExport::exportImagePositionAttributes: don't know this image position!" );
1883 
1884             if ( ( nImagePosition < ImagePosition::LeftTop ) || ( nImagePosition > ImagePosition::Centered ) )
1885                 // this is important to prevent potential buffer overflows below, so don't optimize
1886                 nImagePosition = ImagePosition::Centered;
1887 
1888             if ( nImagePosition == ImagePosition::Centered )
1889             {
1890                 AddAttribute( XML_NAMESPACE_FORM, GetXMLToken( XML_IMAGE_POSITION ), GetXMLToken( XML_CENTER ) );
1891             }
1892             else
1893             {
1894                 XMLTokenEnum eXmlImagePositions[] =
1895                 {
1896                     XML_START, XML_END, XML_TOP, XML_BOTTOM
1897                 };
1898                 XMLTokenEnum eXmlImageAligns[] =
1899                 {
1900                     XML_START, XML_CENTER, XML_END
1901                 };
1902 
1903                 XMLTokenEnum eXmlImagePosition = eXmlImagePositions[ nImagePosition / 3 ];
1904                 XMLTokenEnum eXmlImageAlign    = eXmlImageAligns   [ nImagePosition % 3 ];
1905 
1906                 AddAttribute( XML_NAMESPACE_FORM, GetXMLToken( XML_IMAGE_POSITION ), GetXMLToken( eXmlImagePosition ) );
1907                 AddAttribute( XML_NAMESPACE_FORM, GetXMLToken( XML_IMAGE_ALIGN    ), GetXMLToken( eXmlImageAlign    ) );
1908             }
1909 
1910             exportedProperty( PROPERTY_IMAGE_POSITION );
1911             // some of the controls which have an ImagePosition also have an ImageAlign for compatibility
1912             // reasons. Since the ImageAlign values simply represent a sub set of the ImagePosition values,
1913             // we don't need to export ImageAlign anymore
1914             exportedProperty( PROPERTY_IMAGE_ALIGN );
1915         }
1916         catch( const Exception& )
1917         {
1918             DBG_UNHANDLED_EXCEPTION();
1919         }
1920     }
1921 
1922     //---------------------------------------------------------------------
1923     bool OControlExport::controlHasActiveDataBinding() const
1924     {
1925         try
1926         {
1927             // currently exchanging the data with a database column?
1928             ::rtl::OUString sBoundFieldPropertyName( RTL_CONSTASCII_USTRINGPARAM( "BoundField" ) );
1929             if ( m_xPropertyInfo.is() && m_xPropertyInfo->hasPropertyByName( sBoundFieldPropertyName ) )
1930             {
1931                 Reference< XPropertySet > xBoundField;
1932                 m_xProps->getPropertyValue( sBoundFieldPropertyName ) >>= xBoundField;
1933                 if ( xBoundField.is() )
1934                     return true;
1935             }
1936 
1937             // currently exchanging data with an external binding?
1938             Reference< XBindableValue > xBindable( m_xProps, UNO_QUERY );
1939             if ( xBindable.is() && xBindable->getValueBinding().is() )
1940                 return true;
1941         }
1942         catch( const Exception& )
1943         {
1944             OSL_ENSURE( sal_False, "OColumnExport::controlHasActiveDataBinding: caught an exception!" );
1945         }
1946 
1947         return false;
1948     }
1949 
1950     //---------------------------------------------------------------------
1951     bool OControlExport::controlHasUserSuppliedListEntries() const
1952     {
1953         try
1954         {
1955             // an external list source?
1956             Reference< XListEntrySink > xEntrySink( m_xProps, UNO_QUERY );
1957             if ( xEntrySink.is() && xEntrySink->getListEntrySource().is() )
1958                 return false;
1959 
1960             if ( m_xPropertyInfo.is() && m_xPropertyInfo->hasPropertyByName( PROPERTY_LISTSOURCETYPE ) )
1961             {
1962                 ListSourceType eListSourceType = ListSourceType_VALUELIST;
1963                 OSL_VERIFY( m_xProps->getPropertyValue( PROPERTY_LISTSOURCETYPE ) >>= eListSourceType );
1964                 if ( eListSourceType == ListSourceType_VALUELIST )
1965                     // for value lists, the list entries as entered by the user are used
1966                     return true;
1967 
1968                 // for every other type, the list entries are filled with some data obtained
1969                 // from a database - if and only if the ListSource property is not empty
1970                 return ( 0 == getScalarListSourceValue().getLength() );
1971             }
1972         }
1973         catch( const Exception& )
1974         {
1975             OSL_ENSURE( sal_False, "OControlExport::controlHasUserSuppliedListEntries: caught an exception!" );
1976         }
1977 
1978         OSL_ENSURE( sal_False, "OControlExport::controlHasUserSuppliedListEntries: unreachable code!" );
1979             // this method should be called for list and combo boxes only
1980         return true;
1981     }
1982 
1983     //=====================================================================
1984     //= OColumnExport
1985     //=====================================================================
1986     //---------------------------------------------------------------------
1987     OColumnExport::OColumnExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxControl, const ::rtl::OUString& _rControlId,
1988         const Sequence< ScriptEventDescriptor >& _rEvents)
1989         :OControlExport(_rContext, _rxControl, _rControlId, ::rtl::OUString(), _rEvents)
1990     {
1991     }
1992 
1993     //---------------------------------------------------------------------
1994     OColumnExport::~OColumnExport()
1995     {
1996         implEndElement();
1997     }
1998 
1999     //---------------------------------------------------------------------
2000     void OColumnExport::exportServiceNameAttribute()
2001     {
2002         // the attribute "service name" (which has a slightly different meaning for columns
2003         DBG_CHECK_PROPERTY( PROPERTY_COLUMNSERVICENAME, ::rtl::OUString );
2004         ::rtl::OUString sColumnServiceName;
2005         m_xProps->getPropertyValue(PROPERTY_COLUMNSERVICENAME) >>= sColumnServiceName;
2006         // the service name is a full qualified one (i.e. com.sun.star.form.TextField), but the
2007         // real service name for the column (for use with the XGridColumnFactory) is only the last
2008         // token of this complete name.
2009         sal_Int32 nLastSep = sColumnServiceName.lastIndexOf('.');
2010         OSL_ENSURE(-1 != nLastSep, "OColumnExport::startExportElement: invalid service name!");
2011         sColumnServiceName = sColumnServiceName.copy(nLastSep + 1);
2012         sColumnServiceName =
2013             m_rContext.getGlobalContext().GetNamespaceMap().GetQNameByKey(
2014                 XML_NAMESPACE_OOO, sColumnServiceName );
2015         // add the attribute
2016         AddAttribute( OAttributeMetaData::getCommonControlAttributeNamespace(CCA_SERVICE_NAME)
2017                     , OAttributeMetaData::getCommonControlAttributeName(CCA_SERVICE_NAME)
2018                     , sColumnServiceName);
2019         // flag the property as "handled"
2020         exportedProperty(PROPERTY_COLUMNSERVICENAME);
2021 
2022     }
2023 
2024     //---------------------------------------------------------------------
2025     const sal_Char* OColumnExport::getOuterXMLElementName() const
2026     {
2027         return "column";
2028     }
2029 
2030     //---------------------------------------------------------------------
2031     void OColumnExport::exportAttributes()
2032     {
2033         OControlExport::exportAttributes();
2034 
2035         // the attribute "label"
2036         exportStringPropertyAttribute(
2037             OAttributeMetaData::getCommonControlAttributeNamespace(CCA_LABEL),
2038             OAttributeMetaData::getCommonControlAttributeName(CCA_LABEL),
2039             PROPERTY_LABEL);
2040 
2041         // the style attribute
2042         ::rtl::OUString sStyleName = m_rContext.getObjectStyleName( m_xProps );
2043         if ( sStyleName.getLength() )
2044         {
2045             AddAttribute(
2046                 OAttributeMetaData::getSpecialAttributeNamespace( SCA_COLUMN_STYLE_NAME ),
2047                 OAttributeMetaData::getSpecialAttributeName( SCA_COLUMN_STYLE_NAME ),
2048                 sStyleName
2049             );
2050         }
2051     }
2052 
2053     //---------------------------------------------------------------------
2054     void OColumnExport::examine()
2055     {
2056         OControlExport::examine();
2057 
2058         // grid columns miss some properties of the controls they're representing
2059         m_nIncludeCommon &= ~(CCA_FOR | CCA_PRINTABLE | CCA_TAB_INDEX | CCA_TAB_STOP | CCA_LABEL);
2060         m_nIncludeSpecial &= ~(SCA_ECHO_CHAR | SCA_AUTOMATIC_COMPLETION | SCA_MULTIPLE | SCA_MULTI_LINE);
2061 
2062         if (FormComponentType::DATEFIELD != m_nClassId)
2063             // except date fields, no column has the DropDown property
2064             m_nIncludeCommon &= ~CCA_DROPDOWN;
2065     }
2066 
2067     //=====================================================================
2068     //= OFormExport
2069     //=====================================================================
2070     //---------------------------------------------------------------------
2071     OFormExport::OFormExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxForm,
2072         const Sequence< ScriptEventDescriptor >& _rEvents)
2073         :OElementExport(_rContext, _rxForm, _rEvents)
2074         ,m_bCreateConnectionResourceElement(sal_False)
2075     {
2076         OSL_ENSURE(m_xProps.is(), "OFormExport::OFormExport: invalid arguments!");
2077     }
2078 
2079     //---------------------------------------------------------------------
2080     const sal_Char* OFormExport::getXMLElementName() const
2081     {
2082         return "form";
2083     }
2084 
2085     //---------------------------------------------------------------------
2086     void OFormExport::exportSubTags()
2087     {
2088         if ( m_bCreateConnectionResourceElement && m_xProps.is() )
2089         {
2090             m_rContext.getGlobalContext().ClearAttrList();
2091             ::rtl::OUString sPropValue;
2092             m_xProps->getPropertyValue( PROPERTY_DATASOURCENAME ) >>= sPropValue; // if set it is a file url
2093             if ( !sPropValue.getLength() )
2094                 m_xProps->getPropertyValue( PROPERTY_URL ) >>= sPropValue;
2095             if ( sPropValue.getLength() )
2096                 AddAttribute(
2097                     OAttributeMetaData::getCommonControlAttributeNamespace(CCA_TARGET_LOCATION),
2098                     OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_LOCATION),
2099                     sPropValue);
2100             if ( m_rContext.getGlobalContext().GetAttrList().getLength() )
2101             {
2102                 SvXMLElementExport aFormElement(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, xmloff::token::XML_CONNECTION_RESOURCE, sal_True, sal_True);
2103             }
2104         }
2105 
2106         // let the base class export the remaining properties and the events
2107         OElementExport::exportSubTags();
2108         // loop through all children
2109         Reference< XIndexAccess > xCollection(m_xProps, UNO_QUERY);
2110         OSL_ENSURE(xCollection.is(), "OFormLayerXMLExport::implExportForm: a form which is not an index access? Suspic�ous!");
2111 
2112         if (xCollection.is())
2113             m_rContext.exportCollectionElements(xCollection);
2114     }
2115 
2116     //---------------------------------------------------------------------
2117     void OFormExport::exportAttributes()
2118     {
2119         sal_Int32 i=0;
2120 
2121         // ---------------------
2122         // the string properties
2123         {
2124             static FormAttributes eStringPropertyIds[] =
2125             {
2126                 faName, /*faAction,*/ faCommand, faFilter, faOrder
2127             };
2128             static ::rtl::OUString aStringPropertyNames[] =
2129             {
2130                 PROPERTY_NAME, /*PROPERTY_TARGETURL,*/ PROPERTY_COMMAND, PROPERTY_FILTER, PROPERTY_ORDER
2131             };
2132             sal_Int32 nIdCount = sizeof(eStringPropertyIds) / sizeof(eStringPropertyIds[0]);
2133         #if OSL_DEBUG_LEVEL > 0
2134             sal_Int32 nNameCount = sizeof(aStringPropertyNames) / sizeof(aStringPropertyNames[0]);
2135             OSL_ENSURE((nIdCount == nNameCount),
2136                 "OFormExport::exportAttributes: somebody tampered with the maps (1)!");
2137         #endif
2138             for (i=0; i<nIdCount; ++i)
2139                 exportStringPropertyAttribute(
2140                     OAttributeMetaData::getFormAttributeNamespace(eStringPropertyIds[i]),
2141                     OAttributeMetaData::getFormAttributeName(eStringPropertyIds[i]),
2142                     aStringPropertyNames[i]);
2143 
2144             // #i112082# xlink:type is added as part of exportTargetLocationAttribute
2145 
2146             // now export the data source name or databaselocation or connection resource
2147             ::rtl::OUString sPropValue;
2148             m_xProps->getPropertyValue( PROPERTY_DATASOURCENAME ) >>= sPropValue;
2149             m_bCreateConnectionResourceElement = !sPropValue.getLength();
2150             if ( !m_bCreateConnectionResourceElement )
2151             {
2152                 INetURLObject aURL(sPropValue);
2153                 m_bCreateConnectionResourceElement = ( aURL.GetProtocol() == INET_PROT_FILE );
2154                 if ( !m_bCreateConnectionResourceElement )
2155                     exportStringPropertyAttribute(
2156                         OAttributeMetaData::getFormAttributeNamespace(faDatasource),
2157                         OAttributeMetaData::getFormAttributeName(faDatasource),
2158                         PROPERTY_DATASOURCENAME);
2159             }
2160             else
2161                 exportedProperty(PROPERTY_URL);
2162             if ( m_bCreateConnectionResourceElement )
2163                 exportedProperty(PROPERTY_DATASOURCENAME);
2164         }
2165 
2166         // ----------------------
2167         // the boolean properties
2168         {
2169             static FormAttributes eBooleanPropertyIds[] =
2170             {
2171                 faAllowDeletes, faAllowInserts, faAllowUpdates, faApplyFilter, faEscapeProcessing, faIgnoreResult
2172             };
2173             static const ::rtl::OUString* pBooleanPropertyNames[] =
2174             {
2175                 &PROPERTY_ALLOWDELETES, &PROPERTY_ALLOWINSERTS, &PROPERTY_ALLOWUPDATES, &PROPERTY_APPLYFILTER, &PROPERTY_ESCAPEPROCESSING, &PROPERTY_IGNORERESULT
2176             };
2177             static sal_Int8 nBooleanPropertyAttrFlags[] =
2178             {
2179                 BOOLATTR_DEFAULT_TRUE, BOOLATTR_DEFAULT_TRUE, BOOLATTR_DEFAULT_TRUE, BOOLATTR_DEFAULT_FALSE, BOOLATTR_DEFAULT_TRUE, BOOLATTR_DEFAULT_FALSE
2180             };
2181             sal_Int32 nIdCount = sizeof(eBooleanPropertyIds) / sizeof(eBooleanPropertyIds[0]);
2182         #if OSL_DEBUG_LEVEL > 0
2183             sal_Int32 nNameCount = sizeof(pBooleanPropertyNames) / sizeof(pBooleanPropertyNames[0]);
2184             sal_Int32 nFlagsCount = sizeof(nBooleanPropertyAttrFlags) / sizeof(nBooleanPropertyAttrFlags[0]);
2185             OSL_ENSURE((nIdCount == nNameCount) && (nNameCount == nFlagsCount),
2186                 "OFormExport::exportAttributes: somebody tampered with the maps (2)!");
2187         #endif
2188             for (i=0; i<nIdCount; ++i)
2189                 exportBooleanPropertyAttribute(
2190                     OAttributeMetaData::getFormAttributeNamespace(eBooleanPropertyIds[i]),
2191                     OAttributeMetaData::getFormAttributeName(eBooleanPropertyIds[i]),
2192                     *(pBooleanPropertyNames[i]),
2193                     nBooleanPropertyAttrFlags[i]
2194                 );
2195         }
2196 
2197         // -------------------
2198         // the enum properties
2199         {
2200             static FormAttributes eEnumPropertyIds[] =
2201             {
2202                 faEnctype, faMethod, faCommandType, faNavigationMode, faTabbingCycle
2203             };
2204             static const sal_Char* pEnumPropertyNames[] =
2205             {
2206                 PROPERTY_SUBMIT_ENCODING, PROPERTY_SUBMIT_METHOD, PROPERTY_COMMAND_TYPE, PROPERTY_NAVIGATION, PROPERTY_CYCLE
2207             };
2208             static OEnumMapper::EnumProperties eEnumPropertyMaps[] =
2209             {
2210                 OEnumMapper::epSubmitEncoding, OEnumMapper::epSubmitMethod, OEnumMapper::epCommandType, OEnumMapper::epNavigationType, OEnumMapper::epTabCyle
2211             };
2212             static sal_Int32 nEnumPropertyAttrDefaults[] =
2213             {
2214                 FormSubmitEncoding_URL, FormSubmitMethod_GET, CommandType::COMMAND, NavigationBarMode_CURRENT, TabulatorCycle_RECORDS
2215             };
2216             static sal_Bool nEnumPropertyAttrDefaultFlags[] =
2217             {
2218                 sal_False, sal_False, sal_False, sal_False, sal_True
2219             };
2220             sal_Int32 nIdCount = sizeof(eEnumPropertyIds) / sizeof(eEnumPropertyIds[0]);
2221         #if OSL_DEBUG_LEVEL > 0
2222             sal_Int32 nNameCount = sizeof(pEnumPropertyNames) / sizeof(pEnumPropertyNames[0]);
2223             sal_Int32 nDefaultCount = sizeof(nEnumPropertyAttrDefaults) / sizeof(nEnumPropertyAttrDefaults[0]);
2224             sal_Int32 nDefaultFlagCount = sizeof(nEnumPropertyAttrDefaultFlags) / sizeof(nEnumPropertyAttrDefaultFlags[0]);
2225             sal_Int32 nMapCount = sizeof(eEnumPropertyMaps) / sizeof(eEnumPropertyMaps[0]);
2226             OSL_ENSURE((nIdCount == nNameCount) && (nNameCount == nDefaultCount) && (nDefaultCount == nDefaultFlagCount) && (nDefaultFlagCount == nMapCount),
2227                 "OFormExport::exportAttributes: somebody tampered with the maps (3)!");
2228         #endif
2229             for (i=0; i<nIdCount; ++i)
2230                 exportEnumPropertyAttribute(
2231                     OAttributeMetaData::getFormAttributeNamespace(eEnumPropertyIds[i]),
2232                     OAttributeMetaData::getFormAttributeName(eEnumPropertyIds[i]),
2233                     pEnumPropertyNames[i],
2234                     OEnumMapper::getEnumMap(eEnumPropertyMaps[i]),
2235                     nEnumPropertyAttrDefaults[i],
2236                     nEnumPropertyAttrDefaultFlags[i]
2237                 );
2238         }
2239 
2240         // the service name
2241         exportServiceNameAttribute();
2242         // the target frame
2243         exportTargetFrameAttribute();
2244         // the target URL
2245         exportTargetLocationAttribute(true);    // #i110911# add type attribute (for form, but not for control)
2246 
2247         // master fields
2248         exportStringSequenceAttribute(
2249             OAttributeMetaData::getFormAttributeNamespace(faMasterFields),
2250             OAttributeMetaData::getFormAttributeName(faMasterFields),
2251             PROPERTY_MASTERFIELDS);
2252         // detail fields
2253         exportStringSequenceAttribute(
2254             OAttributeMetaData::getFormAttributeNamespace(faDetailFiels),
2255             OAttributeMetaData::getFormAttributeName(faDetailFiels),
2256             PROPERTY_DETAILFIELDS);
2257     }
2258 //.........................................................................
2259 }   // namespace xmloff
2260 //.........................................................................
2261