/**************************************************************
 * 
 * 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_forms.hxx"

#include "componenttools.hxx"
#include "DatabaseForm.hxx"
#include "EventThread.hxx"
#include "frm_module.hxx"
#include "frm_resource.hrc"
#include "frm_resource.hxx"
#include "GroupManager.hxx"
#include "property.hrc"
#include "property.hxx"
#include "services.hxx"

#include <com/sun/star/awt/XControlContainer.hpp>
#include <com/sun/star/awt/XTextComponent.hpp>
#include <com/sun/star/form/DataSelectionType.hpp>
#include <com/sun/star/form/FormComponentType.hpp>
#include <com/sun/star/form/TabulatorCycle.hpp>
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#include <com/sun/star/frame/XDispatch.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/io/XObjectInputStream.hpp>
#include <com/sun/star/io/XObjectOutputStream.hpp>
#include <com/sun/star/sdb/CommandType.hpp>
#include <com/sun/star/sdb/RowSetVetoException.hpp>
#include <com/sun/star/sdb/SQLContext.hpp>
#include <com/sun/star/sdb/XColumnUpdate.hpp>
#include <com/sun/star/sdbc/DataType.hpp>
#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
#include <com/sun/star/sdbc/ResultSetType.hpp>
#include <com/sun/star/sdbc/XRowSet.hpp>
#include <com/sun/star/sdbcx/Privilege.hpp>
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#include <com/sun/star/util/XCancellable.hpp>
#include <com/sun/star/util/XURLTransformer.hpp>
#include <com/sun/star/util/XModifiable2.hpp>

#include <comphelper/basicio.hxx>
#include <comphelper/container.hxx>
#include <comphelper/enumhelper.hxx>
#include <comphelper/extract.hxx>
#include <comphelper/seqstream.hxx>
#include <comphelper/sequence.hxx>
#include <comphelper/stl_types.hxx>
#include <comphelper/uno3.hxx>
#include <connectivity/dbtools.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <cppuhelper/implbase2.hxx>
#include <osl/mutex.hxx>
#include <rtl/math.hxx>
#include <rtl/tencinfo.h>
#include <svl/inetstrm.hxx>
#include <svl/inettype.hxx>
#include <tools/debug.hxx>
#include <tools/diagnose_ex.h>
#include <tools/fsys.hxx>
#include <tools/inetmsg.hxx>
#include <tools/urlobj.hxx>
#include <unotools/ucblockbytes.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <vcl/svapp.hxx>
#include <vcl/timer.hxx>
#include <vos/mutex.hxx>

#include <ctype.h>
#include <hash_map>

// compatiblity: DatabaseCursorType is dead, but for compatiblity reasons we still have to write it ...
namespace com {
namespace sun {
namespace star {
namespace data {

enum DatabaseCursorType
{
	DatabaseCursorType_FORWARD = 0,
	DatabaseCursorType_SNAPSHOT = 1,
	DatabaseCursorType_KEYSET = 2,
	DatabaseCursorType_DYNAMIC = 3,
	DatabaseCursorType_MAKE_FIXED_SIZE = SAL_MAX_ENUM
};

} } } }

using namespace ::dbtools;
using namespace ::comphelper;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::task;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::form;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::data;
using namespace ::com::sun::star::util;

//--------------------------------------------------------------------------
extern "C" void SAL_CALL createRegistryInfo_ODatabaseForm()
{
	static ::frm::OMultiInstanceAutoRegistration< ::frm::ODatabaseForm > aAutoRegistration;
}

//.........................................................................
namespace frm
{
//.........................................................................

//==================================================================
//= DocumentModifyGuard
//==================================================================
class DocumentModifyGuard
{
public:
    DocumentModifyGuard( const Reference< XInterface >& _rxFormComponent )
        :m_xDocumentModify( getXModel( _rxFormComponent ), UNO_QUERY )
    {
        impl_changeModifiableFlag_nothrow( false );
    }
    ~DocumentModifyGuard()
    {
        impl_changeModifiableFlag_nothrow( true );
    }

private:
    void    impl_changeModifiableFlag_nothrow( const bool _enable )
    {
        try
        {
            if ( m_xDocumentModify.is() )
                _enable ? m_xDocumentModify->enableSetModified() : m_xDocumentModify->disableSetModified();
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
    }

private:
    Reference< XModifiable2 >   m_xDocumentModify;
};

//==================================================================
//= OFormSubmitResetThread
//=-----------------------------------------------------------------
//= submitting and resetting html-forms asynchronously
//==================================================================

//------------------------------------------------------------------
class OFormSubmitResetThread: public OComponentEventThread
{
protected:

	// duplicate an event with respect to it's type
	virtual EventObject *cloneEvent( const EventObject *pEvt ) const;

	// process an event. while processing the mutex isn't locked, and pCompImpl
	// is made sure to remain valid
	virtual void processEvent( ::cppu::OComponentHelper* _pCompImpl,
							   const EventObject* _pEvt,
							   const Reference<XControl>& _rControl,
							   sal_Bool _bSubmit);

public:

	OFormSubmitResetThread(ODatabaseForm* pControl) : OComponentEventThread(pControl) { }
};

//------------------------------------------------------------------
EventObject* OFormSubmitResetThread::cloneEvent(
		const EventObject *pEvt ) const
{
	return new ::com::sun::star::awt::MouseEvent( *(::com::sun::star::awt::MouseEvent *)pEvt );
}

//------------------------------------------------------------------
void OFormSubmitResetThread::processEvent(
		::cppu::OComponentHelper* pCompImpl,
		const EventObject *_pEvt,
		const Reference<XControl>& _rControl,
		sal_Bool _bSubmit)
{
	if (_bSubmit)
		((ODatabaseForm *)pCompImpl)->submit_impl(_rControl, *static_cast<const ::com::sun::star::awt::MouseEvent*>(_pEvt), true);
	else
		((ODatabaseForm *)pCompImpl)->reset_impl(true);
}

//==================================================================
//= ODatabaseForm
//==================================================================

//------------------------------------------------------------------
Reference< XInterface > SAL_CALL ODatabaseForm::Create( const Reference< XMultiServiceFactory >& _rxFactory )
{
	return *( new ODatabaseForm( _rxFactory ) );
}

//------------------------------------------------------------------------------
Sequence<sal_Int8> SAL_CALL ODatabaseForm::getImplementationId() throw(RuntimeException)
{
	return OImplementationIds::getImplementationId(getTypes());
}

//------------------------------------------------------------------
Sequence<Type> SAL_CALL ODatabaseForm::getTypes() throw(RuntimeException)
{
	// ask the aggregate
	Sequence<Type> aAggregateTypes;
	Reference<XTypeProvider> xAggregateTypes;
	if (query_aggregation(m_xAggregate, xAggregateTypes))
		aAggregateTypes = xAggregateTypes->getTypes();

	Sequence< Type > aRet = concatSequences(
        aAggregateTypes, ODatabaseForm_BASE1::getTypes(), OFormComponents::getTypes()
    );
	aRet = concatSequences( aRet, ODatabaseForm_BASE2::getTypes(), ODatabaseForm_BASE3::getTypes() );
    return concatSequences( aRet, OPropertySetAggregationHelper::getTypes() );
}

//------------------------------------------------------------------
Any SAL_CALL ODatabaseForm::queryAggregation(const Type& _rType) throw(RuntimeException)
{
	Any aReturn = ODatabaseForm_BASE1::queryInterface(_rType);
	// our own interfaces
	if (!aReturn.hasValue())
	{
		aReturn = ODatabaseForm_BASE2::queryInterface(_rType);
		// property set related interfaces
		if (!aReturn.hasValue())
		{
			aReturn = OPropertySetAggregationHelper::queryInterface(_rType);

			// form component collection related interfaces
			if (!aReturn.hasValue())
			{
				aReturn = OFormComponents::queryAggregation(_rType);

				// interfaces already present in the aggregate which we want to reroute
				// only available if we could create the aggregate
				if (!aReturn.hasValue() && m_xAggregateAsRowSet.is())
					aReturn = ODatabaseForm_BASE3::queryInterface(_rType);

				// aggregate interfaces
				// (ask the aggregated object _after_ the OComponentHelper (base of OFormComponents),
				// so calls to the XComponent interface reach us and not the aggreagtion)
				if (!aReturn.hasValue() && m_xAggregate.is())
					aReturn = m_xAggregate->queryAggregation(_rType);
			}
		}
	}

	return aReturn;
}

DBG_NAME(ODatabaseForm);
//------------------------------------------------------------------
ODatabaseForm::ODatabaseForm(const Reference<XMultiServiceFactory>& _rxFactory)
    :OFormComponents(_rxFactory)
    ,OPropertySetAggregationHelper(OComponentHelper::rBHelper)
    ,OPropertyChangeListener(m_aMutex)
    ,m_aLoadListeners(m_aMutex)
    ,m_aRowSetApproveListeners(m_aMutex)
    ,m_aRowSetListeners(m_aMutex)
    ,m_aSubmitListeners(m_aMutex)
    ,m_aErrorListeners(m_aMutex)
    ,m_aResetListeners( *this, m_aMutex )
    ,m_aPropertyBagHelper( *this )
    ,m_pAggregatePropertyMultiplexer(NULL)
    ,m_pGroupManager( NULL )
    ,m_aParameterManager( m_aMutex, _rxFactory )
    ,m_aFilterManager( _rxFactory )
    ,m_pLoadTimer(NULL)
    ,m_pThread(NULL)
    ,m_nResetsPending(0)
    ,m_nPrivileges(0)
    ,m_bInsertOnly( sal_False )
    ,m_eSubmitMethod(FormSubmitMethod_GET)
    ,m_eSubmitEncoding(FormSubmitEncoding_URL)
    ,m_eNavigation(NavigationBarMode_CURRENT)
    ,m_bAllowInsert(sal_True)
    ,m_bAllowUpdate(sal_True)
    ,m_bAllowDelete(sal_True)
    ,m_bLoaded(sal_False)
    ,m_bSubForm(sal_False)
    ,m_bForwardingConnection(sal_False)
    ,m_bSharingConnection( sal_False )
{
	DBG_CTOR( ODatabaseForm, NULL );
    impl_construct();
}

//------------------------------------------------------------------
ODatabaseForm::ODatabaseForm( const ODatabaseForm& _cloneSource )
	:OFormComponents( _cloneSource )
	,OPropertySetAggregationHelper( OComponentHelper::rBHelper )
	,OPropertyChangeListener( m_aMutex )
    ,ODatabaseForm_BASE1()
    ,ODatabaseForm_BASE2()
    ,ODatabaseForm_BASE3()
    ,IPropertyBagHelperContext()
	,m_aLoadListeners( m_aMutex )
	,m_aRowSetApproveListeners( m_aMutex )
	,m_aRowSetListeners( m_aMutex )
	,m_aSubmitListeners( m_aMutex )
	,m_aErrorListeners( m_aMutex )
    ,m_aResetListeners( *this, m_aMutex )
    ,m_aPropertyBagHelper( *this )
	,m_pAggregatePropertyMultiplexer( NULL )
    ,m_pGroupManager( NULL )
    ,m_aParameterManager( m_aMutex, _cloneSource.m_xServiceFactory )
    ,m_aFilterManager( _cloneSource.m_xServiceFactory )
	,m_pLoadTimer( NULL )
	,m_pThread( NULL )
	,m_nResetsPending( 0 )
	,m_nPrivileges( 0 )
    ,m_bInsertOnly( _cloneSource.m_bInsertOnly )
    ,m_aControlBorderColorFocus( _cloneSource.m_aControlBorderColorFocus )
    ,m_aControlBorderColorMouse( _cloneSource.m_aControlBorderColorMouse )
    ,m_aControlBorderColorInvalid( _cloneSource.m_aControlBorderColorInvalid )
    ,m_aDynamicControlBorder( _cloneSource.m_aDynamicControlBorder )
    ,m_sName( _cloneSource.m_sName )
    ,m_aTargetURL( _cloneSource.m_aTargetURL )
    ,m_aTargetFrame( _cloneSource.m_aTargetFrame )
	,m_eSubmitMethod( _cloneSource.m_eSubmitMethod )
	,m_eSubmitEncoding( _cloneSource.m_eSubmitEncoding )
	,m_eNavigation( _cloneSource.m_eNavigation )
	,m_bAllowInsert( _cloneSource.m_bAllowInsert )
	,m_bAllowUpdate( _cloneSource.m_bAllowUpdate )
	,m_bAllowDelete( _cloneSource.m_bAllowDelete )
    ,m_bLoaded( sal_False )
	,m_bSubForm( sal_False )
    ,m_bForwardingConnection( sal_False )
	,m_bSharingConnection( sal_False )
{
	DBG_CTOR( ODatabaseForm, NULL );

    impl_construct();

    osl_incrementInterlockedCount( &m_refCount );
    {
        // our aggregated rowset itself is not cloneable, so simply copy the properties
        ::comphelper::copyProperties( _cloneSource.m_xAggregateSet, m_xAggregateSet );

        // also care for the dynamic properties: If the clone source has properties which we do not have,
        // then add them
        try
        {
            Reference< XPropertySet > xSourceProps( const_cast< ODatabaseForm& >( _cloneSource ).queryAggregation(
                XPropertySet::static_type() ), UNO_QUERY_THROW );
            Reference< XPropertySetInfo > xSourcePSI( xSourceProps->getPropertySetInfo(), UNO_SET_THROW );
            Reference< XPropertyState > xSourcePropState( xSourceProps, UNO_QUERY );

            Reference< XPropertySetInfo > xDestPSI( getPropertySetInfo(), UNO_QUERY_THROW );

            Sequence< Property > aSourceProperties( xSourcePSI->getProperties() );
            for (   const Property* pSourceProperty = aSourceProperties.getConstArray();
                    pSourceProperty != aSourceProperties.getConstArray() + aSourceProperties.getLength();
                    ++pSourceProperty
                )
            {
                if ( xDestPSI->hasPropertyByName( pSourceProperty->Name ) )
                    continue;

                // the initial value passed to XPropertyContainer is also used as default, usually. So, try
                // to retrieve the default of the source property
                Any aInitialValue;
                if ( xSourcePropState.is() )
                {
                    aInitialValue = xSourcePropState->getPropertyDefault( pSourceProperty->Name );
                }
                else
                {
                    aInitialValue = xSourceProps->getPropertyValue( pSourceProperty->Name );
                }
                addProperty( pSourceProperty->Name, pSourceProperty->Attributes, aInitialValue );
                setPropertyValue( pSourceProperty->Name, xSourceProps->getPropertyValue( pSourceProperty->Name ) );
            }
        }
        catch( const Exception& )
        {
    	    throw WrappedTargetException(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not clone the given database form." ) ),
                *const_cast< ODatabaseForm* >( &_cloneSource ),
                ::cppu::getCaughtException()
            );
        }
    }
    osl_decrementInterlockedCount( &m_refCount );
}

//------------------------------------------------------------------
void ODatabaseForm::impl_construct()
{
	// aggregate a row set
	increment(m_refCount);
	{
		m_xAggregate = Reference< XAggregation >( m_xServiceFactory->createInstance( SRV_SDB_ROWSET ), UNO_QUERY_THROW );
		m_xAggregateAsRowSet.set( m_xAggregate, UNO_QUERY_THROW );
		setAggregation( m_xAggregate );
	}

	// listen for the properties, important for Parameters
	if ( m_xAggregateSet.is() )
	{
		m_pAggregatePropertyMultiplexer = new OPropertyChangeMultiplexer(this, m_xAggregateSet, sal_False);
		m_pAggregatePropertyMultiplexer->acquire();
		m_pAggregatePropertyMultiplexer->addProperty(PROPERTY_COMMAND);
		m_pAggregatePropertyMultiplexer->addProperty(PROPERTY_ACTIVE_CONNECTION);
	}

    {
        Reference< XWarningsSupplier > xRowSetWarnings( m_xAggregate, UNO_QUERY );
        m_aWarnings.setExternalWarnings( xRowSetWarnings );
    }

	if ( m_xAggregate.is() )
	{
		m_xAggregate->setDelegator( static_cast< XWeak* >( this ) );
	}

    {
        m_aFilterManager.initialize( m_xAggregateSet );
        m_aParameterManager.initialize( this, m_xAggregate );

        declareForwardedProperty( PROPERTY_ID_ACTIVE_CONNECTION );
    }
	decrement( m_refCount );

	m_pGroupManager = new OGroupManager( this );
	m_pGroupManager->acquire();
}

//------------------------------------------------------------------
ODatabaseForm::~ODatabaseForm()
{
	DBG_DTOR(ODatabaseForm,NULL);

	m_pGroupManager->release();
    m_pGroupManager = NULL;

	if (m_xAggregate.is())
		m_xAggregate->setDelegator( NULL );

    m_aWarnings.setExternalWarnings( NULL );

	if (m_pAggregatePropertyMultiplexer)
	{
		m_pAggregatePropertyMultiplexer->dispose();
		m_pAggregatePropertyMultiplexer->release();
		m_pAggregatePropertyMultiplexer = NULL;
	}
}

//==============================================================================
// html tools
//------------------------------------------------------------------------
::rtl::OUString ODatabaseForm::GetDataURLEncoded(const Reference<XControl>& SubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt)
{
    return GetDataEncoded(true,SubmitButton,MouseEvt);
}
// -----------------------------------------------------------------------------
::rtl::OUString ODatabaseForm::GetDataEncoded(bool _bURLEncoded,const Reference<XControl>& SubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt)
{
	// Liste von successful Controls fuellen
	HtmlSuccessfulObjList aSuccObjList;
	FillSuccessfulList( aSuccObjList, SubmitButton, MouseEvt );


	// Liste zu ::rtl::OUString zusammensetzen
	::rtl::OUStringBuffer aResult;
	::rtl::OUString aName;
	::rtl::OUString aValue;

	for	(	HtmlSuccessfulObjListIterator pSuccObj = aSuccObjList.begin();
			pSuccObj < aSuccObjList.end();
			++pSuccObj
		)
	{
		aName = pSuccObj->aName;
		aValue = pSuccObj->aValue;
		if( pSuccObj->nRepresentation == SUCCESSFUL_REPRESENT_FILE && aValue.getLength() )
		{
			// Bei File-URLs wird der Dateiname und keine URL uebertragen,
			// weil Netscape dies so macht.
			INetURLObject aURL;
			aURL.SetSmartProtocol(INET_PROT_FILE);
			aURL.SetSmartURL(aValue);
			if( INET_PROT_FILE == aURL.GetProtocol() )
				aValue = INetURLObject::decode(aURL.PathToFileName(), '%', INetURLObject::DECODE_UNAMBIGUOUS);
		}
		Encode( aName );
		Encode( aValue );

		aResult.append(aName);
		aResult.append(sal_Unicode('='));
		aResult.append(aValue);
        
		if (pSuccObj < aSuccObjList.end() - 1)
        {
            if ( _bURLEncoded )
			    aResult.append(sal_Unicode('&'));
            else
                aResult.appendAscii("\r\n");
        }
	}


	aSuccObjList.clear();

	return aResult.makeStringAndClear();
}

//==============================================================================
// html tools
//------------------------------------------------------------------------
::rtl::OUString ODatabaseForm::GetDataTextEncoded(const Reference<XControl>& SubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt)
{
    return GetDataEncoded(false,SubmitButton,MouseEvt);
}

//------------------------------------------------------------------------
Sequence<sal_Int8> ODatabaseForm::GetDataMultiPartEncoded(const Reference<XControl>& SubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt, ::rtl::OUString& rContentType)
{

	// Parent erzeugen
	INetMIMEMessage aParent;
	aParent.EnableAttachChild( INETMSG_MULTIPART_FORM_DATA );


	// Liste von successful Controls fuellen
	HtmlSuccessfulObjList aSuccObjList;
	FillSuccessfulList( aSuccObjList, SubmitButton, MouseEvt );


	// Liste zu ::rtl::OUString zusammensetzen
	::rtl::OUString aResult;
	for	(	HtmlSuccessfulObjListIterator pSuccObj = aSuccObjList.begin();
			pSuccObj < aSuccObjList.end();
			++pSuccObj
		)
	{
		if( pSuccObj->nRepresentation == SUCCESSFUL_REPRESENT_TEXT )
			InsertTextPart( aParent, pSuccObj->aName, pSuccObj->aValue );
		else if( pSuccObj->nRepresentation == SUCCESSFUL_REPRESENT_FILE )
			InsertFilePart( aParent, pSuccObj->aName, pSuccObj->aValue );
	}


	// Liste loeschen
	aSuccObjList.clear();

	// Fuer Parent MessageStream erzeugen
	INetMIMEMessageStream aMessStream;
	aMessStream.SetSourceMessage( &aParent );
	aMessStream.GenerateHeader( sal_False );

	// MessageStream in SvStream kopieren
	SvMemoryStream aMemStream;
	char* pBuf = new char[1025];
	int nRead;
	while( (nRead = aMessStream.Read(pBuf, 1024)) > 0 )
		aMemStream.Write( pBuf, nRead );
	delete[] pBuf;

	aMemStream.Flush();
	aMemStream.Seek( 0 );
	void* pData = (void*)aMemStream.GetData();
	sal_Int32 nLen = aMemStream.Seek(STREAM_SEEK_TO_END);

	rContentType = UniString(aParent.GetContentType());
	return Sequence<sal_Int8>((sal_Int8*)pData, nLen);
}

//------------------------------------------------------------------------
namespace
{
    static void appendDigits( sal_Int32 _nNumber, sal_Int8 nDigits, ::rtl::OUStringBuffer& _rOut )
    {
        sal_Int32 nCurLen = _rOut.getLength();
        _rOut.append( _nNumber );
        while ( _rOut.getLength() - nCurLen < nDigits )
            _rOut.insert( nCurLen, (sal_Unicode)'0' );
    }
}

//------------------------------------------------------------------------
void ODatabaseForm::AppendComponent(HtmlSuccessfulObjList& rList, const Reference<XPropertySet>& xComponentSet, const ::rtl::OUString& rNamePrefix,
					 const Reference<XControl>& rxSubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt)
{
	if (!xComponentSet.is())
		return;

	// MIB 25.6.98: Geschachtelte Formulare abfangen ... oder muesste
	// man sie submitten?
	if (!hasProperty(PROPERTY_CLASSID, xComponentSet))
		return;

	// Namen ermitteln
	if (!hasProperty(PROPERTY_NAME, xComponentSet))
		return;

	sal_Int16 nClassId = 0;
	xComponentSet->getPropertyValue(PROPERTY_CLASSID) >>= nClassId;
	::rtl::OUString aName;
	xComponentSet->getPropertyValue( PROPERTY_NAME ) >>= aName;
	if( !aName.getLength() && nClassId != FormComponentType::IMAGEBUTTON)
		return;
	else	// Name um den Prefix erweitern
		aName = rNamePrefix + aName;

	switch( nClassId )
	{
		// Buttons
		case FormComponentType::COMMANDBUTTON:
		{
			// Es wird nur der gedrueckte Submit-Button ausgewertet
			// MIB: Sofern ueberhaupt einer uebergeben wurde
			if( rxSubmitButton.is() )
			{
				Reference<XPropertySet>  xSubmitButtonComponent(rxSubmitButton->getModel(), UNO_QUERY);
				if (xSubmitButtonComponent == xComponentSet && hasProperty(PROPERTY_LABEL, xComponentSet))
				{
					// <name>=<label>
					::rtl::OUString aLabel;
					xComponentSet->getPropertyValue( PROPERTY_LABEL ) >>= aLabel;
					rList.push_back( HtmlSuccessfulObj(aName, aLabel) );
				}
			}
		} break;

		// ImageButtons
		case FormComponentType::IMAGEBUTTON:
		{
			// Es wird nur der gedrueckte Submit-Button ausgewertet
			// MIB: Sofern ueberhaupt einer uebergeben wurde
			if( rxSubmitButton.is() )
			{
				Reference<XPropertySet>  xSubmitButtonComponent(rxSubmitButton->getModel(), UNO_QUERY);
				if (xSubmitButtonComponent == xComponentSet)
				{
					// <name>.x=<pos.X>&<name>.y=<pos.Y>
					::rtl::OUString aLhs = aName;
					::rtl::OUString aRhs = ::rtl::OUString::valueOf( MouseEvt.X );

					// nur wenn ein Name vorhanden ist, kann ein name.x
					aLhs += aName.getLength() ? UniString::CreateFromAscii(".x") : UniString::CreateFromAscii("x");
					rList.push_back( HtmlSuccessfulObj(aLhs, aRhs) );

					aLhs = aName;
					aRhs = ::rtl::OUString::valueOf( MouseEvt.Y );
					aLhs += aName.getLength() ? UniString::CreateFromAscii(".y") : UniString::CreateFromAscii("y");
					rList.push_back( HtmlSuccessfulObj(aLhs, aRhs) );

				}
			}
		} break;

		// CheckBoxen / RadioButtons
		case FormComponentType::CHECKBOX:
		case FormComponentType::RADIOBUTTON:
		{
			// <name>=<refValue>
			if( !hasProperty(PROPERTY_STATE, xComponentSet) )
				break;
			sal_Int16 nChecked = 0;
			xComponentSet->getPropertyValue( PROPERTY_STATE ) >>= nChecked;
			if( nChecked != 1 )
				break;

			::rtl::OUString aStrValue;
			if( hasProperty(PROPERTY_REFVALUE, xComponentSet) )
				xComponentSet->getPropertyValue( PROPERTY_REFVALUE ) >>= aStrValue;

			rList.push_back( HtmlSuccessfulObj(aName, aStrValue) );
		} break;

		// Edit
		case FormComponentType::TEXTFIELD:
		{
			// <name>=<text>
			if( !hasProperty(PROPERTY_TEXT, xComponentSet) )
				break;

			// MIB: Spezial-Behandlung fuer Multiline-Edit nur dann, wenn
			// es auch ein Control dazu gibt.
			Any aTmp = xComponentSet->getPropertyValue( PROPERTY_MULTILINE );
			sal_Bool bMulti =	rxSubmitButton.is()
							&& (aTmp.getValueType().getTypeClass() == TypeClass_BOOLEAN)
							&& getBOOL(aTmp);
			::rtl::OUString sText;
			if ( bMulti )	// Bei MultiLineEdit Text am Control abholen
			{

				Reference<XControlContainer>  xControlContainer(rxSubmitButton->getContext(), UNO_QUERY);
				if( !xControlContainer.is() ) break;

				Sequence<Reference<XControl> > aControlSeq = xControlContainer->getControls();
				Reference<XControl>  xControl;
				Reference<XFormComponent>  xControlComponent;

				// Richtiges Control suchen
				sal_Int32 i;
				for( i=0; i<aControlSeq.getLength(); i++ )
				{
					xControl = aControlSeq.getConstArray()[i];
					Reference<XPropertySet>  xModel(xControl->getModel(), UNO_QUERY);
					if (xModel == xComponentSet)
					{
						Reference<XTextComponent>  xTextComponent(xControl, UNO_QUERY);
						if( xTextComponent.is() )
							sText = xTextComponent->getText();
						break;
					}
				}
				// Control nicht gefunden oder nicht existent, (Edit im Grid)
				if (i == aControlSeq.getLength())
					xComponentSet->getPropertyValue( PROPERTY_TEXT ) >>= sText;
			}
			else
				xComponentSet->getPropertyValue( PROPERTY_TEXT ) >>= sText;

			rList.push_back( HtmlSuccessfulObj(aName, sText) );
		} break;

		// ComboBox, Patternfield
		case FormComponentType::COMBOBOX:
		case FormComponentType::PATTERNFIELD:
		{
			// <name>=<text>
			if( hasProperty(PROPERTY_TEXT, xComponentSet) )
			{
				::rtl::OUString aText;
				xComponentSet->getPropertyValue( PROPERTY_TEXT ) >>= aText;
				rList.push_back( HtmlSuccessfulObj(aName, aText) );
			}
		} break;
		case FormComponentType::CURRENCYFIELD:
		case FormComponentType::NUMERICFIELD:
		{
			// <name>=<wert> // wert wird als double mit Punkt als Decimaltrenner
							 // kein Wert angegeben (NULL) -> wert leer
			if( hasProperty(PROPERTY_VALUE, xComponentSet) )
			{
				::rtl::OUString aText;
				Any aVal  = xComponentSet->getPropertyValue( PROPERTY_VALUE );

				double aDoubleVal = 0;
				if (aVal >>= aDoubleVal)
				{
					sal_Int16 nScale = 0;
					xComponentSet->getPropertyValue( PROPERTY_DECIMAL_ACCURACY ) >>= nScale;
					aText = ::rtl::math::doubleToUString(aDoubleVal, rtl_math_StringFormat_F, nScale, '.', sal_True);
				}
				rList.push_back( HtmlSuccessfulObj(aName, aText) );
			}
		}	break;
		case FormComponentType::DATEFIELD:
		{
			// <name>=<wert> // Wert wird als Datum im Format (MM-DD-YYYY)
							 // kein Wert angegeben (NULL) -> wert leer
			if( hasProperty(PROPERTY_DATE, xComponentSet) )
			{
				::rtl::OUString aText;
				Any aVal  = xComponentSet->getPropertyValue( PROPERTY_DATE );
				sal_Int32 nInt32Val = 0;
				if (aVal >>= nInt32Val)
				{
                    ::Date aDate( nInt32Val );
                    ::rtl::OUStringBuffer aBuffer;
                    appendDigits( aDate.GetMonth(), 2, aBuffer );
                    aBuffer.append( (sal_Unicode)'-' );
                    appendDigits( aDate.GetDay(), 2, aBuffer );
                    aBuffer.append( (sal_Unicode)'-' );
                    appendDigits( aDate.GetYear(), 4, aBuffer );
					aText = aBuffer.makeStringAndClear();
				}
				rList.push_back( HtmlSuccessfulObj(aName, aText) );
			}
		}	break;
		case FormComponentType::TIMEFIELD:
		{
			// <name>=<wert> // Wert wird als Zeit im Format (HH:MM:SS) angegeben
							 // kein Wert angegeben (NULL) -> wert leer
			if( hasProperty(PROPERTY_TIME, xComponentSet) )
			{
				::rtl::OUString aText;
				Any aVal  = xComponentSet->getPropertyValue( PROPERTY_TIME );
				sal_Int32 nInt32Val = 0;
				if (aVal >>= nInt32Val)
				{
					::Time aTime(nInt32Val);
                    ::rtl::OUStringBuffer aBuffer;
                    appendDigits( aTime.GetHour(), 2, aBuffer );
                    aBuffer.append( (sal_Unicode)'-' );
                    appendDigits( aTime.GetMin(), 2, aBuffer );
                    aBuffer.append( (sal_Unicode)'-' );
                    appendDigits( aTime.GetSec(), 2, aBuffer );
					aText = aBuffer.makeStringAndClear();
				}
				rList.push_back( HtmlSuccessfulObj(aName, aText) );
			}
		}	break;

		// starform
		case FormComponentType::HIDDENCONTROL:
		{

			// <name>=<value>
			if( hasProperty(PROPERTY_HIDDEN_VALUE, xComponentSet) )
			{
				::rtl::OUString aText;
				xComponentSet->getPropertyValue( PROPERTY_HIDDEN_VALUE ) >>= aText;
				rList.push_back( HtmlSuccessfulObj(aName, aText) );
			}
		} break;

		// starform
		case FormComponentType::FILECONTROL:
		{
			// <name>=<text>
			if( hasProperty(PROPERTY_TEXT, xComponentSet) )
			{

				::rtl::OUString aText;
				xComponentSet->getPropertyValue( PROPERTY_TEXT ) >>= aText;
				rList.push_back( HtmlSuccessfulObj(aName, aText, SUCCESSFUL_REPRESENT_FILE) );
			}
		} break;

		// starform
		case FormComponentType::LISTBOX:
		{

			// <name>=<Token0>&<name>=<Token1>&...&<name>=<TokenN> (Mehrfachselektion)
			if (!hasProperty(PROPERTY_SELECT_SEQ, xComponentSet) ||
				!hasProperty(PROPERTY_STRINGITEMLIST, xComponentSet))
				break;

			// angezeigte Werte
			Sequence< ::rtl::OUString > aVisibleList;
			xComponentSet->getPropertyValue( PROPERTY_STRINGITEMLIST ) >>= aVisibleList;
			sal_Int32 nStringCnt = aVisibleList.getLength();
			const ::rtl::OUString* pStrings = aVisibleList.getConstArray();

			// Werte-Liste
			Sequence< ::rtl::OUString > aValueList;
			xComponentSet->getPropertyValue( PROPERTY_VALUE_SEQ ) >>= aValueList;
			sal_Int32 nValCnt = aValueList.getLength();
			const ::rtl::OUString* pVals = aValueList.getConstArray();

			// Selektion
			Sequence<sal_Int16> aSelectList;
			xComponentSet->getPropertyValue( PROPERTY_SELECT_SEQ ) >>= aSelectList;
			sal_Int32 nSelCount = aSelectList.getLength();
			const sal_Int16* pSels = aSelectList.getConstArray();

			// Einfach- oder Mehrfach-Selektion
			// Bei Einfach-Selektionen beruecksichtigt MT nur den ersten Eintrag
			// in der Liste.
			if (nSelCount > 1 && !getBOOL(xComponentSet->getPropertyValue(PROPERTY_MULTISELECTION)))
				nSelCount = 1;

			// Die Indizes in der Selektions-Liste koennen auch ungueltig sein,
			// also muss man die gueltigen erstmal raussuchen um die Laenge
			// der neuen Liste zu bestimmen.
			sal_Int32 nCurCnt = 0;
			sal_Int32 i;
			for( i=0; i<nSelCount; ++i )
			{
				if( pSels[i] < nStringCnt )
					++nCurCnt;
			}

			::rtl::OUString aSubValue;
			for(i=0; i<nCurCnt; ++i )
			{
				sal_Int16  nSelPos = pSels[i];
				if (nSelPos < nValCnt && pVals[nSelPos].getLength())
				{
                    aSubValue = pVals[nSelPos];
				}
				else
				{
					aSubValue = pStrings[nSelPos];
				}
				rList.push_back( HtmlSuccessfulObj(aName, aSubValue) );
			}
		} break;
		case FormComponentType::GRIDCONTROL:
		{
			// Die einzelnen Spaltenwerte werden verschickt,
			// der Name wird mit dem Prefix des Names des Grids erweitert
			Reference<XIndexAccess>  xContainer(xComponentSet, UNO_QUERY);
			if (!xContainer.is())
				break;

			aName += UniString('.');

			Reference<XPropertySet>  xSet;
			sal_Int32 nCount = xContainer->getCount();
			// we know already how many objects should be appended,
			// so why not allocate the space for them
			rList.reserve( nCount + rList.capacity() ); // not size()
			for (sal_Int32 i = 0; i < nCount; ++i)
			{
				xContainer->getByIndex(i) >>= xSet;
				if (xSet.is())
					AppendComponent(rList, xSet, aName, rxSubmitButton, MouseEvt);
			}
		}
	}
}

//------------------------------------------------------------------------
void ODatabaseForm::FillSuccessfulList( HtmlSuccessfulObjList& rList,
	const Reference<XControl>& rxSubmitButton, const ::com::sun::star::awt::MouseEvent& MouseEvt )
{
	// Liste loeschen
	rList.clear();
	// Ueber Components iterieren
	Reference<XPropertySet> 		xComponentSet;
	::rtl::OUString aPrefix;

	// we know already how many objects should be appended,
	// so why not allocate the space for them
	rList.reserve( getCount() );
	for( sal_Int32 nIndex=0; nIndex < getCount(); nIndex++ )
	{
		getByIndex( nIndex ) >>= xComponentSet;
		AppendComponent(rList, xComponentSet, aPrefix, rxSubmitButton, MouseEvt);
	}
}

//------------------------------------------------------------------------
void ODatabaseForm::Encode( ::rtl::OUString& rString ) const
{
	::rtl::OUString aResult;

	// Immer ANSI #58641
//	rString.Convert(CHARSET_SYSTEM, CHARSET_ANSI);


	// Zeilenendezeichen werden als CR dargestellt
	UniString sConverter = rString;
	sConverter.ConvertLineEnd( LINEEND_CR );
	rString = sConverter;


	// Jeden einzelnen Character ueberpruefen
	sal_Int32 nStrLen = rString.getLength();
	sal_Unicode nCharCode;
	for( sal_Int32 nCurPos=0; nCurPos < nStrLen; ++nCurPos )
	{
		nCharCode = rString[nCurPos];

		// Behandlung fuer chars, die kein alphanumerisches Zeichen sind
		// und CharacterCodes > 127
		if( (!isalnum(nCharCode) && nCharCode != (sal_Unicode)' ') || nCharCode > 127 )
		{
			switch( nCharCode )
			{
				case 13:	// CR
					aResult += ::rtl::OUString::createFromAscii("%0D%0A");	// Hex-Darstellung CR LF
					break;


				// Netscape Sonderbehandlung
				case 42:	// '*'
				case 45:	// '-'
				case 46:	// '.'
				case 64:	// '@'
				case 95:	// '_'
					aResult += UniString(nCharCode);
					break;

				default:
				{
					// In Hex umrechnen
					short nHi = ((sal_Int16)nCharCode) / 16;
					short nLo = ((sal_Int16)nCharCode) - (nHi*16);
					if( nHi > 9 ) nHi += (int)'A'-10; else nHi += (int)'0';
					if( nLo > 9 ) nLo += (int)'A'-10; else nLo += (int)'0';
					aResult += UniString('%');
					aResult += UniString((sal_Unicode)nHi);
					aResult += UniString((sal_Unicode)nLo);
				}
			}
		}
		else
			aResult += UniString(nCharCode);
	}


	// Spaces durch	'+' ersetzen
	aResult = aResult.replace(' ', '+');

	rString = aResult;
}

//------------------------------------------------------------------------
void ODatabaseForm::InsertTextPart( INetMIMEMessage& rParent, const ::rtl::OUString& rName,
	const ::rtl::OUString& rData )
{

	// Part als Message-Child erzeugen
	INetMIMEMessage* pChild = new INetMIMEMessage();


	// Header
	::rtl::OUString aContentDisp = ::rtl::OUString::createFromAscii("form-data; name=\"");
	aContentDisp += rName;
	aContentDisp += UniString('\"');
	pChild->SetContentDisposition( aContentDisp );
	pChild->SetContentType( UniString::CreateFromAscii("text/plain") );

	rtl_TextEncoding eSystemEncoding = gsl_getSystemTextEncoding();
	const sal_Char* pBestMatchingEncoding = rtl_getBestMimeCharsetFromTextEncoding( eSystemEncoding );
	UniString aBestMatchingEncoding = UniString::CreateFromAscii( pBestMatchingEncoding );
	pChild->SetContentTransferEncoding(aBestMatchingEncoding);

	// Body
	SvMemoryStream* pStream = new SvMemoryStream;
	pStream->WriteLine( ByteString( UniString(rData), rtl_getTextEncodingFromMimeCharset(pBestMatchingEncoding) ) );
	pStream->Flush();
	pStream->Seek( 0 );
	pChild->SetDocumentLB( new SvLockBytes(pStream, sal_True) );
	rParent.AttachChild( *pChild );
}

//------------------------------------------------------------------------
sal_Bool ODatabaseForm::InsertFilePart( INetMIMEMessage& rParent, const ::rtl::OUString& rName,
	const ::rtl::OUString& rFileName )
{
	UniString aFileName( rFileName );
	UniString aContentType(UniString::CreateFromAscii(CONTENT_TYPE_STR_TEXT_PLAIN));
	SvStream *pStream = 0;

	if( aFileName.Len() )
	{
		// Bisher koennen wir nur File-URLs verarbeiten
		INetURLObject aURL;
		aURL.SetSmartProtocol(INET_PROT_FILE);
		aURL.SetSmartURL(rFileName);
		if( INET_PROT_FILE == aURL.GetProtocol() )
		{
			aFileName = INetURLObject::decode(aURL.PathToFileName(), '%', INetURLObject::DECODE_UNAMBIGUOUS);
			DirEntry aDirEntry( aFileName );
			if( aDirEntry.Exists() )
			{
				pStream = ::utl::UcbStreamHelper::CreateStream(aFileName, STREAM_READ);
				if (!pStream || (pStream->GetError() != ERRCODE_NONE))
				{
					delete pStream;
					pStream = 0;
				}
			}
			INetContentType eContentType = INetContentTypes::GetContentType4Extension(
																aDirEntry.GetExtension() );
			if (eContentType != CONTENT_TYPE_UNKNOWN)
				aContentType = INetContentTypes::GetContentType(eContentType);
		}
	}

	// Wenn irgendetwas nicht geklappt hat, legen wir einen leeren
	// MemoryStream an
	if( !pStream )
		pStream = new SvMemoryStream;


	// Part als Message-Child erzeugen
	INetMIMEMessage* pChild = new INetMIMEMessage;


	// Header
	::rtl::OUString aContentDisp = ::rtl::OUString::createFromAscii( "form-data; name=\"" );
	aContentDisp += rName;
	aContentDisp += UniString('\"');
	aContentDisp += ::rtl::OUString::createFromAscii("; filename=\"");
	aContentDisp += aFileName;
	aContentDisp += UniString('\"');
	pChild->SetContentDisposition( aContentDisp );
	pChild->SetContentType( aContentType );
	pChild->SetContentTransferEncoding( UniString(::rtl::OUString::createFromAscii("8bit")) );


	// Body
	pChild->SetDocumentLB( new SvLockBytes(pStream, sal_True) );
	rParent.AttachChild( *pChild );

	return sal_True;
}

//==============================================================================
// internals
//------------------------------------------------------------------------------
void ODatabaseForm::onError( const SQLErrorEvent& _rEvent )
{
    m_aErrorListeners.notifyEach( &XSQLErrorListener::errorOccured, _rEvent );
}

//------------------------------------------------------------------------------
void ODatabaseForm::onError( const SQLException& _rException, const ::rtl::OUString& _rContextDescription )
{
	if ( !m_aErrorListeners.getLength() )
		return;

	SQLErrorEvent aEvent( *this, makeAny( prependErrorInfo( _rException, *this, _rContextDescription ) ) );
	onError( aEvent );
}

//------------------------------------------------------------------------------
void ODatabaseForm::updateParameterInfo()
{
    m_aParameterManager.updateParameterInfo( m_aFilterManager );
}

//------------------------------------------------------------------------------
bool ODatabaseForm::hasValidParent() const
{
	// do we have to fill the parameters again?
	if (m_bSubForm)
	{
		Reference<XResultSet>  xResultSet(m_xParent, UNO_QUERY);
		if (!xResultSet.is())
		{
			DBG_ERROR("ODatabaseForm::hasValidParent() : no parent resultset !");
			return false;
		}
		try
		{
			Reference< XPropertySet >  xSet( m_xParent, UNO_QUERY );
			Reference< XLoadable > xLoad( m_xParent, UNO_QUERY );
			if	(	xLoad->isLoaded()
				&&	(	xResultSet->isBeforeFirst()
					||	xResultSet->isAfterLast()
					||	getBOOL( xSet->getPropertyValue( PROPERTY_ISNEW ) )
					)
				)
				// the parent form is loaded and on a "virtual" row -> not valid
				return false;
		}
		catch(Exception&)
		{
			// parent could be forwardonly?
			return false;
		}
	}
	return true;
}

//------------------------------------------------------------------------------
bool ODatabaseForm::fillParameters( ::osl::ResettableMutexGuard& _rClearForNotifies, const Reference< XInteractionHandler >& _rxCompletionHandler )
{
	// do we have to fill the parameters again?
    if ( !m_aParameterManager.isUpToDate() )
		updateParameterInfo();

	// is there a valid parent?
	if ( m_bSubForm && !hasValidParent() )
		return true;

    // ensure we're connected
    if ( !implEnsureConnection() )
        return false;

    if ( m_aParameterManager.isUpToDate() )
        return m_aParameterManager.fillParameterValues( _rxCompletionHandler, _rClearForNotifies );

    return true;
}

//------------------------------------------------------------------------------
void ODatabaseForm::saveInsertOnlyState( )
{
	OSL_ENSURE( !m_aIgnoreResult.hasValue(), "ODatabaseForm::saveInsertOnlyState: overriding old value!" );
	m_aIgnoreResult = m_xAggregateSet->getPropertyValue( PROPERTY_INSERTONLY );
}

//------------------------------------------------------------------------------
void ODatabaseForm::restoreInsertOnlyState( )
{
	if ( m_aIgnoreResult.hasValue() )
	{
		m_xAggregateSet->setPropertyValue( PROPERTY_INSERTONLY, m_aIgnoreResult );
		m_aIgnoreResult = Any();
	}
}

//------------------------------------------------------------------------------
sal_Bool ODatabaseForm::executeRowSet(::osl::ResettableMutexGuard& _rClearForNotifies, sal_Bool bMoveToFirst, const Reference< XInteractionHandler >& _rxCompletionHandler)
{
	if (!m_xAggregateAsRowSet.is())
		return sal_False;

	if (!fillParameters(_rClearForNotifies, _rxCompletionHandler))
		return sal_False;

	restoreInsertOnlyState( );

	// ensure the aggregated row set has the correct properties
    sal_Int32 nConcurrency = ResultSetConcurrency::READ_ONLY;

    // if we have a parent, who is not positioned on a valid row
	// we can't be updatable!
	if (m_bSubForm && !hasValidParent())
	{
		nConcurrency = ResultSetConcurrency::READ_ONLY;

        // don't use any parameters if we don't have a valid parent
        m_aParameterManager.setAllParametersNull();

        // switch to "insert only" mode
		saveInsertOnlyState( );
		m_xAggregateSet->setPropertyValue( PROPERTY_INSERTONLY, makeAny( sal_True ) );
	}
	else if (m_bAllowInsert || m_bAllowUpdate || m_bAllowDelete)
		nConcurrency = ResultSetConcurrency::UPDATABLE;
	else
		nConcurrency = ResultSetConcurrency::READ_ONLY;

    m_xAggregateSet->setPropertyValue( PROPERTY_RESULTSET_CONCURRENCY, makeAny( (sal_Int32)nConcurrency ) );
	m_xAggregateSet->setPropertyValue( PROPERTY_RESULTSET_TYPE, makeAny( (sal_Int32)ResultSetType::SCROLL_SENSITIVE ) );

	sal_Bool bSuccess = sal_False;
	try
	{
		m_xAggregateAsRowSet->execute();
		bSuccess = sal_True;
	}
	catch( const RowSetVetoException& eVeto )
	{
		(void)eVeto;
	}
	catch(SQLException& eDb)
	{
		_rClearForNotifies.clear();
		if (m_sCurrentErrorContext.getLength())
			onError(eDb, m_sCurrentErrorContext);
		else
			onError(eDb, FRM_RES_STRING(RID_STR_READERROR));
		_rClearForNotifies.reset();

        restoreInsertOnlyState( );
	}

	if (bSuccess)
	{
		// adjust the privilege property
		//	m_nPrivileges;
		m_xAggregateSet->getPropertyValue(PROPERTY_PRIVILEGES) >>= m_nPrivileges;
		if (!m_bAllowInsert)
			m_nPrivileges &= ~Privilege::INSERT;
		if (!m_bAllowUpdate)
			m_nPrivileges &= ~Privilege::UPDATE;
		if (!m_bAllowDelete)
			m_nPrivileges &= ~Privilege::DELETE;

		if (bMoveToFirst)
		{
			// the row set is positioned _before_ the first row (per definitionem), so move the set ...
			try
			{
				// if we have an insert only rowset we move to the insert row
				next();
				if (((m_nPrivileges & Privilege::INSERT) == Privilege::INSERT)
					&& isAfterLast())
				{
					// move on the insert row of set
					// resetting must be done later, after the load events have been posted
					// see :moveToInsertRow and load , reload
					Reference<XResultSetUpdate>  xUpdate;
					if (query_aggregation( m_xAggregate, xUpdate))
						xUpdate->moveToInsertRow();
				}
			}
			catch(SQLException& eDB)
			{
				_rClearForNotifies.clear();
				if (m_sCurrentErrorContext.getLength())
					onError(eDB, m_sCurrentErrorContext);
				else
					onError(eDB, FRM_RES_STRING(RID_STR_READERROR));
				_rClearForNotifies.reset();
				bSuccess = sal_False;
			}
		}
	}
	return bSuccess;
}

//------------------------------------------------------------------
void ODatabaseForm::disposing()
{
	if (m_pAggregatePropertyMultiplexer)
		m_pAggregatePropertyMultiplexer->dispose();

	if (m_bLoaded)
		unload();

	// cancel the submit/reset-thread
	{
		::osl::MutexGuard aGuard( m_aMutex );
		if (m_pThread)
		{
			m_pThread->release();
			m_pThread = NULL;
		}
	}

	EventObject aEvt(static_cast<XWeak*>(this));
	m_aLoadListeners.disposeAndClear(aEvt);
	m_aRowSetApproveListeners.disposeAndClear(aEvt);
    m_aParameterManager.disposing( aEvt );
	m_aResetListeners.disposing();
	m_aSubmitListeners.disposeAndClear(aEvt);
	m_aErrorListeners.disposeAndClear(aEvt);

    m_aParameterManager.dispose();   // (to free any references it may have to me)
    m_aFilterManager.dispose();      // (dito)

	OFormComponents::disposing();
	OPropertySetAggregationHelper::disposing();

	// stop listening on the aggregate
	if (m_xAggregateAsRowSet.is())
		m_xAggregateAsRowSet->removeRowSetListener(this);

	// dispose the active connection
	Reference<XComponent>  xAggregationComponent;
	if (query_aggregation(m_xAggregate, xAggregationComponent))
		xAggregationComponent->dispose();

    m_aPropertyBagHelper.dispose();
}

//------------------------------------------------------------------------------
Reference< XConnection > ODatabaseForm::getConnection()
{
	Reference< XConnection > xConn;
	m_xAggregateSet->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xConn;
	return xConn;
}

//------------------------------------------------------------------------------
::osl::Mutex& ODatabaseForm::getMutex()
{
    return m_aMutex;
}

//==============================================================================
// property handling
//------------------------------------------------------------------------------
void ODatabaseForm::describeFixedAndAggregateProperties(
		Sequence< Property >& _rProps,
		Sequence< Property >& _rAggregateProps ) const
{
	BEGIN_DESCRIBE_AGGREGATION_PROPERTIES(22, m_xAggregateSet)
        // we want to "override" the privileges, since we have additional "AllowInsert" etc. properties
		RemoveProperty( _rAggregateProps, PROPERTY_PRIVILEGES );

        // InsertOnly is also to be overridden, since we sometimes change it ourself
		RemoveProperty( _rAggregateProps, PROPERTY_INSERTONLY );

        // we remove and re-declare the DataSourceName property, 'cause we want it to be constrained, and the
		// original property of our aggregate isn't
		RemoveProperty( _rAggregateProps, PROPERTY_DATASOURCE );

        // for connection sharing, we need to override the ActiveConnection property, too
		RemoveProperty( _rAggregateProps, PROPERTY_ACTIVE_CONNECTION );

        // the Filter property is also overwritten, since we have some implicit filters
        // (e.g. the ones which result from linking master fields to detail fields
        // via column names instead of parameters)
		RemoveProperty( _rAggregateProps, PROPERTY_FILTER );
		RemoveProperty( _rAggregateProps, PROPERTY_APPLYFILTER );

		DECL_IFACE_PROP4(ACTIVE_CONNECTION,	XConnection,	                BOUND, TRANSIENT, MAYBEVOID, CONSTRAINED);
        DECL_BOOL_PROP2 ( APPLYFILTER,                                      BOUND, MAYBEDEFAULT            );
        DECL_PROP1      ( NAME,             ::rtl::OUString,                BOUND                          );
        DECL_PROP1      ( MASTERFIELDS,     Sequence< ::rtl::OUString >,    BOUND                          );
        DECL_PROP1      ( DETAILFIELDS,     Sequence< ::rtl::OUString >,    BOUND                          );
        DECL_PROP2      ( DATASOURCE,       ::rtl::OUString,                BOUND, CONSTRAINED             );
        DECL_PROP3      ( CYCLE,            TabulatorCycle,                 BOUND, MAYBEVOID, MAYBEDEFAULT );
        DECL_PROP2      ( FILTER,           ::rtl::OUString,                BOUND, MAYBEDEFAULT            );
        DECL_BOOL_PROP2 ( INSERTONLY,                                       BOUND, MAYBEDEFAULT            );
        DECL_PROP1      ( NAVIGATION,       NavigationBarMode,              BOUND                          );
        DECL_BOOL_PROP1 ( ALLOWADDITIONS,                                   BOUND                          );
        DECL_BOOL_PROP1 ( ALLOWEDITS,                                       BOUND                          );
        DECL_BOOL_PROP1 ( ALLOWDELETIONS,                                   BOUND                          );
        DECL_PROP2      ( PRIVILEGES,       sal_Int32,                      TRANSIENT, READONLY            );
        DECL_PROP1      ( TARGET_URL,       ::rtl::OUString,                BOUND                          );
        DECL_PROP1      ( TARGET_FRAME,     ::rtl::OUString,                BOUND                          );
        DECL_PROP1      ( SUBMIT_METHOD,    FormSubmitMethod,               BOUND                          );
        DECL_PROP1      ( SUBMIT_ENCODING,  FormSubmitEncoding,             BOUND                          );
        DECL_BOOL_PROP3 ( DYNAMIC_CONTROL_BORDER,                           BOUND, MAYBEVOID, MAYBEDEFAULT );
        DECL_PROP3      ( CONTROL_BORDER_COLOR_FOCUS,   sal_Int32,          BOUND, MAYBEVOID, MAYBEDEFAULT );
        DECL_PROP3      ( CONTROL_BORDER_COLOR_MOUSE,   sal_Int32,          BOUND, MAYBEVOID, MAYBEDEFAULT );
        DECL_PROP3      ( CONTROL_BORDER_COLOR_INVALID, sal_Int32,          BOUND, MAYBEVOID, MAYBEDEFAULT );
	END_DESCRIBE_PROPERTIES();
}

//------------------------------------------------------------------------------
Reference< XMultiPropertySet > ODatabaseForm::getPropertiesInterface()
{
    return Reference< XMultiPropertySet >( *this, UNO_QUERY );
}

//------------------------------------------------------------------------------
::cppu::IPropertyArrayHelper& ODatabaseForm::getInfoHelper()
{
    return m_aPropertyBagHelper.getInfoHelper();
}

//------------------------------------------------------------------------------
Reference< XPropertySetInfo > ODatabaseForm::getPropertySetInfo() throw( RuntimeException )
{
	return createPropertySetInfo( getInfoHelper() );
}

//--------------------------------------------------------------------
void SAL_CALL ODatabaseForm::addProperty( const ::rtl::OUString& _rName, ::sal_Int16 _nAttributes, const Any& _rInitialValue ) throw (PropertyExistException, IllegalTypeException, IllegalArgumentException, RuntimeException)
{
    m_aPropertyBagHelper.addProperty( _rName, _nAttributes, _rInitialValue );
}

//--------------------------------------------------------------------
void SAL_CALL ODatabaseForm::removeProperty( const ::rtl::OUString& _rName ) throw (UnknownPropertyException, NotRemoveableException, RuntimeException)
{
    m_aPropertyBagHelper.removeProperty( _rName );
}

//--------------------------------------------------------------------
Sequence< PropertyValue > SAL_CALL ODatabaseForm::getPropertyValues() throw (RuntimeException)
{
    return m_aPropertyBagHelper.getPropertyValues();
}

//--------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setPropertyValues( const Sequence< PropertyValue >& _rProps ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
{
    m_aPropertyBagHelper.setPropertyValues( _rProps );
}

//------------------------------------------------------------------------------
Any SAL_CALL ODatabaseForm::getWarnings(  ) throw (SQLException, RuntimeException)
{
    return m_aWarnings.getWarnings();
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::clearWarnings(  ) throw (SQLException, RuntimeException)
{
    m_aWarnings.clearWarnings();
}

//------------------------------------------------------------------------------
Reference< XCloneable > SAL_CALL ODatabaseForm::createClone(  ) throw (RuntimeException)
{
    ODatabaseForm* pClone = new ODatabaseForm( *this );
    osl_incrementInterlockedCount( &pClone->m_refCount );
    pClone->clonedFrom( *this );
    osl_decrementInterlockedCount( &pClone->m_refCount );
    return pClone;
}

//------------------------------------------------------------------------------
void ODatabaseForm::fire( sal_Int32* pnHandles, const Any* pNewValues, const Any* pOldValues, sal_Int32 nCount, sal_Bool bVetoable )
{
	// same as in getFastPropertyValue(sal_Int32) : if we're resetting currently don't fire any changes of the
	// IsModified property from sal_False to sal_True, as this is only temporary 'til the reset is done
	if (m_nResetsPending > 0)
	{
		// look for the PROPERTY_ID_ISMODIFIED
		sal_Int32 nPos = 0;
		for (nPos=0; nPos<nCount; ++nPos)
			if (pnHandles[nPos] == PROPERTY_ID_ISMODIFIED)
				break;

		if ((nPos < nCount) && (pNewValues[nPos].getValueType().getTypeClass() == TypeClass_BOOLEAN) && getBOOL(pNewValues[nPos]))
		{	// yeah, we found it, and it changed to TRUE
			if (nPos == 0)
			{	// just cut the first element
				++pnHandles;
				++pNewValues;
				++pOldValues;
				--nCount;
			}
			else if (nPos == nCount - 1)
				// just cut the last element
				--nCount;
			else
			{	// split into two base class calls
				OPropertySetAggregationHelper::fire(pnHandles, pNewValues, pOldValues, nPos, bVetoable);
				++nPos;
				OPropertySetAggregationHelper::fire(pnHandles + nPos, pNewValues + nPos, pOldValues + nPos, nCount - nPos, bVetoable);
				return;
			}
		}
	}

	OPropertySetAggregationHelper::fire(pnHandles, pNewValues, pOldValues, nCount, bVetoable);
}

//------------------------------------------------------------------------------
Any SAL_CALL ODatabaseForm::getFastPropertyValue( sal_Int32 nHandle )
	   throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
{
	if ((nHandle == PROPERTY_ID_ISMODIFIED) && (m_nResetsPending > 0))
		return ::cppu::bool2any((sal_False));
		// don't allow the aggregate which is currently being reset to return a (temporary) "yes"
	else
		return OPropertySetAggregationHelper::getFastPropertyValue(nHandle);
}

//------------------------------------------------------------------------------
void ODatabaseForm::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
{
	switch (nHandle)
	{
        case PROPERTY_ID_INSERTONLY:
            rValue <<= m_bInsertOnly;
            break;

        case PROPERTY_ID_FILTER:
            rValue <<= m_aFilterManager.getFilterComponent( FilterManager::fcPublicFilter );
            break;

        case PROPERTY_ID_APPLYFILTER:
            rValue <<= m_aFilterManager.isApplyPublicFilter();
            break;

        case PROPERTY_ID_DATASOURCE:
			rValue = m_xAggregateSet->getPropertyValue( PROPERTY_DATASOURCE );
    		break;

        case PROPERTY_ID_TARGET_URL:
			rValue <<= m_aTargetURL;
			break;
		case PROPERTY_ID_TARGET_FRAME:
			rValue <<= m_aTargetFrame;
			break;
		case PROPERTY_ID_SUBMIT_METHOD:
			rValue <<= m_eSubmitMethod;
			break;
		case PROPERTY_ID_SUBMIT_ENCODING:
			rValue <<= m_eSubmitEncoding;
			break;
		case PROPERTY_ID_NAME:
			rValue <<= m_sName;
			break;
		case PROPERTY_ID_MASTERFIELDS:
			rValue <<= m_aMasterFields;
			break;
		case PROPERTY_ID_DETAILFIELDS:
			rValue <<= m_aDetailFields;
			break;
		case PROPERTY_ID_CYCLE:
			rValue = m_aCycle;
			break;
		case PROPERTY_ID_NAVIGATION:
			rValue <<= m_eNavigation;
			break;
		case PROPERTY_ID_ALLOWADDITIONS:
			rValue <<= (sal_Bool)m_bAllowInsert;
			break;
		case PROPERTY_ID_ALLOWEDITS:
			rValue <<= (sal_Bool)m_bAllowUpdate;
			break;
		case PROPERTY_ID_ALLOWDELETIONS:
			rValue <<= (sal_Bool)m_bAllowDelete;
			break;
		case PROPERTY_ID_PRIVILEGES:
			rValue <<= (sal_Int32)m_nPrivileges;
			break;
        case PROPERTY_ID_DYNAMIC_CONTROL_BORDER:
			rValue = m_aDynamicControlBorder;
			break;
        case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS:
			rValue = m_aControlBorderColorFocus;
			break;
        case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE:
			rValue = m_aControlBorderColorMouse;
			break;
        case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID:
			rValue = m_aControlBorderColorInvalid;
			break;
        default:
            if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( nHandle ) )
                m_aPropertyBagHelper.getDynamicFastPropertyValue( nHandle, rValue );
            else
                OPropertySetAggregationHelper::getFastPropertyValue( rValue, nHandle );
            break;
	}
}

//------------------------------------------------------------------------------
sal_Bool ODatabaseForm::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue,
												sal_Int32 nHandle, const Any& rValue ) throw( IllegalArgumentException )
{
	sal_Bool bModified(sal_False);
	switch (nHandle)
	{
        case PROPERTY_ID_INSERTONLY:
			bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_bInsertOnly );
            break;

        case PROPERTY_ID_FILTER:
			bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_aFilterManager.getFilterComponent( FilterManager::fcPublicFilter ) );
            break;

        case PROPERTY_ID_APPLYFILTER:
			bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_aFilterManager.isApplyPublicFilter() );
            break;

		case PROPERTY_ID_DATASOURCE:
		{
			Any aAggregateProperty;
			getFastPropertyValue(aAggregateProperty, PROPERTY_ID_DATASOURCE);
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, aAggregateProperty, ::getCppuType(static_cast<const ::rtl::OUString*>(NULL)));
		}
		break;
		case PROPERTY_ID_TARGET_URL:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aTargetURL);
			break;
		case PROPERTY_ID_TARGET_FRAME:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aTargetFrame);
			break;
		case PROPERTY_ID_SUBMIT_METHOD:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_eSubmitMethod);
			break;
		case PROPERTY_ID_SUBMIT_ENCODING:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_eSubmitEncoding);
			break;
		case PROPERTY_ID_NAME:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sName);
			break;
		case PROPERTY_ID_MASTERFIELDS:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aMasterFields);
			break;
		case PROPERTY_ID_DETAILFIELDS:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDetailFields);
			break;
		case PROPERTY_ID_CYCLE:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aCycle, ::getCppuType(static_cast<const TabulatorCycle*>(NULL)));
			break;
		case PROPERTY_ID_NAVIGATION:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_eNavigation);
			break;
		case PROPERTY_ID_ALLOWADDITIONS:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bAllowInsert);
			break;
		case PROPERTY_ID_ALLOWEDITS:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bAllowUpdate);
			break;
		case PROPERTY_ID_ALLOWDELETIONS:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bAllowDelete);
			break;
        case PROPERTY_ID_DYNAMIC_CONTROL_BORDER:
            bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_aDynamicControlBorder, ::getBooleanCppuType() );
			break;
        case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS:
			bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_aControlBorderColorFocus, getCppuType( static_cast< sal_Int32* >( NULL ) ) );
			break;
        case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE:
			bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_aControlBorderColorMouse, getCppuType( static_cast< sal_Int32* >( NULL ) ) );
			break;
        case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID:
			bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_aControlBorderColorInvalid, getCppuType( static_cast< sal_Int32* >( NULL ) ) );
			break;
		default:
            if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle ( nHandle ) )
                bModified = m_aPropertyBagHelper.convertDynamicFastPropertyValue( nHandle, rValue, rConvertedValue, rOldValue );
            else
                bModified = OPropertySetAggregationHelper::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue );
            break;
	}
	return bModified;
}

//------------------------------------------------------------------------------
void ODatabaseForm::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw( Exception )
{
	switch (nHandle)
	{
        case PROPERTY_ID_INSERTONLY:
            rValue >>= m_bInsertOnly;
            if ( m_aIgnoreResult.hasValue() )
                m_aIgnoreResult <<= m_bInsertOnly;
            else
                m_xAggregateSet->setPropertyValue( PROPERTY_INSERTONLY, makeAny( m_bInsertOnly ) );
            break;

        case PROPERTY_ID_FILTER:
        {
            ::rtl::OUString sNewFilter;
            rValue >>= sNewFilter;
			m_aFilterManager.setFilterComponent( FilterManager::fcPublicFilter, sNewFilter );
        }
        break;

        case PROPERTY_ID_APPLYFILTER:
        {
            sal_Bool bApply = sal_True;
            rValue >>= bApply;
            m_aFilterManager.setApplyPublicFilter( bApply );
        }
        break;

		case PROPERTY_ID_DATASOURCE:
        {
            Reference< XConnection > xSomeConnection;
            if ( ::dbtools::isEmbeddedInDatabase( getParent(), xSomeConnection ) )
			    throw PropertyVetoException();

			try
			{
				m_xAggregateSet->setPropertyValue(PROPERTY_DATASOURCE, rValue);
			}
			catch(Exception&) { }
		}
		break;
		case PROPERTY_ID_TARGET_URL:
			rValue >>= m_aTargetURL;
			break;
		case PROPERTY_ID_TARGET_FRAME:
			rValue >>= m_aTargetFrame;
			break;
		case PROPERTY_ID_SUBMIT_METHOD:
			rValue >>= m_eSubmitMethod;
			break;
		case PROPERTY_ID_SUBMIT_ENCODING:
			rValue >>= m_eSubmitEncoding;
			break;
		case PROPERTY_ID_NAME:
			rValue >>= m_sName;
			break;
		case PROPERTY_ID_MASTERFIELDS:
			rValue >>= m_aMasterFields;
			invlidateParameters();
			break;
		case PROPERTY_ID_DETAILFIELDS:
			rValue >>= m_aDetailFields;
			invlidateParameters();
			break;
		case PROPERTY_ID_CYCLE:
			m_aCycle = rValue;
			break;
		case PROPERTY_ID_NAVIGATION:
			rValue >>= m_eNavigation;
			break;
		case PROPERTY_ID_ALLOWADDITIONS:
			m_bAllowInsert = getBOOL(rValue);
			break;
		case PROPERTY_ID_ALLOWEDITS:
			m_bAllowUpdate = getBOOL(rValue);
			break;
		case PROPERTY_ID_ALLOWDELETIONS:
			m_bAllowDelete = getBOOL(rValue);
			break;
        case PROPERTY_ID_DYNAMIC_CONTROL_BORDER:
			m_aDynamicControlBorder = rValue;
			break;
        case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS:
			m_aControlBorderColorFocus = rValue;
			break;
        case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE:
			m_aControlBorderColorMouse = rValue;
			break;
        case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID:
			m_aControlBorderColorInvalid = rValue;
			break;

		case PROPERTY_ID_ACTIVE_CONNECTION:
        {
            Reference< XConnection > xOuterConnection;
            if ( ::dbtools::isEmbeddedInDatabase( getParent(), xOuterConnection ) )
            {
                if ( xOuterConnection != Reference< XConnection >( rValue, UNO_QUERY ) )
                    // somebody's trying to set a connection which is not equal the connection
                    // implied by the database we're embedded in
			        throw PropertyVetoException();
            }
            OPropertySetAggregationHelper::setFastPropertyValue_NoBroadcast( nHandle, rValue );
            break;
        }

		default:
            if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( nHandle ) )
                m_aPropertyBagHelper.setDynamicFastPropertyValue( nHandle, rValue );
            else
                OPropertySetAggregationHelper::setFastPropertyValue_NoBroadcast( nHandle, rValue );
            break;
	}
}

//------------------------------------------------------------------
void SAL_CALL ODatabaseForm::forwardingPropertyValue( sal_Int32 _nHandle )
{
    OSL_ENSURE( _nHandle == PROPERTY_ID_ACTIVE_CONNECTION, "ODatabaseForm::forwardingPropertyValue: unexpected property!" );
    if ( _nHandle == PROPERTY_ID_ACTIVE_CONNECTION )
    {
	    if ( m_bSharingConnection )
		    stopSharingConnection( );
        m_bForwardingConnection = sal_True;
    }
}

//------------------------------------------------------------------
void SAL_CALL ODatabaseForm::forwardedPropertyValue( sal_Int32 _nHandle, bool /*_bSuccess*/ )
{
    OSL_ENSURE( _nHandle == PROPERTY_ID_ACTIVE_CONNECTION, "ODatabaseForm::forwardedPropertyValue: unexpected property!" );
    if ( _nHandle == PROPERTY_ID_ACTIVE_CONNECTION )
    {
        m_bForwardingConnection = sal_False;
    }
}

//==============================================================================
// com::sun::star::beans::XPropertyState
//------------------------------------------------------------------
PropertyState ODatabaseForm::getPropertyStateByHandle(sal_Int32 nHandle)
{
	PropertyState eState;
	switch (nHandle)
	{
		case PROPERTY_ID_NAVIGATION:
			return (NavigationBarMode_CURRENT == m_eNavigation) ? PropertyState_DEFAULT_VALUE : PropertyState_DIRECT_VALUE;

        case PROPERTY_ID_CYCLE:
            eState = m_aCycle.hasValue() ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
			break;

        case PROPERTY_ID_INSERTONLY:
            eState = m_bInsertOnly ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
			break;

        case PROPERTY_ID_FILTER:
            if ( !m_aFilterManager.getFilterComponent( FilterManager::fcPublicFilter ).getLength() )
				eState = PropertyState_DEFAULT_VALUE;
			else
				eState = PropertyState_DIRECT_VALUE;
			break;

        case PROPERTY_ID_APPLYFILTER:
            eState = m_aFilterManager.isApplyPublicFilter() ? PropertyState_DEFAULT_VALUE : PropertyState_DIRECT_VALUE;
			break;

        case PROPERTY_ID_DYNAMIC_CONTROL_BORDER:
            eState = m_aDynamicControlBorder.hasValue() ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
			break;

        case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS:
            eState = m_aControlBorderColorFocus.hasValue() ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
			break;

        case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE:
            eState = m_aControlBorderColorMouse.hasValue() ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
			break;

        case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID:
            eState = m_aControlBorderColorInvalid.hasValue() ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
			break;

        default:
			eState = OPropertySetAggregationHelper::getPropertyStateByHandle(nHandle);
	}
	return eState;
}

//------------------------------------------------------------------
void ODatabaseForm::setPropertyToDefaultByHandle(sal_Int32 nHandle)
{
	switch (nHandle)
	{
        case PROPERTY_ID_INSERTONLY:
        case PROPERTY_ID_FILTER:
        case PROPERTY_ID_APPLYFILTER:
		case PROPERTY_ID_NAVIGATION:
		case PROPERTY_ID_CYCLE:
        case PROPERTY_ID_DYNAMIC_CONTROL_BORDER:
        case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS:
        case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE:
        case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID:
            setFastPropertyValue( nHandle, getPropertyDefaultByHandle( nHandle ) );
			break;

        default:
			OPropertySetAggregationHelper::setPropertyToDefaultByHandle(nHandle);
	}
}

//------------------------------------------------------------------
Any ODatabaseForm::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
{
    Any aReturn;
	switch (nHandle)
	{
        case PROPERTY_ID_INSERTONLY:
        case PROPERTY_ID_DYNAMIC_CONTROL_BORDER:
            aReturn <<= sal_False;
            break;

        case PROPERTY_ID_FILTER:
            aReturn <<= ::rtl::OUString();
            break;

        case PROPERTY_ID_APPLYFILTER:
            aReturn <<= sal_True;
            break;

		case PROPERTY_ID_NAVIGATION:
			aReturn = makeAny(NavigationBarMode_CURRENT);
            break;

        case PROPERTY_ID_CYCLE:
        case PROPERTY_ID_CONTROL_BORDER_COLOR_FOCUS:
        case PROPERTY_ID_CONTROL_BORDER_COLOR_MOUSE:
        case PROPERTY_ID_CONTROL_BORDER_COLOR_INVALID:
			break;

        default:
            if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( nHandle ) )
                m_aPropertyBagHelper.getDynamicPropertyDefaultByHandle( nHandle, aReturn );
            else
			    aReturn = OPropertySetAggregationHelper::getPropertyDefaultByHandle( nHandle );
            break;
	}
    return aReturn;
}

//==============================================================================
// com::sun::star::form::XReset
//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::reset() throw( RuntimeException )
{
	::osl::ResettableMutexGuard aGuard(m_aMutex);

	if (isLoaded())
	{
		::osl::MutexGuard aResetGuard(m_aResetSafety);
		++m_nResetsPending;
		reset_impl(true);
		return;
	}

	if ( !m_aResetListeners.empty() )
	{
		::osl::MutexGuard aResetGuard(m_aResetSafety);
		++m_nResetsPending;
		// create an own thread if we have (approve-)reset-listeners (so the listeners can't do that much damage
		// to this thread which is probably the main one)
		if (!m_pThread)
		{
			m_pThread = new OFormSubmitResetThread(this);
			m_pThread->acquire();
			m_pThread->create();
		}
		EventObject aEvt;
		m_pThread->addEvent(&aEvt, sal_False);
	}
	else
	{
		// direct call without any approving by the listeners
		aGuard.clear();

		::osl::MutexGuard aResetGuard(m_aResetSafety);
		++m_nResetsPending;
		reset_impl(false);
	}
}

//-----------------------------------------------------------------------------
void ODatabaseForm::reset_impl(bool _bAproveByListeners)
{
	if ( _bAproveByListeners )
        if ( !m_aResetListeners.approveReset() )
            return;

	::osl::ResettableMutexGuard aResetGuard(m_aResetSafety);
	// do we have a database connected form and stay on the insert row
	sal_Bool bInsertRow = sal_False;
	if (m_xAggregateSet.is())
		bInsertRow = getBOOL(m_xAggregateSet->getPropertyValue(PROPERTY_ISNEW));
	if (bInsertRow)
	{
		try
		{
			// Iterate through all columns and set the default value
			Reference< XColumnsSupplier > xColsSuppl( m_xAggregateSet, UNO_QUERY );
			Reference< XIndexAccess > xIndexCols( xColsSuppl->getColumns(), UNO_QUERY );
			for (sal_Int32 i = 0; i < xIndexCols->getCount(); ++i)
			{
				Reference< XPropertySet > xColProps;
				xIndexCols->getByIndex(i) >>= xColProps;

				Reference< XColumnUpdate > xColUpdate( xColProps, UNO_QUERY );
				if ( !xColUpdate.is() )
					continue;

				Reference< XPropertySetInfo > xPSI;
				if ( xColProps.is() )
					xPSI = xColProps->getPropertySetInfo( );

				static const ::rtl::OUString PROPERTY_CONTROLDEFAULT( RTL_CONSTASCII_USTRINGPARAM( "ControlDefault" ) );
				if ( xPSI.is() && xPSI->hasPropertyByName( PROPERTY_CONTROLDEFAULT ) )
				{
					Any aDefault = xColProps->getPropertyValue( PROPERTY_CONTROLDEFAULT );

					sal_Bool bReadOnly = sal_False;
					if ( xPSI->hasPropertyByName( PROPERTY_ISREADONLY ) )
						xColProps->getPropertyValue( PROPERTY_ISREADONLY ) >>= bReadOnly;

					if ( !bReadOnly )
					{
						try
						{
							if ( aDefault.hasValue() )
								xColUpdate->updateObject( aDefault );
						}
						catch(Exception&)
						{
                            DBG_UNHANDLED_EXCEPTION();
						}
					}
				}
			}
		}
		catch(Exception&)
		{
		}

		if (m_bSubForm)
		{
            Reference< XColumnsSupplier > xParentColSupp( m_xParent, UNO_QUERY );
            Reference< XNameAccess >      xParentCols;
            if ( xParentColSupp.is() )
                xParentCols = xParentColSupp->getColumns();

			if ( xParentCols.is() && xParentCols->hasElements() && m_aMasterFields.getLength() )
			{
				try
				{
					// analyze our parameters
                    if ( !m_aParameterManager.isUpToDate() )
		                updateParameterInfo();

                    m_aParameterManager.resetParameterValues( );
				}
				catch(const Exception&)
				{
					OSL_ENSURE(sal_False, "ODatabaseForm::reset_impl: could not initialize the master-detail-driven parameters!");
				}
			}
		}
	}

	aResetGuard.clear();
	// iterate through all components. don't use an XIndexAccess as this will cause massive
	// problems with the count.
	Reference<XEnumeration>  xIter = createEnumeration();
	while (xIter->hasMoreElements())
	{
		Reference<XReset> xReset;
		xIter->nextElement() >>= xReset;
		if (xReset.is())
		{
			// TODO : all reset-methods have to be thread-safe
			xReset->reset();
		}
	}

	aResetGuard.reset();
	// ensure that the row isn't modified
	// (do this _before_ the listeners are notified ! their reaction (maybe asynchronous) may depend
	// on the modified state of the row
	// 21.02.00 - 73265 - FS)
	if (bInsertRow)
		m_xAggregateSet->setPropertyValue(PROPERTY_ISMODIFIED, ::cppu::bool2any(sal_Bool(sal_False)));

	aResetGuard.clear();
	{
        m_aResetListeners.resetted();
	}

	aResetGuard.reset();
	// and again : ensure the row isn't modified
	// we already did this after we (and maybe our dependents) resetted the values, but the listeners may have changed the row, too
	if (bInsertRow)
		m_xAggregateSet->setPropertyValue(PROPERTY_ISMODIFIED, ::cppu::bool2any((sal_False)));

	--m_nResetsPending;
}

//-----------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::addResetListener(const Reference<XResetListener>& _rListener) throw( RuntimeException )
{
	m_aResetListeners.addTypedListener( _rListener );
}

//-----------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::removeResetListener(const Reference<XResetListener>& _rListener) throw( RuntimeException )
{
	m_aResetListeners.removeTypedListener( _rListener );
}

//==============================================================================
// com::sun::star::form::XSubmit
//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::submit( const Reference<XControl>& Control,
							  const ::com::sun::star::awt::MouseEvent& MouseEvt ) throw( RuntimeException )
{
	{
		::osl::MutexGuard aGuard(m_aMutex);
		// Sind Controls und eine Submit-URL vorhanden?
		if( !getCount() || !m_aTargetURL.getLength() )
			return;
	}

	::osl::ClearableMutexGuard aGuard(m_aMutex);
	if (m_aSubmitListeners.getLength())
	{
		// create an own thread if we have (approve-)submit-listeners (so the listeners can't do that much damage
		// to this thread which is probably the main one)
		if (!m_pThread)
		{
			m_pThread = new OFormSubmitResetThread(this);
			m_pThread->acquire();
			m_pThread->create();
		}
		m_pThread->addEvent(&MouseEvt, Control, sal_True);
	}
	else
	{
		// direct call without any approving by the listeners
		aGuard.clear();
		submit_impl( Control, MouseEvt, true );
	}
}
// -----------------------------------------------------------------------------
void lcl_dispatch(const Reference< XFrame >& xFrame,const Reference<XURLTransformer>& xTransformer,const ::rtl::OUString& aURLStr,const ::rtl::OUString& aReferer,const ::rtl::OUString& aTargetName
                  ,const ::rtl::OUString& aData,rtl_TextEncoding _eEncoding)
{
    URL aURL;
    aURL.Complete = aURLStr;
	xTransformer->parseStrict(aURL);

	Reference< XDispatch >  xDisp = Reference< XDispatchProvider > (xFrame,UNO_QUERY)->queryDispatch(aURL, aTargetName,
		FrameSearchFlag::SELF | FrameSearchFlag::PARENT | FrameSearchFlag::CHILDREN |
		FrameSearchFlag::SIBLINGS | FrameSearchFlag::CREATE | FrameSearchFlag::TASKS);

	if (xDisp.is())
	{
		Sequence<PropertyValue> aArgs(2);
		aArgs.getArray()[0].Name = ::rtl::OUString::createFromAscii("Referer");
		aArgs.getArray()[0].Value <<= aReferer;

		// build a sequence from the to-be-submitted string
		ByteString a8BitData(aData.getStr(), (sal_uInt16)aData.getLength(), _eEncoding);
			// always ANSI #58641
		Sequence< sal_Int8 > aPostData((sal_Int8*)a8BitData.GetBuffer(), a8BitData.Len());
		Reference< XInputStream > xPostData = new SequenceInputStream(aPostData);

		aArgs.getArray()[1].Name = ::rtl::OUString::createFromAscii("PostData");
		aArgs.getArray()[1].Value <<= xPostData;

		xDisp->dispatch(aURL, aArgs);
	} // if (xDisp.is())
}
//------------------------------------------------------------------------------
void ODatabaseForm::submit_impl(const Reference<XControl>& Control, const ::com::sun::star::awt::MouseEvent& MouseEvt, bool _bAproveByListeners)
{

	if (_bAproveByListeners)
	{
		::cppu::OInterfaceIteratorHelper aIter(m_aSubmitListeners);
		EventObject aEvt(static_cast<XWeak*>(this));
		sal_Bool bCanceled = sal_False;
		while (aIter.hasMoreElements() && !bCanceled)
		{
			if (!((XSubmitListener*)aIter.next())->approveSubmit(aEvt))
				bCanceled = sal_True;
		}

		if (bCanceled)
			return;
	}

	FormSubmitEncoding eSubmitEncoding;
	FormSubmitMethod eSubmitMethod;
	::rtl::OUString aURLStr;
	::rtl::OUString aReferer;
	::rtl::OUString aTargetName;
	Reference< XModel >  xModel;
	{
		::vos::OGuard aGuard( Application::GetSolarMutex() );
		// starform->Forms

		Reference<XChild>  xParent(m_xParent, UNO_QUERY);

		if (xParent.is())
			xModel = getXModel(xParent->getParent());

		if (xModel.is())
			aReferer = xModel->getURL();

		// TargetItem
		aTargetName = m_aTargetFrame;

		eSubmitEncoding = m_eSubmitEncoding;
		eSubmitMethod = m_eSubmitMethod;
		aURLStr = m_aTargetURL;
	}

	if (!xModel.is())
		return;
    Reference< XFrame >  xFrame = xModel->getCurrentController()->getFrame();
	if (!xFrame.is())
		return;

	Reference<XURLTransformer>
		xTransformer(m_xServiceFactory->createInstance(
			::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer")), UNO_QUERY);
	DBG_ASSERT(xTransformer.is(), "ODatabaseForm::submit_impl : could not create an URL transformer !");

	// URL-Encoding
	if( eSubmitEncoding == FormSubmitEncoding_URL )
	{
		::rtl::OUString aData;
		{
			::vos::OGuard aGuard( Application::GetSolarMutex() );
			aData = GetDataURLEncoded( Control, MouseEvt );
		}

		URL aURL;
		// FormMethod GET
		if( eSubmitMethod == FormSubmitMethod_GET )
		{
			INetURLObject aUrlObj( aURLStr, INetURLObject::WAS_ENCODED );
			aUrlObj.SetParam( aData, INetURLObject::ENCODE_ALL );
			aURL.Complete = aUrlObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
			if (xTransformer.is())
				xTransformer->parseStrict(aURL);

			Reference< XDispatch >  xDisp = Reference< XDispatchProvider > (xFrame,UNO_QUERY)->queryDispatch(aURL, aTargetName,
					FrameSearchFlag::SELF | FrameSearchFlag::PARENT | FrameSearchFlag::CHILDREN |
					FrameSearchFlag::SIBLINGS | FrameSearchFlag::CREATE | FrameSearchFlag::TASKS);

			if (xDisp.is())
			{
				Sequence<PropertyValue> aArgs(1);
				aArgs.getArray()->Name = ::rtl::OUString::createFromAscii("Referer");
				aArgs.getArray()->Value <<= aReferer;
				xDisp->dispatch(aURL, aArgs);
			}
		}
		// FormMethod POST
		else if( eSubmitMethod == FormSubmitMethod_POST )
		{
			lcl_dispatch(xFrame,xTransformer,aURLStr,aReferer,aTargetName,aData,RTL_TEXTENCODING_MS_1252);
		}
	}
	else if( eSubmitEncoding == FormSubmitEncoding_MULTIPART )
	{
		URL aURL;
		aURL.Complete = aURLStr;
		xTransformer->parseStrict(aURL);

		Reference< XDispatch >  xDisp = Reference< XDispatchProvider > (xFrame,UNO_QUERY)->queryDispatch(aURL, aTargetName,
				FrameSearchFlag::SELF | FrameSearchFlag::PARENT | FrameSearchFlag::CHILDREN |
				FrameSearchFlag::SIBLINGS | FrameSearchFlag::CREATE | FrameSearchFlag::TASKS);

		if (xDisp.is())
		{
			::rtl::OUString aContentType;
			Sequence<sal_Int8> aData;
			{
				::vos::OGuard aGuard( Application::GetSolarMutex() );
				aData = GetDataMultiPartEncoded(Control, MouseEvt, aContentType);
			}
			if (!aData.getLength())
				return;

			Sequence<PropertyValue> aArgs(3);
			aArgs.getArray()[0].Name = ::rtl::OUString::createFromAscii("Referer");
			aArgs.getArray()[0].Value <<= aReferer;
			aArgs.getArray()[1].Name = ::rtl::OUString::createFromAscii("ContentType");
			aArgs.getArray()[1].Value <<= aContentType;

			// build a sequence from the to-be-submitted string
			Reference< XInputStream > xPostData = new SequenceInputStream(aData);

			aArgs.getArray()[2].Name = ::rtl::OUString::createFromAscii("PostData");
			aArgs.getArray()[2].Value <<= xPostData;

			xDisp->dispatch(aURL, aArgs);
		}
	}
	else if( eSubmitEncoding == FormSubmitEncoding_TEXT )
	{
		::rtl::OUString aData;
		{
			::vos::OGuard aGuard( Application::GetSolarMutex() );
			aData = GetDataTextEncoded( Reference<XControl> (), MouseEvt );
		}

        lcl_dispatch(xFrame,xTransformer,aURLStr,aReferer,aTargetName,aData,osl_getThreadTextEncoding());
	}
	else {
		DBG_ERROR("ODatabaseForm::submit_Impl : wrong encoding !");
    }

}

// XSubmit
//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::addSubmitListener(const Reference<XSubmitListener>& _rListener) throw( RuntimeException )
{
	m_aSubmitListeners.addInterface(_rListener);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::removeSubmitListener(const Reference<XSubmitListener>& _rListener) throw( RuntimeException )
{
	m_aSubmitListeners.removeInterface(_rListener);
}

//==============================================================================
// com::sun::star::sdbc::XSQLErrorBroadcaster
//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::addSQLErrorListener(const Reference<XSQLErrorListener>& _rListener) throw( RuntimeException )
{
	m_aErrorListeners.addInterface(_rListener);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::removeSQLErrorListener(const Reference<XSQLErrorListener>& _rListener) throw( RuntimeException )
{
	m_aErrorListeners.removeInterface(_rListener);
}

//------------------------------------------------------------------------------
void ODatabaseForm::invlidateParameters()
{
	::osl::MutexGuard aGuard(m_aMutex);
    m_aParameterManager.clearAllParameterInformation();
}

//==============================================================================
// OChangeListener
//------------------------------------------------------------------------------
void ODatabaseForm::_propertyChanged(const PropertyChangeEvent& evt) throw( RuntimeException )
{
	if ((0 == evt.PropertyName.compareToAscii(PROPERTY_ACTIVE_CONNECTION)) && !m_bForwardingConnection)
	{
		// the rowset changed its active connection itself (without interaction from our side), so
		// we need to fire this event, too
		sal_Int32 nHandle = PROPERTY_ID_ACTIVE_CONNECTION;
		fire(&nHandle, &evt.NewValue, &evt.OldValue, 1, sal_False);
	}
	else	// it was one of the statement relevant props
	{
		// if the statement has changed we have to delete the parameter info
		invlidateParameters();
	}
}

//==============================================================================
// smartXChild
//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setParent(const InterfaceRef& Parent) throw ( ::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException)
{
    // SYNCHRONIZED ----->
	::osl::ResettableMutexGuard aGuard(m_aMutex);

	Reference<XForm>  xParentForm(getParent(), UNO_QUERY);
	if (xParentForm.is())
	{
        try
        {
		    Reference< XRowSetApproveBroadcaster > xParentApprBroadcast( xParentForm, UNO_QUERY_THROW );
			xParentApprBroadcast->removeRowSetApproveListener( this );

            Reference< XLoadable > xParentLoadable( xParentForm, UNO_QUERY_THROW );
			xParentLoadable->removeLoadListener( this );

            Reference< XPropertySet > xParentProperties( xParentForm, UNO_QUERY_THROW );
            xParentProperties->removePropertyChangeListener( PROPERTY_ISNEW, this );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
	}

	OFormComponents::setParent(Parent);

	xParentForm.set(getParent(), UNO_QUERY);
	if ( xParentForm.is() )
	{
        try
        {
		    Reference< XRowSetApproveBroadcaster > xParentApprBroadcast( xParentForm, UNO_QUERY_THROW );
			xParentApprBroadcast->addRowSetApproveListener( this );

            Reference< XLoadable > xParentLoadable( xParentForm, UNO_QUERY_THROW );
			xParentLoadable->addLoadListener( this );

            Reference< XPropertySet > xParentProperties( xParentForm, UNO_QUERY_THROW );
            xParentProperties->addPropertyChangeListener( PROPERTY_ISNEW, this );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
	}

    Reference< XPropertySet > xAggregateProperties( m_xAggregateSet );
	aGuard.clear();
    // <----- SYNCHRONIZED

    Reference< XConnection > xOuterConnection;
    sal_Bool bIsEmbedded = ::dbtools::isEmbeddedInDatabase( Parent, xOuterConnection );

    if ( bIsEmbedded )
        xAggregateProperties->setPropertyValue( PROPERTY_DATASOURCE, makeAny( ::rtl::OUString() ) );
}

//==============================================================================
// smartXTabControllerModel
//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::getGroupControl() throw(com::sun::star::uno::RuntimeException)
{
	::osl::ResettableMutexGuard aGuard(m_aMutex);

    // Sollen Controls in einer TabOrder gruppe zusammengefasst werden?
	if (m_aCycle.hasValue())
	{
		sal_Int32 nCycle = 0;
		::cppu::enum2int(nCycle, m_aCycle);
		return nCycle != TabulatorCycle_PAGE;
	}

	if (isLoaded() && getConnection().is())
		return sal_True;

	return sal_False;
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setControlModels(const Sequence<Reference<XControlModel> >& rControls) throw( RuntimeException )
{
	::osl::ResettableMutexGuard aGuard(m_aMutex);

	// TabIndex in der Reihenfolge der Sequence setzen
	const Reference<XControlModel>* pControls = rControls.getConstArray();
	sal_Int16 nTabIndex = 1;
	sal_Int32 nCount = getCount();
	sal_Int32 nNewCount = rControls.getLength();

	// HiddenControls und Formulare werden nicht aufgefuehrt
	if (nNewCount <= nCount)
	{
		Any aElement;
		for (sal_Int32 i=0; i < nNewCount; ++i, ++pControls)
		{
			Reference<XFormComponent>  xComp(*pControls, UNO_QUERY);
			if (xComp.is())
			{
				// suchen der Componente in der Liste
				for (sal_Int32 j = 0; j < nCount; ++j)
				{
					Reference<XFormComponent> xElement;
					::cppu::extractInterface(xElement, getByIndex(j));
					if (xComp == xElement)
					{
						Reference<XPropertySet>  xSet(xComp, UNO_QUERY);
						if (xSet.is() && hasProperty(PROPERTY_TABINDEX, xSet))
							xSet->setPropertyValue( PROPERTY_TABINDEX, makeAny(nTabIndex++) );
						break;
					}
				}
			}
		}
	}
}

//------------------------------------------------------------------------------
Sequence<Reference<XControlModel> > SAL_CALL ODatabaseForm::getControlModels() throw( RuntimeException )
{
	::osl::MutexGuard aGuard(m_aMutex);
	return m_pGroupManager->getControlModels();
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setGroup( const Sequence<Reference<XControlModel> >& _rGroup, const ::rtl::OUString& Name ) throw( RuntimeException )
{
	::osl::MutexGuard aGuard(m_aMutex);

	// Die Controls werden gruppiert, indem ihr Name dem Namen des ersten
	// Controls der Sequenz angepasst wird
	const Reference<XControlModel>* pControls = _rGroup.getConstArray();
	Reference< XPropertySet > xSet;
	::rtl::OUString sGroupName( Name );

	for( sal_Int32 i=0; i<_rGroup.getLength(); ++i, ++pControls )
	{
		xSet = xSet.query( *pControls );
		if ( !xSet.is() )
		{
			// can't throw an exception other than a RuntimeException (which would not be appropriate),
			// so we ignore (and only assert) this
			OSL_ENSURE( sal_False, "ODatabaseForm::setGroup: invalid arguments!" );
			continue;
		}

		if (!sGroupName.getLength())
			xSet->getPropertyValue(PROPERTY_NAME) >>= sGroupName;
		else
			xSet->setPropertyValue(PROPERTY_NAME, makeAny(sGroupName));
	}
}

//------------------------------------------------------------------------------
sal_Int32 SAL_CALL ODatabaseForm::getGroupCount() throw( RuntimeException )
{
	::osl::MutexGuard aGuard(m_aMutex);
	return m_pGroupManager->getGroupCount();
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::getGroup( sal_Int32 nGroup, Sequence<Reference<XControlModel> >& _rGroup, ::rtl::OUString& _rName ) throw( RuntimeException )
{
	::osl::MutexGuard aGuard(m_aMutex);
	_rGroup.realloc(0);
	_rName = ::rtl::OUString();

	if ((nGroup < 0) || (nGroup >= m_pGroupManager->getGroupCount()))
		return;
	m_pGroupManager->getGroup( nGroup, _rGroup, _rName  );
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::getGroupByName(const ::rtl::OUString& Name, Sequence< Reference<XControlModel>  >& _rGroup) throw( RuntimeException )
{
	::osl::MutexGuard aGuard(m_aMutex);
	_rGroup.realloc(0);
	m_pGroupManager->getGroupByName( Name, _rGroup );
}

//==============================================================================
// com::sun::star::lang::XEventListener
//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::disposing(const EventObject& Source) throw( RuntimeException )
{
	// does the call come from the connection which we are sharing with our parent?
	if ( isSharingConnection() )
	{
		Reference< XConnection > xConnSource( Source.Source, UNO_QUERY );
		if ( xConnSource.is() )
		{
#if OSL_DEBUG_LEVEL > 0
			Reference< XConnection > xActiveConn;
			m_xAggregateSet->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xActiveConn;
			OSL_ENSURE( xActiveConn.get() == xConnSource.get(), "ODatabaseForm::disposing: where did this come from?" );
				// there should be exactly one XConnection object we're listening at - our aggregate connection
#endif
			disposingSharedConnection( xConnSource );
		}
	}

	OInterfaceContainer::disposing(Source);

	// does the disposing come from the aggregate ?
	if (m_xAggregate.is())
	{	// no -> forward it
		com::sun::star::uno::Reference<com::sun::star::lang::XEventListener> xListener;
		if (query_aggregation(m_xAggregate, xListener))
			xListener->disposing(Source);
	}
}

//------------------------------------------------------------------------------
void ODatabaseForm::impl_createLoadTimer()
{
    OSL_PRECOND( m_pLoadTimer == NULL, "ODatabaseForm::impl_createLoadTimer: timer already exists!" );
	m_pLoadTimer = new Timer();
	m_pLoadTimer->SetTimeout(100);
	m_pLoadTimer->SetTimeoutHdl(LINK(this,ODatabaseForm,OnTimeout));
}

//==============================================================================
// com::sun::star::form::XLoadListener
//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::loaded(const EventObject& /*aEvent*/) throw( RuntimeException )
{
	{
		::osl::MutexGuard aGuard( m_aMutex );
	    Reference< XRowSet > xParentRowSet( m_xParent, UNO_QUERY_THROW );
	    xParentRowSet->addRowSetListener( this );

        impl_createLoadTimer();
	}

	load_impl( sal_True );
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::unloading(const EventObject& /*aEvent*/) throw( RuntimeException )
{
	{
		// now stop the rowset listening if we are a subform
		::osl::MutexGuard aGuard( m_aMutex );

        if ( m_pLoadTimer && m_pLoadTimer->IsActive() )
            m_pLoadTimer->Stop();
        DELETEZ( m_pLoadTimer );

        Reference< XRowSet > xParentRowSet( m_xParent, UNO_QUERY_THROW );
        xParentRowSet->removeRowSetListener( this );
	}

	unload();
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::unloaded(const EventObject& /*aEvent*/) throw( RuntimeException )
{
	// nothing to do
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::reloading(const EventObject& /*aEvent*/) throw( RuntimeException )
{
	// now stop the rowset listening if we are a subform
	::osl::MutexGuard aGuard(m_aMutex);
	Reference<XRowSet>  xParentRowSet(m_xParent, UNO_QUERY);
	if (xParentRowSet.is())
		xParentRowSet->removeRowSetListener(this);

	if (m_pLoadTimer && m_pLoadTimer->IsActive())
		m_pLoadTimer->Stop();
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::reloaded(const EventObject& /*aEvent*/) throw( RuntimeException )
{
	reload_impl(sal_True);
	{
		::osl::MutexGuard aGuard(m_aMutex);
		Reference<XRowSet>  xParentRowSet(m_xParent, UNO_QUERY);
		if (xParentRowSet.is())
			xParentRowSet->addRowSetListener(this);
	}
}

//------------------------------------------------------------------------------
IMPL_LINK( ODatabaseForm, OnTimeout, void*, EMPTYARG )
{
    reload_impl(sal_True);
    return 1;
}

//==============================================================================
// com::sun::star::form::XLoadable
//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::load() throw( RuntimeException )
{
	load_impl(sal_False);
}

//------------------------------------------------------------------------------
sal_Bool ODatabaseForm::canShareConnection( const Reference< XPropertySet >& _rxParentProps )
{
	// our own data source
	::rtl::OUString sOwnDatasource;
	m_xAggregateSet->getPropertyValue( PROPERTY_DATASOURCE ) >>= sOwnDatasource;

	// our parents data source
	::rtl::OUString sParentDataSource;
	OSL_ENSURE( _rxParentProps.is() && _rxParentProps->getPropertySetInfo().is() && _rxParentProps->getPropertySetInfo()->hasPropertyByName( PROPERTY_DATASOURCE ),
		"ODatabaseForm::doShareConnection: invalid parent form!" );
	if ( _rxParentProps.is() )
		_rxParentProps->getPropertyValue( PROPERTY_DATASOURCE ) >>= sParentDataSource;

	sal_Bool bCanShareConnection = sal_False;

	// both rowsets share are connected to the same data source
	if ( sParentDataSource == sOwnDatasource )
	{
		if ( 0 != sParentDataSource.getLength() )
			// and it's really a data source name (not empty)
			bCanShareConnection = sal_True;
		else
		{	// the data source name is empty
			// -> ook for the URL
			::rtl::OUString sParentURL;
			::rtl::OUString sMyURL;
			_rxParentProps->getPropertyValue( PROPERTY_URL ) >>= sParentURL;
			m_xAggregateSet->getPropertyValue( PROPERTY_URL ) >>= sMyURL;

			bCanShareConnection = (sParentURL == sMyURL);
		}
	}

	if ( bCanShareConnection )
	{
		// check for the user/password

		// take the user property on the rowset (if any) into account
		::rtl::OUString sParentUser, sParentPwd;
		_rxParentProps->getPropertyValue( PROPERTY_USER ) >>= sParentUser;
		_rxParentProps->getPropertyValue( PROPERTY_PASSWORD ) >>= sParentPwd;

		::rtl::OUString sMyUser, sMyPwd;
		m_xAggregateSet->getPropertyValue( PROPERTY_USER ) >>= sMyUser;
		m_xAggregateSet->getPropertyValue( PROPERTY_PASSWORD ) >>= sMyPwd;

		bCanShareConnection =
				( sParentUser == sMyUser )
			&&	( sParentPwd == sMyPwd );
	}

	return bCanShareConnection;
}

//------------------------------------------------------------------------------
void ODatabaseForm::doShareConnection( const Reference< XPropertySet >& _rxParentProps )
{
	// get the conneciton of the parent
	Reference< XConnection > xParentConn;
	_rxParentProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xParentConn;
	OSL_ENSURE( xParentConn.is(), "ODatabaseForm::doShareConnection: we're a valid sub-form, but the parent has no connection?!" );

	if ( xParentConn.is() )
	{
		// add as dispose listener to the connection
		Reference< XComponent > xParentConnComp( xParentConn, UNO_QUERY );
		OSL_ENSURE( xParentConnComp.is(), "ODatabaseForm::doShareConnection: invalid connection!" );
		xParentConnComp->addEventListener( static_cast< XLoadListener* >( this ) );

		// forward the connection to our own aggreagte
		m_bForwardingConnection = sal_True;
		m_xAggregateSet->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( xParentConn ) );
		m_bForwardingConnection = sal_False;

		m_bSharingConnection = sal_True;
	}
	else
		m_bSharingConnection = sal_False;
}

//------------------------------------------------------------------------------
void ODatabaseForm::disposingSharedConnection( const Reference< XConnection >& /*_rxConn*/ )
{
	stopSharingConnection();

	// TODO: we could think about whether or not to re-connect.
	unload( );
}

//------------------------------------------------------------------------------
void ODatabaseForm::stopSharingConnection( )
{
	OSL_ENSURE( m_bSharingConnection, "ODatabaseForm::stopSharingConnection: invalid call!" );

	if ( m_bSharingConnection )
	{
		// get the connection
		Reference< XConnection > xSharedConn;
		m_xAggregateSet->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xSharedConn;
		OSL_ENSURE( xSharedConn.is(), "ODatabaseForm::stopSharingConnection: there's no conn!" );

		// remove ourself as event listener
		Reference< XComponent > xSharedConnComp( xSharedConn, UNO_QUERY );
		if ( xSharedConnComp.is() )
			xSharedConnComp->removeEventListener( static_cast< XLoadListener* >( this ) );

		// no need to dispose the conn: we're not the owner, this is our parent
		// (in addition, this method may be called if the connection is beeing disposed while we use it)

		// reset the property
		xSharedConn.clear();
		m_bForwardingConnection = sal_True;
		m_xAggregateSet->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( xSharedConn ) );
		m_bForwardingConnection = sal_False;

		// reset the flag
		m_bSharingConnection = sal_False;
	}
}

//------------------------------------------------------------------------------
sal_Bool ODatabaseForm::implEnsureConnection()
{
	try
	{
		if ( getConnection( ).is() )
			// if our aggregate already has a connection, nothing needs to be done about it
			return sal_True;

        // see whether we're an embedded form
        Reference< XConnection > xOuterConnection;
        if ( ::dbtools::isEmbeddedInDatabase( getParent(), xOuterConnection ) )
        {
	        m_xAggregateSet->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( xOuterConnection ) );
            return xOuterConnection.is();
        }

		m_bSharingConnection = sal_False;

		// if we're a sub form, we try to re-use the connection of our parent
		if (m_bSubForm)
		{
			OSL_ENSURE( Reference< XForm >( getParent(), UNO_QUERY ).is(),
				"ODatabaseForm::implEnsureConnection: m_bSubForm is TRUE, but the parent is no form?" );

			Reference< XPropertySet > xParentProps( getParent(), UNO_QUERY );

			// can we re-use (aka share) the connection of the parent?
			if ( canShareConnection( xParentProps ) )
			{
				// yep -> do it
				doShareConnection( xParentProps );
				// success?
				if ( m_bSharingConnection )
					// yes -> outta here
					return sal_True;
			}
		}

		if (m_xAggregateSet.is())
		{
			Reference< XConnection >  xConnection = connectRowset(
				Reference<XRowSet> (m_xAggregate, UNO_QUERY),
				m_xServiceFactory,
                sal_True    // set a calculated connection as ActiveConnection
			);
			return xConnection.is();
		}
	}
	catch(SQLException& eDB)
	{
		onError(eDB, FRM_RES_STRING(RID_STR_CONNECTERROR));
	}
	catch( Exception )
	{
        DBG_UNHANDLED_EXCEPTION();
    }

	return sal_False;
}

//------------------------------------------------------------------------------
void ODatabaseForm::load_impl(sal_Bool bCausedByParentForm, sal_Bool bMoveToFirst, const Reference< XInteractionHandler >& _rxCompletionHandler ) throw( RuntimeException )
{
	::osl::ResettableMutexGuard aGuard(m_aMutex);

	// are we already loaded?
	if (isLoaded())
		return;

	m_bSubForm = bCausedByParentForm;

	// if we don't have a connection, we are not intended to be a database form or the aggregate was not able
	// to establish a connection
	sal_Bool bConnected	= implEnsureConnection();

	// we don't have to execute if we do not have a command to execute
	sal_Bool bExecute = bConnected && m_xAggregateSet.is() && getString(m_xAggregateSet->getPropertyValue(PROPERTY_COMMAND)).getLength();

	// a database form always uses caching
	// we use starting fetchsize with at least 10 rows
	if (bConnected)
		m_xAggregateSet->setPropertyValue(PROPERTY_FETCHSIZE, makeAny((sal_Int32)40));

	// if we're loaded as sub form we got a "rowSetChanged" from the parent rowset _before_ we got the "loaded"
	// so we don't need to execute the statement again, this was already done
	// (and there were no relevant changes between these two listener calls, the "load" of a form is quite an
	// atomar operation.)

	sal_Bool bSuccess = sal_False;
	if (bExecute)
	{
		m_sCurrentErrorContext = FRM_RES_STRING(RID_ERR_LOADING_FORM);
		bSuccess = executeRowSet(aGuard, bMoveToFirst, _rxCompletionHandler);
	}

	if (bSuccess)
	{
		m_bLoaded = sal_True;
		aGuard.clear();
		EventObject aEvt(static_cast<XWeak*>(this));
        m_aLoadListeners.notifyEach( &XLoadListener::loaded, aEvt );

		// if we are on the insert row, we have to reset all controls
		// to set the default values
		if (bExecute && getBOOL(m_xAggregateSet->getPropertyValue(PROPERTY_ISNEW)))
			reset();
	}
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::unload() throw( RuntimeException )
{
	::osl::ResettableMutexGuard aGuard(m_aMutex);
	if (!isLoaded())
		return;

	DELETEZ(m_pLoadTimer);

	aGuard.clear();
	EventObject aEvt(static_cast<XWeak*>(this));
    m_aLoadListeners.notifyEach( &XLoadListener::unloading, aEvt );

	if (m_xAggregateAsRowSet.is())
	{
		// we may have reset the InsertOnly property on the aggregate - restore it
		restoreInsertOnlyState( );

		// clear the parameters if there are any
		invlidateParameters();

		try
		{
			// close the aggregate
			Reference<XCloseable>  xCloseable;
			query_aggregation( m_xAggregate, xCloseable);
			aGuard.clear();
			if (xCloseable.is())
				xCloseable->close();
		}
		catch( const SQLException& e )
		{
			(void)e;
		}
		aGuard.reset();
	}

	m_bLoaded = sal_False;

	// if the connection we used while we were loaded is only shared with our parent, we
	// reset it
	if ( isSharingConnection() )
		stopSharingConnection();

	aGuard.clear();
    m_aLoadListeners.notifyEach( &XLoadListener::unloaded, aEvt );
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::reload() throw( RuntimeException )
{
	reload_impl(sal_True);
}

//------------------------------------------------------------------------------
void ODatabaseForm::reload_impl(sal_Bool bMoveToFirst, const Reference< XInteractionHandler >& _rxCompletionHandler ) throw( RuntimeException )
{
	::osl::ResettableMutexGuard aGuard(m_aMutex);
	if (!isLoaded())
		return;

    DocumentModifyGuard aModifyGuard( *this );
        // ensures the document is not marked as "modified" just because we change some control's content during
        // reloading ...

	EventObject aEvent(static_cast<XWeak*>(this));
	{
		// only if there is no approve listener we can post the event at this time
		// otherwise see approveRowsetChange
		// the aprrovement is done by the aggregate
		if (!m_aRowSetApproveListeners.getLength())
		{
			::cppu::OInterfaceIteratorHelper aIter(m_aLoadListeners);
			aGuard.clear();

			while (aIter.hasMoreElements())
				((XLoadListener*)aIter.next())->reloading(aEvent);

			aGuard.reset();
		}
	}

	sal_Bool bSuccess = sal_True;
	try
	{
		m_sCurrentErrorContext = FRM_RES_STRING(RID_ERR_REFRESHING_FORM);
		bSuccess = executeRowSet(aGuard, bMoveToFirst, _rxCompletionHandler);
	}
	catch( const SQLException& e )
	{
		DBG_ERROR("ODatabaseForm::reload_impl : shouldn't executeRowSet catch this exception?");
		(void)e;
	}

	if (bSuccess)
	{
		::cppu::OInterfaceIteratorHelper aIter(m_aLoadListeners);
		aGuard.clear();
		while (aIter.hasMoreElements())
			((XLoadListener*)aIter.next())->reloaded(aEvent);

		// if we are on the insert row, we have to reset all controls
		// to set the default values
		if (getBOOL(m_xAggregateSet->getPropertyValue(PROPERTY_ISNEW)))
			reset();
	}
	else
		m_bLoaded = sal_False;
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::isLoaded() throw( RuntimeException )
{
	return m_bLoaded;
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::addLoadListener(const Reference<XLoadListener>& aListener) throw( RuntimeException )
{
	m_aLoadListeners.addInterface(aListener);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::removeLoadListener(const Reference<XLoadListener>& aListener) throw( RuntimeException )
{
	m_aLoadListeners.removeInterface(aListener);
}

//==============================================================================
// com::sun::star::sdbc::XCloseable
//==============================================================================
void SAL_CALL ODatabaseForm::close() throw( SQLException, RuntimeException )
{
	// unload will close the aggregate
	unload();
}

//==============================================================================
// com::sun::star::sdbc::XRowSetListener
//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::cursorMoved(const EventObject& /*event*/) throw( RuntimeException )
{
	// reload the subform with the new parameters of the parent
	// do this handling delayed to provide of execute too many SQL Statements
	::osl::ResettableMutexGuard aGuard(m_aMutex);

    DBG_ASSERT( m_pLoadTimer, "ODatabaseForm::cursorMoved: how can this happen?!" );
    if ( !m_pLoadTimer )
        impl_createLoadTimer();

	if ( m_pLoadTimer->IsActive() )
		m_pLoadTimer->Stop();

	// and start the timer again
	m_pLoadTimer->Start();
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::rowChanged(const EventObject& /*event*/) throw( RuntimeException )
{
	// ignore it
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::rowSetChanged(const EventObject& /*event*/) throw( RuntimeException )
{
	// not interested in :
	// if our parent is an ODatabaseForm, too, then after this rowSetChanged we'll get a "reloaded"
	// or a "loaded" event.
	// If somebody gave us another parent which is an XRowSet but doesn't handle an execute as
	// "load" respectivly "reload" ... can't do anything ....
}

//------------------------------------------------------------------------------
bool ODatabaseForm::impl_approveRowChange_throw( const EventObject& _rEvent, const bool _bAllowSQLException,
    ::osl::ClearableMutexGuard& _rGuard )
{
    ::cppu::OInterfaceIteratorHelper aIter( m_aRowSetApproveListeners );
    _rGuard.clear();
    while ( aIter.hasMoreElements() )
    {
        Reference< XRowSetApproveListener > xListener( static_cast< XRowSetApproveListener* >( aIter.next() ) );
        if ( !xListener.is() )
            continue;

        try
        {
            if ( !xListener->approveRowSetChange( _rEvent ) )
                return false;
        }
        catch ( const DisposedException& e )
        {
            if ( e.Context == xListener )
                aIter.remove();
        }
        catch ( const RuntimeException& ) { throw; }
        catch ( const SQLException& )
        {
            if ( _bAllowSQLException )
                throw;
            DBG_UNHANDLED_EXCEPTION();
        }
        catch ( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }
    return true;
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::approveCursorMove(const EventObject& event) throw( RuntimeException )
{
	// is our aggregate calling?
	if (event.Source == InterfaceRef(static_cast<XWeak*>(this)))
	{
		// Our aggregate doesn't have any ApproveRowSetListeners (expect ourself), as we re-routed the queryInterface
		// for XRowSetApproveBroadcaster-interface.
		// So we have to multiplex this approve request.
        ::cppu::OInterfaceIteratorHelper aIter( m_aRowSetApproveListeners );
        while ( aIter.hasMoreElements() )
        {
            Reference< XRowSetApproveListener > xListener( static_cast< XRowSetApproveListener* >( aIter.next() ) );
            if ( !xListener.is() )
                continue;

            try
            {
                if ( !xListener->approveCursorMove( event ) )
                    return sal_False;
            }
            catch ( const DisposedException& e )
            {
                if ( e.Context == xListener )
                    aIter.remove();
            }
            catch ( const RuntimeException& ) { throw; }
            catch ( const Exception& )
            {
                DBG_UNHANDLED_EXCEPTION();
            }
        }
        return true;
	}
	else
	{
		// this is a call from our parent ...
		// a parent's cursor move will result in a re-execute of our own row-set, so we have to
		// ask our own RowSetChangesListeners, too
        ::osl::ClearableMutexGuard aGuard( m_aMutex );
        if ( !impl_approveRowChange_throw( event, false, aGuard ) )
            return sal_False;
	}
	return sal_True;
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::approveRowChange(const RowChangeEvent& event) throw( RuntimeException )
{
	// is our aggregate calling?
	if (event.Source == InterfaceRef(static_cast<XWeak*>(this)))
	{
		// Our aggregate doesn't have any ApproveRowSetListeners (expect ourself), as we re-routed the queryInterface
		// for XRowSetApproveBroadcaster-interface.
		// So we have to multiplex this approve request.
        ::cppu::OInterfaceIteratorHelper aIter( m_aRowSetApproveListeners );
        while ( aIter.hasMoreElements() )
        {
            Reference< XRowSetApproveListener > xListener( static_cast< XRowSetApproveListener* >( aIter.next() ) );
            if ( !xListener.is() )
                continue;

            try
            {
                if ( !xListener->approveRowChange( event ) )
                    return false;
            }
            catch ( const DisposedException& e )
            {
                if ( e.Context == xListener )
                    aIter.remove();
            }
            catch ( const RuntimeException& ) { throw; }
            catch ( const Exception& )
            {
                DBG_UNHANDLED_EXCEPTION();
            }
        }
        return true;
	}
	return sal_True;
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::approveRowSetChange(const EventObject& event) throw( RuntimeException )
{
	if (event.Source == InterfaceRef(static_cast<XWeak*>(this)))	// ignore our aggregate as we handle this approve ourself
	{
        ::osl::ClearableMutexGuard aGuard( m_aMutex );
        bool bWasLoaded = isLoaded();
        if ( !impl_approveRowChange_throw( event, false, aGuard ) )
            return sal_False;

		if ( bWasLoaded )
		{
            m_aLoadListeners.notifyEach( &XLoadListener::reloading, event );
		}
	}
	else
	{
		// this is a call from our parent ...
		// a parent's cursor move will result in a re-execute of our own row-set, so we have to
		// ask our own RowSetChangesListeners, too
        ::osl::ClearableMutexGuard aGuard( m_aMutex );
        if ( !impl_approveRowChange_throw( event, false, aGuard ) )
            return sal_False;
	}
	return sal_True;
}

//==============================================================================
// com::sun::star::sdb::XRowSetApproveBroadcaster
//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::addRowSetApproveListener(const Reference<XRowSetApproveListener>& _rListener) throw( RuntimeException )
{
	::osl::ResettableMutexGuard aGuard(m_aMutex);
	m_aRowSetApproveListeners.addInterface(_rListener);

	// do we have to multiplex ?
	if (m_aRowSetApproveListeners.getLength() == 1)
	{
		Reference<XRowSetApproveBroadcaster>  xBroadcaster;
		if (query_aggregation( m_xAggregate, xBroadcaster))
		{
			Reference<XRowSetApproveListener>  xListener((XRowSetApproveListener*)this);
			xBroadcaster->addRowSetApproveListener(xListener);
		}
	}
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::removeRowSetApproveListener(const Reference<XRowSetApproveListener>& _rListener) throw( RuntimeException )
{
	::osl::ResettableMutexGuard aGuard(m_aMutex);
	// do we have to remove the multiplex ?
	m_aRowSetApproveListeners.removeInterface(_rListener);
	if ( m_aRowSetApproveListeners.getLength() == 0 )
	{
		Reference<XRowSetApproveBroadcaster>  xBroadcaster;
		if (query_aggregation( m_xAggregate, xBroadcaster))
		{
			Reference<XRowSetApproveListener>  xListener((XRowSetApproveListener*)this);
			xBroadcaster->removeRowSetApproveListener(xListener);
		}
	}
}

//==============================================================================
// com::sun:star::form::XDatabaseParameterBroadcaster
//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::addDatabaseParameterListener(const Reference<XDatabaseParameterListener>& _rListener) throw( RuntimeException )
{
	m_aParameterManager.addParameterListener( _rListener );
}
//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::removeDatabaseParameterListener(const Reference<XDatabaseParameterListener>& _rListener) throw( RuntimeException )
{
	m_aParameterManager.removeParameterListener( _rListener );
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::addParameterListener(const Reference<XDatabaseParameterListener>& _rListener) throw( RuntimeException )
{
    ODatabaseForm::addDatabaseParameterListener( _rListener );
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::removeParameterListener(const Reference<XDatabaseParameterListener>& _rListener) throw( RuntimeException )
{
    ODatabaseForm::removeDatabaseParameterListener( _rListener );
}

//==============================================================================
// com::sun::star::sdb::XCompletedExecution
//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::executeWithCompletion( const Reference< XInteractionHandler >& _rxHandler ) throw(SQLException, RuntimeException)
{
	::osl::ClearableMutexGuard aGuard(m_aMutex);
	// the difference between execute and load is, that we position on the first row in case of load
	// after execute we remain before the first row
	if (!isLoaded())
	{
		aGuard.clear();
		load_impl(sal_False, sal_False, _rxHandler);
	}
	else
	{
		EventObject event(static_cast< XWeak* >(this));
        if ( !impl_approveRowChange_throw( event, true, aGuard ) )
            return;

		// we're loaded and somebody want's to execute ourself -> this means a reload
		reload_impl(sal_False, _rxHandler);
	}
}

//==============================================================================
// com::sun::star::sdbc::XRowSet
//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::execute() throw( SQLException, RuntimeException )
{
	::osl::ResettableMutexGuard aGuard(m_aMutex);
	// if somebody calls an execute and we're not loaded we reroute this call to our load method.

	// the difference between execute and load is, that we position on the first row in case of load
	// after execute we remain before the first row
	if (!isLoaded())
	{
		aGuard.clear();
		load_impl(sal_False, sal_False);
	}
	else
	{
		EventObject event(static_cast< XWeak* >(this));
        if ( !impl_approveRowChange_throw( event, true, aGuard ) )
            return;

		// we're loaded and somebody want's to execute ourself -> this means a reload
		reload_impl(sal_False);
	}
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::addRowSetListener(const Reference<XRowSetListener>& _rListener) throw( RuntimeException )
{
	if (m_xAggregateAsRowSet.is())
		m_xAggregateAsRowSet->addRowSetListener(_rListener);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::removeRowSetListener(const Reference<XRowSetListener>& _rListener) throw( RuntimeException )
{
	if (m_xAggregateAsRowSet.is())
		m_xAggregateAsRowSet->removeRowSetListener(_rListener);
}

//==============================================================================
// com::sun::star::sdbc::XResultSet
//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::next() throw( SQLException, RuntimeException )
{
	return m_xAggregateAsRowSet->next();
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::isBeforeFirst() throw( SQLException, RuntimeException )
{
	return m_xAggregateAsRowSet->isBeforeFirst();
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::isAfterLast() throw( SQLException, RuntimeException )
{
	return m_xAggregateAsRowSet->isAfterLast();
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::isFirst() throw( SQLException, RuntimeException )
{
	return m_xAggregateAsRowSet->isFirst();
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::isLast() throw( SQLException, RuntimeException )
{
	return m_xAggregateAsRowSet->isLast();
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::beforeFirst() throw( SQLException, RuntimeException )
{
	m_xAggregateAsRowSet->beforeFirst();
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::afterLast() throw( SQLException, RuntimeException )
{
	m_xAggregateAsRowSet->afterLast();
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::first() throw( SQLException, RuntimeException )
{
	return m_xAggregateAsRowSet->first();
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::last() throw( SQLException, RuntimeException )
{
	return m_xAggregateAsRowSet->last();
}

//------------------------------------------------------------------------------
sal_Int32 SAL_CALL ODatabaseForm::getRow() throw( SQLException, RuntimeException )
{
	return m_xAggregateAsRowSet->getRow();
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::absolute(sal_Int32 row) throw( SQLException, RuntimeException )
{
	return m_xAggregateAsRowSet->absolute(row);
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::relative(sal_Int32 rows) throw( SQLException, RuntimeException )
{
	return m_xAggregateAsRowSet->relative(rows);
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::previous() throw( SQLException, RuntimeException )
{
	return m_xAggregateAsRowSet->previous();
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::refreshRow() throw( SQLException, RuntimeException )
{
	m_xAggregateAsRowSet->refreshRow();
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::rowUpdated() throw( SQLException, RuntimeException )
{
	return m_xAggregateAsRowSet->rowUpdated();
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::rowInserted() throw( SQLException, RuntimeException )
{
	return m_xAggregateAsRowSet->rowInserted();
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::rowDeleted() throw( SQLException, RuntimeException )
{
	return m_xAggregateAsRowSet->rowDeleted();
}

//------------------------------------------------------------------------------
InterfaceRef SAL_CALL ODatabaseForm::getStatement() throw( SQLException, RuntimeException )
{
	return m_xAggregateAsRowSet->getStatement();
}

// com::sun::star::sdbc::XResultSetUpdate
// exceptions during insert update and delete will be forwarded to the errorlistener
//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::insertRow() throw( SQLException, RuntimeException )
{
	try
	{
		Reference<XResultSetUpdate>  xUpdate;
		if (query_aggregation( m_xAggregate, xUpdate))
			xUpdate->insertRow();
	}
	catch( const RowSetVetoException& eVeto )
	{
		(void)eVeto;
		throw;
	}
	catch(SQLException& eDb)
	{
		onError(eDb, FRM_RES_STRING(RID_STR_ERR_INSERTRECORD));
		throw;
	}
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::updateRow() throw( SQLException, RuntimeException )
{
	try
	{
		Reference<XResultSetUpdate>  xUpdate;
		if (query_aggregation( m_xAggregate, xUpdate))
			xUpdate->updateRow();
	}
	catch( const RowSetVetoException& eVeto )
	{
		(void)eVeto;
		throw;
	}
	catch(SQLException& eDb)
	{
		onError(eDb, FRM_RES_STRING(RID_STR_ERR_UPDATERECORD));
		throw;
	}
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::deleteRow() throw( SQLException, RuntimeException )
{
	try
	{
		Reference<XResultSetUpdate>  xUpdate;
		if (query_aggregation( m_xAggregate, xUpdate))
			xUpdate->deleteRow();
	}
	catch( const RowSetVetoException& eVeto )
	{
		(void)eVeto;
		throw;
	}
	catch(SQLException& eDb)
	{
		onError(eDb, FRM_RES_STRING(RID_STR_ERR_DELETERECORD));
		throw;
	}
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::cancelRowUpdates() throw( SQLException, RuntimeException )
{
	try
	{
		Reference<XResultSetUpdate>  xUpdate;
		if (query_aggregation( m_xAggregate, xUpdate))
			xUpdate->cancelRowUpdates();
	}
	catch( const RowSetVetoException& eVeto )
	{
		(void)eVeto;
		throw;
	}
	catch(SQLException& eDb)
	{
		onError(eDb, FRM_RES_STRING(RID_STR_ERR_INSERTRECORD));
		throw;
	}
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::moveToInsertRow() throw( SQLException, RuntimeException )
{
	Reference<XResultSetUpdate>  xUpdate;
	if (query_aggregation( m_xAggregate, xUpdate))
	{
		// _always_ move to the insert row
		//
		// Formerly, the following line was conditioned with a "not is new", means we did not move the aggregate
		// to the insert row if it was already positioned there.
		//
		// This prevented the RowSet implementation from resetting it's column values. We, ourself, formerly
		// did this reset of columns in reset_impl, where we set every column to the ControlDefault, or, if this
		// was not present, to NULL. However, the problem with setting to NULL was #88888#, the problem with
		// _not_ setting to NULL (which was the original fix for #88888#) was #97955#.
		//
		// So now we
		// * move our aggregate to the insert row
		// * in reset_impl
		//   - set the control defaults into the columns if not void
		//   - do _not_ set the columns to NULL if no control default is set
		// This fixes both #88888# and #97955#
		//
		// Still, there is #72756#. During fixing this bug, DG introduced not calling the aggregate here. So
		// in theory, we re-introduced #72756#. But the bug described therein does not happen anymore, as the
		// preliminaries for it changed (no display of guessed values for new records with autoinc fields)
		//
		// BTW: the public Issuezilla bug for #97955# is #i2815#
		//
		// 16.04.2002 - 97955 - fs@openoffice.org
		xUpdate->moveToInsertRow();

		// then set the default values and the parameters given from the parent
		reset();
	}
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::moveToCurrentRow() throw( SQLException, RuntimeException )
{
	Reference<XResultSetUpdate>  xUpdate;
	if (query_aggregation( m_xAggregate, xUpdate))
		xUpdate->moveToCurrentRow();
}

// com::sun::star::sdbcx::XDeleteRows
//------------------------------------------------------------------------------
Sequence<sal_Int32> SAL_CALL ODatabaseForm::deleteRows(const Sequence<Any>& rows) throw( SQLException, RuntimeException )
{
	try
	{
		Reference<XDeleteRows>  xDelete;
		if (query_aggregation( m_xAggregate, xDelete))
			return xDelete->deleteRows(rows);
	}
	catch( const RowSetVetoException& eVeto )
	{
		(void)eVeto; // make compiler happy
		throw;
	}
	catch(SQLException& eDb)
	{
		onError(eDb, FRM_RES_STRING(RID_STR_ERR_DELETERECORDS));
		throw;
	}

	return Sequence< sal_Int32 >();
}

// com::sun::star::sdbc::XParameters
//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setNull(sal_Int32 parameterIndex, sal_Int32 sqlType) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setNull(parameterIndex, sqlType);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setObjectNull(sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& typeName) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setObjectNull(parameterIndex, sqlType, typeName);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setBoolean(sal_Int32 parameterIndex, sal_Bool x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setBoolean(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setByte(sal_Int32 parameterIndex, sal_Int8 x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setByte(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setShort(sal_Int32 parameterIndex, sal_Int16 x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setShort(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setInt(sal_Int32 parameterIndex, sal_Int32 x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setInt(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setLong(sal_Int32 parameterIndex, sal_Int64 x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setLong(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setFloat(sal_Int32 parameterIndex, float x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setFloat(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setDouble(sal_Int32 parameterIndex, double x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setDouble(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setString(sal_Int32 parameterIndex, const ::rtl::OUString& x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setString(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setBytes(sal_Int32 parameterIndex, const Sequence< sal_Int8 >& x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setBytes(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setDate(sal_Int32 parameterIndex, const ::com::sun::star::util::Date& x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setDate(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setTime(sal_Int32 parameterIndex, const ::com::sun::star::util::Time& x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setTime(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setTimestamp(sal_Int32 parameterIndex, const ::com::sun::star::util::DateTime& x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setTimestamp(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setBinaryStream(sal_Int32 parameterIndex, const Reference<XInputStream>& x, sal_Int32 length) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setBinaryStream(parameterIndex, x, length);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setCharacterStream(sal_Int32 parameterIndex, const Reference<XInputStream>& x, sal_Int32 length) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setCharacterStream(parameterIndex, x, length);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setObjectWithInfo(sal_Int32 parameterIndex, const Any& x, sal_Int32 targetSqlType, sal_Int32 scale) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setObjectWithInfo(parameterIndex, x, targetSqlType, scale);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setObject(sal_Int32 parameterIndex, const Any& x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setObject(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setRef(sal_Int32 parameterIndex, const Reference<XRef>& x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setRef(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setBlob(sal_Int32 parameterIndex, const Reference<XBlob>& x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setBlob(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setClob(sal_Int32 parameterIndex, const Reference<XClob>& x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setClob(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setArray(sal_Int32 parameterIndex, const Reference<XArray>& x) throw( SQLException, RuntimeException )
{
	m_aParameterManager.setArray(parameterIndex, x);
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::clearParameters() throw( SQLException, RuntimeException )
{
	m_aParameterManager.clearParameters();
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::propertyChange( const PropertyChangeEvent& evt ) throw (RuntimeException)
{
    if ( evt.Source == m_xParent )
    {
        if ( evt.PropertyName == PROPERTY_ISNEW )
        {
            sal_Bool bCurrentIsNew( sal_False );
            OSL_VERIFY( evt.NewValue >>= bCurrentIsNew );
            if ( !bCurrentIsNew )
	            reload_impl( sal_True );
        }
        return;
    }
    OFormComponents::propertyChange( evt );
}

// com::sun::star::lang::XServiceInfo
//------------------------------------------------------------------------------
::rtl::OUString	SAL_CALL ODatabaseForm::getImplementationName_Static()
{
    return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.forms.ODatabaseForm" ) );
}

//------------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL ODatabaseForm::getCompatibleServiceNames_Static()
{
	Sequence< ::rtl::OUString > aServices( 1 );
	::rtl::OUString* pServices = aServices.getArray();

	*pServices++ = FRM_COMPONENT_FORM;

	return aServices;
}

//------------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL ODatabaseForm::getCurrentServiceNames_Static()
{
	Sequence< ::rtl::OUString > aServices( 5 );
	::rtl::OUString* pServices = aServices.getArray();

	*pServices++ = FRM_SUN_FORMCOMPONENT;
	*pServices++ = ::rtl::OUString::createFromAscii("com.sun.star.form.FormComponents");
	*pServices++ = FRM_SUN_COMPONENT_FORM;
	*pServices++ = FRM_SUN_COMPONENT_HTMLFORM;
	*pServices++ = FRM_SUN_COMPONENT_DATAFORM;

	return aServices;
}

//------------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL ODatabaseForm::getSupportedServiceNames_Static()
{
	return ::comphelper::concatSequences(
		getCurrentServiceNames_Static(),
		getCompatibleServiceNames_Static()
	);
}

//------------------------------------------------------------------------------
::rtl::OUString	SAL_CALL ODatabaseForm::getImplementationName() throw( RuntimeException )
{
	return getImplementationName_Static();
}

//------------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL ODatabaseForm::getSupportedServiceNames() throw( RuntimeException )
{
	// the services of our aggregate
	Sequence< ::rtl::OUString > aServices;
	Reference< XServiceInfo > xInfo;
	if (query_aggregation(m_xAggregate, xInfo))
		aServices = xInfo->getSupportedServiceNames();

	// concat with out own services
	return ::comphelper::concatSequences(
		getCurrentServiceNames_Static(),
		aServices
	);
	// use getCurrentXXX instead of getSupportedXXX, because at runtime, we do not want to have
	// the compatible names
	// This is maily to be consistent with the implementation before fixing #97083#, though the
	// better solution _may_ be to return the compatible names at runtime, too
	// 04.03.2002 - fs@openoffice.org
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseForm::supportsService(const ::rtl::OUString& ServiceName) throw( RuntimeException )
{
	Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() );
	const ::rtl::OUString* pArray = aSupported.getConstArray();
	for( sal_Int32 i = 0; i < aSupported.getLength(); ++i, ++pArray )
		if( pArray->equals( ServiceName ) )
			return sal_True;
	return sal_False;
}

//==============================================================================
// com::sun::star::io::XPersistObject
//------------------------------------------------------------------------------

const sal_uInt16 CYCLE				= 0x0001;
const sal_uInt16 DONTAPPLYFILTER	= 0x0002;

//------------------------------------------------------------------------------
::rtl::OUString ODatabaseForm::getServiceName() throw( RuntimeException )
{
	return FRM_COMPONENT_FORM;	// old (non-sun) name for compatibility !
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::write(const Reference<XObjectOutputStream>& _rxOutStream) throw( IOException, RuntimeException )
{
	DBG_ASSERT(m_xAggregateSet.is(), "ODatabaseForm::write : only to be called if the aggregate exists !");

	// all children
	OFormComponents::write(_rxOutStream);

	// version
	_rxOutStream->writeShort(0x0003);

	// Name
	_rxOutStream << m_sName;

	::rtl::OUString sDataSource;
	if (m_xAggregateSet.is())
		m_xAggregateSet->getPropertyValue(PROPERTY_DATASOURCE) >>= sDataSource;
	_rxOutStream << sDataSource;

	// former CursorSource
	::rtl::OUString sCommand;
	if (m_xAggregateSet.is())
		m_xAggregateSet->getPropertyValue(PROPERTY_COMMAND) >>= sCommand;
	_rxOutStream << sCommand;

	// former MasterFields
	_rxOutStream << m_aMasterFields;
	// former DetailFields
	_rxOutStream << m_aDetailFields;

	// former DataSelectionType
	DataSelectionType eTranslated = DataSelectionType_TABLE;
	if (m_xAggregateSet.is())
	{
		sal_Int32 nCommandType = 0;
		m_xAggregateSet->getPropertyValue(PROPERTY_COMMANDTYPE) >>= nCommandType;
		switch (nCommandType)
		{
			case CommandType::TABLE : eTranslated = DataSelectionType_TABLE; break;
			case CommandType::QUERY : eTranslated = DataSelectionType_QUERY; break;
			case CommandType::COMMAND:
			{
				sal_Bool bEscapeProcessing = getBOOL(m_xAggregateSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING));
				eTranslated = bEscapeProcessing ? DataSelectionType_SQL : DataSelectionType_SQLPASSTHROUGH;
			}
			break;
			default : DBG_ERROR("ODatabaseForm::write : wrong CommandType !");
		}
	}
	_rxOutStream->writeShort((sal_Int16)eTranslated);			// former DataSelectionType

	// very old versions expect a CursorType here
	_rxOutStream->writeShort(DatabaseCursorType_KEYSET);

	_rxOutStream->writeBoolean(m_eNavigation != NavigationBarMode_NONE);

	// former DataEntry
	if (m_xAggregateSet.is())
		_rxOutStream->writeBoolean(getBOOL(m_xAggregateSet->getPropertyValue(PROPERTY_INSERTONLY)));
	else
		_rxOutStream->writeBoolean(sal_False);

	_rxOutStream->writeBoolean(m_bAllowInsert);
	_rxOutStream->writeBoolean(m_bAllowUpdate);
	_rxOutStream->writeBoolean(m_bAllowDelete);

	// html form stuff
	::rtl::OUString sTmp = INetURLObject::decode( m_aTargetURL, '%', INetURLObject::DECODE_UNAMBIGUOUS);
	_rxOutStream << sTmp;
	_rxOutStream->writeShort( (sal_Int16)m_eSubmitMethod );
	_rxOutStream->writeShort( (sal_Int16)m_eSubmitEncoding );
	_rxOutStream << m_aTargetFrame;

	// version 2 didn't know some options and the "default" state
	sal_Int32 nCycle = TabulatorCycle_RECORDS;
	if (m_aCycle.hasValue())
	{
		::cppu::enum2int(nCycle, m_aCycle);
		if (m_aCycle == TabulatorCycle_PAGE)
				// unknown in earlier versions
			nCycle = TabulatorCycle_RECORDS;
	}
	_rxOutStream->writeShort((sal_Int16) nCycle);

	_rxOutStream->writeShort((sal_Int16)m_eNavigation);

	::rtl::OUString sFilter;
	::rtl::OUString sOrder;
	if (m_xAggregateSet.is())
	{
		m_xAggregateSet->getPropertyValue(PROPERTY_FILTER) >>= sFilter;
		m_xAggregateSet->getPropertyValue(PROPERTY_SORT) >>= sOrder;
	}
	_rxOutStream << sFilter;
	_rxOutStream << sOrder;


	// version 3
	sal_uInt16 nAnyMask = 0;
	if (m_aCycle.hasValue())
		nAnyMask |= CYCLE;

	if (m_xAggregateSet.is() && !getBOOL(m_xAggregateSet->getPropertyValue(PROPERTY_APPLYFILTER)))
		nAnyMask |= DONTAPPLYFILTER;

	_rxOutStream->writeShort(nAnyMask);

	if (nAnyMask & CYCLE)
	{
		sal_Int32 nRealCycle = 0;
		::cppu::enum2int(nRealCycle, m_aCycle);
		_rxOutStream->writeShort((sal_Int16)nRealCycle);
	}
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::read(const Reference<XObjectInputStream>& _rxInStream) throw( IOException, RuntimeException )
{
	DBG_ASSERT(m_xAggregateSet.is(), "ODatabaseForm::read : only to be called if the aggregate exists !");

	OFormComponents::read(_rxInStream);

	// version
	sal_uInt16 nVersion = _rxInStream->readShort();

	_rxInStream >> m_sName;

	::rtl::OUString sAggregateProp;
	_rxInStream >> sAggregateProp;
	if (m_xAggregateSet.is())
		m_xAggregateSet->setPropertyValue(PROPERTY_DATASOURCE, makeAny(sAggregateProp));
	_rxInStream >> sAggregateProp;
	if (m_xAggregateSet.is())
		m_xAggregateSet->setPropertyValue(PROPERTY_COMMAND, makeAny(sAggregateProp));

	_rxInStream >> m_aMasterFields;
	_rxInStream >> m_aDetailFields;

	sal_Int16 nCursorSourceType = _rxInStream->readShort();
	sal_Int32 nCommandType = 0;
	switch ((DataSelectionType)nCursorSourceType)
	{
		case DataSelectionType_TABLE : nCommandType = CommandType::TABLE; break;
		case DataSelectionType_QUERY : nCommandType = CommandType::QUERY; break;
		case DataSelectionType_SQL:
		case DataSelectionType_SQLPASSTHROUGH:
		{
			nCommandType = CommandType::COMMAND;
			sal_Bool bEscapeProcessing = ((DataSelectionType)nCursorSourceType) != DataSelectionType_SQLPASSTHROUGH;
			m_xAggregateSet->setPropertyValue(PROPERTY_ESCAPE_PROCESSING, makeAny((sal_Bool)bEscapeProcessing));
		}
		break;
		default : DBG_ERROR("ODatabaseForm::read : wrong CommandType !");
	}
	if (m_xAggregateSet.is())
		m_xAggregateSet->setPropertyValue(PROPERTY_COMMANDTYPE, makeAny(nCommandType));

	// obsolete
	_rxInStream->readShort();

	// navigation mode was a boolean in version 1
	// war in der version 1 ein sal_Bool
	sal_Bool bNavigation = _rxInStream->readBoolean();
	if (nVersion == 1)
		m_eNavigation = bNavigation ? NavigationBarMode_CURRENT : NavigationBarMode_NONE;

	sal_Bool bInsertOnly = _rxInStream->readBoolean();
	if (m_xAggregateSet.is())
		m_xAggregateSet->setPropertyValue(PROPERTY_INSERTONLY, makeAny(bInsertOnly));

	m_bAllowInsert		= _rxInStream->readBoolean();
	m_bAllowUpdate		= _rxInStream->readBoolean();
	m_bAllowDelete		= _rxInStream->readBoolean();

	// html stuff
	::rtl::OUString sTmp;
	_rxInStream >> sTmp;
	m_aTargetURL = INetURLObject::decode( sTmp, '%', INetURLObject::DECODE_UNAMBIGUOUS);
	m_eSubmitMethod		= (FormSubmitMethod)_rxInStream->readShort();
	m_eSubmitEncoding		= (FormSubmitEncoding)_rxInStream->readShort();
	_rxInStream >> m_aTargetFrame;

	if (nVersion > 1)
	{
		sal_Int32 nCycle = _rxInStream->readShort();
		m_aCycle = ::cppu::int2enum(nCycle, ::getCppuType(static_cast<const TabulatorCycle*>(NULL)));
		m_eNavigation = (NavigationBarMode)_rxInStream->readShort();

		_rxInStream >> sAggregateProp;
		setPropertyValue(PROPERTY_FILTER, makeAny(sAggregateProp));

		_rxInStream >> sAggregateProp;
		if (m_xAggregateSet.is())
			m_xAggregateSet->setPropertyValue(PROPERTY_SORT, makeAny(sAggregateProp));
	}

	sal_uInt16 nAnyMask	= 0;
	if (nVersion > 2)
	{
		nAnyMask = _rxInStream->readShort();
		if (nAnyMask & CYCLE)
		{
			sal_Int32 nCycle = _rxInStream->readShort();
			m_aCycle = ::cppu::int2enum(nCycle, ::getCppuType(static_cast<const TabulatorCycle*>(NULL)));
		}
		else
			m_aCycle.clear();
	}
	if (m_xAggregateSet.is())
		m_xAggregateSet->setPropertyValue(PROPERTY_APPLYFILTER, makeAny((sal_Bool)((nAnyMask & DONTAPPLYFILTER) == 0)));
}

//------------------------------------------------------------------------------
void ODatabaseForm::implInserted( const ElementDescription* _pElement )
{
	OFormComponents::implInserted( _pElement );

	Reference< XSQLErrorBroadcaster >	xBroadcaster( _pElement->xInterface, UNO_QUERY );
	Reference< XForm >					xForm		( _pElement->xInterface, UNO_QUERY );

	if ( xBroadcaster.is() && !xForm.is() )
	{	// the object is an error broadcaster, but no form itself -> add ourself as listener
		xBroadcaster->addSQLErrorListener( this );
	}
}

//------------------------------------------------------------------------------
void ODatabaseForm::implRemoved(const InterfaceRef& _rxObject)
{
	OFormComponents::implRemoved( _rxObject );

	Reference<XSQLErrorBroadcaster>  xBroadcaster(_rxObject, UNO_QUERY);
	Reference<XForm>  xForm(_rxObject, UNO_QUERY);
	if (xBroadcaster.is() && !xForm.is())
	{	// the object is an error broadcaster, but no form itself -> remove ourself as listener
		xBroadcaster->removeSQLErrorListener(this);
	}
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::errorOccured(const SQLErrorEvent& _rEvent) throw( RuntimeException )
{
	// give it to my own error listener
	onError(_rEvent);
	// TODO : think about extending the chain with an SQLContext object saying
	// "this was an error of one of my children"
}

// com::sun::star::container::XNamed
//------------------------------------------------------------------------------
::rtl::OUString SAL_CALL ODatabaseForm::getName() throw( RuntimeException )
{
	::rtl::OUString sReturn;
	OPropertySetHelper::getFastPropertyValue(PROPERTY_ID_NAME) >>= sReturn;
	return sReturn;
}

//------------------------------------------------------------------------------
void SAL_CALL ODatabaseForm::setName(const ::rtl::OUString& aName) throw( RuntimeException )
{
	setFastPropertyValue(PROPERTY_ID_NAME, makeAny(aName));
}

//.........................................................................
}	// namespace frm
//.........................................................................

