/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

#include "elementexport.hxx"
#include "strings.hxx"
#include "xmloff/xmlnmspe.hxx"
#include "eventexport.hxx"
#include "formenums.hxx"
#include "formcellbinding.hxx"
#include "formcellbinding.hxx"
#include "xmloff/xformsexport.hxx"
#include "property_meta_data.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/io/XPersistObject.hpp>
#include <com/sun/star/form/FormComponentType.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/form/FormSubmitEncoding.hpp>
#include <com/sun/star/form/FormSubmitMethod.hpp>
#include <com/sun/star/sdb/CommandType.hpp>
#include <com/sun/star/form/NavigationBarMode.hpp>
#include <com/sun/star/form/TabulatorCycle.hpp>
#include <com/sun/star/form/FormButtonType.hpp>
#include <com/sun/star/awt/ScrollBarOrientation.hpp>
#include <com/sun/star/awt/VisualEffect.hpp>
#include <com/sun/star/form/ListSourceType.hpp>
#include <com/sun/star/awt/ImagePosition.hpp>
/** === end UNO includes === **/

#include <tools/wintypes.hxx>		// for check states
#include <xmloff/txtprmap.hxx>
#include <com/sun/star/form/binding/XBindableValue.hpp>
#include <com/sun/star/form/binding/XListEntrySink.hpp>
#include <tools/urlobj.hxx>
#include <xmloff/xmlexp.hxx>
#include <xmloff/nmspmap.hxx>
#include <xmloff/XMLEventExport.hxx>
#include <xmloff/xmluconv.hxx>
#include <xmloff/xmltoken.hxx>
#include <tools/time.hxx>
#include <tools/diagnose_ex.h>
#include <comphelper/extract.hxx>

#include <stdio.h>
#include <algorithm>

//.........................................................................
namespace xmloff
{
//.........................................................................

    #if OSL_DEBUG_LEVEL > 0
        #define RESET_BIT( bitfield, bit ) \
			bitfield = bitfield & ~bit
    #else
        #define RESET_BIT( bitfield, bit )
    #endif

    using namespace ::xmloff::token;
	using namespace ::com::sun::star::uno;
	using namespace ::com::sun::star::sdb;
	using namespace ::com::sun::star::awt;
	using namespace ::com::sun::star::form;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::beans;
	using namespace ::com::sun::star::container;
	using namespace ::com::sun::star::script;
	using namespace ::com::sun::star::io;
	using namespace ::com::sun::star::table;
	using namespace ::com::sun::star::text;
    using namespace ::com::sun::star::form::binding;

	//=====================================================================
	//= OElementExport
	//=====================================================================
	OElementExport::OElementExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxProps,
		const Sequence< ScriptEventDescriptor >& _rEvents)
		:OPropertyExport(_rContext, _rxProps)
		,m_aEvents(_rEvents)
		,m_pXMLElement(NULL)
	{
	}

	//---------------------------------------------------------------------
	OElementExport::~OElementExport()
	{
		implEndElement();
	}

	//---------------------------------------------------------------------
	void OElementExport::doExport()
	{
		// collect some general information about the element
		examine();

		// first add the attributes necessary for the element
		m_rContext.getGlobalContext().ClearAttrList();

		// add the attributes
		exportAttributes();

		// start the XML element
		implStartElement(getXMLElementName());

		// the sub elements (mostly control type dependent)
		exportSubTags();

		implEndElement();
	}

	//---------------------------------------------------------------------
	void OElementExport::examine()
	{
		// nothing to do here
	}

	//---------------------------------------------------------------------
	void OElementExport::exportAttributes()
	{
		// nothing to do here
	}

	//---------------------------------------------------------------------
	void OElementExport::exportSubTags()
	{
		// the properties which where not exported 'til now
		exportRemainingProperties();

		// the script:events sub tags
		exportEvents();
	}

	//---------------------------------------------------------------------
	void OElementExport::implStartElement(const sal_Char* _pName)
	{
		m_pXMLElement = new SvXMLElementExport(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, _pName, sal_True, sal_True);
	}

	//---------------------------------------------------------------------
	void OElementExport::implEndElement()
	{
		delete m_pXMLElement;
		m_pXMLElement = NULL;
	}

	//---------------------------------------------------------------------
	void OElementExport::exportServiceNameAttribute()
	{
		Reference< XPersistObject > xPersistence(m_xProps, UNO_QUERY);
		if (!xPersistence.is())
		{
			OSL_ENSURE(sal_False, "OElementExport::exportServiceNameAttribute: no XPersistObject!");
			return;
		}

		::rtl::OUString sServiceName = xPersistence->getServiceName();
		// we don't want to write the old service name directly: it's a name used for compatibility reasons, but
		// as we start some kind of new file format here (with this xml export), we don't care about
		// compatibility ...
		// So we translate the old persistence service name into new ones, if possible

		::rtl::OUString sToWriteServiceName = sServiceName;
#define CHECK_N_TRANSLATE( name )	\
		else if (0 == sServiceName.compareToAscii(SERVICE_PERSISTENT_COMPONENT_##name))	\
			sToWriteServiceName = SERVICE_##name

		if (sal_False)
			;
		CHECK_N_TRANSLATE( FORM );
		CHECK_N_TRANSLATE( FORM );
		CHECK_N_TRANSLATE( LISTBOX );
		CHECK_N_TRANSLATE( COMBOBOX );
		CHECK_N_TRANSLATE( RADIOBUTTON );
		CHECK_N_TRANSLATE( GROUPBOX );
		CHECK_N_TRANSLATE( FIXEDTEXT );
		CHECK_N_TRANSLATE( COMMANDBUTTON );
		CHECK_N_TRANSLATE( CHECKBOX );
		CHECK_N_TRANSLATE( GRID );
		CHECK_N_TRANSLATE( IMAGEBUTTON );
		CHECK_N_TRANSLATE( FILECONTROL );
		CHECK_N_TRANSLATE( TIMEFIELD );
		CHECK_N_TRANSLATE( DATEFIELD );
		CHECK_N_TRANSLATE( NUMERICFIELD );
		CHECK_N_TRANSLATE( CURRENCYFIELD );
		CHECK_N_TRANSLATE( PATTERNFIELD );
		CHECK_N_TRANSLATE( HIDDENCONTROL );
		CHECK_N_TRANSLATE( IMAGECONTROL );
		CHECK_N_TRANSLATE( FORMATTEDFIELD );
		else if (0 == sServiceName.compareToAscii(SERVICE_PERSISTENT_COMPONENT_EDIT))
		{	// special handling for the edit field: we have two controls using this as persistence service name
			sToWriteServiceName = SERVICE_EDIT;
			Reference< XServiceInfo > xSI(m_xProps, UNO_QUERY);
			if (xSI.is() && xSI->supportsService(SERVICE_FORMATTEDFIELD))
				sToWriteServiceName = SERVICE_FORMATTEDFIELD;
		}
#if OSL_DEBUG_LEVEL > 0
		Reference< XServiceInfo > xSI(m_xProps, UNO_QUERY);
		OSL_ENSURE(xSI.is() && xSI->supportsService(sToWriteServiceName),
			"OElementExport::exportServiceNameAttribute: wrong service name translation!");

#endif
		sToWriteServiceName =
			m_rContext.getGlobalContext().GetNamespaceMap().GetQNameByKey(
				XML_NAMESPACE_OOO, sToWriteServiceName );

		// now write this
		AddAttribute(
			OAttributeMetaData::getCommonControlAttributeNamespace(CCA_SERVICE_NAME),
			OAttributeMetaData::getCommonControlAttributeName(CCA_SERVICE_NAME),
			sToWriteServiceName);
	}

	//---------------------------------------------------------------------
	void OElementExport::exportEvents()
	{
		if (!m_aEvents.getLength())
			// nothing to do
			return;

		Reference< XNameReplace > xWrapper = new OEventDescriptorMapper(m_aEvents);
		m_rContext.getGlobalContext().GetEventExport().Export(xWrapper);
	}

	//=====================================================================
	//= OControlExport
	//=====================================================================
	//---------------------------------------------------------------------
	OControlExport::OControlExport(IFormsExportContext& _rContext,  const Reference< XPropertySet >& _rxControl,
		const ::rtl::OUString& _rControlId, const ::rtl::OUString& _rReferringControls,
		const Sequence< ScriptEventDescriptor >& _rEvents)
		:OElementExport(_rContext, _rxControl, _rEvents)
		,m_sControlId(_rControlId)
		,m_sReferringControls(_rReferringControls)
        ,m_nClassId(FormComponentType::CONTROL)
        ,m_eType( UNKNOWN )
		,m_nIncludeCommon(0)
		,m_nIncludeDatabase(0)
		,m_nIncludeSpecial(0)
		,m_nIncludeEvents(0)
        ,m_nIncludeBindings(0)
		,m_pOuterElement(NULL)
	{
		OSL_ENSURE(m_xProps.is(), "OControlExport::OControlExport: invalid arguments!");
	}

	//---------------------------------------------------------------------
	OControlExport::~OControlExport()
	{
		implEndElement();
	}

	//---------------------------------------------------------------------
	void OControlExport::exportOuterAttributes()
	{
		// the control id
		if (CCA_NAME & m_nIncludeCommon)
		{
			exportStringPropertyAttribute(
				OAttributeMetaData::getCommonControlAttributeNamespace(CCA_NAME),
				OAttributeMetaData::getCommonControlAttributeName(CCA_NAME),
				PROPERTY_NAME
				);
        #if OSL_DEBUG_LEVEL > 0
			//  reset the bit for later checking
			m_nIncludeCommon = m_nIncludeCommon & ~CCA_NAME;
		#endif
		}

		// the service name
		if (m_nIncludeCommon & CCA_SERVICE_NAME)
		{
			exportServiceNameAttribute();
		#if OSL_DEBUG_LEVEL > 0
			//  reset the bit for later checking
			m_nIncludeCommon = m_nIncludeCommon & ~CCA_SERVICE_NAME;
		#endif
		}
	}

	//---------------------------------------------------------------------
	void OControlExport::exportInnerAttributes()
	{
		// the control id
		if (CCA_CONTROL_ID & m_nIncludeCommon)
		{
			OSL_ENSURE(m_sControlId.getLength(), "OControlExport::exportInnerAttributes: have no control id for the control!");
            m_rContext.getGlobalContext().AddAttributeIdLegacy(
                XML_NAMESPACE_FORM, m_sControlId);
		#if OSL_DEBUG_LEVEL > 0
			//  reset the bit for later checking
			m_nIncludeCommon = m_nIncludeCommon & ~CCA_CONTROL_ID;
		#endif
		}

        // "new-style" properties ...
        exportGenericHandlerAttributes();

        // common control attributes
		exportCommonControlAttributes();

		// common database attributes
		exportDatabaseAttributes();

        // attributes related to external bindings
        exportBindingAtributes();

		// attributes special to the respective control type
		exportSpecialAttributes();

		// add the style references to the attributes
		flagStyleProperties();
	}

	//---------------------------------------------------------------------
	void OControlExport::exportAttributes()
	{
		exportOuterAttributes();
	}

	//---------------------------------------------------------------------
	void OControlExport::exportSubTags() throw (Exception)
	{
		// for the upcoming exportRemainingProperties:
		// if a control has the LabelControl property, this is not stored with the control itself, but instead with
		// the control which is referenced by this property. As the base class' exportRemainingProperties doesn't
		// know anything about this, we need to prevent that it tries to export this property
		exportedProperty(PROPERTY_CONTROLLABEL);

        // if it's a control supporting XText, then we need to declare all text-related properties
        // as "already exported". This prevents them from being exported as generic "form:property"-tags.
        // *If* we would export them this way, they would be completely superfluous, and sometimes even
        // disastrous, since they may, at import time, override paragraph properties which already have
        // been set before
        Reference< XText > xControlText( m_xProps, UNO_QUERY );
        if ( xControlText.is() )
        {
            const XMLPropertyMapEntry* pCharAttributeProperties = XMLTextPropertySetMapper::getPropertyMapForType( TEXT_PROP_MAP_TEXT );
            while ( pCharAttributeProperties->msApiName )
            {
                exportedProperty( ::rtl::OUString::createFromAscii( pCharAttributeProperties->msApiName ) );
                ++pCharAttributeProperties;
            }

            const XMLPropertyMapEntry* pParaAttributeProperties = XMLTextPropertySetMapper::getPropertyMapForType( TEXT_PROP_MAP_SHAPE_PARA );
            while ( pParaAttributeProperties->msApiName )
            {
                exportedProperty( ::rtl::OUString::createFromAscii( pParaAttributeProperties->msApiName ) );
                ++pParaAttributeProperties;
            }

            // the RichText property is not exported. The presence of the text:p element
            // will be used - upon reading - as indicator for the value of the RichText property
            exportedProperty( PROPERTY_RICH_TEXT );

            // strange thing: paragraphs support both a CharStrikeout and a CharCrossedOut property
            // The former is a short/enum value, the latter a boolean. The former has a real meaning
            // (the strikeout type), the latter hasn't. But, when the CharCrossedOut is exported and
            // later on imported, it overwrites anything which has previously been imported for
            // CharStrikeout.
            // 2004-04-14 - #i27729# - fs@openoffice.org
            exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharCrossedOut" ) ) );
        }

        if ( m_eType == LISTBOX )
        {
            // will be exported in exportListSourceAsElements:
            if ( controlHasUserSuppliedListEntries() )
                exportedProperty( PROPERTY_DEFAULT_SELECT_SEQ );

            // will not be exported in a generic way. Either exportListSourceAsElements cares
            // for them, or we don't need them
            exportedProperty( PROPERTY_STRING_ITEM_LIST );
            exportedProperty( PROPERTY_VALUE_SEQ );
            exportedProperty( PROPERTY_SELECT_SEQ );
            exportedProperty( PROPERTY_LISTSOURCE );
        }
        if ( m_eType == COMBOBOX )
            exportedProperty( PROPERTY_STRING_ITEM_LIST );

		// let the base class export the remaining properties and the events
		OElementExport::exportSubTags();

		// special sub tags for some controls
		switch (m_eType)
		{
			case LISTBOX:
                // don't export the list entries if the are not provided by the user, but obtained implicitly
                // from other sources
                // #i26944# - 2004-05-17 - fs@openoffice.org
                if ( controlHasUserSuppliedListEntries() )
				    exportListSourceAsElements();
				break;
			case GRID:
			{	// a grid control requires us to store all columns as sub elements
				Reference< XIndexAccess > xColumnContainer(m_xProps, UNO_QUERY);
				OSL_ENSURE(xColumnContainer.is(), "OControlExport::exportSubTags: a grid control which is no IndexAccess?!!");
				if (xColumnContainer.is())
					m_rContext.exportCollectionElements(xColumnContainer);
			}
			break;
			case COMBOBOX:
			{	// a combox box description has sub elements: the items
				DBG_CHECK_PROPERTY( PROPERTY_STRING_ITEM_LIST, Sequence< ::rtl::OUString > );

                // don't export the list entries if the are not provided by the user, but obtained implicitly
                // from other sources
                // #i26944# - 2004-05-17 - fs@openoffice.org
                if ( controlHasUserSuppliedListEntries() )
                {
				    // get the item list
				    Sequence< ::rtl::OUString > aListItems;
				    m_xProps->getPropertyValue(PROPERTY_STRING_ITEM_LIST) >>= aListItems;
				    // loop through it and write the sub elements
				    const ::rtl::OUString* pListItems = aListItems.getConstArray();
				    for (sal_Int32 i=0; i<aListItems.getLength(); ++i, ++pListItems)
				    {
					    m_rContext.getGlobalContext().ClearAttrList();
					    AddAttribute(
						    OAttributeMetaData::getCommonControlAttributeNamespace(CCA_LABEL),
						    OAttributeMetaData::getCommonControlAttributeName(CCA_LABEL),
						    *pListItems);
					    SvXMLElementExport aFormElement(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, "item", sal_True, sal_True);
				    }
                }
			}
			break;

            case TEXT_AREA:
            {
                // if we act as rich text control, we need to export some text:p elements
                if ( xControlText.is() )
                {
                    sal_Bool bActingAsRichText = sal_False;
        			if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_RICH_TEXT ) )
                    {
                        OSL_VERIFY(m_xProps->getPropertyValue( PROPERTY_RICH_TEXT ) >>= bActingAsRichText );
                    }

                    if ( bActingAsRichText )
                		m_rContext.getGlobalContext().GetTextParagraphExport()->exportText( xControlText );
                }
            }
            break;
            default:
                // nothing do to
                break;
		}
	}

    //---------------------------------------------------------------------
    void OControlExport::exportGenericHandlerAttributes()
    {
	    const Sequence< Property > aProperties = m_xPropertyInfo->getProperties();
        for (   const Property* prop = aProperties.getConstArray();
                prop != aProperties.getConstArray() + aProperties.getLength();
                ++prop
            )
        {
            try
            {
                // see if this property can already be handled with an IPropertyHandler (which, on the long
                // term, should be the case for most, if not all, properties)
                const PropertyDescription* propDescription = metadata::getPropertyDescription( prop->Name );
                if ( propDescription == NULL )
                    continue;

                // let the factory provide the concrete handler. Note that caching, if desired, is the task
                // of the factory
                PPropertyHandler handler = (*propDescription->factory)( propDescription->propertyId );
                ENSURE_OR_CONTINUE( handler.get() != NULL,
                    "OControlExport::exportGenericHandlerAttributes: invalid property handler provided by the factory!" );

                ::rtl::OUString attributeValue;
                if ( propDescription->propertyGroup == NO_GROUP )
                {
                    // that's a property which has a direct mapping to an attribute
                    if ( !shouldExportProperty( prop->Name ) )
                        // TODO: in the future, we surely need a more sophisticated approach to this, involving the property
                        // handler, or the property description
                    {
                        exportedProperty( prop->Name );
                        continue;
                    }

                    const Any propValue = m_xProps->getPropertyValue( prop->Name );
                    attributeValue = handler->getAttributeValue( propValue );
                }
                else
                {
                    // that's a property which is part of a group of properties, whose values, in their entity, comprise
                    // a single attribute value

                    // retrieve the descriptions of all other properties which add to the attribute value
                    PropertyDescriptionList descriptions;
                    metadata::getPropertyGroup( propDescription->propertyGroup, descriptions );

                    // retrieve the values for all those properties
                    PropertyValues aValues;
                    for (   PropertyDescriptionList::iterator desc = descriptions.begin();
                            desc != descriptions.end();
                            ++desc
                        )
                    {
                        // TODO: XMultiPropertySet?
                        const Any propValue = m_xProps->getPropertyValue( (*desc)->propertyName );
                        aValues[ (*desc)->propertyId ] = propValue;
                    }

                    // let the handler translate into an XML attribute value
                    attributeValue = handler->getAttributeValue( aValues );
                }

			    AddAttribute(
				    propDescription->attribute.namespacePrefix,
                    token::GetXMLToken( propDescription->attribute.attributeToken ),
				    attributeValue
                );

                exportedProperty( prop->Name );
            }
            catch( const Exception& )
            {
        	    DBG_UNHANDLED_EXCEPTION();
            }
        }
    }

    //---------------------------------------------------------------------
	void OControlExport::exportCommonControlAttributes()
	{
		size_t i=0;

		// I decided to handle all the properties here with some static arrays describing the property-attribute
		// relations. This leads to somewhat ugly code :), but the only alternative I can think of right now
		// would require maps and O(log n) searches, which seems somewhat expensive as this code is used
		// very frequently.

		// the extra indents for the respective blocks are to ensure that there is no copy'n'paste error, using
		// map identifiers from the wrong block

		// --------------------------------------------------------------------
		// some string properties
		{
			// the attribute ids of all properties which are expected to be of type string
			static sal_Int32 nStringPropertyAttributeIds[] =
			{
				CCA_LABEL, CCA_TITLE
			};
			// the names of all properties which are expected to be of type string
			static ::rtl::OUString aStringPropertyNames[] =
			{
				PROPERTY_LABEL, PROPERTY_TITLE
			};
			OSL_ENSURE(	sizeof(aStringPropertyNames)/sizeof(aStringPropertyNames[0]) ==
						sizeof(nStringPropertyAttributeIds)/sizeof(nStringPropertyAttributeIds[0]),
						"OControlExport::exportCommonControlAttributes: somebody tampered with the maps (1)!");

			for (i=0; i<sizeof(nStringPropertyAttributeIds)/sizeof(nStringPropertyAttributeIds[0]); ++i)
				if (nStringPropertyAttributeIds[i] & m_nIncludeCommon)
				{
					exportStringPropertyAttribute(
						OAttributeMetaData::getCommonControlAttributeNamespace(nStringPropertyAttributeIds[i]),
						OAttributeMetaData::getCommonControlAttributeName(nStringPropertyAttributeIds[i]),
						aStringPropertyNames[i]
						);
				#if OSL_DEBUG_LEVEL > 0
					//  reset the bit for later checking
					m_nIncludeCommon = m_nIncludeCommon & ~nStringPropertyAttributeIds[i];
				#endif
				}
		}

		// --------------------------------------------------------------------
		// some boolean properties
		{
			static sal_Int32 nBooleanPropertyAttributeIds[] =
			{	// attribute flags
				CCA_CURRENT_SELECTED, CCA_DISABLED, CCA_DROPDOWN, CCA_PRINTABLE, CCA_READONLY, CCA_SELECTED, CCA_TAB_STOP, CCA_ENABLEVISIBLE
			};
			static const ::rtl::OUString* pBooleanPropertyNames[] =
			{	// property names
				&PROPERTY_STATE, &PROPERTY_ENABLED, &PROPERTY_DROPDOWN, &PROPERTY_PRINTABLE, &PROPERTY_READONLY, &PROPERTY_DEFAULT_STATE, &PROPERTY_TABSTOP, &PROPERTY_ENABLEVISIBLE
			};
			static sal_Bool nBooleanPropertyAttrFlags[] =
			{	// attribute defaults
				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
			};
		#if OSL_DEBUG_LEVEL > 0
			sal_Int32 nIdCount = sizeof(nBooleanPropertyAttributeIds) / sizeof(nBooleanPropertyAttributeIds[0]);
			sal_Int32 nNameCount = sizeof(pBooleanPropertyNames) / sizeof(pBooleanPropertyNames[0]);
			sal_Int32 nFlagsCount = sizeof(nBooleanPropertyAttrFlags) / sizeof(nBooleanPropertyAttrFlags[0]);
			OSL_ENSURE((nIdCount == nNameCount) && (nNameCount == nFlagsCount),
				"OControlExport::exportCommonControlAttributes: somebody tampered with the maps (2)!");
		#endif
			for (i=0; i<sizeof(nBooleanPropertyAttributeIds)/sizeof(nBooleanPropertyAttributeIds[0]); ++i)
				if (nBooleanPropertyAttributeIds[i] & m_nIncludeCommon)
				{
					exportBooleanPropertyAttribute(
						OAttributeMetaData::getCommonControlAttributeNamespace(nBooleanPropertyAttributeIds[i]),
						OAttributeMetaData::getCommonControlAttributeName(nBooleanPropertyAttributeIds[i]),
						*(pBooleanPropertyNames[i]),
						nBooleanPropertyAttrFlags[i]);
		#if OSL_DEBUG_LEVEL > 0
					//  reset the bit for later checking
					m_nIncludeCommon = m_nIncludeCommon & ~nBooleanPropertyAttributeIds[i];
		#endif
				}
		}


		// --------------------------------------------------------------------
		// some integer properties
		{
			// now the common handling
			static sal_Int32 nIntegerPropertyAttributeIds[] =
			{	// attribute flags
				CCA_SIZE, CCA_TAB_INDEX
			};
			static const ::rtl::OUString* pIntegerPropertyNames[] =
			{	// property names
				&PROPERTY_LINECOUNT, &PROPERTY_TABINDEX
			};
			static const sal_Int16 nIntegerPropertyAttrDefaults[] =
			{	// attribute defaults
				5, 0
			};

			if ( m_nIncludeCommon & CCA_MAX_LENGTH )
				exportedProperty(PROPERTY_MAXTEXTLENGTH);

		#if OSL_DEBUG_LEVEL > 0
			sal_Int32 nIdCount = sizeof(nIntegerPropertyAttributeIds) / sizeof(nIntegerPropertyAttributeIds[0]);
			sal_Int32 nNameCount = sizeof(pIntegerPropertyNames) / sizeof(pIntegerPropertyNames[0]);
			sal_Int32 nDefaultCount = sizeof(nIntegerPropertyAttrDefaults) / sizeof(nIntegerPropertyAttrDefaults[0]);
			OSL_ENSURE((nIdCount == nNameCount) && (nNameCount == nDefaultCount),
				"OControlExport::exportCommonControlAttributes: somebody tampered with the maps (3)!");
		#endif
			for (i=0; i<sizeof(nIntegerPropertyAttributeIds)/sizeof(nIntegerPropertyAttributeIds[0]); ++i)
				if (nIntegerPropertyAttributeIds[i] & m_nIncludeCommon)
				{
					exportInt16PropertyAttribute(
						OAttributeMetaData::getCommonControlAttributeNamespace(nIntegerPropertyAttributeIds[i]),
						OAttributeMetaData::getCommonControlAttributeName(nIntegerPropertyAttributeIds[i]),
						*(pIntegerPropertyNames[i]),
						nIntegerPropertyAttrDefaults[i]);
		#if OSL_DEBUG_LEVEL > 0
					//  reset the bit for later checking
					m_nIncludeCommon = m_nIncludeCommon & ~nIntegerPropertyAttributeIds[i];
		#endif
				}


		}

		// --------------------------------------------------------------------
		// some enum properties
		{
			if (m_nIncludeCommon & CCA_BUTTON_TYPE)
			{
				exportEnumPropertyAttribute(
					OAttributeMetaData::getCommonControlAttributeNamespace(CCA_BUTTON_TYPE),
					OAttributeMetaData::getCommonControlAttributeName(CCA_BUTTON_TYPE),
					PROPERTY_BUTTONTYPE,
					OEnumMapper::getEnumMap(OEnumMapper::epButtonType),
					FormButtonType_PUSH);
		#if OSL_DEBUG_LEVEL > 0
				//  reset the bit for later checking
				m_nIncludeCommon = m_nIncludeCommon & ~CCA_BUTTON_TYPE;
		#endif
			}
			if ( m_nIncludeCommon & CCA_ORIENTATION )
			{
				exportEnumPropertyAttribute(
					OAttributeMetaData::getCommonControlAttributeNamespace( CCA_ORIENTATION ),
					OAttributeMetaData::getCommonControlAttributeName( CCA_ORIENTATION ),
					PROPERTY_ORIENTATION,
					OEnumMapper::getEnumMap( OEnumMapper::epOrientation ),
                    ScrollBarOrientation::HORIZONTAL
                );
		#if OSL_DEBUG_LEVEL > 0
				//  reset the bit for later checking
				m_nIncludeCommon = m_nIncludeCommon & ~CCA_ORIENTATION;
		#endif
			}

            if ( m_nIncludeCommon & CCA_VISUAL_EFFECT )
            {
				exportEnumPropertyAttribute(
					OAttributeMetaData::getCommonControlAttributeNamespace( CCA_VISUAL_EFFECT ),
					OAttributeMetaData::getCommonControlAttributeName( CCA_VISUAL_EFFECT ),
					PROPERTY_VISUAL_EFFECT,
					OEnumMapper::getEnumMap( OEnumMapper::epVisualEffect ),
                    VisualEffect::LOOK3D
                );
			#if OSL_DEBUG_LEVEL > 0
				//  reset the bit for later checking
				m_nIncludeCommon = m_nIncludeCommon & ~CCA_VISUAL_EFFECT;
			#endif
            }
		}

		// --------------------------------------------------------------------
		// some properties which require a special handling

		// the target frame
		if (m_nIncludeCommon & CCA_TARGET_FRAME)
		{
			exportTargetFrameAttribute();
		#if OSL_DEBUG_LEVEL > 0
			//  reset the bit for later checking
			m_nIncludeCommon = m_nIncludeCommon & ~CCA_TARGET_FRAME;
		#endif
		}

		// max text length
		if ( m_nIncludeCommon & CCA_MAX_LENGTH )
		{
			// normally, the respective property would be "MaxTextLen"
			// However, if the model has a property "PersistenceMaxTextLength", then we prefer this

			// determine the name of the property to export
			::rtl::OUString sTextLenPropertyName( PROPERTY_MAXTEXTLENGTH );
			if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_PERSISTENCE_MAXTEXTLENGTH ) )
				sTextLenPropertyName = PROPERTY_PERSISTENCE_MAXTEXTLENGTH;

			// export it
			exportInt16PropertyAttribute(
				OAttributeMetaData::getCommonControlAttributeNamespace( CCA_MAX_LENGTH ),
				OAttributeMetaData::getCommonControlAttributeName( CCA_MAX_LENGTH ),
				sTextLenPropertyName,
				0
			);

			// in either way, both properties count as "exported"
			exportedProperty( PROPERTY_MAXTEXTLENGTH );
			exportedProperty( PROPERTY_PERSISTENCE_MAXTEXTLENGTH );

		#if OSL_DEBUG_LEVEL > 0
			//  reset the bit for later checking
			m_nIncludeCommon = m_nIncludeCommon & ~CCA_MAX_LENGTH;
		#endif
		}

		if (m_nIncludeCommon & CCA_TARGET_LOCATION)
		{
			exportTargetLocationAttribute(false);
		#if OSL_DEBUG_LEVEL > 0
			//  reset the bit for later checking
			m_nIncludeCommon = m_nIncludeCommon & ~CCA_TARGET_LOCATION;
		#endif
		}

		// OJ #99721#
		if (m_nIncludeCommon & CCA_IMAGE_DATA)
		{
			exportImageDataAttribute();
		#if OSL_DEBUG_LEVEL > 0
			//  reset the bit for later checking
			m_nIncludeCommon = m_nIncludeCommon & ~CCA_IMAGE_DATA;
		#endif
		}

		// the for attribute
		// the target frame
		if (m_nIncludeCommon & CCA_FOR)
		{
			if (m_sReferringControls.getLength())
			{	// there is at least one control referring to the one we're handling currently
				AddAttribute(
					OAttributeMetaData::getCommonControlAttributeNamespace(CCA_FOR),
					OAttributeMetaData::getCommonControlAttributeName(CCA_FOR),
					m_sReferringControls);
			}
		#if OSL_DEBUG_LEVEL > 0
			//  reset the bit for later checking
			m_nIncludeCommon = m_nIncludeCommon & ~CCA_FOR;
		#endif
		}

		if ((CCA_CURRENT_VALUE | CCA_VALUE) & m_nIncludeCommon)
		{
			const sal_Char* pCurrentValuePropertyName = NULL;
			const sal_Char* pValuePropertyName = NULL;

			// get the property names
			getValuePropertyNames(m_eType, m_nClassId, pCurrentValuePropertyName, pValuePropertyName);

			static const sal_Char* pCurrentValueAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_VALUE);
			static const sal_Char* pValueAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_VALUE);
			static const sal_uInt16 nCurrentValueAttributeNamespaceKey = OAttributeMetaData::getCommonControlAttributeNamespace(CCA_CURRENT_VALUE);
			static const sal_uInt16 nValueAttributeNamespaceKey = OAttributeMetaData::getCommonControlAttributeNamespace(CCA_VALUE);

			// add the atrtributes if necessary and possible
			if (pCurrentValuePropertyName && (CCA_CURRENT_VALUE & m_nIncludeCommon))
            {
                // don't export the current-value if this value originates from a data binding
                // #i26944# - 2004-05-17 - fs@openoffice.org
                if ( controlHasActiveDataBinding() )
                    exportedProperty( ::rtl::OUString::createFromAscii( pCurrentValuePropertyName ) );
                else
				    exportGenericPropertyAttribute(
					    nCurrentValueAttributeNamespaceKey,
					    pCurrentValueAttributeName,
					    pCurrentValuePropertyName
                    );
            }

			if (pValuePropertyName && (CCA_VALUE & m_nIncludeCommon))
				exportGenericPropertyAttribute(
					nValueAttributeNamespaceKey,
					pValueAttributeName,
					pValuePropertyName);

			OSL_ENSURE((NULL == pValuePropertyName) == (0 == (CCA_VALUE & m_nIncludeCommon)),
				"OControlExport::exportCommonControlAttributes: no property found for the value attribute!");
			OSL_ENSURE((NULL == pCurrentValuePropertyName ) == (0 == (CCA_CURRENT_VALUE & m_nIncludeCommon)),
				"OControlExport::exportCommonControlAttributes: no property found for the current-value attribute!");

		#if OSL_DEBUG_LEVEL > 0
			//  reset the bit for later checking
			m_nIncludeCommon = m_nIncludeCommon & ~(CCA_CURRENT_VALUE | CCA_VALUE);
		#endif
		}

		OSL_ENSURE(0 == m_nIncludeCommon,
			"OControlExport::exportCommonControlAttributes: forgot some flags!");
			// in the dbg_util version, we should have removed every bit we handled from the mask, so it should
			// be 0 now ...
	}

	//---------------------------------------------------------------------
	void OControlExport::exportDatabaseAttributes()
	{
#if OSL_DEBUG_LEVEL > 0
		sal_Int32 nIncludeDatabase = m_nIncludeDatabase;
#endif
		// the only string property: DataField
		if (DA_DATA_FIELD & m_nIncludeDatabase)
		{
			exportStringPropertyAttribute(
				OAttributeMetaData::getDatabaseAttributeNamespace(DA_DATA_FIELD),
				OAttributeMetaData::getDatabaseAttributeName(DA_DATA_FIELD),
				PROPERTY_DATAFIELD);
            RESET_BIT( nIncludeDatabase, DA_DATA_FIELD );
		}

        // InputRequired
        if ( DA_INPUT_REQUIRED & m_nIncludeDatabase )
        {
            exportBooleanPropertyAttribute(
                OAttributeMetaData::getDatabaseAttributeNamespace( DA_INPUT_REQUIRED ),
                OAttributeMetaData::getDatabaseAttributeName( DA_INPUT_REQUIRED ),
                PROPERTY_INPUT_REQUIRED,
                BOOLATTR_DEFAULT_TRUE
            );
            RESET_BIT( nIncludeDatabase, DA_INPUT_REQUIRED );
        }

		// the only int16 property: BoundColumn
		if (DA_BOUND_COLUMN & m_nIncludeDatabase)
		{
			exportInt16PropertyAttribute(
				OAttributeMetaData::getDatabaseAttributeNamespace(DA_BOUND_COLUMN),
				OAttributeMetaData::getDatabaseAttributeName(DA_BOUND_COLUMN),
				PROPERTY_BOUNDCOLUMN,
				0);
            RESET_BIT( nIncludeDatabase, DA_BOUND_COLUMN );
		}

		// ConvertEmptyToNull
		if (DA_CONVERT_EMPTY & m_nIncludeDatabase)
		{
			exportBooleanPropertyAttribute(
				OAttributeMetaData::getDatabaseAttributeNamespace(DA_CONVERT_EMPTY),
				OAttributeMetaData::getDatabaseAttributeName(DA_CONVERT_EMPTY),
				PROPERTY_EMPTY_IS_NULL,
				BOOLATTR_DEFAULT_FALSE
				);
            RESET_BIT( nIncludeDatabase, DA_CONVERT_EMPTY );
		}

		// the only enum property: ListSourceType
		if (DA_LIST_SOURCE_TYPE & m_nIncludeDatabase)
		{
			exportEnumPropertyAttribute(
				OAttributeMetaData::getDatabaseAttributeNamespace(DA_LIST_SOURCE_TYPE),
				OAttributeMetaData::getDatabaseAttributeName(DA_LIST_SOURCE_TYPE),
				PROPERTY_LISTSOURCETYPE,
				OEnumMapper::getEnumMap(OEnumMapper::epListSourceType),
				ListSourceType_VALUELIST
				);
            RESET_BIT( nIncludeDatabase, DA_LIST_SOURCE_TYPE );
		}

		if (m_nIncludeDatabase & DA_LIST_SOURCE)
		{
			exportListSourceAsAttribute();
            RESET_BIT( nIncludeDatabase, DA_LIST_SOURCE );
		}

#if OSL_DEBUG_LEVEL > 0
		OSL_ENSURE(0 == nIncludeDatabase,
			"OControlExport::exportDatabaseAttributes: forgot some flags!");
			// in the dbg_util version, we should have removed every bit we handled from the mask, so it should
			// be 0 now ...
#endif
	}

	//---------------------------------------------------------------------
	void OControlExport::exportBindingAtributes()
    {
#if OSL_DEBUG_LEVEL > 0
		sal_Int32 nIncludeBinding = m_nIncludeBindings;
#endif

        // ....................................................
        if ( m_nIncludeBindings & BA_LINKED_CELL )
        {
            exportCellBindingAttributes( ( m_nIncludeBindings & BA_LIST_LINKING_TYPE ) != 0 );
        #if OSL_DEBUG_LEVEL > 0
			//  reset the bit for later checking
			nIncludeBinding = nIncludeBinding & ~( BA_LINKED_CELL | BA_LIST_LINKING_TYPE );
		#endif
        }

        // ....................................................
        if ( m_nIncludeBindings & BA_LIST_CELL_RANGE )
        {
            exportCellListSourceRange();
        #if OSL_DEBUG_LEVEL > 0
			//  reset the bit for later checking
			nIncludeBinding = nIncludeBinding & ~BA_LIST_CELL_RANGE;
		#endif
        }

        if ( m_nIncludeBindings & BA_XFORMS_BIND )
        {
            exportXFormsBindAttributes();
        #if OSL_DEBUG_LEVEL > 0
			//  reset the bit for later checking
			nIncludeBinding = nIncludeBinding & ~BA_XFORMS_BIND;
		#endif
        }

        if ( m_nIncludeBindings & BA_XFORMS_LISTBIND )
        {
            exportXFormsListAttributes();
        #if OSL_DEBUG_LEVEL > 0
			//  reset the bit for later checking
			nIncludeBinding = nIncludeBinding & ~BA_XFORMS_LISTBIND;
		#endif
        }

        if ( m_nIncludeBindings & BA_XFORMS_SUBMISSION )
        {
            exportXFormsSubmissionAttributes();
        #if OSL_DEBUG_LEVEL > 0
			//  reset the bit for later checking
			nIncludeBinding = nIncludeBinding & ~BA_XFORMS_SUBMISSION;
		#endif
        }

        OSL_ENSURE( 0 == nIncludeBinding,
			"OControlExport::exportBindingAtributes: forgot some flags!");
			// in the debug version, we should have removed every bit we handled from the mask, so it should
			// be 0 now ...
    }

	//---------------------------------------------------------------------
	void OControlExport::exportSpecialAttributes()
	{
		sal_Int32 i=0;

		// ----------------------
		// the boolean properties
		{
			static const sal_Int32 nBooleanPropertyAttributeIds[] =
			{	// attribute flags
				SCA_VALIDATION, SCA_MULTI_LINE, SCA_AUTOMATIC_COMPLETION, SCA_MULTIPLE, SCA_DEFAULT_BUTTON, SCA_IS_TRISTATE,
                SCA_TOGGLE, SCA_FOCUS_ON_CLICK
			};
			static const ::rtl::OUString* pBooleanPropertyNames[] =
			{	// property names
				&PROPERTY_STRICTFORMAT, &PROPERTY_MULTILINE, &PROPERTY_AUTOCOMPLETE, &PROPERTY_MULTISELECTION, &PROPERTY_DEFAULTBUTTON, &PROPERTY_TRISTATE,
                &PROPERTY_TOGGLE, &PROPERTY_FOCUS_ON_CLICK
			};
			sal_Int32 nIdCount = sizeof(nBooleanPropertyAttributeIds) / sizeof(nBooleanPropertyAttributeIds[0]);
		#if OSL_DEBUG_LEVEL > 0
			sal_Int32 nNameCount = sizeof(pBooleanPropertyNames) / sizeof(pBooleanPropertyNames[0]);
			OSL_ENSURE((nIdCount == nNameCount),
				"OControlExport::exportSpecialAttributes: somebody tampered with the maps (1)!");
		#endif
            const sal_Int32* pAttributeId = nBooleanPropertyAttributeIds;
            const ::rtl::OUString** pPropertyName = pBooleanPropertyNames;
			for ( i = 0; i < nIdCount; ++i, ++pAttributeId, ++pPropertyName )
            {
				if ( *pAttributeId& m_nIncludeSpecial)
				{
					exportBooleanPropertyAttribute(
						OAttributeMetaData::getSpecialAttributeNamespace( *pAttributeId ),
						OAttributeMetaData::getSpecialAttributeName( *pAttributeId ),
						*(*pPropertyName),
                        ( *pAttributeId == SCA_FOCUS_ON_CLICK ) ? BOOLATTR_DEFAULT_TRUE : BOOLATTR_DEFAULT_FALSE
					);
			#if OSL_DEBUG_LEVEL > 0
				//  reset the bit for later checking
				m_nIncludeSpecial = m_nIncludeSpecial & ~*pAttributeId;
			#endif
				}
            }
		}

		// ----------------------
		// the integer properties
		{
			static sal_Int32 nIntegerPropertyAttributeIds[] =
			{	// attribute flags
				SCA_PAGE_STEP_SIZE
			};
			static const ::rtl::OUString* pIntegerPropertyNames[] =
			{	// property names
                &PROPERTY_BLOCK_INCREMENT
			};
			static const sal_Int32 nIntegerPropertyAttrDefaults[] =
			{	// attribute defaults (XML defaults, not runtime defaults!)
				10
			};

            sal_Int32 nIdCount = sizeof( nIntegerPropertyAttributeIds ) / sizeof( nIntegerPropertyAttributeIds[0] );
		#if OSL_DEBUG_LEVEL > 0
			sal_Int32 nNameCount = sizeof( pIntegerPropertyNames ) / sizeof( pIntegerPropertyNames[0] );
			OSL_ENSURE( ( nIdCount == nNameCount ),
				"OControlExport::exportSpecialAttributes: somebody tampered with the maps (2)!" );
            sal_Int32 nDefaultCount = sizeof( nIntegerPropertyAttrDefaults ) / sizeof( nIntegerPropertyAttrDefaults[0] );
			OSL_ENSURE( ( nIdCount == nDefaultCount ),
				"OControlExport::exportSpecialAttributes: somebody tampered with the maps (3)!" );
		#endif
			for ( i = 0; i < nIdCount; ++i )
				if ( nIntegerPropertyAttributeIds[i] & m_nIncludeSpecial )
				{
					exportInt32PropertyAttribute(
						OAttributeMetaData::getSpecialAttributeNamespace( nIntegerPropertyAttributeIds[i] ),
						OAttributeMetaData::getSpecialAttributeName( nIntegerPropertyAttributeIds[i] ),
						*( pIntegerPropertyNames[i] ),
						nIntegerPropertyAttrDefaults[i]
					);
			#if OSL_DEBUG_LEVEL > 0
				//  reset the bit for later checking
				m_nIncludeSpecial = m_nIncludeSpecial & ~nIntegerPropertyAttributeIds[i];
			#endif
				}

            if ( SCA_STEP_SIZE & m_nIncludeSpecial )
            {
                ::rtl::OUString sPropertyName;
                if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_LINE_INCREMENT ) )
                    sPropertyName = PROPERTY_LINE_INCREMENT;
                else if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_SPIN_INCREMENT ) )
                    sPropertyName = PROPERTY_SPIN_INCREMENT;
                else
                    OSL_ENSURE( sal_False, "OControlExport::exportSpecialAttributes: not property which can be mapped to step-size attribute!" );

                if ( sPropertyName.getLength() )
					exportInt32PropertyAttribute(
						OAttributeMetaData::getSpecialAttributeNamespace( SCA_STEP_SIZE ),
						OAttributeMetaData::getSpecialAttributeName( SCA_STEP_SIZE ),
						sPropertyName,
						1
					);

            #if OSL_DEBUG_LEVEL > 0
				//  reset the bit for later checking
				m_nIncludeSpecial = m_nIncludeSpecial & ~SCA_STEP_SIZE;
			#endif
            }

        }

		// -------------------
		// the enum properties
		{
			if (SCA_STATE & m_nIncludeSpecial)
			{
				exportEnumPropertyAttribute(
					OAttributeMetaData::getSpecialAttributeNamespace(SCA_STATE),
					OAttributeMetaData::getSpecialAttributeName(SCA_STATE),
					PROPERTY_DEFAULT_STATE,
					OEnumMapper::getEnumMap(OEnumMapper::epCheckState),
					STATE_NOCHECK);
			#if OSL_DEBUG_LEVEL > 0
				//  reset the bit for later checking
				m_nIncludeSpecial = m_nIncludeSpecial & ~SCA_STATE;
			#endif
			}

			if (SCA_CURRENT_STATE & m_nIncludeSpecial)
			{
				exportEnumPropertyAttribute(
					OAttributeMetaData::getSpecialAttributeNamespace(SCA_CURRENT_STATE),
					OAttributeMetaData::getSpecialAttributeName(SCA_CURRENT_STATE),
					PROPERTY_STATE,
					OEnumMapper::getEnumMap(OEnumMapper::epCheckState),
					STATE_NOCHECK);
			#if OSL_DEBUG_LEVEL > 0
				//  reset the bit for later checking
				m_nIncludeSpecial = m_nIncludeSpecial & ~SCA_CURRENT_STATE;
			#endif
			}
		}

		// --------------------------------------------------------------------
		// some properties which require a special handling
        // the repeat delay
        {
		    if ( m_nIncludeSpecial & SCA_REPEAT_DELAY )
		    {
		        DBG_CHECK_PROPERTY( PROPERTY_REPEAT_DELAY, sal_Int32 );

                sal_Int32 nRepeatDelay = 0;
                m_xProps->getPropertyValue( PROPERTY_REPEAT_DELAY ) >>= nRepeatDelay;
                Time aTime;
                aTime.MakeTimeFromMS( nRepeatDelay );

			    AddAttribute(OAttributeMetaData::getSpecialAttributeNamespace( SCA_REPEAT_DELAY )
						    ,OAttributeMetaData::getSpecialAttributeName( SCA_REPEAT_DELAY )
						    ,SvXMLUnitConverter::convertTimeDuration( aTime, nRepeatDelay % 1000 ) );

		        exportedProperty( PROPERTY_REPEAT_DELAY );

            #if OSL_DEBUG_LEVEL > 0
			    //  reset the bit for later checking
			    m_nIncludeSpecial = m_nIncludeSpecial & ~SCA_REPEAT_DELAY;
		    #endif
		    }
        }

		// ----------------------------------
		// the EchoChar property needs special handling, cause it's a Int16, but must be stored as one-character-string
		{
			if (SCA_ECHO_CHAR & m_nIncludeSpecial)
			{
				DBG_CHECK_PROPERTY( PROPERTY_ECHO_CHAR, sal_Int16 );
				sal_Int16 nValue(0);
				m_xProps->getPropertyValue(PROPERTY_ECHO_CHAR) >>= nValue;
				if (nValue)
				{
					::rtl::OUString sCharacter(reinterpret_cast<const sal_Unicode*>(&nValue), 1);
					AddAttribute(
						OAttributeMetaData::getSpecialAttributeNamespace(SCA_ECHO_CHAR),
						OAttributeMetaData::getSpecialAttributeName(SCA_ECHO_CHAR),
						sCharacter);
				}
				exportedProperty(PROPERTY_ECHO_CHAR);
			#if OSL_DEBUG_LEVEL > 0
				//  reset the bit for later checking
				m_nIncludeSpecial = m_nIncludeSpecial & ~SCA_ECHO_CHAR;
			#endif
			}
		}

		// ----------------------------------
		if ((SCA_MIN_VALUE | SCA_MAX_VALUE) & m_nIncludeSpecial)
		{
			// need to export the min value and the max value as attributes
			// It depends on the real type (FormComponentType) of the control, which properties hold these
			// values
			const sal_Char* pMinValuePropertyName = NULL;
			const sal_Char* pMaxValuePropertyName = NULL;
			getValueLimitPropertyNames(m_nClassId, pMinValuePropertyName, pMaxValuePropertyName);

			OSL_ENSURE((NULL == pMinValuePropertyName) == (0 == (SCA_MIN_VALUE & m_nIncludeSpecial)),
				"OControlExport::exportCommonControlAttributes: no property found for the min value attribute!");
			OSL_ENSURE((NULL == pMaxValuePropertyName) == (0 == (SCA_MAX_VALUE & m_nIncludeSpecial)),
				"OControlExport::exportCommonControlAttributes: no property found for the max value attribute!");

			// add the two attributes
			static const sal_Char* pMinValueAttributeName = OAttributeMetaData::getSpecialAttributeName(SCA_MIN_VALUE);
			static const sal_Char* pMaxValueAttributeName = OAttributeMetaData::getSpecialAttributeName(SCA_MAX_VALUE);
			static const sal_uInt16 nMinValueNamespaceKey = OAttributeMetaData::getSpecialAttributeNamespace(SCA_MIN_VALUE);
			static const sal_uInt16 nMaxValueNamespaceKey = OAttributeMetaData::getSpecialAttributeNamespace(SCA_MAX_VALUE);

			if (pMinValuePropertyName && (SCA_MIN_VALUE & m_nIncludeSpecial))
				exportGenericPropertyAttribute(
					nMinValueNamespaceKey,
					pMinValueAttributeName,
					pMinValuePropertyName);

			if (pMaxValuePropertyName && (SCA_MAX_VALUE & m_nIncludeSpecial))
				exportGenericPropertyAttribute(
					nMaxValueNamespaceKey,
					pMaxValueAttributeName,
					pMaxValuePropertyName);
		#if OSL_DEBUG_LEVEL > 0
			//  reset the bit for later checking
			m_nIncludeSpecial = m_nIncludeSpecial & ~(SCA_MIN_VALUE | SCA_MAX_VALUE);
		#endif
		}

		// ----------------------------------
        if ( SCA_IMAGE_POSITION & m_nIncludeSpecial )
        {
            exportImagePositionAttributes();
            RESET_BIT( m_nIncludeSpecial, SCA_IMAGE_POSITION );
        }

		OSL_ENSURE(0 == m_nIncludeSpecial,
			"OControlExport::exportSpecialAttributes: forgot some flags!");
			// in the dbg_util version, we should have removed every bit we handled from the mask, so it should
			// be 0 now ...
	}

	//---------------------------------------------------------------------
    ::rtl::OUString OControlExport::getScalarListSourceValue() const
    {
		::rtl::OUString sListSource;
		Any aListSource = m_xProps->getPropertyValue( PROPERTY_LISTSOURCE );
		if ( !( aListSource >>= sListSource ) )
		{
			Sequence< ::rtl::OUString > aListSourceSequence;
			aListSource >>= aListSourceSequence;
			if ( aListSourceSequence.getLength() )
				sListSource = aListSourceSequence[ 0 ];
		}
        return sListSource;
    }

	//---------------------------------------------------------------------
	void OControlExport::exportListSourceAsAttribute()
	{
		// DA_LIST_SOURCE needs some special handling
		DBG_CHECK_PROPERTY_NO_TYPE( PROPERTY_LISTSOURCE );

        ::rtl::OUString sListSource = getScalarListSourceValue();
		if ( sListSource.getLength() )
		{	// the ListSource property needs to be exported as attribute, and it is not empty
			AddAttribute(
				OAttributeMetaData::getDatabaseAttributeNamespace(DA_LIST_SOURCE),
				OAttributeMetaData::getDatabaseAttributeName(DA_LIST_SOURCE),
				sListSource);
		}

        exportedProperty( PROPERTY_LISTSOURCE );
	}

	//---------------------------------------------------------------------
	void OControlExport::getSequenceInt16PropertyAsSet(const ::rtl::OUString& _rPropertyName, Int16Set& _rOut)
	{
		Sequence< sal_Int16 > aValueSequence;
		DBG_CHECK_PROPERTY(_rPropertyName, Sequence< sal_Int16 >);
		m_xProps->getPropertyValue(_rPropertyName) >>= aValueSequence;

		const sal_Int16* pValues = aValueSequence.getConstArray();
		for (sal_Int32 i=0; i<aValueSequence.getLength(); ++i, ++pValues)
			_rOut.insert(*pValues);
	}

	//---------------------------------------------------------------------
	void OControlExport::exportListSourceAsElements()
	{
		// the string lists
		Sequence< ::rtl::OUString > aItems, aValues;
		DBG_CHECK_PROPERTY( PROPERTY_STRING_ITEM_LIST, Sequence< ::rtl::OUString > );
		m_xProps->getPropertyValue(PROPERTY_STRING_ITEM_LIST) >>= aItems;

		DBG_CHECK_PROPERTY( PROPERTY_LISTSOURCE, Sequence< ::rtl::OUString > );
		if ( 0 == ( m_nIncludeDatabase & DA_LIST_SOURCE ) )
			m_xProps->getPropertyValue(PROPERTY_LISTSOURCE) >>= aValues;
		// if we exported the list source as attribute, we do not repeat it as sub elements

		// the selection lists
		Int16Set aSelection, aDefaultSelection;
		getSequenceInt16PropertyAsSet(PROPERTY_SELECT_SEQ, aSelection);
		getSequenceInt16PropertyAsSet(PROPERTY_DEFAULT_SELECT_SEQ, aDefaultSelection);

		// the string for "true"
		::rtl::OUString sTrue;
		::rtl::OUStringBuffer sBuffer;
		m_rContext.getGlobalContext().GetMM100UnitConverter().convertBool(sBuffer, sal_True);
		sTrue = sBuffer.makeStringAndClear();

		// loop through both lists ('til the maximum of both lengths)
		const ::rtl::OUString* pItems = aItems.getConstArray();
		const ::rtl::OUString* pValues = aValues.getConstArray();

		sal_Int32 nItems = aItems.getLength();
		sal_Int32 nValues = aValues.getLength();

		sal_Int16 nMaxLen = (sal_Int16)std::max(nItems, nValues);

		for	(sal_Int16 i=0; i<nMaxLen; ++i )
		{
			m_rContext.getGlobalContext().ClearAttrList();
			if (i < nItems)
			{
				// there is an item at this position
				AddAttribute(
					OAttributeMetaData::getCommonControlAttributeNamespace(CCA_LABEL),
					OAttributeMetaData::getCommonControlAttributeName(CCA_LABEL),
					*pItems);
				++pItems;
			}
			if (i < nValues)
			{
				// there is an value at this position
				AddAttribute(
					OAttributeMetaData::getCommonControlAttributeNamespace(CCA_VALUE),
					OAttributeMetaData::getCommonControlAttributeName(CCA_VALUE),
					*pValues);
				++pValues;
			}

			Int16SetIterator aSelectedPos = aSelection.find(i);
			if (aSelection.end() != aSelectedPos)
			{	// the item at this position is selected
				AddAttribute(
					OAttributeMetaData::getCommonControlAttributeNamespace(CCA_CURRENT_SELECTED),
					OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_SELECTED),
					sTrue
					);
				aSelection.erase(aSelectedPos);
			}

			Int16SetIterator aDefaultSelectedPos = aDefaultSelection.find(i);
			if (aDefaultSelection.end() != aDefaultSelectedPos)
			{	// the item at this position is selected as default
				AddAttribute(
					OAttributeMetaData::getCommonControlAttributeNamespace(CCA_SELECTED),
					OAttributeMetaData::getCommonControlAttributeName(CCA_SELECTED),
					sTrue
					);
				aDefaultSelection.erase(aDefaultSelectedPos);
			}
			SvXMLElementExport aFormElement(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, "option", sal_True, sal_True);
		}

		// There may be more "selected" or "default-selected" items than there are in the lists in real,
		// so we need to store some additional "form:option" items which have no name and no label, but
		// one or both of the selected flags.
		// 21.05.2001 - 85388 - frank.schoenheit@germany.sun.com

		if ( !aSelection.empty() || !aDefaultSelection.empty() )
		{
			sal_Int16 nLastSelected = -1;
			if ( !aSelection.empty() )
				nLastSelected = *(--aSelection.end());

			sal_Int16 nLastDefaultSelected = -1;
			if ( !aDefaultSelection.empty() )
				nLastDefaultSelected = *(--aDefaultSelection.end());

			// the maximum element in both sets
			sal_Int16 nLastReferredEntry = std::max(nLastSelected, nLastDefaultSelected);
			OSL_ENSURE(nLastReferredEntry >= nMaxLen, "OControlExport::exportListSourceAsElements: inconsistence!");
				// if the maximum (selected or default selected) entry number is less than the maximum item count
				// in both lists, the entry number should have been removed from the set

			for (sal_Int16 i=nMaxLen; i<=nLastReferredEntry; ++i)
			{
				if (aSelection.end() != aSelection.find(i))
				{	// the (not existent) item at this position is selected
					AddAttribute(
						OAttributeMetaData::getCommonControlAttributeNamespace(CCA_CURRENT_SELECTED),
						OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_SELECTED),
						sTrue
						);
				}

				if (aDefaultSelection.end() != aDefaultSelection.find(i))
				{	// the (not existent) item at this position is selected as default
					AddAttribute(
						OAttributeMetaData::getCommonControlAttributeNamespace(CCA_SELECTED),
						OAttributeMetaData::getCommonControlAttributeName(CCA_SELECTED),
						sTrue
						);
				}
				SvXMLElementExport aFormElement(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, "option", sal_True, sal_True);
			}
		}
	}

	//---------------------------------------------------------------------
	void OControlExport::implStartElement(const sal_Char* _pName)
	{
		// before we let the base class start it's outer element, we add a wrapper element
		const sal_Char *pOuterElementName = getOuterXMLElementName();
		m_pOuterElement = pOuterElementName
		   					? new SvXMLElementExport(
										m_rContext.getGlobalContext(),
										XML_NAMESPACE_FORM,
										pOuterElementName, sal_True,
										sal_True)
							: 0;

		// add the attributes for the inner element
		exportInnerAttributes();

		// and start the inner element
		OElementExport::implStartElement(_pName);
	}

	//---------------------------------------------------------------------
	void OControlExport::implEndElement()
	{
		// end the inner element
		OElementExport::implEndElement();

		// end the outer element if it exists
		delete m_pOuterElement;
		m_pOuterElement = NULL;
	}

	//---------------------------------------------------------------------
	const sal_Char* OControlExport::getOuterXMLElementName() const
	{
		return 0;
	}

	//---------------------------------------------------------------------
	const sal_Char* OControlExport::getXMLElementName() const
	{
		return getElementName(m_eType);
	}

	//---------------------------------------------------------------------
	void OControlExport::examine()
	{
        OSL_ENSURE( ( m_nIncludeCommon == 0 ) && ( m_nIncludeSpecial == 0 ) && ( m_nIncludeDatabase == 0 )
                 && ( m_nIncludeEvents == 0 ) && ( m_nIncludeBindings == 0),
                 "OControlExport::examine: called me twice? Not initialized?" );

        // get the class id to decide which kind of element we need in the XML stream
		m_nClassId = FormComponentType::CONTROL;
		DBG_CHECK_PROPERTY( PROPERTY_CLASSID, sal_Int16 );
		m_xProps->getPropertyValue(PROPERTY_CLASSID) >>= m_nClassId;
        bool knownType = false;
		switch (m_nClassId)
		{
			case FormComponentType::DATEFIELD:
                m_eType = DATE;
                knownType = true;
                // NO BREAK
			case FormComponentType::TIMEFIELD:
                if ( !knownType )
                {
                    m_eType = TIME;
                    knownType = true;
                }
				m_nIncludeSpecial |= SCA_VALIDATION;
                // NO BREAK
			case FormComponentType::NUMERICFIELD:
			case FormComponentType::CURRENCYFIELD:
			case FormComponentType::PATTERNFIELD:
                if ( !knownType )
                {
				    m_eType = FORMATTED_TEXT;
                    knownType = true;
                }
				// NO BREAK
			case FormComponentType::TEXTFIELD:
			{	// it's some kind of edit. To know which type we need further investigation

				if ( !knownType )
				{
					// check if it's a formatted field
					if (m_xPropertyInfo->hasPropertyByName(PROPERTY_FORMATKEY))
					{
						m_eType = FORMATTED_TEXT;
					}
					else
					{
						// all other controls are represented by an ordinary edit control, but which XML control type
						// it is depends on the current values of some properties

						// if the EchoChar string is not empty, it is a password field
						sal_Int16 nEchoChar = 0;
						if (m_xPropertyInfo->hasPropertyByName(PROPERTY_ECHOCHAR))
							// grid columns do not have this property ....
							m_xProps->getPropertyValue(PROPERTY_ECHOCHAR) >>= nEchoChar;
						if (nEchoChar)
						{
							m_eType = PASSWORD;
							m_nIncludeSpecial |= SCA_ECHO_CHAR;
						}
						else
						{
							// if the MultiLine property is sal_True, it is a TextArea
							sal_Bool bMultiLine = sal_False;
							if (m_xPropertyInfo->hasPropertyByName(PROPERTY_MULTILINE))
								// grid columns do not have this property ....
								bMultiLine = ::cppu::any2bool(m_xProps->getPropertyValue(PROPERTY_MULTILINE));

                            if ( bMultiLine )
								m_eType = TEXT_AREA;
							else
								// the only case left is represented by a Text element
								m_eType = TEXT;
						}
					}
                    knownType = true;
				}

				// attributes which are common to all the types:
				// common attributes
				m_nIncludeCommon =
					CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED |
					CCA_PRINTABLE | CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE;

                if  (   ( m_nClassId != FormComponentType::DATEFIELD )
                    &&  ( m_nClassId != FormComponentType::TIMEFIELD )
                    )
                    // date and time field values are handled differently nowadays
                    m_nIncludeCommon |= CCA_VALUE;

                // database attributes
				m_nIncludeDatabase = DA_DATA_FIELD | DA_INPUT_REQUIRED;

				// event attributes
				m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE | EA_ON_SELECT;

				// only text and pattern fields have a ConvertEmptyToNull property
				if  (   ( m_nClassId == FormComponentType::TEXTFIELD )
                    ||  ( m_nClassId == FormComponentType::PATTERNFIELD )
                    )
					m_nIncludeDatabase |= DA_CONVERT_EMPTY;

				// all controls but the file control fields have a readonly property
				if ( m_nClassId != FormComponentType::FILECONTROL )
					m_nIncludeCommon |= CCA_READONLY;

				// a text field has a max text len
                if ( m_nClassId == FormComponentType::TEXTFIELD )
					m_nIncludeCommon |= CCA_MAX_LENGTH;

				// max and min values and validation:
				if (FORMATTED_TEXT == m_eType)
				{	// in general all controls represented as formatted-text have these props
					if  ( FormComponentType::PATTERNFIELD != m_nClassId )   // except the PatternField
						m_nIncludeSpecial |= SCA_MAX_VALUE | SCA_MIN_VALUE;

					if (FormComponentType::TEXTFIELD != m_nClassId)
						// and the FormattedField does not have a validation flag
						m_nIncludeSpecial |= SCA_VALIDATION;
				}

				// if it's not a password field or rich text control, the CurrentValue needs to be stored, too
				if  (   ( PASSWORD != m_eType )
                    &&  ( DATE != m_eType )
                    &&  ( TIME != m_eType )
                    )
                {
				    m_nIncludeCommon |= CCA_CURRENT_VALUE;
                }
			}
			break;

			case FormComponentType::FILECONTROL:
				m_eType = FILE;
				m_nIncludeCommon =
					CCA_NAME | CCA_SERVICE_NAME | CCA_CURRENT_VALUE | CCA_DISABLED |
					CCA_PRINTABLE | CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE |
					CCA_VALUE;
				m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE | EA_ON_SELECT;
				break;

			case FormComponentType::FIXEDTEXT:
				m_eType = FIXED_TEXT;
				m_nIncludeCommon =
					CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_LABEL |
					CCA_PRINTABLE | CCA_TITLE | CCA_FOR;
				m_nIncludeSpecial = SCA_MULTI_LINE;
				m_nIncludeEvents = EA_CONTROL_EVENTS;
				break;

			case FormComponentType::COMBOBOX:
				m_eType = COMBOBOX;
				m_nIncludeCommon =
					CCA_NAME | CCA_SERVICE_NAME | CCA_CURRENT_VALUE |
					CCA_DISABLED | CCA_DROPDOWN | CCA_MAX_LENGTH | CCA_PRINTABLE | CCA_READONLY | CCA_SIZE |
					CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE | CCA_VALUE;
				m_nIncludeSpecial = SCA_AUTOMATIC_COMPLETION;
				m_nIncludeDatabase = DA_CONVERT_EMPTY | DA_DATA_FIELD | DA_INPUT_REQUIRED | DA_LIST_SOURCE | DA_LIST_SOURCE_TYPE;
				m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE | EA_ON_SELECT;
				break;

			case FormComponentType::LISTBOX:
				m_eType = LISTBOX;
				m_nIncludeCommon =
					CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_DROPDOWN |
					CCA_PRINTABLE | CCA_SIZE | CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE;
				m_nIncludeSpecial = SCA_MULTIPLE;
				m_nIncludeDatabase = DA_BOUND_COLUMN | DA_DATA_FIELD | DA_INPUT_REQUIRED | DA_LIST_SOURCE_TYPE;
				m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE | EA_ON_CLICK | EA_ON_DBLCLICK;
				// check if we need to export the ListSource as attribute
				{
					// for a list box, if the ListSourceType is VALUE_LIST, no ListSource is stored, but instead
					// a sequence of pairs which is build from the StringItemList and the ValueList
					ListSourceType eListSourceType = ListSourceType_VALUELIST;
                #if OSL_DEBUG_LEVEL > 0
					sal_Bool bSuccess =
				#endif
					m_xProps->getPropertyValue(PROPERTY_LISTSOURCETYPE) >>= eListSourceType;
					OSL_ENSURE(bSuccess, "OControlExport::examineControl: could not retrieve the ListSourceType!");
					if (ListSourceType_VALUELIST != eListSourceType)
					{
						m_nIncludeDatabase |= DA_LIST_SOURCE;
					}
				}

				break;

			case FormComponentType::COMMANDBUTTON:
				m_eType = BUTTON;
				m_nIncludeCommon |= CCA_TAB_STOP | CCA_LABEL;
				m_nIncludeSpecial = SCA_DEFAULT_BUTTON | SCA_TOGGLE | SCA_FOCUS_ON_CLICK | SCA_IMAGE_POSITION | SCA_REPEAT_DELAY;
				// NO BREAK !
			case FormComponentType::IMAGEBUTTON:
				if (BUTTON != m_eType)
                {
					// not coming from the previous case
					m_eType = IMAGE;
                }
				m_nIncludeCommon |=
					CCA_NAME | CCA_SERVICE_NAME | CCA_BUTTON_TYPE | CCA_DISABLED |
					CCA_IMAGE_DATA | CCA_PRINTABLE | CCA_TAB_INDEX | CCA_TARGET_FRAME |
					CCA_TARGET_LOCATION | CCA_TITLE;
				m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CLICK	| EA_ON_DBLCLICK;
				break;

			case FormComponentType::CHECKBOX:
				m_eType = CHECKBOX;
				m_nIncludeSpecial = SCA_CURRENT_STATE | SCA_IS_TRISTATE | SCA_STATE;
				// NO BREAK !
			case FormComponentType::RADIOBUTTON:
				m_nIncludeCommon =
					CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_LABEL | CCA_PRINTABLE |
                    CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE | CCA_VALUE | CCA_VISUAL_EFFECT;
				if (CHECKBOX != m_eType)
				{	// not coming from the previous case
					m_eType = RADIO;
					m_nIncludeCommon |= CCA_CURRENT_SELECTED | CCA_SELECTED;
				}
                if ( m_xPropertyInfo->hasPropertyByName( PROPERTY_IMAGE_POSITION ) )
                    m_nIncludeSpecial |= SCA_IMAGE_POSITION;
				m_nIncludeDatabase = DA_DATA_FIELD | DA_INPUT_REQUIRED;
				m_nIncludeEvents = EA_CONTROL_EVENTS | EA_ON_CHANGE;
				break;

			case FormComponentType::GROUPBOX:
				m_eType = FRAME;
				m_nIncludeCommon =
					CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_LABEL |
					CCA_PRINTABLE | CCA_TITLE | CCA_FOR;
				m_nIncludeEvents = EA_CONTROL_EVENTS;
				break;

			case FormComponentType::IMAGECONTROL:
				m_eType = IMAGE_FRAME;
				m_nIncludeCommon =
					CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_IMAGE_DATA |
					CCA_PRINTABLE | CCA_READONLY | CCA_TITLE;
				m_nIncludeDatabase = DA_DATA_FIELD | DA_INPUT_REQUIRED;
				m_nIncludeEvents = EA_CONTROL_EVENTS;
				break;

			case FormComponentType::HIDDENCONTROL:
				m_eType = HIDDEN;
				m_nIncludeCommon =
					CCA_NAME | CCA_SERVICE_NAME | CCA_VALUE;
				break;

			case FormComponentType::GRIDCONTROL:
				m_eType = GRID;
				m_nIncludeCommon =
					CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_PRINTABLE |
					CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE;
				m_nIncludeEvents = EA_CONTROL_EVENTS;
				break;

			case FormComponentType::SCROLLBAR:
			case FormComponentType::SPINBUTTON:
				m_eType = VALUERANGE;
				m_nIncludeCommon =
					CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_PRINTABLE |
                    CCA_TITLE | CCA_CURRENT_VALUE | CCA_VALUE | CCA_ORIENTATION;
                m_nIncludeSpecial = SCA_MAX_VALUE | SCA_STEP_SIZE | SCA_MIN_VALUE | SCA_REPEAT_DELAY;

                if ( m_nClassId == FormComponentType::SCROLLBAR )
                    m_nIncludeSpecial |= SCA_PAGE_STEP_SIZE ;

				m_nIncludeEvents = EA_CONTROL_EVENTS;
                break;

            default:
				OSL_ENSURE(sal_False, "OControlExport::examineControl: unknown control type (class id)!");
                // NO break!

            case FormComponentType::NAVIGATIONBAR:
                // TODO: should we have an own file format for this?
                // NO break

            case FormComponentType::CONTROL:
				m_eType = GENERIC_CONTROL;
				// unknown control type
				m_nIncludeCommon = CCA_NAME | CCA_SERVICE_NAME;
					// at least a name should be there, 'cause without a name the control could never have been
					// inserted into it's parent container
					// In addition, the service name is absolutely necessary to create the control upon reading.
				m_nIncludeEvents = EA_CONTROL_EVENTS;
					// we always should be able to export events - this is not control type dependent
				break;
		}

		// in general, all control types need to export the control id
		m_nIncludeCommon |= CCA_CONTROL_ID;

        // is is a control bound to a calc cell?
        if ( FormCellBindingHelper::livesInSpreadsheetDocument( m_xProps ) )
        {
            FormCellBindingHelper aHelper( m_xProps, NULL );
            {
                if ( aHelper.isCellBinding( aHelper.getCurrentBinding( ) ) )
                {
                    m_nIncludeBindings |= BA_LINKED_CELL;
                    if ( m_nClassId == FormComponentType::LISTBOX )
                        m_nIncludeBindings |= BA_LIST_LINKING_TYPE;
                }
            }

            // is it a list-like control which uses a calc cell range as list source?
            {
                if ( aHelper.isCellRangeListSource( aHelper.getCurrentListSource( ) ) )
                    m_nIncludeBindings |= BA_LIST_CELL_RANGE;
            }
        }

        // is control bound to XForms?
        if( getXFormsBindName( m_xProps ).getLength() > 0 )
        {
            m_nIncludeBindings |= BA_XFORMS_BIND;
        }

        // is (list-)control bound to XForms list?
        if( getXFormsListBindName( m_xProps ).getLength() > 0 )
        {
            m_nIncludeBindings |= BA_XFORMS_LISTBIND;
        }

        // does the control have an XForms submission?
        if( getXFormsSubmissionName( m_xProps ).getLength() > 0 )
        {
            m_nIncludeBindings |= BA_XFORMS_SUBMISSION;
        }
	}

	//---------------------------------------------------------------------
    void OControlExport::exportCellBindingAttributes( bool _bIncludeListLinkageType )
    {
        try
        {
            FormCellBindingHelper aHelper( m_xProps, NULL );
            Reference< XValueBinding > xBinding( aHelper.getCurrentBinding() );
            OSL_ENSURE( xBinding.is(), "OControlExport::exportCellBindingAttributes: invalid bindable or invalid binding!" );
            if ( xBinding.is() )
            {
                // ....................................................
    			AddAttribute(
                    OAttributeMetaData::getBindingAttributeNamespace( BA_LINKED_CELL ),
                    OAttributeMetaData::getBindingAttributeName( BA_LINKED_CELL ),
                    aHelper.getStringAddressFromCellBinding( xBinding )
                );

                // ....................................................
                if ( _bIncludeListLinkageType )
                {
                    sal_Int16 nLinkageType = aHelper.isCellIntegerBinding( xBinding ) ? 1 : 0;

                    ::rtl::OUStringBuffer sBuffer;
			        m_rContext.getGlobalContext().GetMM100UnitConverter().convertEnum(
                        sBuffer,
                        (sal_uInt16)nLinkageType,
                        OEnumMapper::getEnumMap( OEnumMapper::epListLinkageType )
                    );

                    AddAttribute(
                        OAttributeMetaData::getBindingAttributeNamespace( BA_LIST_LINKING_TYPE ),
                        OAttributeMetaData::getBindingAttributeName( BA_LIST_LINKING_TYPE ),
                        sBuffer.makeStringAndClear()
                    );
                }

            }
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "OControlExport::exportCellBindingAttributes: caught an exception!" );
        }
    }

	//---------------------------------------------------------------------
    void OControlExport::exportXFormsBindAttributes()
    {
        rtl::OUString sBindName = getXFormsBindName( m_xProps );
        AddAttribute( XML_NAMESPACE_XFORMS, XML_BIND, sBindName );
    }
	//---------------------------------------------------------------------
    void OControlExport::exportXFormsListAttributes()
    {
        rtl::OUString sBindName = getXFormsListBindName( m_xProps );
        AddAttribute( XML_NAMESPACE_FORM, XML_XFORMS_LIST_SOURCE, sBindName );
    }
	//---------------------------------------------------------------------
    void OControlExport::exportXFormsSubmissionAttributes()
    {
        rtl::OUString sSubmission = getXFormsSubmissionName( m_xProps );
        AddAttribute( XML_NAMESPACE_FORM, XML_XFORMS_SUBMISSION, sSubmission );
    }
	//---------------------------------------------------------------------
    void OControlExport::exportCellListSourceRange( )
    {
        try
        {
            Reference< XListEntrySink > xSink( m_xProps, UNO_QUERY );
            Reference< XListEntrySource > xSource;
            if ( xSink.is() )
                xSource = xSource.query( xSink->getListEntrySource() );
            OSL_ENSURE( xSource.is(), "OControlExport::exportCellListSourceRange: list source or sink!" );
            if ( xSource.is() )
            {
                FormCellBindingHelper aHelper( m_xProps, NULL );

    			AddAttribute(
                    OAttributeMetaData::getBindingAttributeNamespace( BA_LIST_CELL_RANGE ),
                    OAttributeMetaData::getBindingAttributeName( BA_LIST_CELL_RANGE ),
                    aHelper.getStringAddressFromCellListSource( xSource )
                );
            }
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "OControlExport::exportCellListSourceRange: caught an exception!" );
        }
    }

	//---------------------------------------------------------------------
    void OControlExport::exportImagePositionAttributes()
    {
        try
        {
            sal_Int16 nImagePosition = ImagePosition::Centered;
            OSL_VERIFY( m_xProps->getPropertyValue( PROPERTY_IMAGE_POSITION ) >>= nImagePosition );
            OSL_ENSURE( ( nImagePosition >= ImagePosition::LeftTop ) && ( nImagePosition <= ImagePosition::Centered ),
                "OControlExport::exportImagePositionAttributes: don't know this image position!" );

            if ( ( nImagePosition < ImagePosition::LeftTop ) || ( nImagePosition > ImagePosition::Centered ) )
                // this is important to prevent potential buffer overflows below, so don't optimize
                nImagePosition = ImagePosition::Centered;

            if ( nImagePosition == ImagePosition::Centered )
            {
    		    AddAttribute( XML_NAMESPACE_FORM, GetXMLToken( XML_IMAGE_POSITION ), GetXMLToken( XML_CENTER ) );
            }
            else
            {
                XMLTokenEnum eXmlImagePositions[] =
                {
                    XML_START, XML_END, XML_TOP, XML_BOTTOM
                };
                XMLTokenEnum eXmlImageAligns[] =
                {
                    XML_START, XML_CENTER, XML_END
                };

                XMLTokenEnum eXmlImagePosition = eXmlImagePositions[ nImagePosition / 3 ];
                XMLTokenEnum eXmlImageAlign    = eXmlImageAligns   [ nImagePosition % 3 ];

    		    AddAttribute( XML_NAMESPACE_FORM, GetXMLToken( XML_IMAGE_POSITION ), GetXMLToken( eXmlImagePosition ) );
    		    AddAttribute( XML_NAMESPACE_FORM, GetXMLToken( XML_IMAGE_ALIGN    ), GetXMLToken( eXmlImageAlign    ) );
            }

            exportedProperty( PROPERTY_IMAGE_POSITION );
            // some of the controls which have an ImagePosition also have an ImageAlign for compatibility
            // reasons. Since the ImageAlign values simply represent a sub set of the ImagePosition values,
            // we don't need to export ImageAlign anymore
            exportedProperty( PROPERTY_IMAGE_ALIGN );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }

	//---------------------------------------------------------------------
	bool OControlExport::controlHasActiveDataBinding() const
    {
        try
        {
            // currently exchanging the data with a database column?
            ::rtl::OUString sBoundFieldPropertyName( RTL_CONSTASCII_USTRINGPARAM( "BoundField" ) );
            if ( m_xPropertyInfo.is() && m_xPropertyInfo->hasPropertyByName( sBoundFieldPropertyName ) )
            {
                Reference< XPropertySet > xBoundField;
                m_xProps->getPropertyValue( sBoundFieldPropertyName ) >>= xBoundField;
                if ( xBoundField.is() )
                    return true;
            }

            // currently exchanging data with an external binding?
            Reference< XBindableValue > xBindable( m_xProps, UNO_QUERY );
            if ( xBindable.is() && xBindable->getValueBinding().is() )
                return true;
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "OColumnExport::controlHasActiveDataBinding: caught an exception!" );
        }

        return false;
    }

	//---------------------------------------------------------------------
	bool OControlExport::controlHasUserSuppliedListEntries() const
    {
        try
        {
            // an external list source?
            Reference< XListEntrySink > xEntrySink( m_xProps, UNO_QUERY );
            if ( xEntrySink.is() && xEntrySink->getListEntrySource().is() )
                return false;

            if ( m_xPropertyInfo.is() && m_xPropertyInfo->hasPropertyByName( PROPERTY_LISTSOURCETYPE ) )
            {
                ListSourceType eListSourceType = ListSourceType_VALUELIST;
                OSL_VERIFY( m_xProps->getPropertyValue( PROPERTY_LISTSOURCETYPE ) >>= eListSourceType );
                if ( eListSourceType == ListSourceType_VALUELIST )
                    // for value lists, the list entries as entered by the user are used
                    return true;

                // for every other type, the list entries are filled with some data obtained
                // from a database - if and only if the ListSource property is not empty
                return ( 0 == getScalarListSourceValue().getLength() );
            }
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "OControlExport::controlHasUserSuppliedListEntries: caught an exception!" );
        }

        OSL_ENSURE( sal_False, "OControlExport::controlHasUserSuppliedListEntries: unreachable code!" );
            // this method should be called for list and combo boxes only
        return true;
    }

	//=====================================================================
	//= OColumnExport
	//=====================================================================
	//---------------------------------------------------------------------
	OColumnExport::OColumnExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxControl, const ::rtl::OUString& _rControlId,
		const Sequence< ScriptEventDescriptor >& _rEvents)
		:OControlExport(_rContext, _rxControl, _rControlId, ::rtl::OUString(), _rEvents)
	{
	}

	//---------------------------------------------------------------------
	OColumnExport::~OColumnExport()
	{
		implEndElement();
	}

	//---------------------------------------------------------------------
	void OColumnExport::exportServiceNameAttribute()
	{
		// the attribute "service name" (which has a slightly different meaning for columns
		DBG_CHECK_PROPERTY( PROPERTY_COLUMNSERVICENAME, ::rtl::OUString );
		::rtl::OUString sColumnServiceName;
		m_xProps->getPropertyValue(PROPERTY_COLUMNSERVICENAME) >>= sColumnServiceName;
		// the service name is a full qualified one (i.e. com.sun.star.form.TextField), but the
		// real service name for the column (for use with the XGridColumnFactory) is only the last
		// token of this complete name.
		sal_Int32 nLastSep = sColumnServiceName.lastIndexOf('.');
		OSL_ENSURE(-1 != nLastSep, "OColumnExport::startExportElement: invalid service name!");
		sColumnServiceName = sColumnServiceName.copy(nLastSep + 1);
		sColumnServiceName =
			m_rContext.getGlobalContext().GetNamespaceMap().GetQNameByKey(
				XML_NAMESPACE_OOO, sColumnServiceName );
		// add the attribute
		AddAttribute( OAttributeMetaData::getCommonControlAttributeNamespace(CCA_SERVICE_NAME)
					, OAttributeMetaData::getCommonControlAttributeName(CCA_SERVICE_NAME)
					, sColumnServiceName);
		// flag the property as "handled"
		exportedProperty(PROPERTY_COLUMNSERVICENAME);

	}

	//---------------------------------------------------------------------
	const sal_Char* OColumnExport::getOuterXMLElementName() const
	{
		return "column";
	}

	//---------------------------------------------------------------------
	void OColumnExport::exportAttributes()
	{
		OControlExport::exportAttributes();

		// the attribute "label"
		exportStringPropertyAttribute(
			OAttributeMetaData::getCommonControlAttributeNamespace(CCA_LABEL),
			OAttributeMetaData::getCommonControlAttributeName(CCA_LABEL),
			PROPERTY_LABEL);

		// the style attribute
		::rtl::OUString sStyleName = m_rContext.getObjectStyleName( m_xProps );
		if ( sStyleName.getLength() )
		{
			AddAttribute(
				OAttributeMetaData::getSpecialAttributeNamespace( SCA_COLUMN_STYLE_NAME ),
				OAttributeMetaData::getSpecialAttributeName( SCA_COLUMN_STYLE_NAME ),
				sStyleName
			);
		}
	}

	//---------------------------------------------------------------------
	void OColumnExport::examine()
	{
		OControlExport::examine();

		// grid columns miss some properties of the controls they're representing
		m_nIncludeCommon &= ~(CCA_FOR | CCA_PRINTABLE | CCA_TAB_INDEX | CCA_TAB_STOP | CCA_LABEL);
		m_nIncludeSpecial &= ~(SCA_ECHO_CHAR | SCA_AUTOMATIC_COMPLETION | SCA_MULTIPLE | SCA_MULTI_LINE);

		if (FormComponentType::DATEFIELD != m_nClassId)
			// except date fields, no column has the DropDown property
			m_nIncludeCommon &= ~CCA_DROPDOWN;
	}

	//=====================================================================
	//= OFormExport
	//=====================================================================
	//---------------------------------------------------------------------
	OFormExport::OFormExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxForm,
		const Sequence< ScriptEventDescriptor >& _rEvents)
		:OElementExport(_rContext, _rxForm, _rEvents)
		,m_bCreateConnectionResourceElement(sal_False)
	{
		OSL_ENSURE(m_xProps.is(), "OFormExport::OFormExport: invalid arguments!");
	}

	//---------------------------------------------------------------------
	const sal_Char* OFormExport::getXMLElementName() const
	{
		return "form";
	}

	//---------------------------------------------------------------------
	void OFormExport::exportSubTags()
	{
		if ( m_bCreateConnectionResourceElement && m_xProps.is() )
		{
			m_rContext.getGlobalContext().ClearAttrList();
			::rtl::OUString sPropValue;
			m_xProps->getPropertyValue( PROPERTY_DATASOURCENAME ) >>= sPropValue; // if set it is a file url
			if ( !sPropValue.getLength() )
				m_xProps->getPropertyValue( PROPERTY_URL ) >>= sPropValue;
			if ( sPropValue.getLength() )
				AddAttribute(
					OAttributeMetaData::getCommonControlAttributeNamespace(CCA_TARGET_LOCATION),
					OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_LOCATION),
					sPropValue);
			if ( m_rContext.getGlobalContext().GetAttrList().getLength() )
			{
				SvXMLElementExport aFormElement(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, xmloff::token::XML_CONNECTION_RESOURCE, sal_True, sal_True);
			}
		}

		// let the base class export the remaining properties and the events
		OElementExport::exportSubTags();
		// loop through all children
		Reference< XIndexAccess > xCollection(m_xProps, UNO_QUERY);
		OSL_ENSURE(xCollection.is(), "OFormLayerXMLExport::implExportForm: a form which is not an index access? Suspic�ous!");

		if (xCollection.is())
			m_rContext.exportCollectionElements(xCollection);
	}

	//---------------------------------------------------------------------
	void OFormExport::exportAttributes()
	{
		sal_Int32 i=0;

		// ---------------------
		// the string properties
		{
			static FormAttributes eStringPropertyIds[] =
			{
				faName, /*faAction,*/ faCommand, faFilter, faOrder
			};
			static ::rtl::OUString aStringPropertyNames[] =
			{
				PROPERTY_NAME, /*PROPERTY_TARGETURL,*/ PROPERTY_COMMAND, PROPERTY_FILTER, PROPERTY_ORDER
			};
			sal_Int32 nIdCount = sizeof(eStringPropertyIds) / sizeof(eStringPropertyIds[0]);
		#if OSL_DEBUG_LEVEL > 0
			sal_Int32 nNameCount = sizeof(aStringPropertyNames) / sizeof(aStringPropertyNames[0]);
			OSL_ENSURE((nIdCount == nNameCount),
				"OFormExport::exportAttributes: somebody tampered with the maps (1)!");
		#endif
			for (i=0; i<nIdCount; ++i)
				exportStringPropertyAttribute(
					OAttributeMetaData::getFormAttributeNamespace(eStringPropertyIds[i]),
					OAttributeMetaData::getFormAttributeName(eStringPropertyIds[i]),
					aStringPropertyNames[i]);

            // #i112082# xlink:type is added as part of exportTargetLocationAttribute

            // now export the data source name or databaselocation or connection resource
			::rtl::OUString sPropValue;
			m_xProps->getPropertyValue( PROPERTY_DATASOURCENAME ) >>= sPropValue;
            m_bCreateConnectionResourceElement = !sPropValue.getLength();
			if ( !m_bCreateConnectionResourceElement )
			{
				INetURLObject aURL(sPropValue);
                m_bCreateConnectionResourceElement = ( aURL.GetProtocol() == INET_PROT_FILE );
				if ( !m_bCreateConnectionResourceElement )
					exportStringPropertyAttribute(
						OAttributeMetaData::getFormAttributeNamespace(faDatasource),
						OAttributeMetaData::getFormAttributeName(faDatasource),
						PROPERTY_DATASOURCENAME);
			}
			else
				exportedProperty(PROPERTY_URL);
			if ( m_bCreateConnectionResourceElement )
				exportedProperty(PROPERTY_DATASOURCENAME);
		}

		// ----------------------
		// the boolean properties
		{
			static FormAttributes eBooleanPropertyIds[] =
			{
				faAllowDeletes, faAllowInserts, faAllowUpdates, faApplyFilter, faEscapeProcessing, faIgnoreResult
			};
			static const ::rtl::OUString* pBooleanPropertyNames[] =
			{
				&PROPERTY_ALLOWDELETES, &PROPERTY_ALLOWINSERTS, &PROPERTY_ALLOWUPDATES, &PROPERTY_APPLYFILTER, &PROPERTY_ESCAPEPROCESSING, &PROPERTY_IGNORERESULT
			};
			static sal_Int8 nBooleanPropertyAttrFlags[] =
			{
				BOOLATTR_DEFAULT_TRUE, BOOLATTR_DEFAULT_TRUE, BOOLATTR_DEFAULT_TRUE, BOOLATTR_DEFAULT_FALSE, BOOLATTR_DEFAULT_TRUE, BOOLATTR_DEFAULT_FALSE
			};
			sal_Int32 nIdCount = sizeof(eBooleanPropertyIds) / sizeof(eBooleanPropertyIds[0]);
		#if OSL_DEBUG_LEVEL > 0
			sal_Int32 nNameCount = sizeof(pBooleanPropertyNames) / sizeof(pBooleanPropertyNames[0]);
			sal_Int32 nFlagsCount = sizeof(nBooleanPropertyAttrFlags) / sizeof(nBooleanPropertyAttrFlags[0]);
			OSL_ENSURE((nIdCount == nNameCount) && (nNameCount == nFlagsCount),
				"OFormExport::exportAttributes: somebody tampered with the maps (2)!");
		#endif
			for (i=0; i<nIdCount; ++i)
				exportBooleanPropertyAttribute(
					OAttributeMetaData::getFormAttributeNamespace(eBooleanPropertyIds[i]),
					OAttributeMetaData::getFormAttributeName(eBooleanPropertyIds[i]),
					*(pBooleanPropertyNames[i]),
					nBooleanPropertyAttrFlags[i]
				);
		}

		// -------------------
		// the enum properties
		{
			static FormAttributes eEnumPropertyIds[] =
			{
				faEnctype, faMethod, faCommandType, faNavigationMode, faTabbingCycle
			};
			static const sal_Char* pEnumPropertyNames[] =
			{
				PROPERTY_SUBMIT_ENCODING, PROPERTY_SUBMIT_METHOD, PROPERTY_COMMAND_TYPE, PROPERTY_NAVIGATION, PROPERTY_CYCLE
			};
			static OEnumMapper::EnumProperties eEnumPropertyMaps[] =
			{
				OEnumMapper::epSubmitEncoding, OEnumMapper::epSubmitMethod, OEnumMapper::epCommandType, OEnumMapper::epNavigationType, OEnumMapper::epTabCyle
			};
			static sal_Int32 nEnumPropertyAttrDefaults[] =
			{
				FormSubmitEncoding_URL, FormSubmitMethod_GET, CommandType::COMMAND, NavigationBarMode_CURRENT, TabulatorCycle_RECORDS
			};
			static sal_Bool nEnumPropertyAttrDefaultFlags[] =
			{
				sal_False, sal_False, sal_False, sal_False, sal_True
			};
			sal_Int32 nIdCount = sizeof(eEnumPropertyIds) / sizeof(eEnumPropertyIds[0]);
		#if OSL_DEBUG_LEVEL > 0
			sal_Int32 nNameCount = sizeof(pEnumPropertyNames) / sizeof(pEnumPropertyNames[0]);
			sal_Int32 nDefaultCount = sizeof(nEnumPropertyAttrDefaults) / sizeof(nEnumPropertyAttrDefaults[0]);
			sal_Int32 nDefaultFlagCount = sizeof(nEnumPropertyAttrDefaultFlags) / sizeof(nEnumPropertyAttrDefaultFlags[0]);
			sal_Int32 nMapCount = sizeof(eEnumPropertyMaps) / sizeof(eEnumPropertyMaps[0]);
			OSL_ENSURE((nIdCount == nNameCount) && (nNameCount == nDefaultCount) && (nDefaultCount == nDefaultFlagCount) && (nDefaultFlagCount == nMapCount),
				"OFormExport::exportAttributes: somebody tampered with the maps (3)!");
		#endif
			for (i=0; i<nIdCount; ++i)
				exportEnumPropertyAttribute(
					OAttributeMetaData::getFormAttributeNamespace(eEnumPropertyIds[i]),
					OAttributeMetaData::getFormAttributeName(eEnumPropertyIds[i]),
					pEnumPropertyNames[i],
					OEnumMapper::getEnumMap(eEnumPropertyMaps[i]),
					nEnumPropertyAttrDefaults[i],
					nEnumPropertyAttrDefaultFlags[i]
                );
		}

		// the service name
		exportServiceNameAttribute();
		// the target frame
		exportTargetFrameAttribute();
		// the target URL
		exportTargetLocationAttribute(true);    // #i110911# add type attribute (for form, but not for control)

		// master fields
		exportStringSequenceAttribute(
			OAttributeMetaData::getFormAttributeNamespace(faMasterFields),
			OAttributeMetaData::getFormAttributeName(faMasterFields),
			PROPERTY_MASTERFIELDS);
		// detail fields
		exportStringSequenceAttribute(
			OAttributeMetaData::getFormAttributeNamespace(faDetailFiels),
			OAttributeMetaData::getFormAttributeName(faDetailFiels),
			PROPERTY_DETAILFIELDS);
	}
//.........................................................................
}	// namespace xmloff
//.........................................................................
