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