/**************************************************************
 * 
 * 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
//.........................................................................

