1*24acc546SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*24acc546SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*24acc546SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*24acc546SAndrew Rist  * distributed with this work for additional information
6*24acc546SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*24acc546SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*24acc546SAndrew Rist  * "License"); you may not use this file except in compliance
9*24acc546SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*24acc546SAndrew Rist  *
11*24acc546SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*24acc546SAndrew Rist  *
13*24acc546SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*24acc546SAndrew Rist  * software distributed under the License is distributed on an
15*24acc546SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*24acc546SAndrew Rist  * KIND, either express or implied.  See the License for the
17*24acc546SAndrew Rist  * specific language governing permissions and limitations
18*24acc546SAndrew Rist  * under the License.
19*24acc546SAndrew Rist  *
20*24acc546SAndrew Rist  *************************************************************/
21*24acc546SAndrew Rist 
22*24acc546SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_forms.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "frm_resource.hrc"
28cdf0e10cSrcweir #include "frm_resource.hxx"
29cdf0e10cSrcweir #include "InterfaceContainer.hxx"
30cdf0e10cSrcweir #include "componenttools.hxx"
31cdf0e10cSrcweir #include "property.hrc"
32cdf0e10cSrcweir #include "services.hxx"
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
35cdf0e10cSrcweir #include <com/sun/star/container/XNamed.hpp>
36cdf0e10cSrcweir #include <com/sun/star/io/WrongFormatException.hpp>
37cdf0e10cSrcweir #include <com/sun/star/io/XMarkableStream.hpp>
38cdf0e10cSrcweir #include <com/sun/star/lang/XComponent.hpp>
39cdf0e10cSrcweir #include <com/sun/star/util/XCloneable.hpp>
40cdf0e10cSrcweir #include <com/sun/star/form/XForm.hpp>
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include <comphelper/container.hxx>
43cdf0e10cSrcweir #include <comphelper/enumhelper.hxx>
44cdf0e10cSrcweir #include <comphelper/eventattachermgr.hxx>
45cdf0e10cSrcweir #include <comphelper/property.hxx>
46cdf0e10cSrcweir #include <comphelper/sequence.hxx>
47cdf0e10cSrcweir #include <comphelper/types.hxx>
48cdf0e10cSrcweir #include <cppuhelper/exc_hlp.hxx>
49cdf0e10cSrcweir #include <cppuhelper/queryinterface.hxx>
50cdf0e10cSrcweir #include <rtl/logfile.hxx>
51cdf0e10cSrcweir #include <tools/debug.hxx>
52cdf0e10cSrcweir #include <tools/diagnose_ex.h>
53cdf0e10cSrcweir 
54cdf0e10cSrcweir #include <algorithm>
55cdf0e10cSrcweir #include <memory>
56cdf0e10cSrcweir 
57cdf0e10cSrcweir //.........................................................................
58cdf0e10cSrcweir #include <com/sun/star/frame/XModel.hpp>
59cdf0e10cSrcweir #include <com/sun/star/document/XCodeNameQuery.hpp>
60cdf0e10cSrcweir #include <ooo/vba/XVBAToOOEventDescGen.hpp>
61cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
62cdf0e10cSrcweir 
63cdf0e10cSrcweir namespace frm
64cdf0e10cSrcweir {
65cdf0e10cSrcweir //.........................................................................
66cdf0e10cSrcweir 
67cdf0e10cSrcweir using namespace ::com::sun::star::frame;
68cdf0e10cSrcweir using namespace ::com::sun::star::lang;
69cdf0e10cSrcweir using namespace ::com::sun::star::uno;
70cdf0e10cSrcweir using namespace ::com::sun::star::beans;
71cdf0e10cSrcweir using namespace ::com::sun::star::document;
72cdf0e10cSrcweir using namespace ::com::sun::star::container;
73cdf0e10cSrcweir using namespace ::com::sun::star::script;
74cdf0e10cSrcweir using namespace ::com::sun::star::io;
75cdf0e10cSrcweir using namespace ::com::sun::star::form;
76cdf0e10cSrcweir using namespace ::com::sun::star::util;
77cdf0e10cSrcweir 
78cdf0e10cSrcweir namespace
79cdf0e10cSrcweir {
80cdf0e10cSrcweir 	//---------------------------------------------------------------------
lcl_throwIllegalArgumentException()81cdf0e10cSrcweir 	static void lcl_throwIllegalArgumentException()
82cdf0e10cSrcweir 	{
83cdf0e10cSrcweir 		throw IllegalArgumentException();
84cdf0e10cSrcweir 	}
85cdf0e10cSrcweir }
86cdf0e10cSrcweir 
87cdf0e10cSrcweir bool
lcl_hasVbaEvents(const Sequence<ScriptEventDescriptor> & sEvents)88cdf0e10cSrcweir lcl_hasVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents  )
89cdf0e10cSrcweir {
90cdf0e10cSrcweir 	const ScriptEventDescriptor* pDesc = sEvents.getConstArray();
91cdf0e10cSrcweir 	const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() );
92cdf0e10cSrcweir 	for ( ; pDesc != pEnd; ++pDesc )
93cdf0e10cSrcweir 	{
94cdf0e10cSrcweir 		if ( pDesc->ScriptType.equals( rtl::OUString::createFromAscii( "VBAInterop" ) ) )
95cdf0e10cSrcweir 			return true;
96cdf0e10cSrcweir 	}
97cdf0e10cSrcweir 	return false;
98cdf0e10cSrcweir }
99cdf0e10cSrcweir 
100cdf0e10cSrcweir Sequence< ScriptEventDescriptor >
lcl_stripVbaEvents(const Sequence<ScriptEventDescriptor> & sEvents)101cdf0e10cSrcweir lcl_stripVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents )
102cdf0e10cSrcweir {
103cdf0e10cSrcweir 	Sequence< ScriptEventDescriptor > sStripped( sEvents.getLength() );
104cdf0e10cSrcweir 
105cdf0e10cSrcweir 	const ScriptEventDescriptor* pDesc = sEvents.getConstArray();
106cdf0e10cSrcweir 	const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() );
107cdf0e10cSrcweir 	sal_Int32 nCopied = 0;
108cdf0e10cSrcweir 	for ( ; pDesc != pEnd; ++pDesc )
109cdf0e10cSrcweir 	{
110cdf0e10cSrcweir 		if ( !pDesc->ScriptType.equals( rtl::OUString::createFromAscii( "VBAInterop" ) ) )
111cdf0e10cSrcweir 		{
112cdf0e10cSrcweir 			sStripped[ nCopied++ ] = *pDesc;
113cdf0e10cSrcweir 		}
114cdf0e10cSrcweir 	}
115cdf0e10cSrcweir 	if ( nCopied )
116cdf0e10cSrcweir 		sStripped.realloc( nCopied );
117cdf0e10cSrcweir 	return sStripped;
118cdf0e10cSrcweir }
119cdf0e10cSrcweir 
impl_addVbEvents_nolck_nothrow(const sal_Int32 i_nIndex)120cdf0e10cSrcweir void OInterfaceContainer::impl_addVbEvents_nolck_nothrow(  const sal_Int32 i_nIndex )
121cdf0e10cSrcweir {
122cdf0e10cSrcweir 	// we are dealing with form controls
123cdf0e10cSrcweir 	try
124cdf0e10cSrcweir 	{
125cdf0e10cSrcweir         do
126cdf0e10cSrcweir         {
127cdf0e10cSrcweir             Reference< XModel > xDoc( getXModel( static_cast< XContainer *> ( this ) ) );
128cdf0e10cSrcweir 		    if ( !xDoc.is() )
129cdf0e10cSrcweir                 break;
130cdf0e10cSrcweir 
131cdf0e10cSrcweir             Reference< XMultiServiceFactory > xDocFac( xDoc, UNO_QUERY_THROW );
132cdf0e10cSrcweir             Reference< XCodeNameQuery > xNameQuery( xDocFac->createInstance( rtl::OUString::createFromAscii( "ooo.vba.VBACodeNameProvider" ) ), UNO_QUERY );
133cdf0e10cSrcweir             if ( !xNameQuery.is() )
134cdf0e10cSrcweir                 break;
135cdf0e10cSrcweir 
136cdf0e10cSrcweir             ::osl::MutexGuard aGuard( m_rMutex );
137cdf0e10cSrcweir             bool hasVBABindings = lcl_hasVbaEvents( m_xEventAttacher->getScriptEvents( i_nIndex ) );
138cdf0e10cSrcweir 			if ( hasVBABindings )
139cdf0e10cSrcweir 				break;
140cdf0e10cSrcweir 
141cdf0e10cSrcweir             Reference< XInterface > xElement( getByIndex( i_nIndex ) , UNO_QUERY_THROW );
142cdf0e10cSrcweir             Reference< XForm > xElementAsForm( xElement, UNO_QUERY );
143cdf0e10cSrcweir             if ( xElementAsForm.is() )
144cdf0e10cSrcweir                 break;
145cdf0e10cSrcweir 
146cdf0e10cSrcweir             ::rtl::OUString sCodeName( xNameQuery->getCodeNameForObject( xElement ) );
147cdf0e10cSrcweir 
148cdf0e10cSrcweir             Reference< XPropertySet > xProps( xElement, UNO_QUERY_THROW );
149cdf0e10cSrcweir 			::rtl::OUString sServiceName;
150cdf0e10cSrcweir 			xProps->getPropertyValue( rtl::OUString::createFromAscii("DefaultControl" ) ) >>= sServiceName;
151cdf0e10cSrcweir 
152cdf0e10cSrcweir 			Reference< ooo::vba::XVBAToOOEventDescGen > xDescSupplier( m_xServiceFactory->createInstance( rtl::OUString::createFromAscii( "ooo.vba.VBAToOOEventDesc" ) ), UNO_QUERY_THROW );
153cdf0e10cSrcweir 			Sequence< ScriptEventDescriptor > vbaEvents = xDescSupplier->getEventDescriptions( m_xServiceFactory->createInstance( sServiceName ), sCodeName );
154cdf0e10cSrcweir 			// register the vba script events
155cdf0e10cSrcweir 			m_xEventAttacher->registerScriptEvents( i_nIndex, vbaEvents );
156cdf0e10cSrcweir 		}
157cdf0e10cSrcweir         while ( false );
158cdf0e10cSrcweir 	}
159cdf0e10cSrcweir     catch ( const ServiceNotRegisteredException& )
160cdf0e10cSrcweir     {
161cdf0e10cSrcweir         // silence this, not all document types support the ooo.vba.VBACodeNameProvider service
162cdf0e10cSrcweir     }
163cdf0e10cSrcweir 	catch( const Exception& )
164cdf0e10cSrcweir 	{
165cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
166cdf0e10cSrcweir 	}
167cdf0e10cSrcweir 
168cdf0e10cSrcweir }
169cdf0e10cSrcweir //==================================================================
170cdf0e10cSrcweir //= ElementDescription
171cdf0e10cSrcweir //==================================================================
172cdf0e10cSrcweir //------------------------------------------------------------------
ElementDescription()173cdf0e10cSrcweir ElementDescription::ElementDescription( )
174cdf0e10cSrcweir {
175cdf0e10cSrcweir }
176cdf0e10cSrcweir 
177cdf0e10cSrcweir //------------------------------------------------------------------
~ElementDescription()178cdf0e10cSrcweir ElementDescription::~ElementDescription()
179cdf0e10cSrcweir {
180cdf0e10cSrcweir }
181cdf0e10cSrcweir 
182cdf0e10cSrcweir //==================================================================
183cdf0e10cSrcweir //= OInterfaceContainer
184cdf0e10cSrcweir //==================================================================
185cdf0e10cSrcweir //------------------------------------------------------------------
OInterfaceContainer(const Reference<XMultiServiceFactory> & _rxFactory,::osl::Mutex & _rMutex,const Type & _rElementType)186cdf0e10cSrcweir OInterfaceContainer::OInterfaceContainer(
187cdf0e10cSrcweir 				const Reference<XMultiServiceFactory>& _rxFactory,
188cdf0e10cSrcweir 				::osl::Mutex& _rMutex,
189cdf0e10cSrcweir 				const Type& _rElementType)
190cdf0e10cSrcweir     :OInterfaceContainer_BASE()
191cdf0e10cSrcweir     ,m_rMutex(_rMutex)
192cdf0e10cSrcweir     ,m_aContainerListeners(_rMutex)
193cdf0e10cSrcweir     ,m_aElementType(_rElementType)
194cdf0e10cSrcweir     ,m_xServiceFactory(_rxFactory)
195cdf0e10cSrcweir {
196cdf0e10cSrcweir     impl_createEventAttacher_nothrow();
197cdf0e10cSrcweir }
198cdf0e10cSrcweir 
199cdf0e10cSrcweir //------------------------------------------------------------------------------
OInterfaceContainer(::osl::Mutex & _rMutex,const OInterfaceContainer & _cloneSource)200cdf0e10cSrcweir OInterfaceContainer::OInterfaceContainer( ::osl::Mutex& _rMutex, const OInterfaceContainer& _cloneSource )
201cdf0e10cSrcweir     :OInterfaceContainer_BASE()
202cdf0e10cSrcweir     ,m_rMutex( _rMutex )
203cdf0e10cSrcweir     ,m_aContainerListeners( _rMutex )
204cdf0e10cSrcweir     ,m_aElementType( _cloneSource.m_aElementType )
205cdf0e10cSrcweir     ,m_xServiceFactory( _cloneSource.m_xServiceFactory )
206cdf0e10cSrcweir {
207cdf0e10cSrcweir     impl_createEventAttacher_nothrow();
208cdf0e10cSrcweir }
209cdf0e10cSrcweir 
210cdf0e10cSrcweir //------------------------------------------------------------------------------
clonedFrom(const OInterfaceContainer & _cloneSource)211cdf0e10cSrcweir void OInterfaceContainer::clonedFrom( const OInterfaceContainer& _cloneSource )
212cdf0e10cSrcweir {
213cdf0e10cSrcweir     try
214cdf0e10cSrcweir     {
215cdf0e10cSrcweir         const Reference< XIndexAccess > xSourceHierarchy( const_cast< OInterfaceContainer* >( &_cloneSource ) );
216cdf0e10cSrcweir         const sal_Int32 nCount = xSourceHierarchy->getCount();
217cdf0e10cSrcweir         for ( sal_Int32 i=0; i<nCount; ++i )
218cdf0e10cSrcweir         {
219cdf0e10cSrcweir             Reference< XCloneable > xCloneable( xSourceHierarchy->getByIndex( i ), UNO_QUERY_THROW );
220cdf0e10cSrcweir             Reference< XInterface > xClone( xCloneable->createClone() );
221cdf0e10cSrcweir             insertByIndex( i, makeAny( xClone ) );
222cdf0e10cSrcweir         }
223cdf0e10cSrcweir     }
224cdf0e10cSrcweir     catch( const Exception& )
225cdf0e10cSrcweir     {
226cdf0e10cSrcweir         throw WrappedTargetException(
227cdf0e10cSrcweir             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not clone the given interface hierarchy." ) ),
228cdf0e10cSrcweir             static_cast< XIndexContainer* >( const_cast< OInterfaceContainer* >( &_cloneSource ) ),
229cdf0e10cSrcweir             ::cppu::getCaughtException()
230cdf0e10cSrcweir         );
231cdf0e10cSrcweir     }
232cdf0e10cSrcweir }
233cdf0e10cSrcweir 
234cdf0e10cSrcweir //------------------------------------------------------------------------------
impl_createEventAttacher_nothrow()235cdf0e10cSrcweir void OInterfaceContainer::impl_createEventAttacher_nothrow()
236cdf0e10cSrcweir {
237cdf0e10cSrcweir     try
238cdf0e10cSrcweir     {
239cdf0e10cSrcweir 	    m_xEventAttacher.set( ::comphelper::createEventAttacherManager( m_xServiceFactory ), UNO_SET_THROW );
240cdf0e10cSrcweir     }
241cdf0e10cSrcweir     catch( const Exception& )
242cdf0e10cSrcweir     {
243cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
244cdf0e10cSrcweir     }
245cdf0e10cSrcweir }
246cdf0e10cSrcweir 
247cdf0e10cSrcweir //------------------------------------------------------------------------------
~OInterfaceContainer()248cdf0e10cSrcweir OInterfaceContainer::~OInterfaceContainer()
249cdf0e10cSrcweir {
250cdf0e10cSrcweir }
251cdf0e10cSrcweir 
252cdf0e10cSrcweir //------------------------------------------------------------------------------
disposing()253cdf0e10cSrcweir void OInterfaceContainer::disposing()
254cdf0e10cSrcweir {
255cdf0e10cSrcweir 	// dispose all elements
256cdf0e10cSrcweir 	for (sal_Int32 i = m_aItems.size(); i > 0; --i)
257cdf0e10cSrcweir 	{
258cdf0e10cSrcweir 		Reference<XPropertySet>  xSet(m_aItems[i - 1], UNO_QUERY);
259cdf0e10cSrcweir 		if (xSet.is())
260cdf0e10cSrcweir 			xSet->removePropertyChangeListener(PROPERTY_NAME, this);
261cdf0e10cSrcweir 
262cdf0e10cSrcweir 		// revoke event knittings
263cdf0e10cSrcweir         if ( m_xEventAttacher.is() )
264cdf0e10cSrcweir         {
265cdf0e10cSrcweir     		Reference< XInterface > xIfc( xSet, UNO_QUERY );
266cdf0e10cSrcweir 	    	m_xEventAttacher->detach( i - 1, xIfc );
267cdf0e10cSrcweir 		    m_xEventAttacher->removeEntry( i - 1 );
268cdf0e10cSrcweir         }
269cdf0e10cSrcweir 
270cdf0e10cSrcweir 		Reference<XComponent>  xComponent(xSet, UNO_QUERY);
271cdf0e10cSrcweir 		if (xComponent.is())
272cdf0e10cSrcweir 			xComponent->dispose();
273cdf0e10cSrcweir 	}
274cdf0e10cSrcweir 	m_aMap.clear();
275cdf0e10cSrcweir 	m_aItems.clear();
276cdf0e10cSrcweir 
277cdf0e10cSrcweir 	EventObject aEvt(static_cast<XContainer*>(this));
278cdf0e10cSrcweir 	m_aContainerListeners.disposeAndClear(aEvt);
279cdf0e10cSrcweir }
280cdf0e10cSrcweir 
281cdf0e10cSrcweir // XPersistObject
282cdf0e10cSrcweir //------------------------------------------------------------------------------
283cdf0e10cSrcweir namespace
284cdf0e10cSrcweir {
285cdf0e10cSrcweir 	//..........................................................................
lcl_saveEvents(::std::vector<Sequence<ScriptEventDescriptor>> & _rSave,const Reference<XEventAttacherManager> & _rxManager,const sal_Int32 _nItemCount)286cdf0e10cSrcweir 	void lcl_saveEvents( ::std::vector< Sequence< ScriptEventDescriptor > >& _rSave,
287cdf0e10cSrcweir 		const Reference< XEventAttacherManager >& _rxManager, const sal_Int32 _nItemCount )
288cdf0e10cSrcweir 	{
289cdf0e10cSrcweir         OSL_ENSURE( _rxManager.is(), "lcl_saveEvents: invalid event attacher manager!" );
290cdf0e10cSrcweir         if ( !_rxManager.is() )
291cdf0e10cSrcweir             return;
292cdf0e10cSrcweir 
293cdf0e10cSrcweir 		// reserve the space needed
294cdf0e10cSrcweir 		_rSave.reserve( _nItemCount );
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 		// copy the events
297cdf0e10cSrcweir         for (sal_Int32 i=0; i<_nItemCount; ++i)
298cdf0e10cSrcweir             _rSave.push_back(_rxManager->getScriptEvents( i ));
299cdf0e10cSrcweir 	}
300cdf0e10cSrcweir 
301cdf0e10cSrcweir 	//..........................................................................
lcl_restoreEvents(const::std::vector<Sequence<ScriptEventDescriptor>> & _rSave,const Reference<XEventAttacherManager> & _rxManager)302cdf0e10cSrcweir 	void lcl_restoreEvents( const ::std::vector< Sequence< ScriptEventDescriptor > >& _rSave,
303cdf0e10cSrcweir 		const Reference< XEventAttacherManager >& _rxManager )
304cdf0e10cSrcweir 	{
305cdf0e10cSrcweir         OSL_ENSURE( _rxManager.is(), "lcl_restoreEvents: invalid event attacher manager!" );
306cdf0e10cSrcweir         if ( !_rxManager.is() )
307cdf0e10cSrcweir             return;
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 		::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aLoop = _rSave.begin();
310cdf0e10cSrcweir 		::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aEnd = _rSave.end();
311cdf0e10cSrcweir 		for ( sal_Int32 i=0; aLoop != aEnd; ++aLoop, ++i )
312cdf0e10cSrcweir 		{
313cdf0e10cSrcweir 			_rxManager->revokeScriptEvents( i );
314cdf0e10cSrcweir 			_rxManager->registerScriptEvents( i, *aLoop );
315cdf0e10cSrcweir 		}
316cdf0e10cSrcweir 	}
317cdf0e10cSrcweir }
318cdf0e10cSrcweir 
319cdf0e10cSrcweir //------------------------------------------------------------------------------
writeEvents(const Reference<XObjectOutputStream> & _rxOutStream)320cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::writeEvents(const Reference<XObjectOutputStream>& _rxOutStream)
321cdf0e10cSrcweir {
322cdf0e10cSrcweir 	// We're writing a document in SO 5.2 format (or even from earlier versions)
323cdf0e10cSrcweir 	// -> convert the events from the new runtime format to the format of the 5.2 files
324cdf0e10cSrcweir 	// but before, remember the current script events set for our children
325cdf0e10cSrcweir 	::std::vector< Sequence< ScriptEventDescriptor > > aSave;
326cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
327cdf0e10cSrcweir 	    lcl_saveEvents( aSave, m_xEventAttacher, m_aItems.size() );
328cdf0e10cSrcweir 
329cdf0e10cSrcweir     transformEvents( efVersionSO5x );
330cdf0e10cSrcweir 
331cdf0e10cSrcweir 	try
332cdf0e10cSrcweir 	{
333cdf0e10cSrcweir 		Reference<XMarkableStream>  xMark(_rxOutStream, UNO_QUERY);
334cdf0e10cSrcweir 		sal_Int32 nMark = xMark->createMark();
335cdf0e10cSrcweir 
336cdf0e10cSrcweir 		sal_Int32 nObjLen = 0;
337cdf0e10cSrcweir 		_rxOutStream->writeLong(nObjLen);
338cdf0e10cSrcweir 
339cdf0e10cSrcweir 		Reference<XPersistObject>  xScripts(m_xEventAttacher, UNO_QUERY);
340cdf0e10cSrcweir 		if (xScripts.is())
341cdf0e10cSrcweir 			xScripts->write(_rxOutStream);
342cdf0e10cSrcweir 
343cdf0e10cSrcweir 		// feststellen der Laenge
344cdf0e10cSrcweir 		nObjLen = xMark->offsetToMark(nMark) - 4;
345cdf0e10cSrcweir 		xMark->jumpToMark(nMark);
346cdf0e10cSrcweir 		_rxOutStream->writeLong(nObjLen);
347cdf0e10cSrcweir 		xMark->jumpToFurthest();
348cdf0e10cSrcweir 		xMark->deleteMark(nMark);
349cdf0e10cSrcweir 	}
350cdf0e10cSrcweir 	catch( const Exception& )
351cdf0e10cSrcweir 	{
352cdf0e10cSrcweir 		// restore the events
353cdf0e10cSrcweir         if ( m_xEventAttacher.is() )
354cdf0e10cSrcweir 		    lcl_restoreEvents( aSave, m_xEventAttacher );
355cdf0e10cSrcweir 		throw;
356cdf0e10cSrcweir 	}
357cdf0e10cSrcweir 
358cdf0e10cSrcweir 	// restore the events
359cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
360cdf0e10cSrcweir     	lcl_restoreEvents( aSave, m_xEventAttacher );
361cdf0e10cSrcweir }
362cdf0e10cSrcweir 
363cdf0e10cSrcweir //------------------------------------------------------------------------------
364cdf0e10cSrcweir struct TransformEventTo52Format : public ::std::unary_function< ScriptEventDescriptor, void >
365cdf0e10cSrcweir {
operator ()frm::TransformEventTo52Format366cdf0e10cSrcweir 	void operator()( ScriptEventDescriptor& _rDescriptor )
367cdf0e10cSrcweir 	{
368cdf0e10cSrcweir 		if ( 0 == _rDescriptor.ScriptType.compareToAscii( "StarBasic" ) )
369cdf0e10cSrcweir 		{	// it's a starbasic macro
370cdf0e10cSrcweir 			sal_Int32 nPrefixLength = _rDescriptor.ScriptCode.indexOf( ':' );
371cdf0e10cSrcweir 			if ( 0 <= nPrefixLength )
372cdf0e10cSrcweir 			{	// the macro name does not already contain a :
373cdf0e10cSrcweir #ifdef DBG_UTIL
374cdf0e10cSrcweir 				const ::rtl::OUString sPrefix = _rDescriptor.ScriptCode.copy( 0, nPrefixLength );
375cdf0e10cSrcweir 				DBG_ASSERT(	0 == sPrefix.compareToAscii( "document" )
376cdf0e10cSrcweir 						||	0 == sPrefix.compareToAscii( "application" ),
377cdf0e10cSrcweir 						"TransformEventTo52Format: invalid (unknown) prefix!" );
378cdf0e10cSrcweir #endif
379cdf0e10cSrcweir 				// cut the prefix
380cdf0e10cSrcweir 				_rDescriptor.ScriptCode = _rDescriptor.ScriptCode.copy( nPrefixLength + 1 );
381cdf0e10cSrcweir 			}
382cdf0e10cSrcweir 		}
383cdf0e10cSrcweir 	}
384cdf0e10cSrcweir };
385cdf0e10cSrcweir 
386cdf0e10cSrcweir //------------------------------------------------------------------------------
387cdf0e10cSrcweir struct TransformEventTo60Format : public ::std::unary_function< ScriptEventDescriptor, void >
388cdf0e10cSrcweir {
operator ()frm::TransformEventTo60Format389cdf0e10cSrcweir 	void operator()( ScriptEventDescriptor& _rDescriptor )
390cdf0e10cSrcweir 	{
391cdf0e10cSrcweir 		if ( 0 == _rDescriptor.ScriptType.compareToAscii( "StarBasic" ) )
392cdf0e10cSrcweir 		{	// it's a starbasic macro
393cdf0e10cSrcweir 			if ( _rDescriptor.ScriptCode.indexOf( ':' ) < 0 )
394cdf0e10cSrcweir 			{	// the macro name does not already contain a :
395cdf0e10cSrcweir 				// -> default the type to "document"
396cdf0e10cSrcweir 				::rtl::OUString sNewScriptCode( RTL_CONSTASCII_USTRINGPARAM( "document:" ) );
397cdf0e10cSrcweir 				sNewScriptCode += _rDescriptor.ScriptCode;
398cdf0e10cSrcweir 				_rDescriptor.ScriptCode = sNewScriptCode;
399cdf0e10cSrcweir 			}
400cdf0e10cSrcweir 		}
401cdf0e10cSrcweir 	}
402cdf0e10cSrcweir };
403cdf0e10cSrcweir 
404cdf0e10cSrcweir //------------------------------------------------------------------------------
transformEvents(const EventFormat _eTargetFormat)405cdf0e10cSrcweir void OInterfaceContainer::transformEvents( const EventFormat _eTargetFormat )
406cdf0e10cSrcweir {
407cdf0e10cSrcweir     OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::transformEvents: no event attacher manager!" );
408cdf0e10cSrcweir     if ( !m_xEventAttacher.is() )
409cdf0e10cSrcweir         return;
410cdf0e10cSrcweir 
411cdf0e10cSrcweir     try
412cdf0e10cSrcweir 	{
413cdf0e10cSrcweir 		// loop through all our children
414cdf0e10cSrcweir 		sal_Int32 nItems = m_aItems.size();
415cdf0e10cSrcweir 		Sequence< ScriptEventDescriptor > aChildEvents;
416cdf0e10cSrcweir 
417cdf0e10cSrcweir 		for (sal_Int32 i=0; i<nItems; ++i)
418cdf0e10cSrcweir 		{
419cdf0e10cSrcweir 			// get the script events for this object
420cdf0e10cSrcweir 			aChildEvents = m_xEventAttacher->getScriptEvents( i );
421cdf0e10cSrcweir 
422cdf0e10cSrcweir 			if ( aChildEvents.getLength() )
423cdf0e10cSrcweir 			{
424cdf0e10cSrcweir 				// the "iterators" for the events for this child
425cdf0e10cSrcweir 				ScriptEventDescriptor* pChildEvents		=						aChildEvents.getArray();
426cdf0e10cSrcweir 				ScriptEventDescriptor* pChildEventsEnd	=	pChildEvents	+	aChildEvents.getLength();
427cdf0e10cSrcweir 
428cdf0e10cSrcweir 				// do the transformation
429cdf0e10cSrcweir 				if ( efVersionSO6x == _eTargetFormat )
430cdf0e10cSrcweir 					::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo60Format() );
431cdf0e10cSrcweir 				else
432cdf0e10cSrcweir 					::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo52Format() );
433cdf0e10cSrcweir 
434cdf0e10cSrcweir 				// revoke the script events
435cdf0e10cSrcweir 				m_xEventAttacher->revokeScriptEvents( i );
436cdf0e10cSrcweir 				// and re-register them
437cdf0e10cSrcweir 				m_xEventAttacher->registerScriptEvents( i, aChildEvents );
438cdf0e10cSrcweir 			}
439cdf0e10cSrcweir 		}
440cdf0e10cSrcweir 	}
441cdf0e10cSrcweir 	catch( const Exception& )
442cdf0e10cSrcweir 	{
443cdf0e10cSrcweir 		DBG_UNHANDLED_EXCEPTION();
444cdf0e10cSrcweir 	}
445cdf0e10cSrcweir }
446cdf0e10cSrcweir 
447cdf0e10cSrcweir //------------------------------------------------------------------------------
readEvents(const Reference<XObjectInputStream> & _rxInStream)448cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::readEvents(const Reference<XObjectInputStream>& _rxInStream)
449cdf0e10cSrcweir {
450cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_rMutex );
451cdf0e10cSrcweir 
452cdf0e10cSrcweir 	// Scripting Info lesen
453cdf0e10cSrcweir 	Reference<XMarkableStream>  xMark(_rxInStream, UNO_QUERY);
454cdf0e10cSrcweir 	sal_Int32 nObjLen = _rxInStream->readLong();
455cdf0e10cSrcweir 	if (nObjLen)
456cdf0e10cSrcweir 	{
457cdf0e10cSrcweir 		sal_Int32 nMark = xMark->createMark();
458cdf0e10cSrcweir 		Reference<XPersistObject>  xObj(m_xEventAttacher, UNO_QUERY);
459cdf0e10cSrcweir 		if (xObj.is())
460cdf0e10cSrcweir 			xObj->read(_rxInStream);
461cdf0e10cSrcweir 		xMark->jumpToMark(nMark);
462cdf0e10cSrcweir 		_rxInStream->skipBytes(nObjLen);
463cdf0e10cSrcweir 		xMark->deleteMark(nMark);
464cdf0e10cSrcweir 	}
465cdf0e10cSrcweir 
466cdf0e10cSrcweir 	// Attachement lesen
467cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
468cdf0e10cSrcweir     {
469cdf0e10cSrcweir 	    OInterfaceArray::const_iterator aAttach = m_aItems.begin();
470cdf0e10cSrcweir 	    OInterfaceArray::const_iterator aAttachEnd = m_aItems.end();
471cdf0e10cSrcweir 	    for ( sal_Int32 i=0; aAttach != aAttachEnd; ++aAttach, ++i )
472cdf0e10cSrcweir 	    {
473cdf0e10cSrcweir 		    Reference< XInterface > xAsIFace( *aAttach, UNO_QUERY );	// important to normalize this ....
474cdf0e10cSrcweir 		    Reference< XPropertySet > xAsSet( xAsIFace, UNO_QUERY );
475cdf0e10cSrcweir 		    m_xEventAttacher->attach( i, xAsIFace, makeAny( xAsSet ) );
476cdf0e10cSrcweir 	    }
477cdf0e10cSrcweir     }
478cdf0e10cSrcweir }
479cdf0e10cSrcweir 
480cdf0e10cSrcweir //------------------------------------------------------------------------------
write(const Reference<XObjectOutputStream> & _rxOutStream)481cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::write( const Reference< XObjectOutputStream >& _rxOutStream ) throw(IOException, RuntimeException)
482cdf0e10cSrcweir {
483cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_rMutex );
484cdf0e10cSrcweir 	sal_Int32 nLen = m_aItems.size();
485cdf0e10cSrcweir 
486cdf0e10cSrcweir 	// schreiben der laenge
487cdf0e10cSrcweir 	_rxOutStream->writeLong(nLen);
488cdf0e10cSrcweir 
489cdf0e10cSrcweir 	if (nLen)
490cdf0e10cSrcweir 	{
491cdf0e10cSrcweir 		// 1. Version
492cdf0e10cSrcweir 		_rxOutStream->writeShort(0x0001);
493cdf0e10cSrcweir 
494cdf0e10cSrcweir 		// 2. Objekte
495cdf0e10cSrcweir 		for (sal_Int32 i = 0; i < nLen; i++)
496cdf0e10cSrcweir 		{
497cdf0e10cSrcweir 			Reference<XPersistObject>  xObj(m_aItems[i], UNO_QUERY);
498cdf0e10cSrcweir 			if (xObj.is())
499cdf0e10cSrcweir 				_rxOutStream->writeObject(xObj);
500cdf0e10cSrcweir 			else
501cdf0e10cSrcweir 			{
502cdf0e10cSrcweir 				// ::com::sun::star::chaos::Error
503cdf0e10cSrcweir 			}
504cdf0e10cSrcweir 		}
505cdf0e10cSrcweir 
506cdf0e10cSrcweir 		// 3. Scripts
507cdf0e10cSrcweir 		writeEvents(_rxOutStream);
508cdf0e10cSrcweir 	}
509cdf0e10cSrcweir }
510cdf0e10cSrcweir 
511cdf0e10cSrcweir //------------------------------------------------------------------------------
512cdf0e10cSrcweir namespace
513cdf0e10cSrcweir {
lcl_createPlaceHolder(const Reference<XMultiServiceFactory> & _rxORB)514cdf0e10cSrcweir 	Reference< XPersistObject > lcl_createPlaceHolder( const Reference< XMultiServiceFactory >& _rxORB )
515cdf0e10cSrcweir 	{
516cdf0e10cSrcweir 		Reference< XPersistObject > xObject( _rxORB->createInstance( FRM_COMPONENT_HIDDENCONTROL ), UNO_QUERY );
517cdf0e10cSrcweir 		DBG_ASSERT( xObject.is(), "lcl_createPlaceHolder: could not create a substitute for the unknown object!" );
518cdf0e10cSrcweir 		if ( xObject.is() )
519cdf0e10cSrcweir 		{
520cdf0e10cSrcweir 			// set some properties describing what we did
521cdf0e10cSrcweir 			Reference< XPropertySet > xObjProps( xObject, UNO_QUERY );
522cdf0e10cSrcweir 			if ( xObject.is()  )
523cdf0e10cSrcweir 			{
524cdf0e10cSrcweir 				try
525cdf0e10cSrcweir 				{
526cdf0e10cSrcweir 					xObjProps->setPropertyValue( PROPERTY_NAME, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_NAME ) ) );
527cdf0e10cSrcweir 					xObjProps->setPropertyValue( PROPERTY_TAG, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_EPXPLAIN ) ) );
528cdf0e10cSrcweir 				}
529cdf0e10cSrcweir 				catch(Exception&)
530cdf0e10cSrcweir 				{
531cdf0e10cSrcweir 				}
532cdf0e10cSrcweir 			}
533cdf0e10cSrcweir 		}
534cdf0e10cSrcweir 		return xObject;
535cdf0e10cSrcweir 	}
536cdf0e10cSrcweir }
537cdf0e10cSrcweir 
538cdf0e10cSrcweir //------------------------------------------------------------------------------
read(const Reference<XObjectInputStream> & _rxInStream)539cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::read( const Reference< XObjectInputStream >& _rxInStream ) throw(IOException, RuntimeException)
540cdf0e10cSrcweir {
541cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_rMutex );
542cdf0e10cSrcweir 
543cdf0e10cSrcweir 	// after ::read the object is expected to be in the state it was when ::write was called, so we have
544cdf0e10cSrcweir 	// to empty ourself here
545cdf0e10cSrcweir 	// FS - 71598 - 12.01.00
546cdf0e10cSrcweir 	while (getCount())
547cdf0e10cSrcweir 		removeByIndex(0);
548cdf0e10cSrcweir 
549cdf0e10cSrcweir     // Schreibt nur in Abhaengigkeit der Laenge
550cdf0e10cSrcweir 	sal_Int32 nLen = _rxInStream->readLong();
551cdf0e10cSrcweir 
552cdf0e10cSrcweir 	if (nLen)
553cdf0e10cSrcweir 	{
554cdf0e10cSrcweir 		// 1. Version
555cdf0e10cSrcweir 		sal_uInt16 nVersion = _rxInStream->readShort(); (void)nVersion;
556cdf0e10cSrcweir 
557cdf0e10cSrcweir 		// 2. Objekte
558cdf0e10cSrcweir 		for (sal_Int32 i = 0; i < nLen; i++)
559cdf0e10cSrcweir 		{
560cdf0e10cSrcweir 			Reference<XPersistObject>  xObj;
561cdf0e10cSrcweir 			try
562cdf0e10cSrcweir 			{
563cdf0e10cSrcweir 				xObj = _rxInStream->readObject();
564cdf0e10cSrcweir 			}
565cdf0e10cSrcweir 			catch(WrongFormatException& e)
566cdf0e10cSrcweir 			{
567cdf0e10cSrcweir 				(void)e;    // make compiler happy
568cdf0e10cSrcweir 				// the object could not be read
569cdf0e10cSrcweir 				// create a object (so the readEvents below will assign the events to the right controls)
570cdf0e10cSrcweir 				xObj = lcl_createPlaceHolder( m_xServiceFactory );
571cdf0e10cSrcweir 				if ( !xObj.is() )
572cdf0e10cSrcweir 					// couldn't handle it
573cdf0e10cSrcweir 					throw;
574cdf0e10cSrcweir 				// 72133 - 09.02.00 - FS
575cdf0e10cSrcweir 			}
576cdf0e10cSrcweir 			catch(Exception&)
577cdf0e10cSrcweir 			{
578cdf0e10cSrcweir 				// unsere Map leeren
579cdf0e10cSrcweir 				while (!m_aItems.empty())
580cdf0e10cSrcweir 					removeElementsNoEvents(0);
581cdf0e10cSrcweir 
582cdf0e10cSrcweir 				// und die Exception nach aussen
583cdf0e10cSrcweir 				throw;
584cdf0e10cSrcweir 			}
585cdf0e10cSrcweir 
586cdf0e10cSrcweir 			if ( xObj.is() )
587cdf0e10cSrcweir 			{
588cdf0e10cSrcweir 				Reference< XPropertySet > xElement( xObj, UNO_QUERY );
589cdf0e10cSrcweir 				try
590cdf0e10cSrcweir 				{
591cdf0e10cSrcweir 					implInsert(
592cdf0e10cSrcweir 						m_aItems.size(),	// position
593cdf0e10cSrcweir 						xElement,			// element to insert
594cdf0e10cSrcweir 						sal_False,			// no event attacher manager handling
595cdf0e10cSrcweir 						NULL,				// not yet approved - let implInsert do it
596cdf0e10cSrcweir 						sal_True			// fire the event
597cdf0e10cSrcweir 					);
598cdf0e10cSrcweir 				}
599cdf0e10cSrcweir 				catch( const Exception& )
600cdf0e10cSrcweir 				{
601cdf0e10cSrcweir 					DBG_ERROR( "OInterfaceContainerHelper::read: reading succeeded, but not inserting!" );
602cdf0e10cSrcweir 					// create a placeholder
603cdf0e10cSrcweir 					xElement = xElement.query( lcl_createPlaceHolder( m_xServiceFactory ) );
604cdf0e10cSrcweir 					if ( !xElement.is() )
605cdf0e10cSrcweir 						// couldn't handle it
606cdf0e10cSrcweir 						throw;
607cdf0e10cSrcweir 					// insert the placeholder
608cdf0e10cSrcweir 					implInsert( m_aItems.size(), xElement, sal_False, NULL, sal_True );
609cdf0e10cSrcweir 				}
610cdf0e10cSrcweir 			}
611cdf0e10cSrcweir 		}
612cdf0e10cSrcweir 
613cdf0e10cSrcweir 		readEvents(_rxInStream);
614cdf0e10cSrcweir 	}
615cdf0e10cSrcweir 	else
616cdf0e10cSrcweir     {
617cdf0e10cSrcweir         try
618cdf0e10cSrcweir         {
619cdf0e10cSrcweir 		    m_xEventAttacher = ::comphelper::createEventAttacherManager( m_xServiceFactory );
620cdf0e10cSrcweir             OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::read: could not create an event attacher manager!" );
621cdf0e10cSrcweir         }
622cdf0e10cSrcweir         catch( const Exception& )
623cdf0e10cSrcweir         {
624cdf0e10cSrcweir             DBG_UNHANDLED_EXCEPTION();
625cdf0e10cSrcweir         }
626cdf0e10cSrcweir     }
627cdf0e10cSrcweir }
628cdf0e10cSrcweir 
629cdf0e10cSrcweir // XContainer
630cdf0e10cSrcweir //------------------------------------------------------------------------------
addContainerListener(const Reference<XContainerListener> & _rxListener)631cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::addContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException )
632cdf0e10cSrcweir {
633cdf0e10cSrcweir 	m_aContainerListeners.addInterface(_rxListener);
634cdf0e10cSrcweir }
635cdf0e10cSrcweir 
636cdf0e10cSrcweir //------------------------------------------------------------------------------
removeContainerListener(const Reference<XContainerListener> & _rxListener)637cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::removeContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException )
638cdf0e10cSrcweir {
639cdf0e10cSrcweir 	m_aContainerListeners.removeInterface(_rxListener);
640cdf0e10cSrcweir }
641cdf0e10cSrcweir 
642cdf0e10cSrcweir // XEventListener
643cdf0e10cSrcweir //------------------------------------------------------------------------------
disposing(const EventObject & _rSource)644cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::disposing(const EventObject& _rSource) throw( RuntimeException )
645cdf0e10cSrcweir {
646cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_rMutex );
647cdf0e10cSrcweir 
648cdf0e10cSrcweir 	Reference< XInterface > xSource( _rSource.Source, UNO_QUERY );
649cdf0e10cSrcweir 		// normalized source
650cdf0e10cSrcweir 
651cdf0e10cSrcweir 	OInterfaceArray::iterator j;
652cdf0e10cSrcweir 	for ( j = m_aItems.begin(); j != m_aItems.end(); ++j )
653cdf0e10cSrcweir 	{
654cdf0e10cSrcweir 		DBG_ASSERT( j->get() == Reference< XInterface >( *j, UNO_QUERY ).get(),
655cdf0e10cSrcweir 			"OInterfaceContainer::disposing: vector element not normalized!" );
656cdf0e10cSrcweir 
657cdf0e10cSrcweir 		if ( xSource.get() == j->get() )
658cdf0e10cSrcweir 			// found the element
659cdf0e10cSrcweir 			break;
660cdf0e10cSrcweir 	}
661cdf0e10cSrcweir 
662cdf0e10cSrcweir 	if ( m_aItems.end() != j )
663cdf0e10cSrcweir 	{
664cdf0e10cSrcweir         m_aItems.erase(j);
665cdf0e10cSrcweir 
666cdf0e10cSrcweir         // look up in, and erase from, m_aMap, too
667cdf0e10cSrcweir 		OInterfaceMap::iterator i = m_aMap.begin();
668cdf0e10cSrcweir 		while ( i != m_aMap.end() )
669cdf0e10cSrcweir 		{
670cdf0e10cSrcweir 			DBG_ASSERT( i->second.get() == Reference< XInterface >( i->second, UNO_QUERY ).get(),
671cdf0e10cSrcweir 				"OInterfaceContainer::disposing: map element not normalized!" );
672cdf0e10cSrcweir 
673cdf0e10cSrcweir 			if ( i->second.get() == xSource.get() )
674cdf0e10cSrcweir             {
675cdf0e10cSrcweir 				// found it
676cdf0e10cSrcweir                 m_aMap.erase(i);
677cdf0e10cSrcweir 				break;
678cdf0e10cSrcweir             }
679cdf0e10cSrcweir 
680cdf0e10cSrcweir 			++i;
681cdf0e10cSrcweir 
682cdf0e10cSrcweir             DBG_ASSERT( i != m_aMap.end(), "OInterfaceContainer::disposing: inconsistency: the element was in m_aItems, but not in m_aMap!" );
683cdf0e10cSrcweir 		}
684cdf0e10cSrcweir 	}
685cdf0e10cSrcweir }
686cdf0e10cSrcweir 
687cdf0e10cSrcweir // XPropertyChangeListener
688cdf0e10cSrcweir //------------------------------------------------------------------------------
propertyChange(const PropertyChangeEvent & evt)689cdf0e10cSrcweir void OInterfaceContainer::propertyChange(const PropertyChangeEvent& evt)
690cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) {
691cdf0e10cSrcweir 	if (evt.PropertyName == PROPERTY_NAME)
692cdf0e10cSrcweir 	{
693cdf0e10cSrcweir 		::osl::MutexGuard aGuard( m_rMutex );
694cdf0e10cSrcweir 		OInterfaceMap::iterator i = ::std::find(m_aMap.begin(), m_aMap.end(),
695cdf0e10cSrcweir 			::std::pair<const ::rtl::OUString, InterfaceRef >(::comphelper::getString(evt.OldValue),evt.Source));
696cdf0e10cSrcweir 		if (i != m_aMap.end())
697cdf0e10cSrcweir 		{
698cdf0e10cSrcweir 			InterfaceRef  xCorrectType((*i).second);
699cdf0e10cSrcweir 			m_aMap.erase(i);
700cdf0e10cSrcweir 			m_aMap.insert(::std::pair<const ::rtl::OUString, InterfaceRef >(::comphelper::getString(evt.NewValue),xCorrectType));
701cdf0e10cSrcweir 		}
702cdf0e10cSrcweir 	}
703cdf0e10cSrcweir }
704cdf0e10cSrcweir 
705cdf0e10cSrcweir // XElementAccess
706cdf0e10cSrcweir //------------------------------------------------------------------------------
hasElements()707cdf0e10cSrcweir sal_Bool SAL_CALL OInterfaceContainer::hasElements() throw( RuntimeException )
708cdf0e10cSrcweir {
709cdf0e10cSrcweir 	return !m_aMap.empty();
710cdf0e10cSrcweir }
711cdf0e10cSrcweir 
712cdf0e10cSrcweir //------------------------------------------------------------------------------
getElementType()713cdf0e10cSrcweir Type SAL_CALL OInterfaceContainer::getElementType() throw(RuntimeException)
714cdf0e10cSrcweir {
715cdf0e10cSrcweir 	return m_aElementType;
716cdf0e10cSrcweir }
717cdf0e10cSrcweir 
718cdf0e10cSrcweir // XEnumerationAccess
719cdf0e10cSrcweir //------------------------------------------------------------------------------
createEnumeration()720cdf0e10cSrcweir Reference<XEnumeration> SAL_CALL OInterfaceContainer::createEnumeration() throw( RuntimeException )
721cdf0e10cSrcweir {
722cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_rMutex );
723cdf0e10cSrcweir 	return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this));
724cdf0e10cSrcweir }
725cdf0e10cSrcweir 
726cdf0e10cSrcweir // XNameAccess
727cdf0e10cSrcweir //------------------------------------------------------------------------------
getByName(const::rtl::OUString & _rName)728cdf0e10cSrcweir Any SAL_CALL OInterfaceContainer::getByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
729cdf0e10cSrcweir {
730cdf0e10cSrcweir 	::std::pair <OInterfaceMap::iterator,
731cdf0e10cSrcweir 		  OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
732cdf0e10cSrcweir 
733cdf0e10cSrcweir 	if (aPair.first == aPair.second)
734cdf0e10cSrcweir 		throw NoSuchElementException();
735cdf0e10cSrcweir 
736cdf0e10cSrcweir 	return (*aPair.first).second->queryInterface( m_aElementType );
737cdf0e10cSrcweir }
738cdf0e10cSrcweir 
739cdf0e10cSrcweir //------------------------------------------------------------------------------
getElementNames()740cdf0e10cSrcweir StringSequence SAL_CALL OInterfaceContainer::getElementNames() throw(RuntimeException)
741cdf0e10cSrcweir {
742cdf0e10cSrcweir 	StringSequence aNameList(m_aItems.size());
743cdf0e10cSrcweir 	::rtl::OUString* pStringArray = aNameList.getArray();
744cdf0e10cSrcweir 
745cdf0e10cSrcweir 	for (OInterfaceMap::const_iterator i = m_aMap.begin(); i != m_aMap.end(); ++i, ++pStringArray)
746cdf0e10cSrcweir 	{
747cdf0e10cSrcweir 		*pStringArray = (*i).first;
748cdf0e10cSrcweir 	}
749cdf0e10cSrcweir 	return aNameList;
750cdf0e10cSrcweir }
751cdf0e10cSrcweir 
752cdf0e10cSrcweir //------------------------------------------------------------------------------
hasByName(const::rtl::OUString & _rName)753cdf0e10cSrcweir sal_Bool SAL_CALL OInterfaceContainer::hasByName( const ::rtl::OUString& _rName ) throw(RuntimeException)
754cdf0e10cSrcweir {
755cdf0e10cSrcweir 	::std::pair <OInterfaceMap::iterator,
756cdf0e10cSrcweir 		  OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
757cdf0e10cSrcweir 	return aPair.first != aPair.second;
758cdf0e10cSrcweir }
759cdf0e10cSrcweir 
760cdf0e10cSrcweir // XIndexAccess
761cdf0e10cSrcweir //------------------------------------------------------------------------------
getCount()762cdf0e10cSrcweir sal_Int32 OInterfaceContainer::getCount() throw( RuntimeException )
763cdf0e10cSrcweir {
764cdf0e10cSrcweir 	return m_aItems.size();
765cdf0e10cSrcweir }
766cdf0e10cSrcweir 
767cdf0e10cSrcweir //------------------------------------------------------------------------------
getByIndex(sal_Int32 _nIndex)768cdf0e10cSrcweir Any OInterfaceContainer::getByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
769cdf0e10cSrcweir {
770cdf0e10cSrcweir 	if (_nIndex < 0 || (_nIndex >= (sal_Int32)m_aItems.size()))
771cdf0e10cSrcweir 		throw IndexOutOfBoundsException();
772cdf0e10cSrcweir 
773cdf0e10cSrcweir 	return m_aItems[_nIndex]->queryInterface( m_aElementType );
774cdf0e10cSrcweir }
775cdf0e10cSrcweir 
776cdf0e10cSrcweir //------------------------------------------------------------------------------
approveNewElement(const Reference<XPropertySet> & _rxObject,ElementDescription * _pElement)777cdf0e10cSrcweir void OInterfaceContainer::approveNewElement( const Reference< XPropertySet >& _rxObject, ElementDescription* _pElement )
778cdf0e10cSrcweir {
779cdf0e10cSrcweir 	// it has to be non-NULL
780cdf0e10cSrcweir 	if ( !_rxObject.is() )
781cdf0e10cSrcweir 		throw IllegalArgumentException(FRM_RES_STRING(RID_STR_NEED_NON_NULL_OBJECT), static_cast<XContainer*>(this), 1);
782cdf0e10cSrcweir 
783cdf0e10cSrcweir 	// it has to support our element type interface
784cdf0e10cSrcweir 	Any aCorrectType = _rxObject->queryInterface( m_aElementType );
785cdf0e10cSrcweir 	if ( !aCorrectType.hasValue() )
786cdf0e10cSrcweir 		lcl_throwIllegalArgumentException();
787cdf0e10cSrcweir 
788cdf0e10cSrcweir 	// it has to have a "Name" property
789cdf0e10cSrcweir 	if ( !hasProperty( PROPERTY_NAME, _rxObject ) )
790cdf0e10cSrcweir 		lcl_throwIllegalArgumentException();
791cdf0e10cSrcweir 
792cdf0e10cSrcweir 	// it has to be a child, and it must not have a parent already
793cdf0e10cSrcweir 	Reference< XChild > xChild( _rxObject, UNO_QUERY );
794cdf0e10cSrcweir 	if ( !xChild.is() || xChild->getParent().is() )
795cdf0e10cSrcweir 	{
796cdf0e10cSrcweir #ifdef FS_PRIV_DEBUG
797cdf0e10cSrcweir 		::rtl::OUString sChildName, sParentName;
798cdf0e10cSrcweir 		Reference< XNamed > xNamed( xChild, UNO_QUERY );
799cdf0e10cSrcweir 		if ( xNamed.is() )
800cdf0e10cSrcweir 			sChildName = xNamed->getName();
801cdf0e10cSrcweir 		if ( xChild.is() )
802cdf0e10cSrcweir 		{
803cdf0e10cSrcweir 			xNamed = xNamed.query( xChild->getParent() );
804cdf0e10cSrcweir 			if ( xNamed.is() )
805cdf0e10cSrcweir 				sParentName = xNamed->getName();
806cdf0e10cSrcweir 		}
807cdf0e10cSrcweir #endif
808cdf0e10cSrcweir 		lcl_throwIllegalArgumentException();
809cdf0e10cSrcweir 	}
810cdf0e10cSrcweir 
811cdf0e10cSrcweir 	// passed all tests. cache the information we have so far
812cdf0e10cSrcweir 	DBG_ASSERT( _pElement, "OInterfaceContainer::approveNewElement: invalid event descriptor!" );
813cdf0e10cSrcweir 	if ( _pElement )
814cdf0e10cSrcweir 	{
815cdf0e10cSrcweir 		_pElement->xPropertySet = _rxObject;
816cdf0e10cSrcweir 		_pElement->xChild = xChild;
817cdf0e10cSrcweir 		_pElement->aElementTypeInterface = aCorrectType;
818cdf0e10cSrcweir 		_pElement->xInterface = Reference< XInterface >( _rxObject, UNO_QUERY );	// normalized XInterface
819cdf0e10cSrcweir 	}
820cdf0e10cSrcweir }
821cdf0e10cSrcweir 
822cdf0e10cSrcweir //------------------------------------------------------------------------------
implInsert(sal_Int32 _nIndex,const Reference<XPropertySet> & _rxElement,sal_Bool _bEvents,ElementDescription * _pApprovalResult,sal_Bool _bFire)823cdf0e10cSrcweir void OInterfaceContainer::implInsert(sal_Int32 _nIndex, const Reference< XPropertySet >& _rxElement,
824cdf0e10cSrcweir 	sal_Bool _bEvents, ElementDescription* _pApprovalResult, sal_Bool _bFire ) throw( IllegalArgumentException )
825cdf0e10cSrcweir {
826cdf0e10cSrcweir     const bool bHandleEvents = _bEvents && m_xEventAttacher.is();
827cdf0e10cSrcweir 
828cdf0e10cSrcweir     // SYNCHRONIZED ----->
829cdf0e10cSrcweir 	::osl::ClearableMutexGuard aGuard( m_rMutex );
830cdf0e10cSrcweir 
831cdf0e10cSrcweir 	::std::auto_ptr< ElementDescription > aAutoDeleteMetaData;
832cdf0e10cSrcweir 	ElementDescription* pElementMetaData = _pApprovalResult;
833cdf0e10cSrcweir 	if ( !pElementMetaData )
834cdf0e10cSrcweir 	{	// not yet approved by the caller -> do ourself
835cdf0e10cSrcweir 		pElementMetaData = createElementMetaData();
836cdf0e10cSrcweir 		DBG_ASSERT( pElementMetaData, "OInterfaceContainer::implInsert: createElementMetaData returned nonsense!" );
837cdf0e10cSrcweir 
838cdf0e10cSrcweir 		// ensure that the meta data structure will be deleted later on
839cdf0e10cSrcweir 		aAutoDeleteMetaData = ::std::auto_ptr< ElementDescription >( pElementMetaData );
840cdf0e10cSrcweir 
841cdf0e10cSrcweir 		// will throw an exception if necessary
842cdf0e10cSrcweir 		approveNewElement( _rxElement, pElementMetaData );
843cdf0e10cSrcweir 	}
844cdf0e10cSrcweir 
845cdf0e10cSrcweir 
846cdf0e10cSrcweir 	// approveNewElement (no matter if called here or outside) has ensure that all relevant interfaces
847cdf0e10cSrcweir 	// exist
848cdf0e10cSrcweir 
849cdf0e10cSrcweir 	// set the name, and add as change listener for the name
850cdf0e10cSrcweir 	::rtl::OUString sName;
851cdf0e10cSrcweir 	_rxElement->getPropertyValue(PROPERTY_NAME) >>= sName;
852cdf0e10cSrcweir 	_rxElement->addPropertyChangeListener(PROPERTY_NAME, this);
853cdf0e10cSrcweir 
854cdf0e10cSrcweir 	// insert the object into our internal structures
855cdf0e10cSrcweir 	if (_nIndex > (sal_Int32)m_aItems.size()) // ermitteln des tatsaechlichen Indexs
856cdf0e10cSrcweir 	{
857cdf0e10cSrcweir 		_nIndex = m_aItems.size();
858cdf0e10cSrcweir 		m_aItems.push_back( pElementMetaData->xInterface );
859cdf0e10cSrcweir 	}
860cdf0e10cSrcweir 	else
861cdf0e10cSrcweir 		m_aItems.insert( m_aItems.begin() + _nIndex, pElementMetaData->xInterface );
862cdf0e10cSrcweir 
863cdf0e10cSrcweir 	m_aMap.insert( ::std::pair< const ::rtl::OUString, InterfaceRef >( sName, pElementMetaData->xInterface ) );
864cdf0e10cSrcweir 
865cdf0e10cSrcweir 	// announce ourself as parent to the new element
866cdf0e10cSrcweir 	pElementMetaData->xChild->setParent(static_cast<XContainer*>(this));
867cdf0e10cSrcweir 
868cdf0e10cSrcweir 	// handle the events
869cdf0e10cSrcweir 	if ( bHandleEvents )
870cdf0e10cSrcweir 	{
871cdf0e10cSrcweir 		m_xEventAttacher->insertEntry(_nIndex);
872cdf0e10cSrcweir 		m_xEventAttacher->attach( _nIndex, pElementMetaData->xInterface, makeAny( _rxElement ) );
873cdf0e10cSrcweir 	}
874cdf0e10cSrcweir 
875cdf0e10cSrcweir 	// notify derived classes
876cdf0e10cSrcweir 	implInserted( pElementMetaData );
877cdf0e10cSrcweir 
878cdf0e10cSrcweir     aGuard.clear();
879cdf0e10cSrcweir     // <----- SYNCHRONIZED
880cdf0e10cSrcweir 
881cdf0e10cSrcweir 	// insert faked VBA events?
882cdf0e10cSrcweir 	if ( bHandleEvents )
883cdf0e10cSrcweir 	{
884cdf0e10cSrcweir 	    Reference< XEventAttacherManager > xMgr ( pElementMetaData->xInterface, UNO_QUERY );
885cdf0e10cSrcweir 	    if ( xMgr.is() )
886cdf0e10cSrcweir 	    {
887cdf0e10cSrcweir 		    OInterfaceContainer* pIfcMgr = dynamic_cast< OInterfaceContainer* >( xMgr.get() );
888cdf0e10cSrcweir 		    sal_Int32 nLen = pIfcMgr->getCount();
889cdf0e10cSrcweir 		    for ( sal_Int32 i = 0; (i < nLen) && pIfcMgr ; ++i )
890cdf0e10cSrcweir 		    {
891cdf0e10cSrcweir 			    // add fake events to the control at index i
892cdf0e10cSrcweir 			    pIfcMgr->impl_addVbEvents_nolck_nothrow( i );
893cdf0e10cSrcweir 		    }
894cdf0e10cSrcweir 	    }
895cdf0e10cSrcweir 	    else
896cdf0e10cSrcweir 	    {
897cdf0e10cSrcweir 		    // add fake events to the control at index i
898cdf0e10cSrcweir 		    impl_addVbEvents_nolck_nothrow( _nIndex );
899cdf0e10cSrcweir 	    }
900cdf0e10cSrcweir     }
901cdf0e10cSrcweir 
902cdf0e10cSrcweir 	// fire the notification about the change
903cdf0e10cSrcweir 	if ( _bFire )
904cdf0e10cSrcweir 	{
905cdf0e10cSrcweir 		// notify listeners
906cdf0e10cSrcweir 		ContainerEvent aEvt;
907cdf0e10cSrcweir 		aEvt.Source   = static_cast<XContainer*>(this);
908cdf0e10cSrcweir 		aEvt.Accessor <<= _nIndex;
909cdf0e10cSrcweir 		aEvt.Element  = pElementMetaData->aElementTypeInterface;
910cdf0e10cSrcweir 
911cdf0e10cSrcweir 		aGuard.clear();
912cdf0e10cSrcweir         m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvt );
913cdf0e10cSrcweir 	}
914cdf0e10cSrcweir }
915cdf0e10cSrcweir 
916cdf0e10cSrcweir //------------------------------------------------------------------------------
removeElementsNoEvents(sal_Int32 nIndex)917cdf0e10cSrcweir void OInterfaceContainer::removeElementsNoEvents(sal_Int32 nIndex)
918cdf0e10cSrcweir {
919cdf0e10cSrcweir 	OInterfaceArray::iterator i = m_aItems.begin() + nIndex;
920cdf0e10cSrcweir 	InterfaceRef  xElement(*i);
921cdf0e10cSrcweir 
922cdf0e10cSrcweir 	OInterfaceMap::iterator j = m_aMap.begin();
923cdf0e10cSrcweir 	while (j != m_aMap.end() && (*j).second != xElement) ++j;
924cdf0e10cSrcweir 
925cdf0e10cSrcweir 	m_aItems.erase(i);
926cdf0e10cSrcweir 	m_aMap.erase(j);
927cdf0e10cSrcweir 
928cdf0e10cSrcweir 	Reference<XPropertySet>  xSet(xElement, UNO_QUERY);
929cdf0e10cSrcweir 	if (xSet.is())
930cdf0e10cSrcweir 		xSet->removePropertyChangeListener(PROPERTY_NAME, this);
931cdf0e10cSrcweir 
932cdf0e10cSrcweir 	Reference<XChild>  xChild(xElement, UNO_QUERY);
933cdf0e10cSrcweir 	if (xChild.is())
934cdf0e10cSrcweir 		xChild->setParent(InterfaceRef ());
935cdf0e10cSrcweir }
936cdf0e10cSrcweir 
937cdf0e10cSrcweir //------------------------------------------------------------------------------
implInserted(const ElementDescription *)938cdf0e10cSrcweir void OInterfaceContainer::implInserted( const ElementDescription* /*_pElement*/ )
939cdf0e10cSrcweir {
940cdf0e10cSrcweir     // not inrerested in
941cdf0e10cSrcweir }
942cdf0e10cSrcweir 
943cdf0e10cSrcweir //------------------------------------------------------------------------------
implRemoved(const InterfaceRef &)944cdf0e10cSrcweir void OInterfaceContainer::implRemoved( const InterfaceRef& /*_rxObject*/ )
945cdf0e10cSrcweir {
946cdf0e10cSrcweir     // not inrerested in
947cdf0e10cSrcweir }
948cdf0e10cSrcweir 
949cdf0e10cSrcweir //------------------------------------------------------------------------------
impl_replacedElement(const ContainerEvent & _rEvent,::osl::ClearableMutexGuard & _rInstanceLock)950cdf0e10cSrcweir void OInterfaceContainer::impl_replacedElement( const ContainerEvent& _rEvent, ::osl::ClearableMutexGuard& _rInstanceLock )
951cdf0e10cSrcweir {
952cdf0e10cSrcweir     _rInstanceLock.clear();
953cdf0e10cSrcweir     m_aContainerListeners.notifyEach( &XContainerListener::elementReplaced, _rEvent );
954cdf0e10cSrcweir }
955cdf0e10cSrcweir 
956cdf0e10cSrcweir // XIndexContainer
957cdf0e10cSrcweir //------------------------------------------------------------------------------
insertByIndex(sal_Int32 _nIndex,const Any & _rElement)958cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::insertByIndex( sal_Int32 _nIndex, const Any& _rElement ) throw(IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
959cdf0e10cSrcweir {
960cdf0e10cSrcweir 	Reference< XPropertySet > xElement;
961cdf0e10cSrcweir 	_rElement >>= xElement;
962cdf0e10cSrcweir 	implInsert( _nIndex, xElement, sal_True /* event handling */ , NULL /* not yet approved */ , sal_True /* notification */ );
963cdf0e10cSrcweir }
964cdf0e10cSrcweir 
965cdf0e10cSrcweir //------------------------------------------------------------------------------
implReplaceByIndex(const sal_Int32 _nIndex,const Any & _rNewElement,::osl::ClearableMutexGuard & _rClearBeforeNotify)966cdf0e10cSrcweir void OInterfaceContainer::implReplaceByIndex( const sal_Int32 _nIndex, const Any& _rNewElement, ::osl::ClearableMutexGuard& _rClearBeforeNotify )
967cdf0e10cSrcweir {
968cdf0e10cSrcweir 	OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implReplaceByIndex: precondition not met (index)!" );
969cdf0e10cSrcweir 
970cdf0e10cSrcweir 	// approve the new object
971cdf0e10cSrcweir 	::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
972cdf0e10cSrcweir 	DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::implReplaceByIndex: createElementMetaData returned nonsense!" );
973cdf0e10cSrcweir 	{
974cdf0e10cSrcweir 		Reference< XPropertySet > xElementProps;
975cdf0e10cSrcweir 		_rNewElement >>= xElementProps;
976cdf0e10cSrcweir 		approveNewElement( xElementProps, aElementMetaData.get() );
977cdf0e10cSrcweir 	}
978cdf0e10cSrcweir 
979cdf0e10cSrcweir 	// get the old element
980cdf0e10cSrcweir 	InterfaceRef  xOldElement( m_aItems[ _nIndex ] );
981cdf0e10cSrcweir 	DBG_ASSERT( xOldElement.get() == Reference< XInterface >( xOldElement, UNO_QUERY ).get(),
982cdf0e10cSrcweir 		"OInterfaceContainer::implReplaceByIndex: elements should be held normalized!" );
983cdf0e10cSrcweir 
984cdf0e10cSrcweir 	// locate the old element in the map
985cdf0e10cSrcweir 	OInterfaceMap::iterator j = m_aMap.begin();
986cdf0e10cSrcweir 	while ( ( j != m_aMap.end() ) && ( j->second.get() != xOldElement.get() ) )
987cdf0e10cSrcweir 		++j;
988cdf0e10cSrcweir 
989cdf0e10cSrcweir 	// remove event knittings
990cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
991cdf0e10cSrcweir     {
992cdf0e10cSrcweir     	InterfaceRef xNormalized( xOldElement, UNO_QUERY );
993cdf0e10cSrcweir 	    m_xEventAttacher->detach( _nIndex, xNormalized );
994cdf0e10cSrcweir 	    m_xEventAttacher->removeEntry( _nIndex );
995cdf0e10cSrcweir     }
996cdf0e10cSrcweir 
997cdf0e10cSrcweir 	// don't listen for property changes anymore
998cdf0e10cSrcweir 	Reference<XPropertySet>  xSet( xOldElement, UNO_QUERY );
999cdf0e10cSrcweir 	if (xSet.is())
1000cdf0e10cSrcweir 		xSet->removePropertyChangeListener(PROPERTY_NAME, this);
1001cdf0e10cSrcweir 
1002cdf0e10cSrcweir 	// give the old element a new (void) parent
1003cdf0e10cSrcweir 	Reference<XChild>  xChild(xOldElement, UNO_QUERY);
1004cdf0e10cSrcweir 	if (xChild.is())
1005cdf0e10cSrcweir 		xChild->setParent(InterfaceRef ());
1006cdf0e10cSrcweir 
1007cdf0e10cSrcweir 	// remove the old one
1008cdf0e10cSrcweir 	m_aMap.erase(j);
1009cdf0e10cSrcweir 
1010cdf0e10cSrcweir 	// examine the new element
1011cdf0e10cSrcweir 	::rtl::OUString sName;
1012cdf0e10cSrcweir 	DBG_ASSERT( aElementMetaData.get()->xPropertySet.is(), "OInterfaceContainer::implReplaceByIndex: what did approveNewElement do?" );
1013cdf0e10cSrcweir 
1014cdf0e10cSrcweir 	aElementMetaData.get()->xPropertySet->getPropertyValue(PROPERTY_NAME) >>= sName;
1015cdf0e10cSrcweir 	aElementMetaData.get()->xPropertySet->addPropertyChangeListener(PROPERTY_NAME, this);
1016cdf0e10cSrcweir 
1017cdf0e10cSrcweir 	// insert the new one
1018cdf0e10cSrcweir 	m_aMap.insert( ::std::pair<const ::rtl::OUString, InterfaceRef  >( sName, aElementMetaData.get()->xInterface ) );
1019cdf0e10cSrcweir 	m_aItems[ _nIndex ] = aElementMetaData.get()->xInterface;
1020cdf0e10cSrcweir 
1021cdf0e10cSrcweir 	aElementMetaData.get()->xChild->setParent(static_cast<XContainer*>(this));
1022cdf0e10cSrcweir 
1023cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
1024cdf0e10cSrcweir     {
1025cdf0e10cSrcweir 	    m_xEventAttacher->insertEntry( _nIndex );
1026cdf0e10cSrcweir 	    m_xEventAttacher->attach( _nIndex, aElementMetaData.get()->xInterface, makeAny( aElementMetaData.get()->xPropertySet ) );
1027cdf0e10cSrcweir     }
1028cdf0e10cSrcweir 
1029cdf0e10cSrcweir 	ContainerEvent aReplaceEvent;
1030cdf0e10cSrcweir 	aReplaceEvent.Source   = static_cast< XContainer* >( this );
1031cdf0e10cSrcweir 	aReplaceEvent.Accessor <<= _nIndex;
1032cdf0e10cSrcweir 	aReplaceEvent.Element  = aElementMetaData.get()->xInterface->queryInterface( m_aElementType );
1033cdf0e10cSrcweir 	aReplaceEvent.ReplacedElement = xOldElement->queryInterface( m_aElementType );
1034cdf0e10cSrcweir 
1035cdf0e10cSrcweir 	impl_replacedElement( aReplaceEvent, _rClearBeforeNotify );
1036cdf0e10cSrcweir }
1037cdf0e10cSrcweir 
1038cdf0e10cSrcweir //------------------------------------------------------------------------------
implCheckIndex(const sal_Int32 _nIndex)1039cdf0e10cSrcweir void OInterfaceContainer::implCheckIndex( const sal_Int32 _nIndex ) SAL_THROW( ( ::com::sun::star::lang::IndexOutOfBoundsException ) )
1040cdf0e10cSrcweir {
1041cdf0e10cSrcweir 	if (_nIndex < 0 || _nIndex >= (sal_Int32)m_aItems.size())
1042cdf0e10cSrcweir 		throw IndexOutOfBoundsException();
1043cdf0e10cSrcweir }
1044cdf0e10cSrcweir 
1045cdf0e10cSrcweir //------------------------------------------------------------------------------
replaceByIndex(sal_Int32 _nIndex,const Any & Element)1046cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::replaceByIndex(sal_Int32 _nIndex, const Any& Element) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1047cdf0e10cSrcweir {
1048cdf0e10cSrcweir 	::osl::ClearableMutexGuard aGuard( m_rMutex );
1049cdf0e10cSrcweir 	// check the index
1050cdf0e10cSrcweir 	implCheckIndex( _nIndex );
1051cdf0e10cSrcweir 	// do the replace
1052cdf0e10cSrcweir 	implReplaceByIndex( _nIndex, Element, aGuard );
1053cdf0e10cSrcweir }
1054cdf0e10cSrcweir 
1055cdf0e10cSrcweir //------------------------------------------------------------------------------
implRemoveByIndex(const sal_Int32 _nIndex,::osl::ClearableMutexGuard & _rClearBeforeNotify)1056cdf0e10cSrcweir void OInterfaceContainer::implRemoveByIndex( const sal_Int32 _nIndex, ::osl::ClearableMutexGuard& _rClearBeforeNotify )
1057cdf0e10cSrcweir {
1058cdf0e10cSrcweir 	OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implRemoveByIndex: precondition not met (index)!" );
1059cdf0e10cSrcweir 
1060cdf0e10cSrcweir 	OInterfaceArray::iterator i = m_aItems.begin() + _nIndex;
1061cdf0e10cSrcweir 	InterfaceRef  xElement(*i);
1062cdf0e10cSrcweir 
1063cdf0e10cSrcweir 	OInterfaceMap::iterator j = m_aMap.begin();
1064cdf0e10cSrcweir 	while (j != m_aMap.end() && (*j).second != xElement) ++j;
1065cdf0e10cSrcweir 
1066cdf0e10cSrcweir 	m_aItems.erase(i);
1067cdf0e10cSrcweir 	m_aMap.erase(j);
1068cdf0e10cSrcweir 
1069cdf0e10cSrcweir 	// remove event knittings
1070cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
1071cdf0e10cSrcweir     {
1072cdf0e10cSrcweir     	InterfaceRef xNormalized( xElement, UNO_QUERY );
1073cdf0e10cSrcweir 	    m_xEventAttacher->detach( _nIndex, xNormalized );
1074cdf0e10cSrcweir 	    m_xEventAttacher->removeEntry( _nIndex );
1075cdf0e10cSrcweir     }
1076cdf0e10cSrcweir 
1077cdf0e10cSrcweir 	Reference<XPropertySet>  xSet(xElement, UNO_QUERY);
1078cdf0e10cSrcweir 	if (xSet.is())
1079cdf0e10cSrcweir 		xSet->removePropertyChangeListener(PROPERTY_NAME, this);
1080cdf0e10cSrcweir 
1081cdf0e10cSrcweir 	Reference<XChild>  xChild(xElement, UNO_QUERY);
1082cdf0e10cSrcweir 	if (xChild.is())
1083cdf0e10cSrcweir 		xChild->setParent(InterfaceRef ());
1084cdf0e10cSrcweir 
1085cdf0e10cSrcweir 	// notify derived classes
1086cdf0e10cSrcweir 	implRemoved(xElement);
1087cdf0e10cSrcweir 
1088cdf0e10cSrcweir 	// notify listeners
1089cdf0e10cSrcweir 	ContainerEvent aEvt;
1090cdf0e10cSrcweir 	aEvt.Source     = static_cast<XContainer*>(this);
1091cdf0e10cSrcweir 	aEvt.Element    = xElement->queryInterface( m_aElementType );
1092cdf0e10cSrcweir 	aEvt.Accessor   <<= _nIndex;
1093cdf0e10cSrcweir 
1094cdf0e10cSrcweir 	_rClearBeforeNotify.clear();
1095cdf0e10cSrcweir     m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvt );
1096cdf0e10cSrcweir }
1097cdf0e10cSrcweir 
1098cdf0e10cSrcweir //------------------------------------------------------------------------------
removeByIndex(sal_Int32 _nIndex)1099cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::removeByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1100cdf0e10cSrcweir {
1101cdf0e10cSrcweir 	::osl::ClearableMutexGuard aGuard( m_rMutex );
1102cdf0e10cSrcweir 	// check the index
1103cdf0e10cSrcweir 	implCheckIndex( _nIndex );
1104cdf0e10cSrcweir 	// do the removal
1105cdf0e10cSrcweir 	implRemoveByIndex( _nIndex, aGuard );
1106cdf0e10cSrcweir }
1107cdf0e10cSrcweir 
1108cdf0e10cSrcweir //------------------------------------------------------------------------
createElementMetaData()1109cdf0e10cSrcweir ElementDescription* OInterfaceContainer::createElementMetaData( )
1110cdf0e10cSrcweir {
1111cdf0e10cSrcweir 	return new ElementDescription;
1112cdf0e10cSrcweir }
1113cdf0e10cSrcweir 
1114cdf0e10cSrcweir //------------------------------------------------------------------------
insertByName(const::rtl::OUString & _rName,const Any & _rElement)1115cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::insertByName(const ::rtl::OUString& _rName, const Any& _rElement) throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException )
1116cdf0e10cSrcweir {
1117cdf0e10cSrcweir 	Reference< XPropertySet > xElementProps;
1118cdf0e10cSrcweir 
1119cdf0e10cSrcweir 	::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
1120cdf0e10cSrcweir 	DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::insertByName: createElementMetaData returned nonsense!" );
1121cdf0e10cSrcweir 
1122cdf0e10cSrcweir 	// ensure the correct name of the element
1123cdf0e10cSrcweir 	try
1124cdf0e10cSrcweir 	{
1125cdf0e10cSrcweir 		_rElement >>= xElementProps;
1126cdf0e10cSrcweir 		approveNewElement( xElementProps, aElementMetaData.get() );
1127cdf0e10cSrcweir 
1128cdf0e10cSrcweir 		xElementProps->setPropertyValue( PROPERTY_NAME, makeAny( _rName ) );
1129cdf0e10cSrcweir 	}
1130cdf0e10cSrcweir 	catch( const IllegalArgumentException& )
1131cdf0e10cSrcweir 	{
1132cdf0e10cSrcweir 		throw;	// allowed to leave
1133cdf0e10cSrcweir 	}
1134cdf0e10cSrcweir 	catch( const ElementExistException& )
1135cdf0e10cSrcweir 	{
1136cdf0e10cSrcweir 		throw;	// allowed to leave
1137cdf0e10cSrcweir 	}
1138cdf0e10cSrcweir 	catch( const Exception& )
1139cdf0e10cSrcweir 	{
1140cdf0e10cSrcweir 		DBG_ERROR( "OInterfaceContainer::insertByName: caught an exception!" );
1141cdf0e10cSrcweir 	}
1142cdf0e10cSrcweir 	implInsert( m_aItems.size(), xElementProps, sal_True, aElementMetaData.get(), sal_True );
1143cdf0e10cSrcweir }
1144cdf0e10cSrcweir 
1145cdf0e10cSrcweir //------------------------------------------------------------------------
replaceByName(const::rtl::OUString & Name,const Any & Element)1146cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::replaceByName(const ::rtl::OUString& Name, const Any& Element) throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException )
1147cdf0e10cSrcweir {
1148cdf0e10cSrcweir 	::osl::ClearableMutexGuard aGuard( m_rMutex );
1149cdf0e10cSrcweir 	::std::pair <OInterfaceMap::iterator,
1150cdf0e10cSrcweir 		  OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
1151cdf0e10cSrcweir 	if (aPair.first == aPair.second)
1152cdf0e10cSrcweir 		throw NoSuchElementException();
1153cdf0e10cSrcweir 
1154cdf0e10cSrcweir 	if (Element.getValueType().getTypeClass() != TypeClass_INTERFACE)
1155cdf0e10cSrcweir 		lcl_throwIllegalArgumentException();
1156cdf0e10cSrcweir 
1157cdf0e10cSrcweir 	Reference<XPropertySet> xSet;
1158cdf0e10cSrcweir 	Element >>= xSet;
1159cdf0e10cSrcweir 	if (xSet.is())
1160cdf0e10cSrcweir 	{
1161cdf0e10cSrcweir 		if (!hasProperty(PROPERTY_NAME, xSet))
1162cdf0e10cSrcweir 			lcl_throwIllegalArgumentException();
1163cdf0e10cSrcweir 
1164cdf0e10cSrcweir 		xSet->setPropertyValue(PROPERTY_NAME, makeAny(Name));
1165cdf0e10cSrcweir 	}
1166cdf0e10cSrcweir 
1167cdf0e10cSrcweir 	// determine the element pos
1168cdf0e10cSrcweir 	sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
1169cdf0e10cSrcweir 
1170cdf0e10cSrcweir 	implReplaceByIndex( nPos, Element, aGuard );
1171cdf0e10cSrcweir }
1172cdf0e10cSrcweir 
1173cdf0e10cSrcweir //------------------------------------------------------------------------
removeByName(const::rtl::OUString & Name)1174cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::removeByName(const ::rtl::OUString& Name) throw( NoSuchElementException, WrappedTargetException, RuntimeException )
1175cdf0e10cSrcweir {
1176cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_rMutex );
1177cdf0e10cSrcweir 	::std::pair <OInterfaceMap::iterator,
1178cdf0e10cSrcweir 		  OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
1179cdf0e10cSrcweir 	if (aPair.first == aPair.second)
1180cdf0e10cSrcweir 		throw NoSuchElementException();
1181cdf0e10cSrcweir 
1182cdf0e10cSrcweir 	sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
1183cdf0e10cSrcweir 	removeByIndex(nPos);
1184cdf0e10cSrcweir }
1185cdf0e10cSrcweir 
1186cdf0e10cSrcweir 
1187cdf0e10cSrcweir // XEventAttacherManager
1188cdf0e10cSrcweir //------------------------------------------------------------------------
registerScriptEvent(sal_Int32 nIndex,const ScriptEventDescriptor & aScriptEvent)1189cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::registerScriptEvent( sal_Int32 nIndex, const ScriptEventDescriptor& aScriptEvent ) throw(IllegalArgumentException, RuntimeException)
1190cdf0e10cSrcweir {
1191cdf0e10cSrcweir 	::osl::ClearableMutexGuard aGuard( m_rMutex );
1192cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
1193cdf0e10cSrcweir     {
1194cdf0e10cSrcweir 	    m_xEventAttacher->registerScriptEvent( nIndex, aScriptEvent );
1195cdf0e10cSrcweir         aGuard.clear();
1196cdf0e10cSrcweir         impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
1197cdf0e10cSrcweir     }
1198cdf0e10cSrcweir }
1199cdf0e10cSrcweir 
1200cdf0e10cSrcweir //------------------------------------------------------------------------
registerScriptEvents(sal_Int32 nIndex,const Sequence<ScriptEventDescriptor> & aScriptEvents)1201cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::registerScriptEvents( sal_Int32 nIndex, const Sequence< ScriptEventDescriptor >& aScriptEvents ) throw(IllegalArgumentException, RuntimeException)
1202cdf0e10cSrcweir {
1203cdf0e10cSrcweir 	::osl::ClearableMutexGuard aGuard( m_rMutex );
1204cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
1205cdf0e10cSrcweir     {
1206cdf0e10cSrcweir     	m_xEventAttacher->registerScriptEvents( nIndex, aScriptEvents );
1207cdf0e10cSrcweir         aGuard.clear();
1208cdf0e10cSrcweir         impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
1209cdf0e10cSrcweir     }
1210cdf0e10cSrcweir }
1211cdf0e10cSrcweir 
1212cdf0e10cSrcweir //------------------------------------------------------------------------
revokeScriptEvent(sal_Int32 nIndex,const::rtl::OUString & aListenerType,const::rtl::OUString & aEventMethod,const::rtl::OUString & aRemoveListenerParam)1213cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::revokeScriptEvent( sal_Int32 nIndex, const ::rtl::OUString& aListenerType, const ::rtl::OUString& aEventMethod, const ::rtl::OUString& aRemoveListenerParam ) throw(IllegalArgumentException, RuntimeException)
1214cdf0e10cSrcweir {
1215cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
1216cdf0e10cSrcweir     	m_xEventAttacher->revokeScriptEvent( nIndex, aListenerType, aEventMethod, aRemoveListenerParam );
1217cdf0e10cSrcweir }
1218cdf0e10cSrcweir 
1219cdf0e10cSrcweir //------------------------------------------------------------------------
revokeScriptEvents(sal_Int32 nIndex)1220cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::revokeScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
1221cdf0e10cSrcweir {
1222cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
1223cdf0e10cSrcweir         m_xEventAttacher->revokeScriptEvents( nIndex );
1224cdf0e10cSrcweir }
1225cdf0e10cSrcweir 
1226cdf0e10cSrcweir //------------------------------------------------------------------------
insertEntry(sal_Int32 nIndex)1227cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::insertEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
1228cdf0e10cSrcweir {
1229cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
1230cdf0e10cSrcweir     	m_xEventAttacher->insertEntry( nIndex );
1231cdf0e10cSrcweir }
1232cdf0e10cSrcweir 
1233cdf0e10cSrcweir //------------------------------------------------------------------------
removeEntry(sal_Int32 nIndex)1234cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::removeEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
1235cdf0e10cSrcweir {
1236cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
1237cdf0e10cSrcweir 	    m_xEventAttacher->removeEntry( nIndex );
1238cdf0e10cSrcweir }
1239cdf0e10cSrcweir 
1240cdf0e10cSrcweir //------------------------------------------------------------------------
getScriptEvents(sal_Int32 nIndex)1241cdf0e10cSrcweir Sequence< ScriptEventDescriptor > SAL_CALL OInterfaceContainer::getScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
1242cdf0e10cSrcweir {
1243cdf0e10cSrcweir     Sequence< ScriptEventDescriptor > aReturn;
1244cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
1245cdf0e10cSrcweir     {
1246cdf0e10cSrcweir 	    aReturn = m_xEventAttacher->getScriptEvents( nIndex );
1247cdf0e10cSrcweir             if ( lcl_hasVbaEvents( aReturn ) )
1248cdf0e10cSrcweir             {
1249cdf0e10cSrcweir                 aReturn = lcl_stripVbaEvents( aReturn );
1250cdf0e10cSrcweir             }
1251cdf0e10cSrcweir     }
1252cdf0e10cSrcweir     return aReturn;
1253cdf0e10cSrcweir }
1254cdf0e10cSrcweir 
1255cdf0e10cSrcweir //------------------------------------------------------------------------
attach(sal_Int32 nIndex,const Reference<XInterface> & xObject,const Any & aHelper)1256cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::attach( sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any& aHelper ) throw(IllegalArgumentException, ServiceNotRegisteredException, RuntimeException)
1257cdf0e10cSrcweir {
1258cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
1259cdf0e10cSrcweir     	m_xEventAttacher->attach( nIndex, xObject, aHelper );
1260cdf0e10cSrcweir }
1261cdf0e10cSrcweir 
1262cdf0e10cSrcweir //------------------------------------------------------------------------
detach(sal_Int32 nIndex,const Reference<XInterface> & xObject)1263cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::detach( sal_Int32 nIndex, const Reference< XInterface >& xObject ) throw(IllegalArgumentException, RuntimeException)
1264cdf0e10cSrcweir {
1265cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
1266cdf0e10cSrcweir 	    m_xEventAttacher->detach( nIndex, xObject );
1267cdf0e10cSrcweir }
1268cdf0e10cSrcweir 
1269cdf0e10cSrcweir //------------------------------------------------------------------------
addScriptListener(const Reference<XScriptListener> & xListener)1270cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::addScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException)
1271cdf0e10cSrcweir {
1272cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
1273cdf0e10cSrcweir 	    m_xEventAttacher->addScriptListener( xListener );
1274cdf0e10cSrcweir }
1275cdf0e10cSrcweir 
1276cdf0e10cSrcweir //------------------------------------------------------------------------
removeScriptListener(const Reference<XScriptListener> & xListener)1277cdf0e10cSrcweir void SAL_CALL OInterfaceContainer::removeScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException)
1278cdf0e10cSrcweir {
1279cdf0e10cSrcweir     if ( m_xEventAttacher.is() )
1280cdf0e10cSrcweir 	    m_xEventAttacher->removeScriptListener( xListener );
1281cdf0e10cSrcweir }
1282cdf0e10cSrcweir 
1283cdf0e10cSrcweir //==================================================================
1284cdf0e10cSrcweir //= OFormComponents
1285cdf0e10cSrcweir //==================================================================
1286cdf0e10cSrcweir //------------------------------------------------------------------------------
queryAggregation(const Type & _rType)1287cdf0e10cSrcweir Any SAL_CALL OFormComponents::queryAggregation(const Type& _rType) throw(RuntimeException)
1288cdf0e10cSrcweir {
1289cdf0e10cSrcweir 	Any aReturn = OFormComponents_BASE::queryInterface(_rType);
1290cdf0e10cSrcweir 	if (!aReturn.hasValue())
1291cdf0e10cSrcweir 	{
1292cdf0e10cSrcweir 		aReturn = OInterfaceContainer::queryInterface(_rType);
1293cdf0e10cSrcweir 
1294cdf0e10cSrcweir 		if (!aReturn.hasValue())
1295cdf0e10cSrcweir 			aReturn = FormComponentsBase::queryAggregation(_rType);
1296cdf0e10cSrcweir 	}
1297cdf0e10cSrcweir 
1298cdf0e10cSrcweir 	return aReturn;
1299cdf0e10cSrcweir }
1300cdf0e10cSrcweir 
1301cdf0e10cSrcweir //------------------------------------------------------------------
getTypes()1302cdf0e10cSrcweir Sequence<Type> SAL_CALL OFormComponents::getTypes() throw(RuntimeException)
1303cdf0e10cSrcweir {
1304cdf0e10cSrcweir 	return ::comphelper::concatSequences(OInterfaceContainer::getTypes(), FormComponentsBase::getTypes(), OFormComponents_BASE::getTypes());
1305cdf0e10cSrcweir }
1306cdf0e10cSrcweir 
1307cdf0e10cSrcweir //------------------------------------------------------------------------------
OFormComponents(const Reference<XMultiServiceFactory> & _rxFactory)1308cdf0e10cSrcweir OFormComponents::OFormComponents(const Reference<XMultiServiceFactory>& _rxFactory)
1309cdf0e10cSrcweir     :FormComponentsBase( m_aMutex )
1310cdf0e10cSrcweir     ,OInterfaceContainer( _rxFactory, m_aMutex, XFormComponent::static_type() )
1311cdf0e10cSrcweir     ,OFormComponents_BASE()
1312cdf0e10cSrcweir {
1313cdf0e10cSrcweir }
1314cdf0e10cSrcweir 
1315cdf0e10cSrcweir //------------------------------------------------------------------------------
OFormComponents(const OFormComponents & _cloneSource)1316cdf0e10cSrcweir OFormComponents::OFormComponents( const OFormComponents& _cloneSource )
1317cdf0e10cSrcweir     :FormComponentsBase( m_aMutex )
1318cdf0e10cSrcweir     ,OInterfaceContainer( m_aMutex, _cloneSource )
1319cdf0e10cSrcweir     ,OFormComponents_BASE()
1320cdf0e10cSrcweir {
1321cdf0e10cSrcweir }
1322cdf0e10cSrcweir 
1323cdf0e10cSrcweir //------------------------------------------------------------------------------
~OFormComponents()1324cdf0e10cSrcweir OFormComponents::~OFormComponents()
1325cdf0e10cSrcweir {
1326cdf0e10cSrcweir 	if (!FormComponentsBase::rBHelper.bDisposed)
1327cdf0e10cSrcweir 	{
1328cdf0e10cSrcweir 		acquire();
1329cdf0e10cSrcweir 		dispose();
1330cdf0e10cSrcweir 	}
1331cdf0e10cSrcweir }
1332cdf0e10cSrcweir 
1333cdf0e10cSrcweir // OComponentHelper
1334cdf0e10cSrcweir //------------------------------------------------------------------------------
disposing()1335cdf0e10cSrcweir void OFormComponents::disposing()
1336cdf0e10cSrcweir {
1337cdf0e10cSrcweir 	OInterfaceContainer::disposing();
1338cdf0e10cSrcweir 	FormComponentsBase::disposing();
1339cdf0e10cSrcweir 	m_xParent = NULL;
1340cdf0e10cSrcweir }
1341cdf0e10cSrcweir 
1342cdf0e10cSrcweir //XChild
1343cdf0e10cSrcweir //------------------------------------------------------------------------------
setParent(const InterfaceRef & Parent)1344cdf0e10cSrcweir void OFormComponents::setParent(const InterfaceRef& Parent) throw( NoSupportException, RuntimeException )
1345cdf0e10cSrcweir {
1346cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
1347cdf0e10cSrcweir 	m_xParent = Parent;
1348cdf0e10cSrcweir }
1349cdf0e10cSrcweir 
1350cdf0e10cSrcweir //------------------------------------------------------------------------------
getParent()1351cdf0e10cSrcweir InterfaceRef OFormComponents::getParent() throw( RuntimeException )
1352cdf0e10cSrcweir {
1353cdf0e10cSrcweir 	return m_xParent;
1354cdf0e10cSrcweir }
1355cdf0e10cSrcweir 
1356cdf0e10cSrcweir //.........................................................................
1357cdf0e10cSrcweir }	// namespace frm
1358cdf0e10cSrcweir //.........................................................................
1359cdf0e10cSrcweir 
1360