/**************************************************************
 *
 * 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 "frm_resource.hrc"
#include "frm_resource.hxx"
#include "InterfaceContainer.hxx"
#include "componenttools.hxx"
#include "property.hrc"
#include "services.hxx"

#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/io/WrongFormatException.hpp>
#include <com/sun/star/io/XMarkableStream.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/util/XCloneable.hpp>
#include <com/sun/star/form/XForm.hpp>

#include <comphelper/container.hxx>
#include <comphelper/enumhelper.hxx>
#include <comphelper/eventattachermgr.hxx>
#include <comphelper/property.hxx>
#include <comphelper/sequence.hxx>
#include <comphelper/types.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <cppuhelper/queryinterface.hxx>
#include <rtl/logfile.hxx>
#include <tools/debug.hxx>
#include <tools/diagnose_ex.h>

#include <algorithm>
#include <memory>

//.........................................................................
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/document/XCodeNameQuery.hpp>
#include <ooo/vba/XVBAToOOEventDescGen.hpp>
#include <comphelper/processfactory.hxx>

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

using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::document;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::script;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::form;
using namespace ::com::sun::star::util;

namespace
{
	//---------------------------------------------------------------------
	static void lcl_throwIllegalArgumentException()
	{
		throw IllegalArgumentException();
	}
}

bool
lcl_hasVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents  )
{
	const ScriptEventDescriptor* pDesc = sEvents.getConstArray();
	const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() );
	for ( ; pDesc != pEnd; ++pDesc )
	{
		if ( pDesc->ScriptType.equals( rtl::OUString::createFromAscii( "VBAInterop" ) ) )
			return true;
	}
	return false;
}

Sequence< ScriptEventDescriptor >
lcl_stripVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents )
{
	Sequence< ScriptEventDescriptor > sStripped( sEvents.getLength() );

	const ScriptEventDescriptor* pDesc = sEvents.getConstArray();
	const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() );
	sal_Int32 nCopied = 0;
	for ( ; pDesc != pEnd; ++pDesc )
	{
		if ( !pDesc->ScriptType.equals( rtl::OUString::createFromAscii( "VBAInterop" ) ) )
		{
			sStripped[ nCopied++ ] = *pDesc;
		}
	}
	if ( nCopied )
		sStripped.realloc( nCopied );
	return sStripped;
}

void OInterfaceContainer::impl_addVbEvents_nolck_nothrow(  const sal_Int32 i_nIndex )
{
	// we are dealing with form controls
	try
	{
        do
        {
            Reference< XModel > xDoc( getXModel( static_cast< XContainer *> ( this ) ) );
		    if ( !xDoc.is() )
                break;

            Reference< XMultiServiceFactory > xDocFac( xDoc, UNO_QUERY_THROW );
            Reference< XCodeNameQuery > xNameQuery( xDocFac->createInstance( rtl::OUString::createFromAscii( "ooo.vba.VBACodeNameProvider" ) ), UNO_QUERY );
            if ( !xNameQuery.is() )
                break;

            ::osl::MutexGuard aGuard( m_rMutex );
            bool hasVBABindings = lcl_hasVbaEvents( m_xEventAttacher->getScriptEvents( i_nIndex ) );
			if ( hasVBABindings )
				break;

            Reference< XInterface > xElement( getByIndex( i_nIndex ) , UNO_QUERY_THROW );
            Reference< XForm > xElementAsForm( xElement, UNO_QUERY );
            if ( xElementAsForm.is() )
                break;

            ::rtl::OUString sCodeName( xNameQuery->getCodeNameForObject( xElement ) );

            Reference< XPropertySet > xProps( xElement, UNO_QUERY_THROW );
			::rtl::OUString sServiceName;
			xProps->getPropertyValue( rtl::OUString::createFromAscii("DefaultControl" ) ) >>= sServiceName;

			Reference< ooo::vba::XVBAToOOEventDescGen > xDescSupplier( m_xServiceFactory->createInstance( rtl::OUString::createFromAscii( "ooo.vba.VBAToOOEventDesc" ) ), UNO_QUERY_THROW );
			Sequence< ScriptEventDescriptor > vbaEvents = xDescSupplier->getEventDescriptions( m_xServiceFactory->createInstance( sServiceName ), sCodeName );
			// register the vba script events
			m_xEventAttacher->registerScriptEvents( i_nIndex, vbaEvents );
		}
        while ( false );
	}
    catch ( const ServiceNotRegisteredException& )
    {
        // silence this, not all document types support the ooo.vba.VBACodeNameProvider service
    }
	catch( const Exception& )
	{
        DBG_UNHANDLED_EXCEPTION();
	}

}
//==================================================================
//= ElementDescription
//==================================================================
//------------------------------------------------------------------
ElementDescription::ElementDescription( )
{
}

//------------------------------------------------------------------
ElementDescription::~ElementDescription()
{
}

//==================================================================
//= OInterfaceContainer
//==================================================================
//------------------------------------------------------------------
OInterfaceContainer::OInterfaceContainer(
				const Reference<XMultiServiceFactory>& _rxFactory,
				::osl::Mutex& _rMutex,
				const Type& _rElementType)
    :OInterfaceContainer_BASE()
    ,m_rMutex(_rMutex)
    ,m_aContainerListeners(_rMutex)
    ,m_aElementType(_rElementType)
    ,m_xServiceFactory(_rxFactory)
{
    impl_createEventAttacher_nothrow();
}

//------------------------------------------------------------------------------
OInterfaceContainer::OInterfaceContainer( ::osl::Mutex& _rMutex, const OInterfaceContainer& _cloneSource )
    :OInterfaceContainer_BASE()
    ,m_rMutex( _rMutex )
    ,m_aContainerListeners( _rMutex )
    ,m_aElementType( _cloneSource.m_aElementType )
    ,m_xServiceFactory( _cloneSource.m_xServiceFactory )
{
    impl_createEventAttacher_nothrow();
}

//------------------------------------------------------------------------------
void OInterfaceContainer::clonedFrom( const OInterfaceContainer& _cloneSource )
{
    try
    {
        const Reference< XIndexAccess > xSourceHierarchy( const_cast< OInterfaceContainer* >( &_cloneSource ) );
        const sal_Int32 nCount = xSourceHierarchy->getCount();
        for ( sal_Int32 i=0; i<nCount; ++i )
        {
            Reference< XCloneable > xCloneable( xSourceHierarchy->getByIndex( i ), UNO_QUERY_THROW );
            Reference< XInterface > xClone( xCloneable->createClone() );
            insertByIndex( i, makeAny( xClone ) );
        }
    }
    catch( const Exception& )
    {
        throw WrappedTargetException(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not clone the given interface hierarchy." ) ),
            static_cast< XIndexContainer* >( const_cast< OInterfaceContainer* >( &_cloneSource ) ),
            ::cppu::getCaughtException()
        );
    }
}

//------------------------------------------------------------------------------
void OInterfaceContainer::impl_createEventAttacher_nothrow()
{
    try
    {
	    m_xEventAttacher.set( ::comphelper::createEventAttacherManager( m_xServiceFactory ), UNO_SET_THROW );
    }
    catch( const Exception& )
    {
        DBG_UNHANDLED_EXCEPTION();
    }
}

//------------------------------------------------------------------------------
OInterfaceContainer::~OInterfaceContainer()
{
}

//------------------------------------------------------------------------------
void OInterfaceContainer::disposing()
{
	// dispose all elements
	for (sal_Int32 i = m_aItems.size(); i > 0; --i)
	{
		Reference<XPropertySet>  xSet(m_aItems[i - 1], UNO_QUERY);
		if (xSet.is())
			xSet->removePropertyChangeListener(PROPERTY_NAME, this);

		// revoke event knittings
        if ( m_xEventAttacher.is() )
        {
    		Reference< XInterface > xIfc( xSet, UNO_QUERY );
	    	m_xEventAttacher->detach( i - 1, xIfc );
		    m_xEventAttacher->removeEntry( i - 1 );
        }

		Reference<XComponent>  xComponent(xSet, UNO_QUERY);
		if (xComponent.is())
			xComponent->dispose();
	}
	m_aMap.clear();
	m_aItems.clear();

	EventObject aEvt(static_cast<XContainer*>(this));
	m_aContainerListeners.disposeAndClear(aEvt);
}

// XPersistObject
//------------------------------------------------------------------------------
namespace
{
	//..........................................................................
	void lcl_saveEvents( ::std::vector< Sequence< ScriptEventDescriptor > >& _rSave,
		const Reference< XEventAttacherManager >& _rxManager, const sal_Int32 _nItemCount )
	{
        OSL_ENSURE( _rxManager.is(), "lcl_saveEvents: invalid event attacher manager!" );
        if ( !_rxManager.is() )
            return;

		// reserve the space needed
		_rSave.reserve( _nItemCount );

		// copy the events
        for (sal_Int32 i=0; i<_nItemCount; ++i)
            _rSave.push_back(_rxManager->getScriptEvents( i ));
	}

	//..........................................................................
	void lcl_restoreEvents( const ::std::vector< Sequence< ScriptEventDescriptor > >& _rSave,
		const Reference< XEventAttacherManager >& _rxManager )
	{
        OSL_ENSURE( _rxManager.is(), "lcl_restoreEvents: invalid event attacher manager!" );
        if ( !_rxManager.is() )
            return;

		::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aLoop = _rSave.begin();
		::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aEnd = _rSave.end();
		for ( sal_Int32 i=0; aLoop != aEnd; ++aLoop, ++i )
		{
			_rxManager->revokeScriptEvents( i );
			_rxManager->registerScriptEvents( i, *aLoop );
		}
	}
}

//------------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::writeEvents(const Reference<XObjectOutputStream>& _rxOutStream)
{
	// We're writing a document in SO 5.2 format (or even from earlier versions)
	// -> convert the events from the new runtime format to the format of the 5.2 files
	// but before, remember the current script events set for our children
	::std::vector< Sequence< ScriptEventDescriptor > > aSave;
    if ( m_xEventAttacher.is() )
	    lcl_saveEvents( aSave, m_xEventAttacher, m_aItems.size() );

    transformEvents( efVersionSO5x );

	try
	{
		Reference<XMarkableStream>  xMark(_rxOutStream, UNO_QUERY);
		sal_Int32 nMark = xMark->createMark();

		sal_Int32 nObjLen = 0;
		_rxOutStream->writeLong(nObjLen);

		Reference<XPersistObject>  xScripts(m_xEventAttacher, UNO_QUERY);
		if (xScripts.is())
			xScripts->write(_rxOutStream);

		// feststellen der Laenge
		nObjLen = xMark->offsetToMark(nMark) - 4;
		xMark->jumpToMark(nMark);
		_rxOutStream->writeLong(nObjLen);
		xMark->jumpToFurthest();
		xMark->deleteMark(nMark);
	}
	catch( const Exception& )
	{
		// restore the events
        if ( m_xEventAttacher.is() )
		    lcl_restoreEvents( aSave, m_xEventAttacher );
		throw;
	}

	// restore the events
    if ( m_xEventAttacher.is() )
    	lcl_restoreEvents( aSave, m_xEventAttacher );
}

//------------------------------------------------------------------------------
struct TransformEventTo52Format : public ::std::unary_function< ScriptEventDescriptor, void >
{
	void operator()( ScriptEventDescriptor& _rDescriptor )
	{
		if ( 0 == _rDescriptor.ScriptType.compareToAscii( "StarBasic" ) )
		{	// it's a starbasic macro
			sal_Int32 nPrefixLength = _rDescriptor.ScriptCode.indexOf( ':' );
			if ( 0 <= nPrefixLength )
			{	// the macro name does not already contain a :
#ifdef DBG_UTIL
				const ::rtl::OUString sPrefix = _rDescriptor.ScriptCode.copy( 0, nPrefixLength );
				DBG_ASSERT(	0 == sPrefix.compareToAscii( "document" )
						||	0 == sPrefix.compareToAscii( "application" ),
						"TransformEventTo52Format: invalid (unknown) prefix!" );
#endif
				// cut the prefix
				_rDescriptor.ScriptCode = _rDescriptor.ScriptCode.copy( nPrefixLength + 1 );
			}
		}
	}
};

//------------------------------------------------------------------------------
struct TransformEventTo60Format : public ::std::unary_function< ScriptEventDescriptor, void >
{
	void operator()( ScriptEventDescriptor& _rDescriptor )
	{
		if ( 0 == _rDescriptor.ScriptType.compareToAscii( "StarBasic" ) )
		{	// it's a starbasic macro
			if ( _rDescriptor.ScriptCode.indexOf( ':' ) < 0 )
			{	// the macro name does not already contain a :
				// -> default the type to "document"
				::rtl::OUString sNewScriptCode( RTL_CONSTASCII_USTRINGPARAM( "document:" ) );
				sNewScriptCode += _rDescriptor.ScriptCode;
				_rDescriptor.ScriptCode = sNewScriptCode;
			}
		}
	}
};

//------------------------------------------------------------------------------
void OInterfaceContainer::transformEvents( const EventFormat _eTargetFormat )
{
    OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::transformEvents: no event attacher manager!" );
    if ( !m_xEventAttacher.is() )
        return;

    try
	{
		// loop through all our children
		sal_Int32 nItems = m_aItems.size();
		Sequence< ScriptEventDescriptor > aChildEvents;

		for (sal_Int32 i=0; i<nItems; ++i)
		{
			// get the script events for this object
			aChildEvents = m_xEventAttacher->getScriptEvents( i );

			if ( aChildEvents.getLength() )
			{
				// the "iterators" for the events for this child
				ScriptEventDescriptor* pChildEvents		=						aChildEvents.getArray();
				ScriptEventDescriptor* pChildEventsEnd	=	pChildEvents	+	aChildEvents.getLength();

				// do the transformation
				if ( efVersionSO6x == _eTargetFormat )
					::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo60Format() );
				else
					::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo52Format() );

				// revoke the script events
				m_xEventAttacher->revokeScriptEvents( i );
				// and re-register them
				m_xEventAttacher->registerScriptEvents( i, aChildEvents );
			}
		}
	}
	catch( const Exception& )
	{
		DBG_UNHANDLED_EXCEPTION();
	}
}

//------------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::readEvents(const Reference<XObjectInputStream>& _rxInStream)
{
	::osl::MutexGuard aGuard( m_rMutex );

	// Scripting Info lesen
	Reference<XMarkableStream>  xMark(_rxInStream, UNO_QUERY);
	sal_Int32 nObjLen = _rxInStream->readLong();
	if (nObjLen)
	{
		sal_Int32 nMark = xMark->createMark();
		Reference<XPersistObject>  xObj(m_xEventAttacher, UNO_QUERY);
		if (xObj.is())
			xObj->read(_rxInStream);
		xMark->jumpToMark(nMark);
		_rxInStream->skipBytes(nObjLen);
		xMark->deleteMark(nMark);
	}

	// Attachement lesen
    if ( m_xEventAttacher.is() )
    {
	    OInterfaceArray::const_iterator aAttach = m_aItems.begin();
	    OInterfaceArray::const_iterator aAttachEnd = m_aItems.end();
	    for ( sal_Int32 i=0; aAttach != aAttachEnd; ++aAttach, ++i )
	    {
		    Reference< XInterface > xAsIFace( *aAttach, UNO_QUERY );	// important to normalize this ....
		    Reference< XPropertySet > xAsSet( xAsIFace, UNO_QUERY );
		    m_xEventAttacher->attach( i, xAsIFace, makeAny( xAsSet ) );
	    }
    }
}

//------------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::write( const Reference< XObjectOutputStream >& _rxOutStream ) throw(IOException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_rMutex );
	sal_Int32 nLen = m_aItems.size();

	// schreiben der laenge
	_rxOutStream->writeLong(nLen);

	if (nLen)
	{
		// 1. Version
		_rxOutStream->writeShort(0x0001);

		// 2. Objekte
		for (sal_Int32 i = 0; i < nLen; i++)
		{
			Reference<XPersistObject>  xObj(m_aItems[i], UNO_QUERY);
			if (xObj.is())
				_rxOutStream->writeObject(xObj);
			else
			{
				// ::com::sun::star::chaos::Error
			}
		}

		// 3. Scripts
		writeEvents(_rxOutStream);
	}
}

//------------------------------------------------------------------------------
namespace
{
	Reference< XPersistObject > lcl_createPlaceHolder( const Reference< XMultiServiceFactory >& _rxORB )
	{
		Reference< XPersistObject > xObject( _rxORB->createInstance( FRM_COMPONENT_HIDDENCONTROL ), UNO_QUERY );
		DBG_ASSERT( xObject.is(), "lcl_createPlaceHolder: could not create a substitute for the unknown object!" );
		if ( xObject.is() )
		{
			// set some properties describing what we did
			Reference< XPropertySet > xObjProps( xObject, UNO_QUERY );
			if ( xObject.is()  )
			{
				try
				{
					xObjProps->setPropertyValue( PROPERTY_NAME, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_NAME ) ) );
					xObjProps->setPropertyValue( PROPERTY_TAG, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_EPXPLAIN ) ) );
				}
				catch(Exception&)
				{
				}
			}
		}
		return xObject;
	}
}

//------------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::read( const Reference< XObjectInputStream >& _rxInStream ) throw(IOException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_rMutex );

	// after ::read the object is expected to be in the state it was when ::write was called, so we have
	// to empty ourself here
	// FS - 71598 - 12.01.00
	while (getCount())
		removeByIndex(0);

    // Schreibt nur in Abhaengigkeit der Laenge
	sal_Int32 nLen = _rxInStream->readLong();

	if (nLen)
	{
		// 1. Version
		sal_uInt16 nVersion = _rxInStream->readShort(); (void)nVersion;

		// 2. Objekte
		for (sal_Int32 i = 0; i < nLen; i++)
		{
			Reference<XPersistObject>  xObj;
			try
			{
				xObj = _rxInStream->readObject();
			}
			catch(WrongFormatException& e)
			{
				(void)e;    // make compiler happy
				// the object could not be read
				// create a object (so the readEvents below will assign the events to the right controls)
				xObj = lcl_createPlaceHolder( m_xServiceFactory );
				if ( !xObj.is() )
					// couldn't handle it
					throw;
				// 72133 - 09.02.00 - FS
			}
			catch(Exception&)
			{
				// unsere Map leeren
				while (!m_aItems.empty())
					removeElementsNoEvents(0);

				// und die Exception nach aussen
				throw;
			}

			if ( xObj.is() )
			{
				Reference< XPropertySet > xElement( xObj, UNO_QUERY );
				try
				{
					implInsert(
						m_aItems.size(),	// position
						xElement,			// element to insert
						sal_False,			// no event attacher manager handling
						NULL,				// not yet approved - let implInsert do it
						sal_True			// fire the event
					);
				}
				catch( const Exception& )
				{
					DBG_ERROR( "OInterfaceContainerHelper::read: reading succeeded, but not inserting!" );
					// create a placeholder
					xElement = xElement.query( lcl_createPlaceHolder( m_xServiceFactory ) );
					if ( !xElement.is() )
						// couldn't handle it
						throw;
					// insert the placeholder
					implInsert( m_aItems.size(), xElement, sal_False, NULL, sal_True );
				}
			}
		}

		readEvents(_rxInStream);
	}
	else
    {
        try
        {
		    m_xEventAttacher = ::comphelper::createEventAttacherManager( m_xServiceFactory );
            OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::read: could not create an event attacher manager!" );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }
}

// XContainer
//------------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::addContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException )
{
	m_aContainerListeners.addInterface(_rxListener);
}

//------------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::removeContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException )
{
	m_aContainerListeners.removeInterface(_rxListener);
}

// XEventListener
//------------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::disposing(const EventObject& _rSource) throw( RuntimeException )
{
	::osl::MutexGuard aGuard( m_rMutex );

	Reference< XInterface > xSource( _rSource.Source, UNO_QUERY );
		// normalized source

	OInterfaceArray::iterator j;
	for ( j = m_aItems.begin(); j != m_aItems.end(); ++j )
	{
		DBG_ASSERT( j->get() == Reference< XInterface >( *j, UNO_QUERY ).get(),
			"OInterfaceContainer::disposing: vector element not normalized!" );

		if ( xSource.get() == j->get() )
			// found the element
			break;
	}

	if ( m_aItems.end() != j )
	{
        m_aItems.erase(j);

        // look up in, and erase from, m_aMap, too
		OInterfaceMap::iterator i = m_aMap.begin();
		while ( i != m_aMap.end() )
		{
			DBG_ASSERT( i->second.get() == Reference< XInterface >( i->second, UNO_QUERY ).get(),
				"OInterfaceContainer::disposing: map element not normalized!" );

			if ( i->second.get() == xSource.get() )
            {
				// found it
                m_aMap.erase(i);
				break;
            }

			++i;

            DBG_ASSERT( i != m_aMap.end(), "OInterfaceContainer::disposing: inconsistency: the element was in m_aItems, but not in m_aMap!" );
		}
	}
}

// XPropertyChangeListener
//------------------------------------------------------------------------------
void OInterfaceContainer::propertyChange(const PropertyChangeEvent& evt)
throw (::com::sun::star::uno::RuntimeException) {
	if (evt.PropertyName == PROPERTY_NAME)
	{
		::osl::MutexGuard aGuard( m_rMutex );
		OInterfaceMap::iterator i = ::std::find(m_aMap.begin(), m_aMap.end(),
			::std::pair<const ::rtl::OUString, InterfaceRef >(::comphelper::getString(evt.OldValue),evt.Source));
		if (i != m_aMap.end())
		{
			InterfaceRef  xCorrectType((*i).second);
			m_aMap.erase(i);
			m_aMap.insert(::std::pair<const ::rtl::OUString, InterfaceRef >(::comphelper::getString(evt.NewValue),xCorrectType));
		}
	}
}

// XElementAccess
//------------------------------------------------------------------------------
sal_Bool SAL_CALL OInterfaceContainer::hasElements() throw( RuntimeException )
{
	return !m_aMap.empty();
}

//------------------------------------------------------------------------------
Type SAL_CALL OInterfaceContainer::getElementType() throw(RuntimeException)
{
	return m_aElementType;
}

// XEnumerationAccess
//------------------------------------------------------------------------------
Reference<XEnumeration> SAL_CALL OInterfaceContainer::createEnumeration() throw( RuntimeException )
{
	::osl::MutexGuard aGuard( m_rMutex );
	return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this));
}

// XNameAccess
//------------------------------------------------------------------------------
Any SAL_CALL OInterfaceContainer::getByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
{
	::std::pair <OInterfaceMap::iterator,
		  OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);

	if (aPair.first == aPair.second)
		throw NoSuchElementException();

	return (*aPair.first).second->queryInterface( m_aElementType );
}

//------------------------------------------------------------------------------
StringSequence SAL_CALL OInterfaceContainer::getElementNames() throw(RuntimeException)
{
	StringSequence aNameList(m_aItems.size());
	::rtl::OUString* pStringArray = aNameList.getArray();

	for (OInterfaceMap::const_iterator i = m_aMap.begin(); i != m_aMap.end(); ++i, ++pStringArray)
	{
		*pStringArray = (*i).first;
	}
	return aNameList;
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL OInterfaceContainer::hasByName( const ::rtl::OUString& _rName ) throw(RuntimeException)
{
	::std::pair <OInterfaceMap::iterator,
		  OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
	return aPair.first != aPair.second;
}

// XIndexAccess
//------------------------------------------------------------------------------
sal_Int32 OInterfaceContainer::getCount() throw( RuntimeException )
{
	return m_aItems.size();
}

//------------------------------------------------------------------------------
Any OInterfaceContainer::getByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
{
	if (_nIndex < 0 || (_nIndex >= (sal_Int32)m_aItems.size()))
		throw IndexOutOfBoundsException();

	return m_aItems[_nIndex]->queryInterface( m_aElementType );
}

//------------------------------------------------------------------------------
void OInterfaceContainer::approveNewElement( const Reference< XPropertySet >& _rxObject, ElementDescription* _pElement )
{
	// it has to be non-NULL
	if ( !_rxObject.is() )
		throw IllegalArgumentException(FRM_RES_STRING(RID_STR_NEED_NON_NULL_OBJECT), static_cast<XContainer*>(this), 1);

	// it has to support our element type interface
	Any aCorrectType = _rxObject->queryInterface( m_aElementType );
	if ( !aCorrectType.hasValue() )
		lcl_throwIllegalArgumentException();

	// it has to have a "Name" property
	if ( !hasProperty( PROPERTY_NAME, _rxObject ) )
		lcl_throwIllegalArgumentException();

	// it has to be a child, and it must not have a parent already
	Reference< XChild > xChild( _rxObject, UNO_QUERY );
	if ( !xChild.is() || xChild->getParent().is() )
	{
#ifdef FS_PRIV_DEBUG
		::rtl::OUString sChildName, sParentName;
		Reference< XNamed > xNamed( xChild, UNO_QUERY );
		if ( xNamed.is() )
			sChildName = xNamed->getName();
		if ( xChild.is() )
		{
			xNamed = xNamed.query( xChild->getParent() );
			if ( xNamed.is() )
				sParentName = xNamed->getName();
		}
#endif
		lcl_throwIllegalArgumentException();
	}

	// passed all tests. cache the information we have so far
	DBG_ASSERT( _pElement, "OInterfaceContainer::approveNewElement: invalid event descriptor!" );
	if ( _pElement )
	{
		_pElement->xPropertySet = _rxObject;
		_pElement->xChild = xChild;
		_pElement->aElementTypeInterface = aCorrectType;
		_pElement->xInterface = Reference< XInterface >( _rxObject, UNO_QUERY );	// normalized XInterface
	}
}

//------------------------------------------------------------------------------
void OInterfaceContainer::implInsert(sal_Int32 _nIndex, const Reference< XPropertySet >& _rxElement,
	sal_Bool _bEvents, ElementDescription* _pApprovalResult, sal_Bool _bFire ) throw( IllegalArgumentException )
{
    const bool bHandleEvents = _bEvents && m_xEventAttacher.is();

    // SYNCHRONIZED ----->
	::osl::ClearableMutexGuard aGuard( m_rMutex );

	::std::auto_ptr< ElementDescription > aAutoDeleteMetaData;
	ElementDescription* pElementMetaData = _pApprovalResult;
	if ( !pElementMetaData )
	{	// not yet approved by the caller -> do ourself
		pElementMetaData = createElementMetaData();
		DBG_ASSERT( pElementMetaData, "OInterfaceContainer::implInsert: createElementMetaData returned nonsense!" );

		// ensure that the meta data structure will be deleted later on
		aAutoDeleteMetaData = ::std::auto_ptr< ElementDescription >( pElementMetaData );

		// will throw an exception if necessary
		approveNewElement( _rxElement, pElementMetaData );
	}


	// approveNewElement (no matter if called here or outside) has ensure that all relevant interfaces
	// exist

	// set the name, and add as change listener for the name
	::rtl::OUString sName;
	_rxElement->getPropertyValue(PROPERTY_NAME) >>= sName;
	_rxElement->addPropertyChangeListener(PROPERTY_NAME, this);

	// insert the object into our internal structures
	if (_nIndex > (sal_Int32)m_aItems.size()) // ermitteln des tatsaechlichen Indexs
	{
		_nIndex = m_aItems.size();
		m_aItems.push_back( pElementMetaData->xInterface );
	}
	else
		m_aItems.insert( m_aItems.begin() + _nIndex, pElementMetaData->xInterface );

	m_aMap.insert( ::std::pair< const ::rtl::OUString, InterfaceRef >( sName, pElementMetaData->xInterface ) );

	// announce ourself as parent to the new element
	pElementMetaData->xChild->setParent(static_cast<XContainer*>(this));

	// handle the events
	if ( bHandleEvents )
	{
		m_xEventAttacher->insertEntry(_nIndex);
		m_xEventAttacher->attach( _nIndex, pElementMetaData->xInterface, makeAny( _rxElement ) );
	}

	// notify derived classes
	implInserted( pElementMetaData );

    aGuard.clear();
    // <----- SYNCHRONIZED

	// insert faked VBA events?
	if ( bHandleEvents )
	{
	    Reference< XEventAttacherManager > xMgr ( pElementMetaData->xInterface, UNO_QUERY );
	    if ( xMgr.is() )
	    {
		    OInterfaceContainer* pIfcMgr = dynamic_cast< OInterfaceContainer* >( xMgr.get() );
		    sal_Int32 nLen = pIfcMgr->getCount();
		    for ( sal_Int32 i = 0; (i < nLen) && pIfcMgr ; ++i )
		    {
			    // add fake events to the control at index i
			    pIfcMgr->impl_addVbEvents_nolck_nothrow( i );
		    }
	    }
	    else
	    {
		    // add fake events to the control at index i
		    impl_addVbEvents_nolck_nothrow( _nIndex );
	    }
    }

	// fire the notification about the change
	if ( _bFire )
	{
		// notify listeners
		ContainerEvent aEvt;
		aEvt.Source   = static_cast<XContainer*>(this);
		aEvt.Accessor <<= _nIndex;
		aEvt.Element  = pElementMetaData->aElementTypeInterface;

		aGuard.clear();
        m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvt );
	}
}

//------------------------------------------------------------------------------
void OInterfaceContainer::removeElementsNoEvents(sal_Int32 nIndex)
{
	OInterfaceArray::iterator i = m_aItems.begin() + nIndex;
	InterfaceRef  xElement(*i);

	OInterfaceMap::iterator j = m_aMap.begin();
	while (j != m_aMap.end() && (*j).second != xElement) ++j;

	m_aItems.erase(i);
	m_aMap.erase(j);

	Reference<XPropertySet>  xSet(xElement, UNO_QUERY);
	if (xSet.is())
		xSet->removePropertyChangeListener(PROPERTY_NAME, this);

	Reference<XChild>  xChild(xElement, UNO_QUERY);
	if (xChild.is())
		xChild->setParent(InterfaceRef ());
}

//------------------------------------------------------------------------------
void OInterfaceContainer::implInserted( const ElementDescription* /*_pElement*/ )
{
    // not inrerested in
}

//------------------------------------------------------------------------------
void OInterfaceContainer::implRemoved( const InterfaceRef& /*_rxObject*/ )
{
    // not inrerested in
}

//------------------------------------------------------------------------------
void OInterfaceContainer::impl_replacedElement( const ContainerEvent& _rEvent, ::osl::ClearableMutexGuard& _rInstanceLock )
{
    _rInstanceLock.clear();
    m_aContainerListeners.notifyEach( &XContainerListener::elementReplaced, _rEvent );
}

// XIndexContainer
//------------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::insertByIndex( sal_Int32 _nIndex, const Any& _rElement ) throw(IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
{
	Reference< XPropertySet > xElement;
	_rElement >>= xElement;
	implInsert( _nIndex, xElement, sal_True /* event handling */ , NULL /* not yet approved */ , sal_True /* notification */ );
}

//------------------------------------------------------------------------------
void OInterfaceContainer::implReplaceByIndex( const sal_Int32 _nIndex, const Any& _rNewElement, ::osl::ClearableMutexGuard& _rClearBeforeNotify )
{
	OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implReplaceByIndex: precondition not met (index)!" );

	// approve the new object
	::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
	DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::implReplaceByIndex: createElementMetaData returned nonsense!" );
	{
		Reference< XPropertySet > xElementProps;
		_rNewElement >>= xElementProps;
		approveNewElement( xElementProps, aElementMetaData.get() );
	}

	// get the old element
	InterfaceRef  xOldElement( m_aItems[ _nIndex ] );
	DBG_ASSERT( xOldElement.get() == Reference< XInterface >( xOldElement, UNO_QUERY ).get(),
		"OInterfaceContainer::implReplaceByIndex: elements should be held normalized!" );

	// locate the old element in the map
	OInterfaceMap::iterator j = m_aMap.begin();
	while ( ( j != m_aMap.end() ) && ( j->second.get() != xOldElement.get() ) )
		++j;

	// remove event knittings
    if ( m_xEventAttacher.is() )
    {
    	InterfaceRef xNormalized( xOldElement, UNO_QUERY );
	    m_xEventAttacher->detach( _nIndex, xNormalized );
	    m_xEventAttacher->removeEntry( _nIndex );
    }

	// don't listen for property changes anymore
	Reference<XPropertySet>  xSet( xOldElement, UNO_QUERY );
	if (xSet.is())
		xSet->removePropertyChangeListener(PROPERTY_NAME, this);

	// give the old element a new (void) parent
	Reference<XChild>  xChild(xOldElement, UNO_QUERY);
	if (xChild.is())
		xChild->setParent(InterfaceRef ());

	// remove the old one
	m_aMap.erase(j);

	// examine the new element
	::rtl::OUString sName;
	DBG_ASSERT( aElementMetaData.get()->xPropertySet.is(), "OInterfaceContainer::implReplaceByIndex: what did approveNewElement do?" );

	aElementMetaData.get()->xPropertySet->getPropertyValue(PROPERTY_NAME) >>= sName;
	aElementMetaData.get()->xPropertySet->addPropertyChangeListener(PROPERTY_NAME, this);

	// insert the new one
	m_aMap.insert( ::std::pair<const ::rtl::OUString, InterfaceRef  >( sName, aElementMetaData.get()->xInterface ) );
	m_aItems[ _nIndex ] = aElementMetaData.get()->xInterface;

	aElementMetaData.get()->xChild->setParent(static_cast<XContainer*>(this));

    if ( m_xEventAttacher.is() )
    {
	    m_xEventAttacher->insertEntry( _nIndex );
	    m_xEventAttacher->attach( _nIndex, aElementMetaData.get()->xInterface, makeAny( aElementMetaData.get()->xPropertySet ) );
    }

	ContainerEvent aReplaceEvent;
	aReplaceEvent.Source   = static_cast< XContainer* >( this );
	aReplaceEvent.Accessor <<= _nIndex;
	aReplaceEvent.Element  = aElementMetaData.get()->xInterface->queryInterface( m_aElementType );
	aReplaceEvent.ReplacedElement = xOldElement->queryInterface( m_aElementType );

	impl_replacedElement( aReplaceEvent, _rClearBeforeNotify );
}

//------------------------------------------------------------------------------
void OInterfaceContainer::implCheckIndex( const sal_Int32 _nIndex ) SAL_THROW( ( ::com::sun::star::lang::IndexOutOfBoundsException ) )
{
	if (_nIndex < 0 || _nIndex >= (sal_Int32)m_aItems.size())
		throw IndexOutOfBoundsException();
}

//------------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::replaceByIndex(sal_Int32 _nIndex, const Any& Element) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
{
	::osl::ClearableMutexGuard aGuard( m_rMutex );
	// check the index
	implCheckIndex( _nIndex );
	// do the replace
	implReplaceByIndex( _nIndex, Element, aGuard );
}

//------------------------------------------------------------------------------
void OInterfaceContainer::implRemoveByIndex( const sal_Int32 _nIndex, ::osl::ClearableMutexGuard& _rClearBeforeNotify )
{
	OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implRemoveByIndex: precondition not met (index)!" );

	OInterfaceArray::iterator i = m_aItems.begin() + _nIndex;
	InterfaceRef  xElement(*i);

	OInterfaceMap::iterator j = m_aMap.begin();
	while (j != m_aMap.end() && (*j).second != xElement) ++j;

	m_aItems.erase(i);
	m_aMap.erase(j);

	// remove event knittings
    if ( m_xEventAttacher.is() )
    {
    	InterfaceRef xNormalized( xElement, UNO_QUERY );
	    m_xEventAttacher->detach( _nIndex, xNormalized );
	    m_xEventAttacher->removeEntry( _nIndex );
    }

	Reference<XPropertySet>  xSet(xElement, UNO_QUERY);
	if (xSet.is())
		xSet->removePropertyChangeListener(PROPERTY_NAME, this);

	Reference<XChild>  xChild(xElement, UNO_QUERY);
	if (xChild.is())
		xChild->setParent(InterfaceRef ());

	// notify derived classes
	implRemoved(xElement);

	// notify listeners
	ContainerEvent aEvt;
	aEvt.Source     = static_cast<XContainer*>(this);
	aEvt.Element    = xElement->queryInterface( m_aElementType );
	aEvt.Accessor   <<= _nIndex;

	_rClearBeforeNotify.clear();
    m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvt );
}

//------------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::removeByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
{
	::osl::ClearableMutexGuard aGuard( m_rMutex );
	// check the index
	implCheckIndex( _nIndex );
	// do the removal
	implRemoveByIndex( _nIndex, aGuard );
}

//------------------------------------------------------------------------
ElementDescription* OInterfaceContainer::createElementMetaData( )
{
	return new ElementDescription;
}

//------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::insertByName(const ::rtl::OUString& _rName, const Any& _rElement) throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException )
{
	Reference< XPropertySet > xElementProps;

	::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
	DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::insertByName: createElementMetaData returned nonsense!" );

	// ensure the correct name of the element
	try
	{
		_rElement >>= xElementProps;
		approveNewElement( xElementProps, aElementMetaData.get() );

		xElementProps->setPropertyValue( PROPERTY_NAME, makeAny( _rName ) );
	}
	catch( const IllegalArgumentException& )
	{
		throw;	// allowed to leave
	}
	catch( const ElementExistException& )
	{
		throw;	// allowed to leave
	}
	catch( const Exception& )
	{
		DBG_ERROR( "OInterfaceContainer::insertByName: caught an exception!" );
	}
	implInsert( m_aItems.size(), xElementProps, sal_True, aElementMetaData.get(), sal_True );
}

//------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::replaceByName(const ::rtl::OUString& Name, const Any& Element) throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException )
{
	::osl::ClearableMutexGuard aGuard( m_rMutex );
	::std::pair <OInterfaceMap::iterator,
		  OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
	if (aPair.first == aPair.second)
		throw NoSuchElementException();

	if (Element.getValueType().getTypeClass() != TypeClass_INTERFACE)
		lcl_throwIllegalArgumentException();

	Reference<XPropertySet> xSet;
	Element >>= xSet;
	if (xSet.is())
	{
		if (!hasProperty(PROPERTY_NAME, xSet))
			lcl_throwIllegalArgumentException();

		xSet->setPropertyValue(PROPERTY_NAME, makeAny(Name));
	}

	// determine the element pos
	sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();

	implReplaceByIndex( nPos, Element, aGuard );
}

//------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::removeByName(const ::rtl::OUString& Name) throw( NoSuchElementException, WrappedTargetException, RuntimeException )
{
	::osl::MutexGuard aGuard( m_rMutex );
	::std::pair <OInterfaceMap::iterator,
		  OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
	if (aPair.first == aPair.second)
		throw NoSuchElementException();

	sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
	removeByIndex(nPos);
}


// XEventAttacherManager
//------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::registerScriptEvent( sal_Int32 nIndex, const ScriptEventDescriptor& aScriptEvent ) throw(IllegalArgumentException, RuntimeException)
{
	::osl::ClearableMutexGuard aGuard( m_rMutex );
    if ( m_xEventAttacher.is() )
    {
	    m_xEventAttacher->registerScriptEvent( nIndex, aScriptEvent );
        aGuard.clear();
        impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
    }
}

//------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::registerScriptEvents( sal_Int32 nIndex, const Sequence< ScriptEventDescriptor >& aScriptEvents ) throw(IllegalArgumentException, RuntimeException)
{
	::osl::ClearableMutexGuard aGuard( m_rMutex );
    if ( m_xEventAttacher.is() )
    {
    	m_xEventAttacher->registerScriptEvents( nIndex, aScriptEvents );
        aGuard.clear();
        impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
    }
}

//------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::revokeScriptEvent( sal_Int32 nIndex, const ::rtl::OUString& aListenerType, const ::rtl::OUString& aEventMethod, const ::rtl::OUString& aRemoveListenerParam ) throw(IllegalArgumentException, RuntimeException)
{
    if ( m_xEventAttacher.is() )
    	m_xEventAttacher->revokeScriptEvent( nIndex, aListenerType, aEventMethod, aRemoveListenerParam );
}

//------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::revokeScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
{
    if ( m_xEventAttacher.is() )
        m_xEventAttacher->revokeScriptEvents( nIndex );
}

//------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::insertEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
{
    if ( m_xEventAttacher.is() )
    	m_xEventAttacher->insertEntry( nIndex );
}

//------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::removeEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
{
    if ( m_xEventAttacher.is() )
	    m_xEventAttacher->removeEntry( nIndex );
}

//------------------------------------------------------------------------
Sequence< ScriptEventDescriptor > SAL_CALL OInterfaceContainer::getScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
{
    Sequence< ScriptEventDescriptor > aReturn;
    if ( m_xEventAttacher.is() )
    {
	    aReturn = m_xEventAttacher->getScriptEvents( nIndex );
            if ( lcl_hasVbaEvents( aReturn ) )
            {
                aReturn = lcl_stripVbaEvents( aReturn );
            }
    }
    return aReturn;
}

//------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::attach( sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any& aHelper ) throw(IllegalArgumentException, ServiceNotRegisteredException, RuntimeException)
{
    if ( m_xEventAttacher.is() )
    	m_xEventAttacher->attach( nIndex, xObject, aHelper );
}

//------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::detach( sal_Int32 nIndex, const Reference< XInterface >& xObject ) throw(IllegalArgumentException, RuntimeException)
{
    if ( m_xEventAttacher.is() )
	    m_xEventAttacher->detach( nIndex, xObject );
}

//------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::addScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException)
{
    if ( m_xEventAttacher.is() )
	    m_xEventAttacher->addScriptListener( xListener );
}

//------------------------------------------------------------------------
void SAL_CALL OInterfaceContainer::removeScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException)
{
    if ( m_xEventAttacher.is() )
	    m_xEventAttacher->removeScriptListener( xListener );
}

//==================================================================
//= OFormComponents
//==================================================================
//------------------------------------------------------------------------------
Any SAL_CALL OFormComponents::queryAggregation(const Type& _rType) throw(RuntimeException)
{
	Any aReturn = OFormComponents_BASE::queryInterface(_rType);
	if (!aReturn.hasValue())
	{
		aReturn = OInterfaceContainer::queryInterface(_rType);

		if (!aReturn.hasValue())
			aReturn = FormComponentsBase::queryAggregation(_rType);
	}

	return aReturn;
}

//------------------------------------------------------------------
Sequence<Type> SAL_CALL OFormComponents::getTypes() throw(RuntimeException)
{
	return ::comphelper::concatSequences(OInterfaceContainer::getTypes(), FormComponentsBase::getTypes(), OFormComponents_BASE::getTypes());
}

//------------------------------------------------------------------------------
OFormComponents::OFormComponents(const Reference<XMultiServiceFactory>& _rxFactory)
    :FormComponentsBase( m_aMutex )
    ,OInterfaceContainer( _rxFactory, m_aMutex, XFormComponent::static_type() )
    ,OFormComponents_BASE()
{
}

//------------------------------------------------------------------------------
OFormComponents::OFormComponents( const OFormComponents& _cloneSource )
    :FormComponentsBase( m_aMutex )
    ,OInterfaceContainer( m_aMutex, _cloneSource )
    ,OFormComponents_BASE()
{
}

//------------------------------------------------------------------------------
OFormComponents::~OFormComponents()
{
	if (!FormComponentsBase::rBHelper.bDisposed)
	{
		acquire();
		dispose();
	}
}

// OComponentHelper
//------------------------------------------------------------------------------
void OFormComponents::disposing()
{
	OInterfaceContainer::disposing();
	FormComponentsBase::disposing();
	m_xParent = NULL;
}

//XChild
//------------------------------------------------------------------------------
void OFormComponents::setParent(const InterfaceRef& Parent) throw( NoSupportException, RuntimeException )
{
	::osl::MutexGuard aGuard( m_aMutex );
	m_xParent = Parent;
}

//------------------------------------------------------------------------------
InterfaceRef OFormComponents::getParent() throw( RuntimeException )
{
	return m_xParent;
}

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