/**************************************************************
 *
 * 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 "layerimport.hxx"
#include "formenums.hxx"
#include "elementimport.hxx"
#include "officeforms.hxx"
#include "strings.hxx"
#include "formstyles.hxx"
#include <xmloff/xmlictxt.hxx>
#include <xmloff/xmlstyle.hxx>
#include <xmloff/families.hxx>
#include <xmloff/xmlprmap.hxx>
#include <xmloff/prstylei.hxx>
#include <xmloff/xmlimp.hxx>
#include "XMLEventImportHelper.hxx"
#include <xmloff/xmlimppr.hxx>
#include <xmloff/xmlnumfi.hxx>
#include <com/sun/star/util/XNumberFormatsSupplier.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 <tools/wintypes.hxx>		// for check states
#include <com/sun/star/lang/Locale.hpp>
#include <xmloff/controlpropertyhdl.hxx>
#include "controlpropertymap.hxx"
#include "formevents.hxx"
#include "formcellbinding.hxx"
#include "xmloff/xformsimport.hxx"
#include <xmloff/xmltoken.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <rtl/logfile.hxx>
#include <algorithm>

SV_IMPL_REF( SvXMLStylesContext );

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

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::xml;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::form;
using namespace ::com::sun::star::sdb;

//=====================================================================
//= OFormLayerXMLImport_Impl
//=====================================================================
//---------------------------------------------------------------------
OFormLayerXMLImport_Impl::OFormLayerXMLImport_Impl(SvXMLImport& _rImporter)
	:m_rImporter(_rImporter)
	,m_pAutoStyles(NULL)
{
	// build the attribute2property map
	// string properties which are exported as attributes
	m_aAttributeMetaData.addStringProperty(
		OAttributeMetaData::getCommonControlAttributeName(CCA_NAME), PROPERTY_NAME);
	m_aAttributeMetaData.addStringProperty(
		OAttributeMetaData::getCommonControlAttributeName(CCA_IMAGE_DATA), PROPERTY_IMAGEURL);
	m_aAttributeMetaData.addStringProperty(
		OAttributeMetaData::getCommonControlAttributeName(CCA_LABEL), PROPERTY_LABEL);
	m_aAttributeMetaData.addStringProperty(
		OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_LOCATION), PROPERTY_TARGETURL);
	m_aAttributeMetaData.addStringProperty(
		OAttributeMetaData::getCommonControlAttributeName(CCA_TITLE), PROPERTY_TITLE);
	m_aAttributeMetaData.addStringProperty(
		OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_FRAME), PROPERTY_TARGETFRAME, "_blank");
	m_aAttributeMetaData.addStringProperty(
		OAttributeMetaData::getDatabaseAttributeName(DA_DATA_FIELD), PROPERTY_DATAFIELD);
	m_aAttributeMetaData.addStringProperty(
		OAttributeMetaData::getFormAttributeName(faCommand), PROPERTY_COMMAND);
	m_aAttributeMetaData.addStringProperty(
		OAttributeMetaData::getFormAttributeName(faDatasource), PROPERTY_DATASOURCENAME);
	m_aAttributeMetaData.addStringProperty(
		OAttributeMetaData::getFormAttributeName(faFilter), PROPERTY_FILTER);
	m_aAttributeMetaData.addStringProperty(
		OAttributeMetaData::getFormAttributeName(faOrder), PROPERTY_ORDER);

	// properties not added because they're already present in another form
	OSL_ENSURE(
		0 == ::rtl::OUString::createFromAscii(OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_LOCATION)).compareToAscii(
			OAttributeMetaData::getFormAttributeName(faAction)),
		"OFormLayerXMLImport_Impl::OFormLayerXMLImport_Impl: invalid attribute names (1)!");
		// if this fails, we would have to add a translation from faAction->PROPERTY_TARGETURL
		// We did not because we already have one CCA_TARGET_LOCATION->PROPERTY_TARGETURL,
		// and CCA_TARGET_LOCATION and faAction should be represented by the same attribute

	OSL_ENSURE(
		0 == ::rtl::OUString::createFromAscii(OAttributeMetaData::getCommonControlAttributeName(CCA_NAME)).compareToAscii(
			OAttributeMetaData::getFormAttributeName(faName)),
		"OFormLayerXMLImport_Impl::OFormLayerXMLImport_Impl: invalid attribute names (2)!");
		// the same for faName, CCA_NAME and PROPERTY_NAME

	// boolean properties which are exported as attributes
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_SELECTED), PROPERTY_STATE, sal_False);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getCommonControlAttributeName(CCA_DISABLED), PROPERTY_ENABLED, sal_False, sal_True);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getCommonControlAttributeName(CCA_DROPDOWN), PROPERTY_DROPDOWN, sal_False);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getCommonControlAttributeName(CCA_PRINTABLE), PROPERTY_PRINTABLE, sal_True);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getCommonControlAttributeName(CCA_READONLY), PROPERTY_READONLY, sal_False);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getCommonControlAttributeName(CCA_SELECTED), PROPERTY_DEFAULT_STATE, sal_False);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getCommonControlAttributeName(CCA_TAB_STOP), PROPERTY_TABSTOP, sal_True);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getDatabaseAttributeName(DA_CONVERT_EMPTY), PROPERTY_EMPTY_IS_NULL, sal_False);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getSpecialAttributeName(SCA_VALIDATION), PROPERTY_STRICTFORMAT, sal_False);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getSpecialAttributeName(SCA_MULTI_LINE), PROPERTY_MULTILINE, sal_False);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getSpecialAttributeName(SCA_AUTOMATIC_COMPLETION), PROPERTY_AUTOCOMPLETE, sal_False);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getSpecialAttributeName(SCA_MULTIPLE), PROPERTY_MULTISELECTION, sal_False);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getSpecialAttributeName(SCA_DEFAULT_BUTTON), PROPERTY_DEFAULTBUTTON, sal_False);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getSpecialAttributeName(SCA_IS_TRISTATE), PROPERTY_TRISTATE, sal_False);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getFormAttributeName(faAllowDeletes), PROPERTY_ALLOWDELETES, sal_True);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getFormAttributeName(faAllowInserts), PROPERTY_ALLOWINSERTS, sal_True);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getFormAttributeName(faAllowUpdates), PROPERTY_ALLOWUPDATES, sal_True);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getFormAttributeName(faApplyFilter), PROPERTY_APPLYFILTER, sal_False);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getFormAttributeName(faEscapeProcessing), PROPERTY_ESCAPEPROCESSING, sal_True);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getFormAttributeName(faIgnoreResult), PROPERTY_IGNORERESULT, sal_False);
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getSpecialAttributeName( SCA_TOGGLE ), PROPERTY_TOGGLE, sal_False );
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getSpecialAttributeName( SCA_FOCUS_ON_CLICK ), PROPERTY_FOCUS_ON_CLICK, sal_True );
	m_aAttributeMetaData.addBooleanProperty(
		OAttributeMetaData::getDatabaseAttributeName( DA_INPUT_REQUIRED ), PROPERTY_INPUT_REQUIRED, sal_False );

	// the int16 attributes
	m_aAttributeMetaData.addInt16Property(
		OAttributeMetaData::getCommonControlAttributeName(CCA_MAX_LENGTH), PROPERTY_MAXTEXTLENGTH, 0);
	m_aAttributeMetaData.addInt16Property(
		OAttributeMetaData::getCommonControlAttributeName(CCA_SIZE), PROPERTY_LINECOUNT, 5);
	m_aAttributeMetaData.addInt16Property(
		OAttributeMetaData::getCommonControlAttributeName(CCA_TAB_INDEX), PROPERTY_TABINDEX, 0);
	m_aAttributeMetaData.addInt16Property(
		OAttributeMetaData::getDatabaseAttributeName(DA_BOUND_COLUMN), PROPERTY_BOUNDCOLUMN, 0);

	// the int32 attributes
	m_aAttributeMetaData.addInt32Property(
		OAttributeMetaData::getSpecialAttributeName( SCA_PAGE_STEP_SIZE ), PROPERTY_BLOCK_INCREMENT, 10 );

	// the enum attributes
	m_aAttributeMetaData.addEnumProperty(
		OAttributeMetaData::getCommonControlAttributeName( CCA_VISUAL_EFFECT ), PROPERTY_VISUAL_EFFECT,
		VisualEffect::LOOK3D, OEnumMapper::getEnumMap( OEnumMapper::epVisualEffect ),
		&::getCppuType( static_cast< sal_Int16* >( NULL ) ) );
	m_aAttributeMetaData.addEnumProperty(
		OAttributeMetaData::getCommonControlAttributeName( CCA_ORIENTATION ), PROPERTY_ORIENTATION,
		ScrollBarOrientation::HORIZONTAL, OEnumMapper::getEnumMap( OEnumMapper::epOrientation ),
		&::getCppuType( static_cast< sal_Int32* >( NULL ) ) );
	m_aAttributeMetaData.addEnumProperty(
		OAttributeMetaData::getCommonControlAttributeName(CCA_BUTTON_TYPE), PROPERTY_BUTTONTYPE,
		FormButtonType_PUSH, OEnumMapper::getEnumMap(OEnumMapper::epButtonType),
		&::getCppuType( static_cast<FormButtonType*>(NULL) ));
	m_aAttributeMetaData.addEnumProperty(
		OAttributeMetaData::getDatabaseAttributeName(DA_LIST_SOURCE_TYPE), PROPERTY_LISTSOURCETYPE,
		ListSourceType_VALUELIST, OEnumMapper::getEnumMap(OEnumMapper::epListSourceType),
		&::getCppuType( static_cast<ListSourceType*>(NULL) ));
	m_aAttributeMetaData.addEnumProperty(
		OAttributeMetaData::getSpecialAttributeName(SCA_STATE), PROPERTY_DEFAULT_STATE, STATE_NOCHECK,
		OEnumMapper::getEnumMap(OEnumMapper::epCheckState),
		&::getCppuType( static_cast< sal_Int16* >(NULL)));
	m_aAttributeMetaData.addEnumProperty(
		OAttributeMetaData::getSpecialAttributeName(SCA_CURRENT_STATE), PROPERTY_STATE, STATE_NOCHECK,
		OEnumMapper::getEnumMap(OEnumMapper::epCheckState),
		&::getCppuType( static_cast< sal_Int16* >(NULL)));
	m_aAttributeMetaData.addEnumProperty(
		OAttributeMetaData::getFormAttributeName(faEnctype), PROPERTY_SUBMIT_ENCODING,
		FormSubmitEncoding_URL, OEnumMapper::getEnumMap(OEnumMapper::epSubmitEncoding),
		&::getCppuType( static_cast<FormSubmitEncoding*>(NULL) ));
	m_aAttributeMetaData.addEnumProperty(
		OAttributeMetaData::getFormAttributeName(faMethod), PROPERTY_SUBMIT_METHOD,
		FormSubmitMethod_GET, OEnumMapper::getEnumMap(OEnumMapper::epSubmitMethod),
		&::getCppuType( static_cast<FormSubmitMethod*>(NULL) ));
	m_aAttributeMetaData.addEnumProperty(
		OAttributeMetaData::getFormAttributeName(faCommandType), PROPERTY_COMMAND_TYPE,
		CommandType::COMMAND, OEnumMapper::getEnumMap(OEnumMapper::epCommandType));
	m_aAttributeMetaData.addEnumProperty(
		OAttributeMetaData::getFormAttributeName(faNavigationMode), PROPERTY_NAVIGATION,
		NavigationBarMode_NONE, OEnumMapper::getEnumMap(OEnumMapper::epNavigationType),
		&::getCppuType( static_cast<NavigationBarMode*>(NULL) ));
	m_aAttributeMetaData.addEnumProperty(
		OAttributeMetaData::getFormAttributeName(faTabbingCycle), PROPERTY_CYCLE,
		TabulatorCycle_RECORDS, OEnumMapper::getEnumMap(OEnumMapper::epTabCyle),
		&::getCppuType( static_cast<TabulatorCycle*>(NULL) ));

	// 'initialize'
	m_aCurrentPageIds = m_aControlIds.end();
}

//---------------------------------------------------------------------
OFormLayerXMLImport_Impl::~OFormLayerXMLImport_Impl()
{
	// outlined to allow forward declaration of OAttribute2Property in the header

	if (m_pAutoStyles)
		m_pAutoStyles->ReleaseRef();
}

//---------------------------------------------------------------------
void OFormLayerXMLImport_Impl::setAutoStyleContext(SvXMLStylesContext* _pNewContext)
{
	OSL_ENSURE(!m_pAutoStyles, "OFormLayerXMLImport_Impl::setAutoStyleContext: not to be called twice!");
	m_pAutoStyles = _pNewContext;
	if (m_pAutoStyles)
		m_pAutoStyles->AddRef();
}

//---------------------------------------------------------------------
void OFormLayerXMLImport_Impl::applyControlNumberStyle(const Reference< XPropertySet >& _rxControlModel, const ::rtl::OUString& _rControlNumerStyleName)
{
	OSL_ENSURE(_rxControlModel.is() && (0 != _rControlNumerStyleName.getLength()),
		"OFormLayerXMLImport_Impl::applyControlNumberStyle: invalid arguments (this will crash)!");

	OSL_ENSURE(m_pAutoStyles, "OFormLayerXMLImport_Impl::applyControlNumberStyle: have no auto style context!");
	if (!m_pAutoStyles)
	{
		m_pAutoStyles = m_rImporter.GetShapeImport()->GetAutoStylesContext();
		if (m_pAutoStyles)
			m_pAutoStyles->AddRef();
	}

	if (m_pAutoStyles)
	{
		const SvXMLStyleContext* pStyle = m_pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_DATA_STYLE, _rControlNumerStyleName);
		if (pStyle)
		{
			const SvXMLNumFormatContext* pDataStyle = static_cast<const SvXMLNumFormatContext*>(pStyle);

			// set this format at the control model
			try
			{
				// the models number format supplier and formats
				Reference< XNumberFormatsSupplier > xFormatsSupplier;
				_rxControlModel->getPropertyValue(PROPERTY_FORMATSSUPPLIER) >>= xFormatsSupplier;
				Reference< XNumberFormats > xFormats;
				if (xFormatsSupplier.is())
					xFormats = xFormatsSupplier->getNumberFormats();
				OSL_ENSURE(xFormats.is(), "OFormLayerXMLImport_Impl::applyControlNumberStyle: could not obtain the controls number formats!");

				// obtain a key
				if (xFormats.is())
				{
			        sal_Int32 nFormatKey = const_cast<SvXMLNumFormatContext*>(pDataStyle)->CreateAndInsert( xFormatsSupplier );
					OSL_ENSURE(-1 != nFormatKey, "OFormLayerXMLImport_Impl::applyControlNumberStyle: could not obtain a format key!");

                    // set the format on the control model
					_rxControlModel->setPropertyValue(PROPERTY_FORMATKEY, makeAny(nFormatKey));
				}
			}
			catch(const Exception&)
			{
				OSL_ENSURE(sal_False, "OFormLayerXMLImport_Impl::applyControlNumberStyle: couldn't set the format!");
			}
		}
		else
			OSL_ENSURE(sal_False, "OFormLayerXMLImport_Impl::applyControlNumberStyle: did not find the style with the given name!");
	}
}

//---------------------------------------------------------------------
void OFormLayerXMLImport_Impl::registerCellValueBinding( const Reference< XPropertySet >& _rxControlModel, const ::rtl::OUString& _rCellAddress )
{
    OSL_ENSURE( _rxControlModel.is() && _rCellAddress.getLength(),
        "OFormLayerXMLImport_Impl::registerCellValueBinding: invalid arguments!" );
    m_aCellValueBindings.push_back( ModelStringPair( _rxControlModel, _rCellAddress ) );
}

//---------------------------------------------------------------------
void OFormLayerXMLImport_Impl::registerXFormsValueBinding(
    const Reference< XPropertySet >& _rxControlModel,
    const ::rtl::OUString& _rBindingID )
{
    // TODO: is an empty binding name allowed?
    OSL_ENSURE( _rxControlModel.is(), "need  model" );

    m_aXFormsValueBindings.push_back(
        ModelStringPair( _rxControlModel, _rBindingID ) );
}

//---------------------------------------------------------------------
void OFormLayerXMLImport_Impl::registerXFormsListBinding(
    const Reference< XPropertySet >& _rxControlModel,
    const ::rtl::OUString& _rBindingID )
{
    // TODO: is an empty binding name allowed?
    OSL_ENSURE( _rxControlModel.is(), "need  model" );

    m_aXFormsListBindings.push_back(
        ModelStringPair( _rxControlModel, _rBindingID ) );
}

//---------------------------------------------------------------------
void OFormLayerXMLImport_Impl::registerXFormsSubmission(
    const Reference< XPropertySet >& _rxControlModel,
    const ::rtl::OUString& _rSubmissionID )
{
    // TODO: is an empty binding name allowed?
    OSL_ENSURE( _rxControlModel.is(), "need  model" );

    m_aXFormsSubmissions.push_back(
        ModelStringPair( _rxControlModel, _rSubmissionID ) );
}

//---------------------------------------------------------------------
void OFormLayerXMLImport_Impl::registerCellRangeListSource( const Reference< XPropertySet >& _rxControlModel, const ::rtl::OUString& _rCellRangeAddress )
{
    OSL_ENSURE( _rxControlModel.is() && _rCellRangeAddress.getLength(),
        "OFormLayerXMLImport_Impl::registerCellRangeListSource: invalid arguments!" );
    m_aCellRangeListSources.push_back( ModelStringPair( _rxControlModel, _rCellRangeAddress ) );
}
//---------------------------------------------------------------------
const SvXMLStyleContext* OFormLayerXMLImport_Impl::getStyleElement(const ::rtl::OUString& _rStyleName) const
{
	OSL_ENSURE( m_pAutoStyles, "OFormLayerXMLImport_Impl::getStyleElement: have no auto style context!" );
		// did you use setAutoStyleContext?

	const SvXMLStyleContext* pControlStyle =
		m_pAutoStyles ? m_pAutoStyles->FindStyleChildContext( XML_STYLE_FAMILY_TEXT_PARAGRAPH, _rStyleName ) : NULL;
	OSL_ENSURE( pControlStyle || !m_pAutoStyles,
				::rtl::OString( "OFormLayerXMLImport_Impl::getStyleElement: did not find the style named \"" )
			+=	::rtl::OString( _rStyleName.getStr(), _rStyleName.getLength(), RTL_TEXTENCODING_ASCII_US )
			+=	::rtl::OString( "\"!" ) );
	return pControlStyle;
}

//---------------------------------------------------------------------
void OFormLayerXMLImport_Impl::enterEventContext()
{
	// install our own translation table. We need to disable the other tables because of name conflicts.
	m_rImporter.GetEventImport().PushTranslationTable();
	m_rImporter.GetEventImport().AddTranslationTable(g_pFormsEventTranslation);
}

//---------------------------------------------------------------------
void OFormLayerXMLImport_Impl::leaveEventContext()
{
	// install the original event tables.
	m_rImporter.GetEventImport().PopTranslationTable();
}

//---------------------------------------------------------------------
void OFormLayerXMLImport_Impl::registerControlId(const Reference< XPropertySet >& _rxControl, const ::rtl::OUString& _rId)
{
	OSL_ENSURE(m_aCurrentPageIds != m_aControlIds.end(), "OFormLayerXMLImport_Impl::registerControlId: no current page!");
	OSL_ENSURE(_rId.getLength(), "OFormLayerXMLImport_Impl::registerControlId: invalid (empty) control id!");

	OSL_ENSURE(m_aCurrentPageIds->second.end() == m_aCurrentPageIds->second.find(_rId), "OFormLayerXMLImport_Impl::registerControlId: control id already used!");
	m_aCurrentPageIds->second[_rId] = _rxControl;
}

//---------------------------------------------------------------------
void OFormLayerXMLImport_Impl::registerControlReferences(const Reference< XPropertySet >& _rxControl, const ::rtl::OUString& _rReferringControls)
{
	OSL_ENSURE(_rReferringControls.getLength(), "OFormLayerXMLImport_Impl::registerControlReferences: invalid (empty) control id list!");
	OSL_ENSURE(_rxControl.is(), "OFormLayerXMLImport_Impl::registerControlReferences: invalid (NULL) control!");
	m_aControlReferences.push_back( ModelStringPair( _rxControl, _rReferringControls ) );
}

//---------------------------------------------------------------------
void OFormLayerXMLImport_Impl::startPage(const Reference< XDrawPage >& _rxDrawPage)
{
	m_xCurrentPageFormsSupp.clear();

	OSL_ENSURE(_rxDrawPage.is(), "OFormLayerXMLImport_Impl::startPage: NULL page!");
	m_xCurrentPageFormsSupp = m_xCurrentPageFormsSupp.query( _rxDrawPage );
	OSL_ENSURE( m_xCurrentPageFormsSupp.is(), "OFormLayerXMLImport_Impl::startPage: invalid draw page (no XFormsSupplier)!" );
	if ( !m_xCurrentPageFormsSupp.is() )
		return;

	// add a new entry to our page map
	::std::pair< MapDrawPage2MapIterator, bool > aPagePosition;
	aPagePosition =
		m_aControlIds.insert(MapDrawPage2Map::value_type(_rxDrawPage, MapString2PropertySet()));
	OSL_ENSURE(aPagePosition.second, "OFormLayerXMLImport_Impl::startPage: already imported this page!");
	m_aCurrentPageIds = aPagePosition.first;
}

//---------------------------------------------------------------------
void OFormLayerXMLImport_Impl::endPage()
{
	OSL_ENSURE( m_xCurrentPageFormsSupp.is(), "OFormLayerXMLImport_Impl::endPage: sure you called startPage before?" );

	// do some knittings for the controls which are referring to each other
	try
	{
		static const sal_Unicode s_nSeparator = ',';
		::rtl::OUString sReferring;
		::rtl::OUString sCurrentReferring;
		::rtl::OUString sSeparator(&s_nSeparator, 1);
		Reference< XPropertySet > xCurrentReferring;
		sal_Int32 nSeparator, nPrevSep;
        ::std::vector< ModelStringPair >::const_iterator aEnd = m_aControlReferences.end();
        for	(	::std::vector< ModelStringPair >::const_iterator aReferences = m_aControlReferences.begin();
				aReferences != aEnd;
				++aReferences
			)
		{
			// the list of control ids is comma separated

			// in a list of n ids there are only n-1 separators ... have to catch this last id
			// -> normalize the list
			sReferring = aReferences->second;
			sReferring += sSeparator;

			nPrevSep = -1;
			while (-1 != (nSeparator = sReferring.indexOf(s_nSeparator, nPrevSep + 1)))
			{
				sCurrentReferring = sReferring.copy(nPrevSep + 1, nSeparator - nPrevSep - 1);
				xCurrentReferring = lookupControlId(sCurrentReferring);
				if (xCurrentReferring.is())
					// if this condition fails, this is an error, but lookupControlId should have asserted this ...
					xCurrentReferring->setPropertyValue( PROPERTY_CONTROLLABEL, makeAny( aReferences->first ) );

				nPrevSep = nSeparator;
			}
		}
	}
	catch(Exception&)
	{
		OSL_ENSURE(sal_False, "OFormLayerXMLImport_Impl::endPage: unable to knit the control references (caught an exception)!");
	}

	// now that we have all children of the forms collection, attach the events
	Reference< XIndexAccess > xIndexContainer;
    if ( m_xCurrentPageFormsSupp.is() && m_xCurrentPageFormsSupp->hasForms() )
        xIndexContainer = xIndexContainer.query( m_xCurrentPageFormsSupp->getForms() );
	if ( xIndexContainer.is() )
		ODefaultEventAttacherManager::setEvents( xIndexContainer );

	// clear the structures for the control references.
	m_aControlReferences.clear();

	// and no we have no current page anymore
	m_aCurrentPageIds = m_aControlIds.end();
}

//---------------------------------------------------------------------
Reference< XPropertySet > OFormLayerXMLImport_Impl::lookupControlId(const ::rtl::OUString& _rControlId)
{
	OSL_ENSURE(m_aCurrentPageIds != m_aControlIds.end(), "OFormLayerXMLImport_Impl::lookupControlId: no current page!");
	Reference< XPropertySet > xReturn;
	if (m_aCurrentPageIds != m_aControlIds.end())
	{
		ConstMapString2PropertySetIterator aPos = m_aCurrentPageIds->second.find(_rControlId);
		if (m_aCurrentPageIds->second.end() != aPos)
			xReturn = aPos->second;
		else
			OSL_ENSURE(sal_False, "OFormLayerXMLImport_Impl::lookupControlId: invalid control id (did not find it)!");
	}
	return xReturn;
}

//---------------------------------------------------------------------
SvXMLImportContext* OFormLayerXMLImport_Impl::createOfficeFormsContext(
	SvXMLImport& _rImport,
	sal_uInt16 _nPrefix,
	const rtl::OUString& _rLocalName)
{
	return new OFormsRootImport( _rImport, _nPrefix, _rLocalName );
}

//---------------------------------------------------------------------
SvXMLImportContext* OFormLayerXMLImport_Impl::createContext(const sal_uInt16 _nPrefix, const rtl::OUString& _rLocalName,
	const Reference< sax::XAttributeList >&)
{
    SvXMLImportContext* pContext = NULL;
    if ( 0 == _rLocalName.compareToAscii( "form" ) )
    {
        if ( m_xCurrentPageFormsSupp.is() )
            pContext = new OFormImport(*this, *this, _nPrefix, _rLocalName, m_xCurrentPageFormsSupp->getForms() );
    }
    else if (  ( _nPrefix == XML_NAMESPACE_XFORMS
            && ( xmloff::token::IsXMLToken( _rLocalName, xmloff::token::XML_MODEL ) ) )
            )
    {
        pContext = createXFormsModelContext( m_rImporter, _nPrefix, _rLocalName );
    }

    if ( !pContext )
    {
        OSL_ENSURE( false, "unknown element" );
        pContext =
            new SvXMLImportContext(m_rImporter, _nPrefix, _rLocalName);
    }

	return pContext;
}

//---------------------------------------------------------------------
void OFormLayerXMLImport_Impl::seekPage(const Reference< XDrawPage >& _rxDrawPage)
{
	OSL_ENSURE(m_aCurrentPageIds == m_aControlIds.end(), "OFormLayerXMLImport_Impl::seekPage: importing another page currently! This will smash your import!");
	m_aCurrentPageIds = m_aControlIds.find(_rxDrawPage);
	OSL_ENSURE(m_aCurrentPageIds != m_aControlIds.end(), "OFormLayerXMLImport_Impl::seekPage: did not find the given page (perhaps it has not been imported, yet?)!");
}

//---------------------------------------------------------------------
void OFormLayerXMLImport_Impl::documentDone( )
{
    SvXMLImport& rImport = getGlobalContext();
    if ( ( rImport.getImportFlags() & IMPORT_CONTENT ) == 0 )
        return;

    // create (and bind) the spreadsheet cell bindings
    if  (   !m_aCellValueBindings.empty()
        &&  FormCellBindingHelper::isCellBindingAllowed( rImport.GetModel() )
        )
    {
        static ::rtl::OUString s_sIndex( RTL_CONSTASCII_USTRINGPARAM( ":index" ) );
        ::std::vector< ModelStringPair >::const_iterator aEnd = m_aCellValueBindings.end();
        for (   ::std::vector< ModelStringPair >::const_iterator aCellBindings = m_aCellValueBindings.begin();
                aCellBindings != aEnd;
                ++aCellBindings
            )
        {
            try
            {
                FormCellBindingHelper aHelper( aCellBindings->first, rImport.GetModel() );
                OSL_ENSURE( aHelper.isCellBindingAllowed(), "OFormLayerXMLImport_Impl::documentDone: can't bind this control model!" );
                if ( aHelper.isCellBindingAllowed() )
                {
                    // There are special bindings for listboxes. See
                    // OListAndComboImport::doRegisterCellValueBinding for a comment on this HACK.
                    ::rtl::OUString sBoundCellAddress( aCellBindings->second );
                    sal_Int32 nIndicator = sBoundCellAddress.lastIndexOf( s_sIndex );

                    bool bUseIndexBinding = false;
                    if ( nIndicator != -1 )
                    {
                        sBoundCellAddress = sBoundCellAddress.copy( 0, nIndicator );
                        bUseIndexBinding = true;
                    }

                    aHelper.setBinding( aHelper.createCellBindingFromStringAddress( sBoundCellAddress, bUseIndexBinding ) );
                }
            }
            catch( const Exception& )
            {
                OSL_ENSURE( sal_False, "OFormLayerXMLImport_Impl::documentDone: caught an exception while binding to a cell!" );
            }
        }
        m_aCellValueBindings.clear();
    }

    // the same for the spreadsheet cell range list sources
    if  (   !m_aCellRangeListSources.empty()
        &&  FormCellBindingHelper::isListCellRangeAllowed( rImport.GetModel() )
        )
    {
        for (   ::std::vector< ModelStringPair >::const_iterator aRangeBindings = m_aCellRangeListSources.begin();
                aRangeBindings != m_aCellRangeListSources.end();
                ++aRangeBindings
            )
        {
            try
            {
                FormCellBindingHelper aHelper( aRangeBindings->first, rImport.GetModel() );
                OSL_ENSURE( aHelper.isListCellRangeAllowed(), "OFormLayerXMLImport_Impl::documentDone: can't bind this control model!" );
                if ( aHelper.isListCellRangeAllowed() )
                {
                    aHelper.setListSource( aHelper.createCellListSourceFromStringAddress( aRangeBindings->second ) );
                }
            }
            catch( const Exception& )
            {
                OSL_ENSURE( sal_False, "OFormLayerXMLImport_Impl::documentDone: caught an exception while binding to a cell range!" );
            }
        }
        m_aCellRangeListSources.clear();
    }

    // process XForms-bindings; call registerXFormsValueBinding for each
    std::for_each( m_aXFormsValueBindings.begin(),
                   m_aXFormsValueBindings.end(),
                   bind1st( ptr_fun( bindXFormsValueBinding ),
                            rImport.GetModel() ) );
    // same for list bindings
    std::for_each( m_aXFormsListBindings.begin(),
                   m_aXFormsListBindings.end(),
                   bind1st( ptr_fun( bindXFormsListBinding ),
                            rImport.GetModel() ) );
    // same for submissions
    std::for_each( m_aXFormsSubmissions.begin(),
                   m_aXFormsSubmissions.end(),
                   bind1st( ptr_fun( bindXFormsSubmission ),
                            rImport.GetModel() ) );
}

//.........................................................................
}	// namespace xmloff
//.........................................................................
