update dev300-m58
[ooovba.git] / forms / source / misc / InterfaceContainer.cxx
blob250aed4da58b1606fe29cf6584fb88cca5f196e9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: InterfaceContainer.cxx,v $
10 * $Revision: 1.30 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_forms.hxx"
34 #include "frm_resource.hrc"
35 #include "frm_resource.hxx"
36 #include "InterfaceContainer.hxx"
37 #include "property.hrc"
38 #include "services.hxx"
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include <com/sun/star/container/XNamed.hpp>
42 #include <com/sun/star/io/WrongFormatException.hpp>
43 #include <com/sun/star/io/XMarkableStream.hpp>
44 #include <com/sun/star/lang/XComponent.hpp>
45 #include <com/sun/star/util/XCloneable.hpp>
47 #include <comphelper/container.hxx>
48 #include <comphelper/enumhelper.hxx>
49 #include <comphelper/eventattachermgr.hxx>
50 #include <comphelper/property.hxx>
51 #include <comphelper/sequence.hxx>
52 #include <comphelper/types.hxx>
53 #include <cppuhelper/exc_hlp.hxx>
54 #include <cppuhelper/queryinterface.hxx>
55 #include <rtl/logfile.hxx>
56 #include <tools/debug.hxx>
57 #include <tools/diagnose_ex.h>
59 #include <algorithm>
60 #include <memory>
62 //.........................................................................
63 #include <com/sun/star/frame/XModel.hpp>
64 #include <com/sun/star/document/XCodeNameQuery.hpp>
65 #include <ooo/vba/XVBAToOOEventDescGen.hpp>
66 #include <comphelper/processfactory.hxx>
68 namespace frm
70 //.........................................................................
72 using namespace ::com::sun::star::frame;
73 using namespace ::com::sun::star::lang;
74 using namespace ::com::sun::star::uno;
75 using namespace ::com::sun::star::beans;
76 using namespace ::com::sun::star::document;
77 using namespace ::com::sun::star::container;
78 using namespace ::com::sun::star::script;
79 using namespace ::com::sun::star::io;
80 using namespace ::com::sun::star::form;
81 using namespace ::com::sun::star::util;
83 namespace
85 //---------------------------------------------------------------------
86 static void lcl_throwIllegalArgumentException()
88 throw IllegalArgumentException();
92 bool
93 lcl_hasVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents )
95 const ScriptEventDescriptor* pDesc = sEvents.getConstArray();
96 const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() );
97 for ( ; pDesc != pEnd; ++pDesc )
99 if ( pDesc->ScriptType.equals( rtl::OUString::createFromAscii( "VBAInterop" ) ) )
100 return true;
102 return false;
105 Sequence< ScriptEventDescriptor >
106 lcl_stripVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents )
108 Sequence< ScriptEventDescriptor > sStripped( sEvents.getLength() );
110 const ScriptEventDescriptor* pDesc = sEvents.getConstArray();
111 const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() );
112 sal_Int32 nCopied = 0;
113 for ( ; pDesc != pEnd; ++pDesc )
115 if ( !pDesc->ScriptType.equals( rtl::OUString::createFromAscii( "VBAInterop" ) ) )
117 sStripped[ nCopied++ ] = *pDesc;
120 if ( nCopied )
121 sStripped.realloc( nCopied );
122 return sStripped;
125 void
126 OInterfaceContainer::fakeVbaEventsHack( sal_Int32 _nIndex )
128 // we are dealing with form controls
131 Reference< XFormComponent > xForm( static_cast< XContainer* >(this), UNO_QUERY_THROW );
132 // grand-parent should be the model, no parent ? if not
133 // we'll ignore, we'll get called back here anyway )
134 Reference< XChild > xChild( xForm->getParent(), UNO_QUERY_THROW );
135 Reference< XModel > xDocOwner( xChild->getParent(), UNO_QUERY );
136 OSL_TRACE(" Is DOC ????? %s", xDocOwner.is() ? "true" : "false" );
137 if ( xDocOwner.is() )
139 bool hasVBABindings = lcl_hasVbaEvents( m_xEventAttacher->getScriptEvents( _nIndex ) );
140 if ( hasVBABindings )
142 OSL_TRACE("Has VBA bindings already, returning ");
143 return;
145 Reference< XMultiServiceFactory > xFac( comphelper::getProcessServiceFactory(), UNO_QUERY );
146 Reference< XMultiServiceFactory > xDocFac( xDocOwner, UNO_QUERY );
147 if ( xFac.is() && xDocFac.is() )
151 Reference< ooo::vba::XVBAToOOEventDescGen > xDescSupplier( xFac->createInstance( rtl::OUString::createFromAscii( "ooo.vba.VBAToOOEventDesc" ) ), UNO_QUERY_THROW );
152 Reference< XInterface > xIf( getByIndex( _nIndex ) , UNO_QUERY_THROW );
153 Reference< XCodeNameQuery > xNameQuery( xDocFac->createInstance( rtl::OUString::createFromAscii( "ooo.vba.VBACodeNameProvider" ) ), UNO_QUERY_THROW );
154 rtl::OUString sCodeName;
155 sCodeName = xNameQuery->getCodeNameForObject( xIf );
156 Reference< XPropertySet > xProps( xIf, UNO_QUERY );
157 rtl::OUString sServiceName;
158 xProps->getPropertyValue( rtl::OUString::createFromAscii("DefaultControl" ) ) >>= sServiceName;
160 Sequence< ScriptEventDescriptor > vbaEvents = xDescSupplier->getEventDescriptions( xFac->createInstance( sServiceName ), sCodeName );
161 // register the vba script events
162 if ( m_xEventAttacher.is() )
163 m_xEventAttacher->registerScriptEvents( _nIndex, vbaEvents );
165 catch( Exception& e ){ OSL_TRACE("lcl_fakevbaevents - Caught Exception trying to create control eventstuff "); }
170 catch( Exception& e )
175 //==================================================================
176 //= ElementDescription
177 //==================================================================
178 //------------------------------------------------------------------
179 ElementDescription::ElementDescription( )
183 //------------------------------------------------------------------
184 ElementDescription::~ElementDescription()
188 //==================================================================
189 //= OInterfaceContainer
190 //==================================================================
191 //------------------------------------------------------------------
192 OInterfaceContainer::OInterfaceContainer(
193 const Reference<XMultiServiceFactory>& _rxFactory,
194 ::osl::Mutex& _rMutex,
195 const Type& _rElementType)
196 :OInterfaceContainer_BASE()
197 ,m_rMutex(_rMutex)
198 ,m_aContainerListeners(_rMutex)
199 ,m_aElementType(_rElementType)
200 ,m_xServiceFactory(_rxFactory)
202 impl_createEventAttacher_nothrow();
205 //------------------------------------------------------------------------------
206 OInterfaceContainer::OInterfaceContainer( ::osl::Mutex& _rMutex, const OInterfaceContainer& _cloneSource )
207 :OInterfaceContainer_BASE()
208 ,m_rMutex( _rMutex )
209 ,m_aContainerListeners( _rMutex )
210 ,m_aElementType( _cloneSource.m_aElementType )
211 ,m_xServiceFactory( _cloneSource.m_xServiceFactory )
213 impl_createEventAttacher_nothrow();
216 //------------------------------------------------------------------------------
217 void OInterfaceContainer::clonedFrom( const OInterfaceContainer& _cloneSource )
221 const Reference< XIndexAccess > xSourceHierarchy( const_cast< OInterfaceContainer* >( &_cloneSource ) );
222 const sal_Int32 nCount = xSourceHierarchy->getCount();
223 for ( sal_Int32 i=0; i<nCount; ++i )
225 Reference< XCloneable > xCloneable( xSourceHierarchy->getByIndex( i ), UNO_QUERY_THROW );
226 Reference< XInterface > xClone( xCloneable->createClone() );
227 insertByIndex( i, makeAny( xClone ) );
230 catch( const Exception& )
232 throw WrappedTargetException(
233 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not clone the given interface hierarchy." ) ),
234 static_cast< XIndexContainer* >( const_cast< OInterfaceContainer* >( &_cloneSource ) ),
235 ::cppu::getCaughtException()
240 //------------------------------------------------------------------------------
241 void OInterfaceContainer::impl_createEventAttacher_nothrow()
245 m_xEventAttacher.set( ::comphelper::createEventAttacherManager( m_xServiceFactory ), UNO_SET_THROW );
247 catch( const Exception& )
249 DBG_UNHANDLED_EXCEPTION();
253 //------------------------------------------------------------------------------
254 OInterfaceContainer::~OInterfaceContainer()
258 //------------------------------------------------------------------------------
259 void OInterfaceContainer::disposing()
261 // dispose all elements
262 for (sal_Int32 i = m_aItems.size(); i > 0; --i)
264 Reference<XPropertySet> xSet(m_aItems[i - 1], UNO_QUERY);
265 if (xSet.is())
266 xSet->removePropertyChangeListener(PROPERTY_NAME, this);
268 // revoke event knittings
269 if ( m_xEventAttacher.is() )
271 Reference< XInterface > xIfc( xSet, UNO_QUERY );
272 m_xEventAttacher->detach( i - 1, xIfc );
273 m_xEventAttacher->removeEntry( i - 1 );
276 Reference<XComponent> xComponent(xSet, UNO_QUERY);
277 if (xComponent.is())
278 xComponent->dispose();
280 m_aMap.clear();
281 m_aItems.clear();
283 EventObject aEvt(static_cast<XContainer*>(this));
284 m_aContainerListeners.disposeAndClear(aEvt);
287 // XPersistObject
288 //------------------------------------------------------------------------------
289 namespace
291 //..........................................................................
292 void lcl_saveEvents( ::std::vector< Sequence< ScriptEventDescriptor > >& _rSave,
293 const Reference< XEventAttacherManager >& _rxManager, const sal_Int32 _nItemCount )
295 OSL_ENSURE( _rxManager.is(), "lcl_saveEvents: invalid event attacher manager!" );
296 if ( !_rxManager.is() )
297 return;
299 // reserve the space needed
300 _rSave.reserve( _nItemCount );
302 // copy the events
303 for (sal_Int32 i=0; i<_nItemCount; ++i)
304 _rSave.push_back(_rxManager->getScriptEvents( i ));
307 //..........................................................................
308 void lcl_restoreEvents( const ::std::vector< Sequence< ScriptEventDescriptor > >& _rSave,
309 const Reference< XEventAttacherManager >& _rxManager )
311 OSL_ENSURE( _rxManager.is(), "lcl_restoreEvents: invalid event attacher manager!" );
312 if ( !_rxManager.is() )
313 return;
315 ::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aLoop = _rSave.begin();
316 ::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aEnd = _rSave.end();
317 for ( sal_Int32 i=0; aLoop != aEnd; ++aLoop, ++i )
319 _rxManager->revokeScriptEvents( i );
320 _rxManager->registerScriptEvents( i, *aLoop );
325 //------------------------------------------------------------------------------
326 void SAL_CALL OInterfaceContainer::writeEvents(const Reference<XObjectOutputStream>& _rxOutStream)
328 // We're writing a document in SO 5.2 format (or even from earlier versions)
329 // -> convert the events from the new runtime format to the format of the 5.2 files
330 // but before, remember the current script events set for our children
331 ::std::vector< Sequence< ScriptEventDescriptor > > aSave;
332 if ( m_xEventAttacher.is() )
333 lcl_saveEvents( aSave, m_xEventAttacher, m_aItems.size() );
335 transformEvents( efVersionSO5x );
339 Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
340 sal_Int32 nMark = xMark->createMark();
342 sal_Int32 nObjLen = 0;
343 _rxOutStream->writeLong(nObjLen);
345 Reference<XPersistObject> xScripts(m_xEventAttacher, UNO_QUERY);
346 if (xScripts.is())
347 xScripts->write(_rxOutStream);
349 // feststellen der Laenge
350 nObjLen = xMark->offsetToMark(nMark) - 4;
351 xMark->jumpToMark(nMark);
352 _rxOutStream->writeLong(nObjLen);
353 xMark->jumpToFurthest();
354 xMark->deleteMark(nMark);
356 catch( const Exception& )
358 // restore the events
359 if ( m_xEventAttacher.is() )
360 lcl_restoreEvents( aSave, m_xEventAttacher );
361 throw;
364 // restore the events
365 if ( m_xEventAttacher.is() )
366 lcl_restoreEvents( aSave, m_xEventAttacher );
369 //------------------------------------------------------------------------------
370 struct TransformEventTo52Format : public ::std::unary_function< ScriptEventDescriptor, void >
372 void operator()( ScriptEventDescriptor& _rDescriptor )
374 if ( 0 == _rDescriptor.ScriptType.compareToAscii( "StarBasic" ) )
375 { // it's a starbasic macro
376 sal_Int32 nPrefixLength = _rDescriptor.ScriptCode.indexOf( ':' );
377 if ( 0 <= nPrefixLength )
378 { // the macro name does not already contain a :
379 #ifdef DBG_UTIL
380 const ::rtl::OUString sPrefix = _rDescriptor.ScriptCode.copy( 0, nPrefixLength );
381 DBG_ASSERT( 0 == sPrefix.compareToAscii( "document" )
382 || 0 == sPrefix.compareToAscii( "application" ),
383 "TransformEventTo52Format: invalid (unknown) prefix!" );
384 #endif
385 // cut the prefix
386 _rDescriptor.ScriptCode = _rDescriptor.ScriptCode.copy( nPrefixLength + 1 );
392 //------------------------------------------------------------------------------
393 struct TransformEventTo60Format : public ::std::unary_function< ScriptEventDescriptor, void >
395 void operator()( ScriptEventDescriptor& _rDescriptor )
397 if ( 0 == _rDescriptor.ScriptType.compareToAscii( "StarBasic" ) )
398 { // it's a starbasic macro
399 if ( _rDescriptor.ScriptCode.indexOf( ':' ) < 0 )
400 { // the macro name does not already contain a :
401 // -> default the type to "document"
402 ::rtl::OUString sNewScriptCode( RTL_CONSTASCII_USTRINGPARAM( "document:" ) );
403 sNewScriptCode += _rDescriptor.ScriptCode;
404 _rDescriptor.ScriptCode = sNewScriptCode;
410 //------------------------------------------------------------------------------
411 void OInterfaceContainer::transformEvents( const EventFormat _eTargetFormat )
413 OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::transformEvents: no event attacher manager!" );
414 if ( !m_xEventAttacher.is() )
415 return;
419 // loop through all our children
420 sal_Int32 nItems = m_aItems.size();
421 Sequence< ScriptEventDescriptor > aChildEvents;
423 for (sal_Int32 i=0; i<nItems; ++i)
425 // get the script events for this object
426 aChildEvents = m_xEventAttacher->getScriptEvents( i );
428 if ( aChildEvents.getLength() )
430 // the "iterators" for the events for this child
431 ScriptEventDescriptor* pChildEvents = aChildEvents.getArray();
432 ScriptEventDescriptor* pChildEventsEnd = pChildEvents + aChildEvents.getLength();
434 // do the transformation
435 if ( efVersionSO6x == _eTargetFormat )
436 ::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo60Format() );
437 else
438 ::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo52Format() );
440 // revoke the script events
441 m_xEventAttacher->revokeScriptEvents( i );
442 // and re-register them
443 m_xEventAttacher->registerScriptEvents( i, aChildEvents );
447 catch( const Exception& )
449 DBG_UNHANDLED_EXCEPTION();
453 //------------------------------------------------------------------------------
454 void SAL_CALL OInterfaceContainer::readEvents(const Reference<XObjectInputStream>& _rxInStream)
456 ::osl::MutexGuard aGuard( m_rMutex );
458 // Scripting Info lesen
459 Reference<XMarkableStream> xMark(_rxInStream, UNO_QUERY);
460 sal_Int32 nObjLen = _rxInStream->readLong();
461 if (nObjLen)
463 sal_Int32 nMark = xMark->createMark();
464 Reference<XPersistObject> xObj(m_xEventAttacher, UNO_QUERY);
465 if (xObj.is())
466 xObj->read(_rxInStream);
467 xMark->jumpToMark(nMark);
468 _rxInStream->skipBytes(nObjLen);
469 xMark->deleteMark(nMark);
472 // Attachement lesen
473 if ( m_xEventAttacher.is() )
475 OInterfaceArray::const_iterator aAttach = m_aItems.begin();
476 OInterfaceArray::const_iterator aAttachEnd = m_aItems.end();
477 for ( sal_Int32 i=0; aAttach != aAttachEnd; ++aAttach, ++i )
479 Reference< XInterface > xAsIFace( *aAttach, UNO_QUERY ); // important to normalize this ....
480 Reference< XPropertySet > xAsSet( xAsIFace, UNO_QUERY );
481 m_xEventAttacher->attach( i, xAsIFace, makeAny( xAsSet ) );
486 //------------------------------------------------------------------------------
487 void SAL_CALL OInterfaceContainer::write( const Reference< XObjectOutputStream >& _rxOutStream ) throw(IOException, RuntimeException)
489 ::osl::MutexGuard aGuard( m_rMutex );
490 sal_Int32 nLen = m_aItems.size();
492 // schreiben der laenge
493 _rxOutStream->writeLong(nLen);
495 if (nLen)
497 // 1. Version
498 _rxOutStream->writeShort(0x0001);
500 // 2. Objekte
501 for (sal_Int32 i = 0; i < nLen; i++)
503 Reference<XPersistObject> xObj(m_aItems[i], UNO_QUERY);
504 if (xObj.is())
505 _rxOutStream->writeObject(xObj);
506 else
508 // ::com::sun::star::chaos::Error
512 // 3. Scripts
513 writeEvents(_rxOutStream);
517 //------------------------------------------------------------------------------
518 namespace
520 Reference< XPersistObject > lcl_createPlaceHolder( const Reference< XMultiServiceFactory >& _rxORB )
522 Reference< XPersistObject > xObject( _rxORB->createInstance( FRM_COMPONENT_HIDDENCONTROL ), UNO_QUERY );
523 DBG_ASSERT( xObject.is(), "lcl_createPlaceHolder: could not create a substitute for the unknown object!" );
524 if ( xObject.is() )
526 // set some properties describing what we did
527 Reference< XPropertySet > xObjProps( xObject, UNO_QUERY );
528 if ( xObject.is() )
532 xObjProps->setPropertyValue( PROPERTY_NAME, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_NAME ) ) );
533 xObjProps->setPropertyValue( PROPERTY_TAG, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_EPXPLAIN ) ) );
535 catch(Exception&)
540 return xObject;
544 //------------------------------------------------------------------------------
545 void SAL_CALL OInterfaceContainer::read( const Reference< XObjectInputStream >& _rxInStream ) throw(IOException, RuntimeException)
547 ::osl::MutexGuard aGuard( m_rMutex );
549 // after ::read the object is expected to be in the state it was when ::write was called, so we have
550 // to empty ourself here
551 // FS - 71598 - 12.01.00
552 while (getCount())
553 removeByIndex(0);
555 // Schreibt nur in Abhaengigkeit der Laenge
556 sal_Int32 nLen = _rxInStream->readLong();
558 if (nLen)
560 // 1. Version
561 sal_uInt16 nVersion = _rxInStream->readShort(); (void)nVersion;
563 // 2. Objekte
564 for (sal_Int32 i = 0; i < nLen; i++)
566 Reference<XPersistObject> xObj;
569 xObj = _rxInStream->readObject();
571 catch(WrongFormatException& e)
573 (void)e; // make compiler happy
574 // the object could not be read
575 // create a object (so the readEvents below will assign the events to the right controls)
576 xObj = lcl_createPlaceHolder( m_xServiceFactory );
577 if ( !xObj.is() )
578 // couldn't handle it
579 throw;
580 // 72133 - 09.02.00 - FS
582 catch(Exception&)
584 // unsere Map leeren
585 while (!m_aItems.empty())
586 removeElementsNoEvents(0);
588 // und die Exception nach aussen
589 throw;
592 if ( xObj.is() )
594 Reference< XPropertySet > xElement( xObj, UNO_QUERY );
597 implInsert(
598 m_aItems.size(), // position
599 xElement, // element to insert
600 sal_False, // no event attacher manager handling
601 NULL, // not yet approved - let implInsert do it
602 sal_True // fire the event
605 catch( const Exception& )
607 DBG_ERROR( "OInterfaceContainerHelper::read: reading succeeded, but not inserting!" );
608 // create a placeholder
609 xElement = xElement.query( lcl_createPlaceHolder( m_xServiceFactory ) );
610 if ( !xElement.is() )
611 // couldn't handle it
612 throw;
613 // insert the placeholder
614 implInsert( m_aItems.size(), xElement, sal_False, NULL, sal_True );
619 readEvents(_rxInStream);
621 else
625 m_xEventAttacher = ::comphelper::createEventAttacherManager( m_xServiceFactory );
626 OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::read: could not create an event attacher manager!" );
628 catch( const Exception& )
630 DBG_UNHANDLED_EXCEPTION();
635 // XContainer
636 //------------------------------------------------------------------------------
637 void SAL_CALL OInterfaceContainer::addContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException )
639 m_aContainerListeners.addInterface(_rxListener);
642 //------------------------------------------------------------------------------
643 void SAL_CALL OInterfaceContainer::removeContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException )
645 m_aContainerListeners.removeInterface(_rxListener);
648 // XEventListener
649 //------------------------------------------------------------------------------
650 void SAL_CALL OInterfaceContainer::disposing(const EventObject& _rSource) throw( RuntimeException )
652 ::osl::MutexGuard aGuard( m_rMutex );
654 Reference< XInterface > xSource( _rSource.Source, UNO_QUERY );
655 // normalized source
657 OInterfaceArray::iterator j;
658 for ( j = m_aItems.begin(); j != m_aItems.end(); ++j )
660 DBG_ASSERT( j->get() == Reference< XInterface >( *j, UNO_QUERY ).get(),
661 "OInterfaceContainer::disposing: vector element not normalized!" );
663 if ( xSource.get() == j->get() )
664 // found the element
665 break;
668 if ( m_aItems.end() != j )
670 m_aItems.erase(j);
672 // look up in, and erase from, m_aMap, too
673 OInterfaceMap::iterator i = m_aMap.begin();
674 while ( i != m_aMap.end() )
676 DBG_ASSERT( i->second.get() == Reference< XInterface >( i->second, UNO_QUERY ).get(),
677 "OInterfaceContainer::disposing: map element not normalized!" );
679 if ( i->second.get() == xSource.get() )
681 // found it
682 m_aMap.erase(i);
683 break;
686 ++i;
688 DBG_ASSERT( i != m_aMap.end(), "OInterfaceContainer::disposing: inconsistency: the element was in m_aItems, but not in m_aMap!" );
693 // XPropertyChangeListener
694 //------------------------------------------------------------------------------
695 void OInterfaceContainer::propertyChange(const PropertyChangeEvent& evt)
696 throw (::com::sun::star::uno::RuntimeException) {
697 if (evt.PropertyName == PROPERTY_NAME)
699 ::osl::MutexGuard aGuard( m_rMutex );
700 OInterfaceMap::iterator i = ::std::find(m_aMap.begin(), m_aMap.end(),
701 ::std::pair<const ::rtl::OUString, InterfaceRef >(::comphelper::getString(evt.OldValue),evt.Source));
702 if (i != m_aMap.end())
704 InterfaceRef xCorrectType((*i).second);
705 m_aMap.erase(i);
706 m_aMap.insert(::std::pair<const ::rtl::OUString, InterfaceRef >(::comphelper::getString(evt.NewValue),xCorrectType));
711 // XElementAccess
712 //------------------------------------------------------------------------------
713 sal_Bool SAL_CALL OInterfaceContainer::hasElements() throw( RuntimeException )
715 return !m_aMap.empty();
718 //------------------------------------------------------------------------------
719 Type SAL_CALL OInterfaceContainer::getElementType() throw(RuntimeException)
721 return m_aElementType;
724 // XEnumerationAccess
725 //------------------------------------------------------------------------------
726 Reference<XEnumeration> SAL_CALL OInterfaceContainer::createEnumeration() throw( RuntimeException )
728 ::osl::MutexGuard aGuard( m_rMutex );
729 return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this));
732 // XNameAccess
733 //------------------------------------------------------------------------------
734 Any SAL_CALL OInterfaceContainer::getByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
736 ::std::pair <OInterfaceMap::iterator,
737 OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
739 if (aPair.first == aPair.second)
740 throw NoSuchElementException();
742 return (*aPair.first).second->queryInterface( m_aElementType );
745 //------------------------------------------------------------------------------
746 StringSequence SAL_CALL OInterfaceContainer::getElementNames() throw(RuntimeException)
748 StringSequence aNameList(m_aItems.size());
749 ::rtl::OUString* pStringArray = aNameList.getArray();
751 for (OInterfaceMap::const_iterator i = m_aMap.begin(); i != m_aMap.end(); ++i, ++pStringArray)
753 *pStringArray = (*i).first;
755 return aNameList;
758 //------------------------------------------------------------------------------
759 sal_Bool SAL_CALL OInterfaceContainer::hasByName( const ::rtl::OUString& _rName ) throw(RuntimeException)
761 ::std::pair <OInterfaceMap::iterator,
762 OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
763 return aPair.first != aPair.second;
766 // XIndexAccess
767 //------------------------------------------------------------------------------
768 sal_Int32 OInterfaceContainer::getCount() throw( RuntimeException )
770 return m_aItems.size();
773 //------------------------------------------------------------------------------
774 Any OInterfaceContainer::getByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
776 if (_nIndex < 0 || (_nIndex >= (sal_Int32)m_aItems.size()))
777 throw IndexOutOfBoundsException();
779 return m_aItems[_nIndex]->queryInterface( m_aElementType );
782 //------------------------------------------------------------------------------
783 void OInterfaceContainer::approveNewElement( const Reference< XPropertySet >& _rxObject, ElementDescription* _pElement )
785 // it has to be non-NULL
786 if ( !_rxObject.is() )
787 throw IllegalArgumentException(FRM_RES_STRING(RID_STR_NEED_NON_NULL_OBJECT), static_cast<XContainer*>(this), 1);
789 // it has to support our element type interface
790 Any aCorrectType = _rxObject->queryInterface( m_aElementType );
791 if ( !aCorrectType.hasValue() )
792 lcl_throwIllegalArgumentException();
794 // it has to have a "Name" property
795 if ( !hasProperty( PROPERTY_NAME, _rxObject ) )
796 lcl_throwIllegalArgumentException();
798 // it has to be a child, and it must not have a parent already
799 Reference< XChild > xChild( _rxObject, UNO_QUERY );
800 if ( !xChild.is() || xChild->getParent().is() )
802 #ifdef FS_PRIV_DEBUG
803 ::rtl::OUString sChildName, sParentName;
804 Reference< XNamed > xNamed( xChild, UNO_QUERY );
805 if ( xNamed.is() )
806 sChildName = xNamed->getName();
807 if ( xChild.is() )
809 xNamed = xNamed.query( xChild->getParent() );
810 if ( xNamed.is() )
811 sParentName = xNamed->getName();
813 #endif
814 lcl_throwIllegalArgumentException();
817 // passed all tests. cache the information we have so far
818 DBG_ASSERT( _pElement, "OInterfaceContainer::approveNewElement: invalid event descriptor!" );
819 if ( _pElement )
821 _pElement->xPropertySet = _rxObject;
822 _pElement->xChild = xChild;
823 _pElement->aElementTypeInterface = aCorrectType;
824 _pElement->xInterface = Reference< XInterface >( _rxObject, UNO_QUERY ); // normalized XInterface
828 //------------------------------------------------------------------------------
829 void OInterfaceContainer::implInsert(sal_Int32 _nIndex, const Reference< XPropertySet >& _rxElement,
830 sal_Bool _bEvents, ElementDescription* _pApprovalResult, sal_Bool _bFire ) throw( IllegalArgumentException )
832 OSL_TRACE("OInterfaceContainer::implInsert( %d)", _nIndex );
833 RTL_LOGFILE_CONTEXT( aLogger, "forms::OInterfaceContainer::implInsert" );
835 ::osl::ClearableMutexGuard aGuard( m_rMutex );
837 ::std::auto_ptr< ElementDescription > aAutoDeleteMetaData;
838 ElementDescription* pElementMetaData = _pApprovalResult;
839 if ( !pElementMetaData )
840 { // not yet approved by the caller -> do ourself
841 pElementMetaData = createElementMetaData();
842 DBG_ASSERT( pElementMetaData, "OInterfaceContainer::implInsert: createElementMetaData returned nonsense!" );
844 // ensure that the meta data structure will be deleted later on
845 aAutoDeleteMetaData = ::std::auto_ptr< ElementDescription >( pElementMetaData );
847 // will throw an exception if necessary
848 approveNewElement( _rxElement, pElementMetaData );
852 // approveNewElement (no matter if called here or outside) has ensure that all relevant interfaces
853 // exist
855 // set the name, and add as change listener for the name
856 ::rtl::OUString sName;
857 _rxElement->getPropertyValue(PROPERTY_NAME) >>= sName;
858 _rxElement->addPropertyChangeListener(PROPERTY_NAME, this);
860 // insert the object into our internal structures
861 if (_nIndex > (sal_Int32)m_aItems.size()) // ermitteln des tatsaechlichen Indexs
863 _nIndex = m_aItems.size();
864 m_aItems.push_back( pElementMetaData->xInterface );
866 else
867 m_aItems.insert( m_aItems.begin() + _nIndex, pElementMetaData->xInterface );
869 m_aMap.insert( ::std::pair< const ::rtl::OUString, InterfaceRef >( sName, pElementMetaData->xInterface ) );
871 // announce ourself as parent to the new element
873 RTL_LOGFILE_CONTEXT( aLogger, "forms::OInterfaceContainer::implInsert::settingParent" );
874 pElementMetaData->xChild->setParent(static_cast<XContainer*>(this));
877 // handle the events
878 if ( _bEvents && m_xEventAttacher.is() )
880 m_xEventAttacher->insertEntry(_nIndex);
881 m_xEventAttacher->attach( _nIndex, pElementMetaData->xInterface, makeAny( _rxElement ) );
882 // insert fake events?
883 Reference< XEventAttacherManager > xMgr ( pElementMetaData->xInterface, UNO_QUERY );
884 if ( xMgr.is() )
886 OInterfaceContainer* pIfcMgr = dynamic_cast< OInterfaceContainer* >( xMgr.get() );
887 sal_Int32 nLen = pIfcMgr->getCount();
888 for ( sal_Int32 i = 0; (i < nLen) && pIfcMgr ; ++i )
890 // add fake events to the control at index i
891 pIfcMgr->fakeVbaEventsHack( i );
894 else
896 // add fake events to the control at index i
897 fakeVbaEventsHack( _nIndex );
901 // notify derived classes
902 implInserted( pElementMetaData );
904 // fire the notification about the change
905 if ( _bFire )
907 // notify listeners
908 ContainerEvent aEvt;
909 aEvt.Source = static_cast<XContainer*>(this);
910 aEvt.Accessor <<= _nIndex;
911 aEvt.Element = pElementMetaData->aElementTypeInterface;
913 aGuard.clear();
914 m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvt );
918 //------------------------------------------------------------------------------
919 void OInterfaceContainer::removeElementsNoEvents(sal_Int32 nIndex)
921 OInterfaceArray::iterator i = m_aItems.begin() + nIndex;
922 InterfaceRef xElement(*i);
924 OInterfaceMap::iterator j = m_aMap.begin();
925 while (j != m_aMap.end() && (*j).second != xElement) ++j;
927 m_aItems.erase(i);
928 m_aMap.erase(j);
930 Reference<XPropertySet> xSet(xElement, UNO_QUERY);
931 if (xSet.is())
932 xSet->removePropertyChangeListener(PROPERTY_NAME, this);
934 Reference<XChild> xChild(xElement, UNO_QUERY);
935 if (xChild.is())
936 xChild->setParent(InterfaceRef ());
939 //------------------------------------------------------------------------------
940 void OInterfaceContainer::implInserted( const ElementDescription* /*_pElement*/ )
942 // not inrerested in
945 //------------------------------------------------------------------------------
946 void OInterfaceContainer::implRemoved( const InterfaceRef& /*_rxObject*/ )
948 // not inrerested in
951 //------------------------------------------------------------------------------
952 void OInterfaceContainer::impl_replacedElement( const ContainerEvent& _rEvent, ::osl::ClearableMutexGuard& _rInstanceLock )
954 _rInstanceLock.clear();
955 m_aContainerListeners.notifyEach( &XContainerListener::elementReplaced, _rEvent );
958 // XIndexContainer
959 //------------------------------------------------------------------------------
960 void SAL_CALL OInterfaceContainer::insertByIndex( sal_Int32 _nIndex, const Any& _rElement ) throw(IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
962 Reference< XPropertySet > xElement;
963 _rElement >>= xElement;
964 implInsert( _nIndex, xElement, sal_True /* event handling */ , NULL /* not yet approved */ , sal_True /* notification */ );
967 //------------------------------------------------------------------------------
968 void OInterfaceContainer::implReplaceByIndex( const sal_Int32 _nIndex, const Any& _rNewElement, ::osl::ClearableMutexGuard& _rClearBeforeNotify )
970 OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implReplaceByIndex: precondition not met (index)!" );
972 // approve the new object
973 ::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
974 DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::implReplaceByIndex: createElementMetaData returned nonsense!" );
976 Reference< XPropertySet > xElementProps;
977 _rNewElement >>= xElementProps;
978 approveNewElement( xElementProps, aElementMetaData.get() );
981 // get the old element
982 InterfaceRef xOldElement( m_aItems[ _nIndex ] );
983 DBG_ASSERT( xOldElement.get() == Reference< XInterface >( xOldElement, UNO_QUERY ).get(),
984 "OInterfaceContainer::implReplaceByIndex: elements should be held normalized!" );
986 // locate the old element in the map
987 OInterfaceMap::iterator j = m_aMap.begin();
988 while ( ( j != m_aMap.end() ) && ( j->second.get() != xOldElement.get() ) )
989 ++j;
991 // remove event knittings
992 if ( m_xEventAttacher.is() )
994 InterfaceRef xNormalized( xOldElement, UNO_QUERY );
995 m_xEventAttacher->detach( _nIndex, xNormalized );
996 m_xEventAttacher->removeEntry( _nIndex );
999 // don't listen for property changes anymore
1000 Reference<XPropertySet> xSet( xOldElement, UNO_QUERY );
1001 if (xSet.is())
1002 xSet->removePropertyChangeListener(PROPERTY_NAME, this);
1004 // give the old element a new (void) parent
1005 Reference<XChild> xChild(xOldElement, UNO_QUERY);
1006 if (xChild.is())
1007 xChild->setParent(InterfaceRef ());
1009 // remove the old one
1010 m_aMap.erase(j);
1012 // examine the new element
1013 ::rtl::OUString sName;
1014 DBG_ASSERT( aElementMetaData.get()->xPropertySet.is(), "OInterfaceContainer::implReplaceByIndex: what did approveNewElement do?" );
1016 aElementMetaData.get()->xPropertySet->getPropertyValue(PROPERTY_NAME) >>= sName;
1017 aElementMetaData.get()->xPropertySet->addPropertyChangeListener(PROPERTY_NAME, this);
1019 // insert the new one
1020 m_aMap.insert( ::std::pair<const ::rtl::OUString, InterfaceRef >( sName, aElementMetaData.get()->xInterface ) );
1021 m_aItems[ _nIndex ] = aElementMetaData.get()->xInterface;
1023 aElementMetaData.get()->xChild->setParent(static_cast<XContainer*>(this));
1025 if ( m_xEventAttacher.is() )
1027 m_xEventAttacher->insertEntry( _nIndex );
1028 m_xEventAttacher->attach( _nIndex, aElementMetaData.get()->xInterface, makeAny( aElementMetaData.get()->xPropertySet ) );
1031 ContainerEvent aReplaceEvent;
1032 aReplaceEvent.Source = static_cast< XContainer* >( this );
1033 aReplaceEvent.Accessor <<= _nIndex;
1034 aReplaceEvent.Element = aElementMetaData.get()->xInterface->queryInterface( m_aElementType );
1035 aReplaceEvent.ReplacedElement = xOldElement->queryInterface( m_aElementType );
1037 impl_replacedElement( aReplaceEvent, _rClearBeforeNotify );
1040 //------------------------------------------------------------------------------
1041 void OInterfaceContainer::implCheckIndex( const sal_Int32 _nIndex ) SAL_THROW( ( ::com::sun::star::lang::IndexOutOfBoundsException ) )
1043 if (_nIndex < 0 || _nIndex >= (sal_Int32)m_aItems.size())
1044 throw IndexOutOfBoundsException();
1047 //------------------------------------------------------------------------------
1048 void SAL_CALL OInterfaceContainer::replaceByIndex(sal_Int32 _nIndex, const Any& Element) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1050 ::osl::ClearableMutexGuard aGuard( m_rMutex );
1051 // check the index
1052 implCheckIndex( _nIndex );
1053 // do the replace
1054 implReplaceByIndex( _nIndex, Element, aGuard );
1057 //------------------------------------------------------------------------------
1058 void OInterfaceContainer::implRemoveByIndex( const sal_Int32 _nIndex, ::osl::ClearableMutexGuard& _rClearBeforeNotify )
1060 OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implRemoveByIndex: precondition not met (index)!" );
1062 OInterfaceArray::iterator i = m_aItems.begin() + _nIndex;
1063 InterfaceRef xElement(*i);
1065 OInterfaceMap::iterator j = m_aMap.begin();
1066 while (j != m_aMap.end() && (*j).second != xElement) ++j;
1068 m_aItems.erase(i);
1069 m_aMap.erase(j);
1071 // remove event knittings
1072 if ( m_xEventAttacher.is() )
1074 InterfaceRef xNormalized( xElement, UNO_QUERY );
1075 m_xEventAttacher->detach( _nIndex, xNormalized );
1076 m_xEventAttacher->removeEntry( _nIndex );
1079 Reference<XPropertySet> xSet(xElement, UNO_QUERY);
1080 if (xSet.is())
1081 xSet->removePropertyChangeListener(PROPERTY_NAME, this);
1083 Reference<XChild> xChild(xElement, UNO_QUERY);
1084 if (xChild.is())
1085 xChild->setParent(InterfaceRef ());
1087 // notify derived classes
1088 implRemoved(xElement);
1090 // notify listeners
1091 ContainerEvent aEvt;
1092 aEvt.Source = static_cast<XContainer*>(this);
1093 aEvt.Element = xElement->queryInterface( m_aElementType );
1094 aEvt.Accessor <<= _nIndex;
1096 _rClearBeforeNotify.clear();
1097 m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvt );
1100 //------------------------------------------------------------------------------
1101 void SAL_CALL OInterfaceContainer::removeByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1103 ::osl::ClearableMutexGuard aGuard( m_rMutex );
1104 // check the index
1105 implCheckIndex( _nIndex );
1106 // do the removal
1107 implRemoveByIndex( _nIndex, aGuard );
1110 //------------------------------------------------------------------------
1111 ElementDescription* OInterfaceContainer::createElementMetaData( )
1113 return new ElementDescription;
1116 //------------------------------------------------------------------------
1117 void SAL_CALL OInterfaceContainer::insertByName(const ::rtl::OUString& _rName, const Any& _rElement) throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException )
1119 Reference< XPropertySet > xElementProps;
1121 ::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
1122 DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::insertByName: createElementMetaData returned nonsense!" );
1124 // ensure the correct name of the element
1127 _rElement >>= xElementProps;
1128 approveNewElement( xElementProps, aElementMetaData.get() );
1130 xElementProps->setPropertyValue( PROPERTY_NAME, makeAny( _rName ) );
1132 catch( const IllegalArgumentException& )
1134 throw; // allowed to leave
1136 catch( const ElementExistException& )
1138 throw; // allowed to leave
1140 catch( const Exception& )
1142 DBG_ERROR( "OInterfaceContainer::insertByName: caught an exception!" );
1144 implInsert( m_aItems.size(), xElementProps, sal_True, aElementMetaData.get(), sal_True );
1147 //------------------------------------------------------------------------
1148 void SAL_CALL OInterfaceContainer::replaceByName(const ::rtl::OUString& Name, const Any& Element) throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException )
1150 ::osl::ClearableMutexGuard aGuard( m_rMutex );
1151 ::std::pair <OInterfaceMap::iterator,
1152 OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
1153 if (aPair.first == aPair.second)
1154 throw NoSuchElementException();
1156 if (Element.getValueType().getTypeClass() != TypeClass_INTERFACE)
1157 lcl_throwIllegalArgumentException();
1159 Reference<XPropertySet> xSet;
1160 Element >>= xSet;
1161 if (xSet.is())
1163 if (!hasProperty(PROPERTY_NAME, xSet))
1164 lcl_throwIllegalArgumentException();
1166 xSet->setPropertyValue(PROPERTY_NAME, makeAny(Name));
1169 // determine the element pos
1170 sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
1172 implReplaceByIndex( nPos, Element, aGuard );
1175 //------------------------------------------------------------------------
1176 void SAL_CALL OInterfaceContainer::removeByName(const ::rtl::OUString& Name) throw( NoSuchElementException, WrappedTargetException, RuntimeException )
1178 ::osl::MutexGuard aGuard( m_rMutex );
1179 ::std::pair <OInterfaceMap::iterator,
1180 OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
1181 if (aPair.first == aPair.second)
1182 throw NoSuchElementException();
1184 sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
1185 removeByIndex(nPos);
1189 // XEventAttacherManager
1190 //------------------------------------------------------------------------
1191 void SAL_CALL OInterfaceContainer::registerScriptEvent( sal_Int32 nIndex, const ScriptEventDescriptor& aScriptEvent ) throw(IllegalArgumentException, RuntimeException)
1193 OSL_TRACE("*** registerScriptEvent %d", nIndex);
1194 if ( m_xEventAttacher.is() )
1196 m_xEventAttacher->registerScriptEvent( nIndex, aScriptEvent );
1197 fakeVbaEventsHack( nIndex ); // add fake vba events
1201 //------------------------------------------------------------------------
1202 void SAL_CALL OInterfaceContainer::registerScriptEvents( sal_Int32 nIndex, const Sequence< ScriptEventDescriptor >& aScriptEvents ) throw(IllegalArgumentException, RuntimeException)
1204 OSL_TRACE("*** registerScriptEvent(s) %d", nIndex);
1205 if ( m_xEventAttacher.is() )
1207 m_xEventAttacher->registerScriptEvents( nIndex, aScriptEvents );
1208 fakeVbaEventsHack( nIndex ); // add fake vba events
1212 //------------------------------------------------------------------------
1213 void SAL_CALL OInterfaceContainer::revokeScriptEvent( sal_Int32 nIndex, const ::rtl::OUString& aListenerType, const ::rtl::OUString& aEventMethod, const ::rtl::OUString& aRemoveListenerParam ) throw(IllegalArgumentException, RuntimeException)
1215 OSL_TRACE("*** revokeScriptEvent %d listenertype %s, eventMethod %s", nIndex, rtl::OUStringToOString( aListenerType, RTL_TEXTENCODING_UTF8 ).getStr(), rtl::OUStringToOString( aEventMethod, RTL_TEXTENCODING_UTF8 ).getStr());
1216 if ( m_xEventAttacher.is() )
1217 m_xEventAttacher->revokeScriptEvent( nIndex, aListenerType, aEventMethod, aRemoveListenerParam );
1220 //------------------------------------------------------------------------
1221 void SAL_CALL OInterfaceContainer::revokeScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
1223 if ( m_xEventAttacher.is() )
1224 m_xEventAttacher->revokeScriptEvents( nIndex );
1227 //------------------------------------------------------------------------
1228 void SAL_CALL OInterfaceContainer::insertEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
1230 if ( m_xEventAttacher.is() )
1231 m_xEventAttacher->insertEntry( nIndex );
1234 //------------------------------------------------------------------------
1235 void SAL_CALL OInterfaceContainer::removeEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
1237 if ( m_xEventAttacher.is() )
1238 m_xEventAttacher->removeEntry( nIndex );
1241 //------------------------------------------------------------------------
1242 Sequence< ScriptEventDescriptor > SAL_CALL OInterfaceContainer::getScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
1244 OSL_TRACE("getScriptEvents");
1245 Sequence< ScriptEventDescriptor > aReturn;
1246 if ( m_xEventAttacher.is() )
1248 aReturn = m_xEventAttacher->getScriptEvents( nIndex );
1249 if ( lcl_hasVbaEvents( aReturn ) )
1251 aReturn = lcl_stripVbaEvents( aReturn );
1254 return aReturn;
1257 //------------------------------------------------------------------------
1258 void SAL_CALL OInterfaceContainer::attach( sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any& aHelper ) throw(IllegalArgumentException, ServiceNotRegisteredException, RuntimeException)
1260 if ( m_xEventAttacher.is() )
1261 m_xEventAttacher->attach( nIndex, xObject, aHelper );
1264 //------------------------------------------------------------------------
1265 void SAL_CALL OInterfaceContainer::detach( sal_Int32 nIndex, const Reference< XInterface >& xObject ) throw(IllegalArgumentException, RuntimeException)
1267 if ( m_xEventAttacher.is() )
1268 m_xEventAttacher->detach( nIndex, xObject );
1271 //------------------------------------------------------------------------
1272 void SAL_CALL OInterfaceContainer::addScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException)
1274 if ( m_xEventAttacher.is() )
1275 m_xEventAttacher->addScriptListener( xListener );
1278 //------------------------------------------------------------------------
1279 void SAL_CALL OInterfaceContainer::removeScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException)
1281 if ( m_xEventAttacher.is() )
1282 m_xEventAttacher->removeScriptListener( xListener );
1285 //==================================================================
1286 //= OFormComponents
1287 //==================================================================
1288 //------------------------------------------------------------------------------
1289 Any SAL_CALL OFormComponents::queryAggregation(const Type& _rType) throw(RuntimeException)
1291 Any aReturn = OFormComponents_BASE::queryInterface(_rType);
1292 if (!aReturn.hasValue())
1294 aReturn = OInterfaceContainer::queryInterface(_rType);
1296 if (!aReturn.hasValue())
1297 aReturn = FormComponentsBase::queryAggregation(_rType);
1300 return aReturn;
1303 //------------------------------------------------------------------
1304 Sequence<Type> SAL_CALL OFormComponents::getTypes() throw(RuntimeException)
1306 return ::comphelper::concatSequences(OInterfaceContainer::getTypes(), FormComponentsBase::getTypes(), OFormComponents_BASE::getTypes());
1309 //------------------------------------------------------------------------------
1310 OFormComponents::OFormComponents(const Reference<XMultiServiceFactory>& _rxFactory)
1311 :FormComponentsBase( m_aMutex )
1312 ,OInterfaceContainer( _rxFactory, m_aMutex, XFormComponent::static_type() )
1313 ,OFormComponents_BASE()
1317 //------------------------------------------------------------------------------
1318 OFormComponents::OFormComponents( const OFormComponents& _cloneSource )
1319 :FormComponentsBase( m_aMutex )
1320 ,OInterfaceContainer( m_aMutex, _cloneSource )
1321 ,OFormComponents_BASE()
1325 //------------------------------------------------------------------------------
1326 OFormComponents::~OFormComponents()
1328 if (!FormComponentsBase::rBHelper.bDisposed)
1330 acquire();
1331 dispose();
1335 // OComponentHelper
1336 //------------------------------------------------------------------------------
1337 void OFormComponents::disposing()
1339 OInterfaceContainer::disposing();
1340 FormComponentsBase::disposing();
1341 m_xParent = NULL;
1344 //XChild
1345 //------------------------------------------------------------------------------
1346 void OFormComponents::setParent(const InterfaceRef& Parent) throw( NoSupportException, RuntimeException )
1348 ::osl::MutexGuard aGuard( m_aMutex );
1349 m_xParent = Parent;
1352 //------------------------------------------------------------------------------
1353 InterfaceRef OFormComponents::getParent() throw( RuntimeException )
1355 return m_xParent;
1358 //.........................................................................
1359 } // namespace frm
1360 //.........................................................................