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