bump product version to 4.1.6.2
[LibreOffice.git] / forms / source / misc / InterfaceContainer.cxx
blob3a1361db17cc80404972f1563d0ea707b070407d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "frm_resource.hrc"
22 #include "frm_resource.hxx"
23 #include "InterfaceContainer.hxx"
24 #include "componenttools.hxx"
25 #include "property.hrc"
26 #include "services.hxx"
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <com/sun/star/container/XNamed.hpp>
30 #include <com/sun/star/io/WrongFormatException.hpp>
31 #include <com/sun/star/io/XMarkableStream.hpp>
32 #include <com/sun/star/lang/XComponent.hpp>
33 #include <com/sun/star/util/XCloneable.hpp>
34 #include <com/sun/star/form/XForm.hpp>
36 #include <comphelper/container.hxx>
37 #include <comphelper/enumhelper.hxx>
38 #include <comphelper/eventattachermgr.hxx>
39 #include <comphelper/property.hxx>
40 #include <comphelper/sequence.hxx>
41 #include <comphelper/types.hxx>
42 #include <cppuhelper/exc_hlp.hxx>
43 #include <cppuhelper/queryinterface.hxx>
44 #include <rtl/logfile.hxx>
45 #include <tools/debug.hxx>
46 #include <tools/diagnose_ex.h>
48 #include <algorithm>
49 #include <memory>
51 //.........................................................................
52 #include <com/sun/star/frame/XModel.hpp>
53 #include <com/sun/star/document/XCodeNameQuery.hpp>
54 #include <ooo/vba/XVBAToOOEventDescGen.hpp>
55 #include <comphelper/processfactory.hxx>
57 namespace frm
59 //.........................................................................
61 using namespace ::com::sun::star::frame;
62 using namespace ::com::sun::star::lang;
63 using namespace ::com::sun::star::uno;
64 using namespace ::com::sun::star::beans;
65 using namespace ::com::sun::star::document;
66 using namespace ::com::sun::star::container;
67 using namespace ::com::sun::star::script;
68 using namespace ::com::sun::star::io;
69 using namespace ::com::sun::star::form;
70 using namespace ::com::sun::star::util;
72 namespace
74 //---------------------------------------------------------------------
75 static void lcl_throwIllegalArgumentException()
77 throw IllegalArgumentException();
81 bool
82 lcl_hasVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents )
84 const ScriptEventDescriptor* pDesc = sEvents.getConstArray();
85 const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() );
86 for ( ; pDesc != pEnd; ++pDesc )
88 if ( pDesc->ScriptType == "VBAInterop" )
89 return true;
91 return false;
94 Sequence< ScriptEventDescriptor >
95 lcl_stripVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents )
97 Sequence< ScriptEventDescriptor > sStripped( sEvents.getLength() );
99 const ScriptEventDescriptor* pDesc = sEvents.getConstArray();
100 const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() );
101 sal_Int32 nCopied = 0;
102 for ( ; pDesc != pEnd; ++pDesc )
104 if ( pDesc->ScriptType != "VBAInterop" )
106 sStripped[ nCopied++ ] = *pDesc;
109 if ( nCopied )
110 sStripped.realloc( nCopied );
111 return sStripped;
114 void OInterfaceContainer::impl_addVbEvents_nolck_nothrow( const sal_Int32 i_nIndex )
116 // we are dealing with form controls
121 Reference< XModel > xDoc( getXModel( static_cast< XContainer *> ( this ) ) );
122 if ( !xDoc.is() )
123 break;
125 Reference< XMultiServiceFactory > xDocFac( xDoc, UNO_QUERY_THROW );
126 Reference< XCodeNameQuery > xNameQuery( xDocFac->createInstance( OUString("ooo.vba.VBACodeNameProvider") ), UNO_QUERY );
127 if ( !xNameQuery.is() )
128 break;
130 ::osl::MutexGuard aGuard( m_rMutex );
131 bool hasVBABindings = lcl_hasVbaEvents( m_xEventAttacher->getScriptEvents( i_nIndex ) );
132 if ( hasVBABindings )
133 break;
135 Reference< XInterface > xElement( getByIndex( i_nIndex ) , UNO_QUERY_THROW );
136 Reference< XForm > xElementAsForm( xElement, UNO_QUERY );
137 if ( xElementAsForm.is() )
138 break;
140 // Try getting the code name from the container first (faster),
141 // then from the element if that fails (slower).
142 Reference<XInterface> xThis = static_cast<XContainer*>(this);
143 OUString sCodeName = xNameQuery->getCodeNameForContainer(xThis);
144 if (sCodeName.isEmpty())
145 sCodeName = xNameQuery->getCodeNameForObject(xElement);
147 Reference< XPropertySet > xProps( xElement, UNO_QUERY_THROW );
148 OUString sServiceName;
149 xProps->getPropertyValue( OUString("DefaultControl") ) >>= sServiceName;
151 Reference< ooo::vba::XVBAToOOEventDescGen > xDescSupplier( m_xServiceFactory->createInstance( OUString("ooo.vba.VBAToOOEventDesc") ), UNO_QUERY_THROW );
152 Sequence< ScriptEventDescriptor > vbaEvents = xDescSupplier->getEventDescriptions( sServiceName , sCodeName );
154 // register the vba script events
155 m_xEventAttacher->registerScriptEvents( i_nIndex, vbaEvents );
157 while ( false );
159 catch ( const ServiceNotRegisteredException& )
161 // silence this, not all document types support the ooo.vba.VBACodeNameProvider service
163 catch( const Exception& )
165 DBG_UNHANDLED_EXCEPTION();
169 //==================================================================
170 //= ElementDescription
171 //==================================================================
172 //------------------------------------------------------------------
173 ElementDescription::ElementDescription( )
177 //------------------------------------------------------------------
178 ElementDescription::~ElementDescription()
182 //==================================================================
183 //= OInterfaceContainer
184 //==================================================================
185 //------------------------------------------------------------------
186 OInterfaceContainer::OInterfaceContainer(
187 const Reference<XMultiServiceFactory>& _rxFactory,
188 ::osl::Mutex& _rMutex,
189 const Type& _rElementType)
190 :OInterfaceContainer_BASE()
191 ,m_rMutex(_rMutex)
192 ,m_aContainerListeners(_rMutex)
193 ,m_aElementType(_rElementType)
194 ,m_xServiceFactory(_rxFactory)
196 impl_createEventAttacher_nothrow();
199 //------------------------------------------------------------------------------
200 OInterfaceContainer::OInterfaceContainer( ::osl::Mutex& _rMutex, const OInterfaceContainer& _cloneSource )
201 :OInterfaceContainer_BASE()
202 ,m_rMutex( _rMutex )
203 ,m_aContainerListeners( _rMutex )
204 ,m_aElementType( _cloneSource.m_aElementType )
205 ,m_xServiceFactory( _cloneSource.m_xServiceFactory )
207 impl_createEventAttacher_nothrow();
210 //------------------------------------------------------------------------------
211 void OInterfaceContainer::clonedFrom( const OInterfaceContainer& _cloneSource )
215 const Reference< XIndexAccess > xSourceHierarchy( const_cast< OInterfaceContainer* >( &_cloneSource ) );
216 const sal_Int32 nCount = xSourceHierarchy->getCount();
217 for ( sal_Int32 i=0; i<nCount; ++i )
219 Reference< XCloneable > xCloneable( xSourceHierarchy->getByIndex( i ), UNO_QUERY_THROW );
220 Reference< XInterface > xClone( xCloneable->createClone() );
221 insertByIndex( i, makeAny( xClone ) );
224 catch( const Exception& )
226 throw WrappedTargetException(
227 OUString( "Could not clone the given interface hierarchy." ),
228 static_cast< XIndexContainer* >( const_cast< OInterfaceContainer* >( &_cloneSource ) ),
229 ::cppu::getCaughtException()
234 //------------------------------------------------------------------------------
235 void OInterfaceContainer::impl_createEventAttacher_nothrow()
239 m_xEventAttacher.set( ::comphelper::createEventAttacherManager( comphelper::getComponentContext(m_xServiceFactory) ), UNO_SET_THROW );
241 catch( const Exception& )
243 DBG_UNHANDLED_EXCEPTION();
247 //------------------------------------------------------------------------------
248 OInterfaceContainer::~OInterfaceContainer()
252 //------------------------------------------------------------------------------
253 void OInterfaceContainer::disposing()
255 // dispose all elements
256 for (sal_Int32 i = m_aItems.size(); i > 0; --i)
258 Reference<XPropertySet> xSet(m_aItems[i - 1], UNO_QUERY);
259 if (xSet.is())
260 xSet->removePropertyChangeListener(PROPERTY_NAME, this);
262 // revoke event knittings
263 if ( m_xEventAttacher.is() )
265 Reference< XInterface > xIfc( xSet, UNO_QUERY );
266 m_xEventAttacher->detach( i - 1, xIfc );
267 m_xEventAttacher->removeEntry( i - 1 );
270 Reference<XComponent> xComponent(xSet, UNO_QUERY);
271 if (xComponent.is())
272 xComponent->dispose();
274 m_aMap.clear();
275 m_aItems.clear();
277 EventObject aEvt(static_cast<XContainer*>(this));
278 m_aContainerListeners.disposeAndClear(aEvt);
281 // XPersistObject
282 //------------------------------------------------------------------------------
283 namespace
285 //..........................................................................
286 void lcl_saveEvents( ::std::vector< Sequence< ScriptEventDescriptor > >& _rSave,
287 const Reference< XEventAttacherManager >& _rxManager, const sal_Int32 _nItemCount )
289 OSL_ENSURE( _rxManager.is(), "lcl_saveEvents: invalid event attacher manager!" );
290 if ( !_rxManager.is() )
291 return;
293 // reserve the space needed
294 _rSave.reserve( _nItemCount );
296 // copy the events
297 for (sal_Int32 i=0; i<_nItemCount; ++i)
298 _rSave.push_back(_rxManager->getScriptEvents( i ));
301 //..........................................................................
302 void lcl_restoreEvents( const ::std::vector< Sequence< ScriptEventDescriptor > >& _rSave,
303 const Reference< XEventAttacherManager >& _rxManager )
305 OSL_ENSURE( _rxManager.is(), "lcl_restoreEvents: invalid event attacher manager!" );
306 if ( !_rxManager.is() )
307 return;
309 ::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aLoop = _rSave.begin();
310 ::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aEnd = _rSave.end();
311 for ( sal_Int32 i=0; aLoop != aEnd; ++aLoop, ++i )
313 _rxManager->revokeScriptEvents( i );
314 _rxManager->registerScriptEvents( i, *aLoop );
319 //------------------------------------------------------------------------------
320 void SAL_CALL OInterfaceContainer::writeEvents(const Reference<XObjectOutputStream>& _rxOutStream)
322 // We're writing a document in SO 5.2 format (or even from earlier versions)
323 // -> convert the events from the new runtime format to the format of the 5.2 files
324 // but before, remember the current script events set for our children
325 ::std::vector< Sequence< ScriptEventDescriptor > > aSave;
326 if ( m_xEventAttacher.is() )
327 lcl_saveEvents( aSave, m_xEventAttacher, m_aItems.size() );
329 transformEvents( efVersionSO5x );
333 Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
334 sal_Int32 nMark = xMark->createMark();
336 sal_Int32 nObjLen = 0;
337 _rxOutStream->writeLong(nObjLen);
339 Reference<XPersistObject> xScripts(m_xEventAttacher, UNO_QUERY);
340 if (xScripts.is())
341 xScripts->write(_rxOutStream);
343 // feststellen der Laenge
344 nObjLen = xMark->offsetToMark(nMark) - 4;
345 xMark->jumpToMark(nMark);
346 _rxOutStream->writeLong(nObjLen);
347 xMark->jumpToFurthest();
348 xMark->deleteMark(nMark);
350 catch( const Exception& )
352 // restore the events
353 if ( m_xEventAttacher.is() )
354 lcl_restoreEvents( aSave, m_xEventAttacher );
355 throw;
358 // restore the events
359 if ( m_xEventAttacher.is() )
360 lcl_restoreEvents( aSave, m_xEventAttacher );
363 //------------------------------------------------------------------------------
364 struct TransformEventTo52Format : public ::std::unary_function< ScriptEventDescriptor, void >
366 void operator()( ScriptEventDescriptor& _rDescriptor )
368 if ( 0 == _rDescriptor.ScriptType.compareToAscii( "StarBasic" ) )
369 { // it's a starbasic macro
370 sal_Int32 nPrefixLength = _rDescriptor.ScriptCode.indexOf( ':' );
371 if ( 0 <= nPrefixLength )
372 { // the macro name does not already contain a :
373 #ifdef DBG_UTIL
374 const OUString sPrefix = _rDescriptor.ScriptCode.copy( 0, nPrefixLength );
375 DBG_ASSERT( 0 == sPrefix.compareToAscii( "document" )
376 || 0 == sPrefix.compareToAscii( "application" ),
377 "TransformEventTo52Format: invalid (unknown) prefix!" );
378 #endif
379 // cut the prefix
380 _rDescriptor.ScriptCode = _rDescriptor.ScriptCode.copy( nPrefixLength + 1 );
386 //------------------------------------------------------------------------------
387 struct TransformEventTo60Format : public ::std::unary_function< ScriptEventDescriptor, void >
389 void operator()( ScriptEventDescriptor& _rDescriptor )
391 if ( 0 == _rDescriptor.ScriptType.compareToAscii( "StarBasic" ) )
392 { // it's a starbasic macro
393 if ( _rDescriptor.ScriptCode.indexOf( ':' ) < 0 )
394 { // the macro name does not already contain a :
395 // -> default the type to "document"
396 OUString sNewScriptCode( "document:" );
397 sNewScriptCode += _rDescriptor.ScriptCode;
398 _rDescriptor.ScriptCode = sNewScriptCode;
404 //------------------------------------------------------------------------------
405 void OInterfaceContainer::transformEvents( const EventFormat _eTargetFormat )
407 OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::transformEvents: no event attacher manager!" );
408 if ( !m_xEventAttacher.is() )
409 return;
413 // loop through all our children
414 sal_Int32 nItems = m_aItems.size();
415 Sequence< ScriptEventDescriptor > aChildEvents;
417 for (sal_Int32 i=0; i<nItems; ++i)
419 // get the script events for this object
420 aChildEvents = m_xEventAttacher->getScriptEvents( i );
422 if ( aChildEvents.getLength() )
424 // the "iterators" for the events for this child
425 ScriptEventDescriptor* pChildEvents = aChildEvents.getArray();
426 ScriptEventDescriptor* pChildEventsEnd = pChildEvents + aChildEvents.getLength();
428 // do the transformation
429 if ( efVersionSO6x == _eTargetFormat )
430 ::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo60Format() );
431 else
432 ::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo52Format() );
434 // revoke the script events
435 m_xEventAttacher->revokeScriptEvents( i );
436 // and re-register them
437 m_xEventAttacher->registerScriptEvents( i, aChildEvents );
441 catch( const Exception& )
443 DBG_UNHANDLED_EXCEPTION();
447 //------------------------------------------------------------------------------
448 void SAL_CALL OInterfaceContainer::readEvents(const Reference<XObjectInputStream>& _rxInStream)
450 ::osl::MutexGuard aGuard( m_rMutex );
452 // Scripting Info lesen
453 Reference<XMarkableStream> xMark(_rxInStream, UNO_QUERY);
454 sal_Int32 nObjLen = _rxInStream->readLong();
455 if (nObjLen)
457 sal_Int32 nMark = xMark->createMark();
458 Reference<XPersistObject> xObj(m_xEventAttacher, UNO_QUERY);
459 if (xObj.is())
460 xObj->read(_rxInStream);
461 xMark->jumpToMark(nMark);
462 _rxInStream->skipBytes(nObjLen);
463 xMark->deleteMark(nMark);
466 // Attachement lesen
467 if ( m_xEventAttacher.is() )
469 OInterfaceArray::const_iterator aAttach = m_aItems.begin();
470 OInterfaceArray::const_iterator aAttachEnd = m_aItems.end();
471 for ( sal_Int32 i=0; aAttach != aAttachEnd; ++aAttach, ++i )
473 Reference< XInterface > xAsIFace( *aAttach, UNO_QUERY ); // important to normalize this ....
474 Reference< XPropertySet > xAsSet( xAsIFace, UNO_QUERY );
475 m_xEventAttacher->attach( i, xAsIFace, makeAny( xAsSet ) );
480 //------------------------------------------------------------------------------
481 void SAL_CALL OInterfaceContainer::write( const Reference< XObjectOutputStream >& _rxOutStream ) throw(IOException, RuntimeException)
483 ::osl::MutexGuard aGuard( m_rMutex );
484 sal_Int32 nLen = m_aItems.size();
486 // schreiben der laenge
487 _rxOutStream->writeLong(nLen);
489 if (nLen)
491 // 1. Version
492 _rxOutStream->writeShort(0x0001);
494 // 2. Objekte
495 for (sal_Int32 i = 0; i < nLen; i++)
497 Reference<XPersistObject> xObj(m_aItems[i], UNO_QUERY);
498 if (xObj.is())
499 _rxOutStream->writeObject(xObj);
500 else
502 // ::com::sun::star::chaos::Error
506 // 3. Scripts
507 writeEvents(_rxOutStream);
511 //------------------------------------------------------------------------------
512 namespace
514 Reference< XPersistObject > lcl_createPlaceHolder( const Reference< XMultiServiceFactory >& _rxORB )
516 Reference< XPersistObject > xObject( _rxORB->createInstance( FRM_COMPONENT_HIDDENCONTROL ), UNO_QUERY );
517 DBG_ASSERT( xObject.is(), "lcl_createPlaceHolder: could not create a substitute for the unknown object!" );
518 if ( xObject.is() )
520 // set some properties describing what we did
521 Reference< XPropertySet > xObjProps( xObject, UNO_QUERY );
522 if ( xObject.is() )
526 xObjProps->setPropertyValue( PROPERTY_NAME, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_NAME ) ) );
527 xObjProps->setPropertyValue( PROPERTY_TAG, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_EPXPLAIN ) ) );
529 catch(const Exception&)
534 return xObject;
538 //------------------------------------------------------------------------------
539 void SAL_CALL OInterfaceContainer::read( const Reference< XObjectInputStream >& _rxInStream ) throw(IOException, RuntimeException)
541 ::osl::MutexGuard aGuard( m_rMutex );
543 // after ::read the object is expected to be in the state it was when ::write was called, so we have
544 // to empty ourself here
545 while (getCount())
546 removeByIndex(0);
548 // Schreibt nur in Abhaengigkeit der Laenge
549 sal_Int32 nLen = _rxInStream->readLong();
551 if (nLen)
553 // 1. Version
554 sal_uInt16 nVersion = _rxInStream->readShort(); (void)nVersion;
556 // 2. Objekte
557 for (sal_Int32 i = 0; i < nLen; i++)
559 Reference<XPersistObject> xObj;
562 xObj = _rxInStream->readObject();
564 catch(const WrongFormatException&)
566 // the object could not be read
567 // create a object (so the readEvents below will assign the events to the right controls)
568 xObj = lcl_createPlaceHolder( m_xServiceFactory );
569 if ( !xObj.is() )
570 // couldn't handle it
571 throw;
573 catch(const Exception&)
575 // unsere Map leeren
576 while (!m_aItems.empty())
577 removeElementsNoEvents(0);
579 // und die Exception nach aussen
580 throw;
583 if ( xObj.is() )
585 Reference< XPropertySet > xElement( xObj, UNO_QUERY );
588 implInsert(
589 m_aItems.size(), // position
590 xElement, // element to insert
591 sal_False, // no event attacher manager handling
592 NULL, // not yet approved - let implInsert do it
593 sal_True // fire the event
596 catch( const Exception& )
598 OSL_FAIL( "OInterfaceContainerHelper::read: reading succeeded, but not inserting!" );
599 // create a placeholder
600 xElement = xElement.query( lcl_createPlaceHolder( m_xServiceFactory ) );
601 if ( !xElement.is() )
602 // couldn't handle it
603 throw;
604 // insert the placeholder
605 implInsert( m_aItems.size(), xElement, sal_False, NULL, sal_True );
610 readEvents(_rxInStream);
612 else
616 m_xEventAttacher = ::comphelper::createEventAttacherManager( comphelper::getComponentContext(m_xServiceFactory) );
617 OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::read: could not create an event attacher manager!" );
619 catch( const Exception& )
621 DBG_UNHANDLED_EXCEPTION();
626 // XContainer
627 //------------------------------------------------------------------------------
628 void SAL_CALL OInterfaceContainer::addContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException )
630 m_aContainerListeners.addInterface(_rxListener);
633 //------------------------------------------------------------------------------
634 void SAL_CALL OInterfaceContainer::removeContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException )
636 m_aContainerListeners.removeInterface(_rxListener);
639 // XEventListener
640 //------------------------------------------------------------------------------
641 void SAL_CALL OInterfaceContainer::disposing(const EventObject& _rSource) throw( RuntimeException )
643 ::osl::MutexGuard aGuard( m_rMutex );
645 Reference< XInterface > xSource( _rSource.Source, UNO_QUERY );
646 // normalized source
648 OInterfaceArray::iterator j;
649 for ( j = m_aItems.begin(); j != m_aItems.end(); ++j )
651 DBG_ASSERT( j->get() == Reference< XInterface >( *j, UNO_QUERY ).get(),
652 "OInterfaceContainer::disposing: vector element not normalized!" );
654 if ( xSource.get() == j->get() )
655 // found the element
656 break;
659 if ( m_aItems.end() != j )
661 m_aItems.erase(j);
663 // look up in, and erase from, m_aMap, too
664 OInterfaceMap::iterator i = m_aMap.begin();
665 while ( i != m_aMap.end() )
667 DBG_ASSERT( i->second.get() == Reference< XInterface >( i->second, UNO_QUERY ).get(),
668 "OInterfaceContainer::disposing: map element not normalized!" );
670 if ( i->second.get() == xSource.get() )
672 // found it
673 m_aMap.erase(i);
674 break;
677 ++i;
679 DBG_ASSERT( i != m_aMap.end(), "OInterfaceContainer::disposing: inconsistency: the element was in m_aItems, but not in m_aMap!" );
684 // XPropertyChangeListener
685 //------------------------------------------------------------------------------
686 void OInterfaceContainer::propertyChange(const PropertyChangeEvent& evt)
687 throw (::com::sun::star::uno::RuntimeException) {
688 if (evt.PropertyName == PROPERTY_NAME)
690 ::osl::MutexGuard aGuard( m_rMutex );
691 OInterfaceMap::iterator i = ::std::find(m_aMap.begin(), m_aMap.end(),
692 ::std::pair<const OUString, InterfaceRef >(::comphelper::getString(evt.OldValue),evt.Source));
693 if (i != m_aMap.end())
695 InterfaceRef xCorrectType((*i).second);
696 m_aMap.erase(i);
697 m_aMap.insert(::std::pair<const OUString, InterfaceRef >(::comphelper::getString(evt.NewValue),xCorrectType));
702 // XElementAccess
703 //------------------------------------------------------------------------------
704 sal_Bool SAL_CALL OInterfaceContainer::hasElements() throw( RuntimeException )
706 return !m_aMap.empty();
709 //------------------------------------------------------------------------------
710 Type SAL_CALL OInterfaceContainer::getElementType() throw(RuntimeException)
712 return m_aElementType;
715 // XEnumerationAccess
716 //------------------------------------------------------------------------------
717 Reference<XEnumeration> SAL_CALL OInterfaceContainer::createEnumeration() throw( RuntimeException )
719 ::osl::MutexGuard aGuard( m_rMutex );
720 return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this));
723 // XNameAccess
724 //------------------------------------------------------------------------------
725 Any SAL_CALL OInterfaceContainer::getByName( const OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
727 ::std::pair <OInterfaceMap::iterator,
728 OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
730 if (aPair.first == aPair.second)
731 throw NoSuchElementException();
733 return (*aPair.first).second->queryInterface( m_aElementType );
736 //------------------------------------------------------------------------------
737 StringSequence SAL_CALL OInterfaceContainer::getElementNames() throw(RuntimeException)
739 StringSequence aNameList(m_aItems.size());
740 OUString* pStringArray = aNameList.getArray();
742 for (OInterfaceMap::const_iterator i = m_aMap.begin(); i != m_aMap.end(); ++i, ++pStringArray)
744 *pStringArray = (*i).first;
746 return aNameList;
749 //------------------------------------------------------------------------------
750 sal_Bool SAL_CALL OInterfaceContainer::hasByName( const OUString& _rName ) throw(RuntimeException)
752 ::std::pair <OInterfaceMap::iterator,
753 OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
754 return aPair.first != aPair.second;
757 // XIndexAccess
758 //------------------------------------------------------------------------------
759 sal_Int32 OInterfaceContainer::getCount() throw( RuntimeException )
761 return m_aItems.size();
764 //------------------------------------------------------------------------------
765 Any OInterfaceContainer::getByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
767 if (_nIndex < 0 || (_nIndex >= (sal_Int32)m_aItems.size()))
768 throw IndexOutOfBoundsException();
770 return m_aItems[_nIndex]->queryInterface( m_aElementType );
773 //------------------------------------------------------------------------------
774 void OInterfaceContainer::approveNewElement( const Reference< XPropertySet >& _rxObject, ElementDescription* _pElement )
776 // it has to be non-NULL
777 if ( !_rxObject.is() )
778 throw IllegalArgumentException(FRM_RES_STRING(RID_STR_NEED_NON_NULL_OBJECT), static_cast<XContainer*>(this), 1);
780 // it has to support our element type interface
781 Any aCorrectType = _rxObject->queryInterface( m_aElementType );
782 if ( !aCorrectType.hasValue() )
783 lcl_throwIllegalArgumentException();
785 // it has to have a "Name" property
786 if ( !hasProperty( PROPERTY_NAME, _rxObject ) )
787 lcl_throwIllegalArgumentException();
789 // it has to be a child, and it must not have a parent already
790 Reference< XChild > xChild( _rxObject, UNO_QUERY );
791 if ( !xChild.is() || xChild->getParent().is() )
793 lcl_throwIllegalArgumentException();
796 // passed all tests. cache the information we have so far
797 DBG_ASSERT( _pElement, "OInterfaceContainer::approveNewElement: invalid event descriptor!" );
798 if ( _pElement )
800 _pElement->xPropertySet = _rxObject;
801 _pElement->xChild = xChild;
802 _pElement->aElementTypeInterface = aCorrectType;
803 _pElement->xInterface = Reference< XInterface >( _rxObject, UNO_QUERY ); // normalized XInterface
807 //------------------------------------------------------------------------------
808 void OInterfaceContainer::implInsert(sal_Int32 _nIndex, const Reference< XPropertySet >& _rxElement,
809 sal_Bool _bEvents, ElementDescription* _pApprovalResult, sal_Bool _bFire ) throw( IllegalArgumentException )
811 const bool bHandleEvents = _bEvents && m_xEventAttacher.is();
813 // SYNCHRONIZED ----->
814 ::osl::ClearableMutexGuard aGuard( m_rMutex );
816 SAL_WNODEPRECATED_DECLARATIONS_PUSH
817 ::std::auto_ptr< ElementDescription > aAutoDeleteMetaData;
818 SAL_WNODEPRECATED_DECLARATIONS_POP
819 ElementDescription* pElementMetaData = _pApprovalResult;
820 if ( !pElementMetaData )
821 { // not yet approved by the caller -> do ourself
822 pElementMetaData = createElementMetaData();
823 DBG_ASSERT( pElementMetaData, "OInterfaceContainer::implInsert: createElementMetaData returned nonsense!" );
825 // ensure that the meta data structure will be deleted later on
826 SAL_WNODEPRECATED_DECLARATIONS_PUSH
827 aAutoDeleteMetaData = ::std::auto_ptr< ElementDescription >( pElementMetaData );
828 SAL_WNODEPRECATED_DECLARATIONS_POP
830 // will throw an exception if necessary
831 approveNewElement( _rxElement, pElementMetaData );
835 // approveNewElement (no matter if called here or outside) has ensure that all relevant interfaces
836 // exist
838 // set the name, and add as change listener for the name
839 OUString sName;
840 _rxElement->getPropertyValue(PROPERTY_NAME) >>= sName;
841 _rxElement->addPropertyChangeListener(PROPERTY_NAME, this);
843 // insert the object into our internal structures
844 if (_nIndex > (sal_Int32)m_aItems.size()) // ermitteln des tatsaechlichen Indexs
846 _nIndex = m_aItems.size();
847 m_aItems.push_back( pElementMetaData->xInterface );
849 else
850 m_aItems.insert( m_aItems.begin() + _nIndex, pElementMetaData->xInterface );
852 m_aMap.insert( ::std::pair< const OUString, InterfaceRef >( sName, pElementMetaData->xInterface ) );
854 // announce ourself as parent to the new element
855 pElementMetaData->xChild->setParent(static_cast<XContainer*>(this));
857 // handle the events
858 if ( bHandleEvents )
860 m_xEventAttacher->insertEntry(_nIndex);
861 m_xEventAttacher->attach( _nIndex, pElementMetaData->xInterface, makeAny( _rxElement ) );
864 // notify derived classes
865 implInserted( pElementMetaData );
867 aGuard.clear();
868 // <----- SYNCHRONIZED
870 // insert faked VBA events?
871 bool bHandleVbaEvents = false;
874 _rxElement->getPropertyValue(OUString("GenerateVbaEvents") ) >>= bHandleVbaEvents;
876 catch( const Exception& )
879 if ( bHandleVbaEvents )
881 Reference< XEventAttacherManager > xMgr ( pElementMetaData->xInterface, UNO_QUERY );
882 if ( xMgr.is() )
884 OInterfaceContainer* pIfcMgr = dynamic_cast< OInterfaceContainer* >( xMgr.get() );
885 sal_Int32 nLen = pIfcMgr->getCount();
886 for ( sal_Int32 i = 0; (i < nLen) && pIfcMgr ; ++i )
888 // add fake events to the control at index i
889 pIfcMgr->impl_addVbEvents_nolck_nothrow( i );
892 else
894 // add fake events to the control at index i
895 impl_addVbEvents_nolck_nothrow( _nIndex );
899 // fire the notification about the change
900 if ( _bFire )
902 // notify listeners
903 ContainerEvent aEvt;
904 aEvt.Source = static_cast<XContainer*>(this);
905 aEvt.Accessor <<= _nIndex;
906 aEvt.Element = pElementMetaData->aElementTypeInterface;
908 aGuard.clear();
909 m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvt );
913 //------------------------------------------------------------------------------
914 void OInterfaceContainer::removeElementsNoEvents(sal_Int32 nIndex)
916 OInterfaceArray::iterator i = m_aItems.begin() + nIndex;
917 InterfaceRef xElement(*i);
919 OInterfaceMap::iterator j = m_aMap.begin();
920 while (j != m_aMap.end() && (*j).second != xElement) ++j;
922 m_aItems.erase(i);
923 m_aMap.erase(j);
925 Reference<XPropertySet> xSet(xElement, UNO_QUERY);
926 if (xSet.is())
927 xSet->removePropertyChangeListener(PROPERTY_NAME, this);
929 Reference<XChild> xChild(xElement, UNO_QUERY);
930 if (xChild.is())
931 xChild->setParent(InterfaceRef ());
934 //------------------------------------------------------------------------------
935 void OInterfaceContainer::implInserted( const ElementDescription* /*_pElement*/ )
937 // not inrerested in
940 //------------------------------------------------------------------------------
941 void OInterfaceContainer::implRemoved( const InterfaceRef& /*_rxObject*/ )
943 // not inrerested in
946 //------------------------------------------------------------------------------
947 void OInterfaceContainer::impl_replacedElement( const ContainerEvent& _rEvent, ::osl::ClearableMutexGuard& _rInstanceLock )
949 _rInstanceLock.clear();
950 m_aContainerListeners.notifyEach( &XContainerListener::elementReplaced, _rEvent );
953 // XIndexContainer
954 //------------------------------------------------------------------------------
955 void SAL_CALL OInterfaceContainer::insertByIndex( sal_Int32 _nIndex, const Any& _rElement ) throw(IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
957 Reference< XPropertySet > xElement;
958 _rElement >>= xElement;
959 implInsert( _nIndex, xElement, sal_True /* event handling */ , NULL /* not yet approved */ , sal_True /* notification */ );
962 //------------------------------------------------------------------------------
963 void OInterfaceContainer::implReplaceByIndex( const sal_Int32 _nIndex, const Any& _rNewElement, ::osl::ClearableMutexGuard& _rClearBeforeNotify )
965 OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implReplaceByIndex: precondition not met (index)!" );
967 // approve the new object
968 SAL_WNODEPRECATED_DECLARATIONS_PUSH
969 ::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
970 SAL_WNODEPRECATED_DECLARATIONS_POP
971 DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::implReplaceByIndex: createElementMetaData returned nonsense!" );
973 Reference< XPropertySet > xElementProps;
974 _rNewElement >>= xElementProps;
975 approveNewElement( xElementProps, aElementMetaData.get() );
978 // get the old element
979 InterfaceRef xOldElement( m_aItems[ _nIndex ] );
980 DBG_ASSERT( xOldElement.get() == Reference< XInterface >( xOldElement, UNO_QUERY ).get(),
981 "OInterfaceContainer::implReplaceByIndex: elements should be held normalized!" );
983 // locate the old element in the map
984 OInterfaceMap::iterator j = m_aMap.begin();
985 while ( ( j != m_aMap.end() ) && ( j->second.get() != xOldElement.get() ) )
986 ++j;
988 // remove event knittings
989 if ( m_xEventAttacher.is() )
991 InterfaceRef xNormalized( xOldElement, UNO_QUERY );
992 m_xEventAttacher->detach( _nIndex, xNormalized );
993 m_xEventAttacher->removeEntry( _nIndex );
996 // don't listen for property changes anymore
997 Reference<XPropertySet> xSet( xOldElement, UNO_QUERY );
998 if (xSet.is())
999 xSet->removePropertyChangeListener(PROPERTY_NAME, this);
1001 // give the old element a new (void) parent
1002 Reference<XChild> xChild(xOldElement, UNO_QUERY);
1003 if (xChild.is())
1004 xChild->setParent(InterfaceRef ());
1006 // remove the old one
1007 m_aMap.erase(j);
1009 // examine the new element
1010 OUString sName;
1011 DBG_ASSERT( aElementMetaData.get()->xPropertySet.is(), "OInterfaceContainer::implReplaceByIndex: what did approveNewElement do?" );
1013 aElementMetaData.get()->xPropertySet->getPropertyValue(PROPERTY_NAME) >>= sName;
1014 aElementMetaData.get()->xPropertySet->addPropertyChangeListener(PROPERTY_NAME, this);
1016 // insert the new one
1017 m_aMap.insert( ::std::pair<const OUString, InterfaceRef >( sName, aElementMetaData.get()->xInterface ) );
1018 m_aItems[ _nIndex ] = aElementMetaData.get()->xInterface;
1020 aElementMetaData.get()->xChild->setParent(static_cast<XContainer*>(this));
1022 if ( m_xEventAttacher.is() )
1024 m_xEventAttacher->insertEntry( _nIndex );
1025 m_xEventAttacher->attach( _nIndex, aElementMetaData.get()->xInterface, makeAny( aElementMetaData.get()->xPropertySet ) );
1028 ContainerEvent aReplaceEvent;
1029 aReplaceEvent.Source = static_cast< XContainer* >( this );
1030 aReplaceEvent.Accessor <<= _nIndex;
1031 aReplaceEvent.Element = aElementMetaData.get()->xInterface->queryInterface( m_aElementType );
1032 aReplaceEvent.ReplacedElement = xOldElement->queryInterface( m_aElementType );
1034 impl_replacedElement( aReplaceEvent, _rClearBeforeNotify );
1037 //------------------------------------------------------------------------------
1038 void OInterfaceContainer::implCheckIndex( const sal_Int32 _nIndex ) SAL_THROW( ( ::com::sun::star::lang::IndexOutOfBoundsException ) )
1040 if (_nIndex < 0 || _nIndex >= (sal_Int32)m_aItems.size())
1041 throw IndexOutOfBoundsException();
1044 //------------------------------------------------------------------------------
1045 void SAL_CALL OInterfaceContainer::replaceByIndex(sal_Int32 _nIndex, const Any& Element) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1047 ::osl::ClearableMutexGuard aGuard( m_rMutex );
1048 // check the index
1049 implCheckIndex( _nIndex );
1050 // do the replace
1051 implReplaceByIndex( _nIndex, Element, aGuard );
1054 //------------------------------------------------------------------------------
1055 void OInterfaceContainer::implRemoveByIndex( const sal_Int32 _nIndex, ::osl::ClearableMutexGuard& _rClearBeforeNotify )
1057 OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implRemoveByIndex: precondition not met (index)!" );
1059 OInterfaceArray::iterator i = m_aItems.begin() + _nIndex;
1060 InterfaceRef xElement(*i);
1062 OInterfaceMap::iterator j = m_aMap.begin();
1063 while (j != m_aMap.end() && (*j).second != xElement) ++j;
1065 m_aItems.erase(i);
1066 m_aMap.erase(j);
1068 // remove event knittings
1069 if ( m_xEventAttacher.is() )
1071 InterfaceRef xNormalized( xElement, UNO_QUERY );
1072 m_xEventAttacher->detach( _nIndex, xNormalized );
1073 m_xEventAttacher->removeEntry( _nIndex );
1076 Reference<XPropertySet> xSet(xElement, UNO_QUERY);
1077 if (xSet.is())
1078 xSet->removePropertyChangeListener(PROPERTY_NAME, this);
1080 Reference<XChild> xChild(xElement, UNO_QUERY);
1081 if (xChild.is())
1082 xChild->setParent(InterfaceRef ());
1084 // notify derived classes
1085 implRemoved(xElement);
1087 // notify listeners
1088 ContainerEvent aEvt;
1089 aEvt.Source = static_cast<XContainer*>(this);
1090 aEvt.Element = xElement->queryInterface( m_aElementType );
1091 aEvt.Accessor <<= _nIndex;
1093 _rClearBeforeNotify.clear();
1094 m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvt );
1097 //------------------------------------------------------------------------------
1098 void SAL_CALL OInterfaceContainer::removeByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1100 ::osl::ClearableMutexGuard aGuard( m_rMutex );
1101 // check the index
1102 implCheckIndex( _nIndex );
1103 // do the removal
1104 implRemoveByIndex( _nIndex, aGuard );
1107 //------------------------------------------------------------------------
1108 ElementDescription* OInterfaceContainer::createElementMetaData( )
1110 return new ElementDescription;
1113 //------------------------------------------------------------------------
1114 void SAL_CALL OInterfaceContainer::insertByName(const OUString& _rName, const Any& _rElement) throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException )
1116 Reference< XPropertySet > xElementProps;
1118 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1119 ::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
1120 SAL_WNODEPRECATED_DECLARATIONS_POP
1121 DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::insertByName: createElementMetaData returned nonsense!" );
1123 // ensure the correct name of the element
1126 _rElement >>= xElementProps;
1127 approveNewElement( xElementProps, aElementMetaData.get() );
1129 xElementProps->setPropertyValue( PROPERTY_NAME, makeAny( _rName ) );
1131 catch( const IllegalArgumentException& )
1133 throw; // allowed to leave
1135 catch( const ElementExistException& )
1137 throw; // allowed to leave
1139 catch( const Exception& )
1141 OSL_FAIL( "OInterfaceContainer::insertByName: caught an exception!" );
1143 implInsert( m_aItems.size(), xElementProps, sal_True, aElementMetaData.get(), sal_True );
1146 //------------------------------------------------------------------------
1147 void SAL_CALL OInterfaceContainer::replaceByName(const OUString& Name, const Any& Element) throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException )
1149 ::osl::ClearableMutexGuard aGuard( m_rMutex );
1150 ::std::pair <OInterfaceMap::iterator,
1151 OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
1152 if (aPair.first == aPair.second)
1153 throw NoSuchElementException();
1155 if (Element.getValueType().getTypeClass() != TypeClass_INTERFACE)
1156 lcl_throwIllegalArgumentException();
1158 Reference<XPropertySet> xSet;
1159 Element >>= xSet;
1160 if (xSet.is())
1162 if (!hasProperty(PROPERTY_NAME, xSet))
1163 lcl_throwIllegalArgumentException();
1165 xSet->setPropertyValue(PROPERTY_NAME, makeAny(Name));
1168 // determine the element pos
1169 sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
1171 implReplaceByIndex( nPos, Element, aGuard );
1174 //------------------------------------------------------------------------
1175 void SAL_CALL OInterfaceContainer::removeByName(const OUString& Name) throw( NoSuchElementException, WrappedTargetException, RuntimeException )
1177 ::osl::MutexGuard aGuard( m_rMutex );
1178 ::std::pair <OInterfaceMap::iterator,
1179 OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
1180 if (aPair.first == aPair.second)
1181 throw NoSuchElementException();
1183 sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
1184 removeByIndex(nPos);
1188 // XEventAttacherManager
1189 //------------------------------------------------------------------------
1190 void SAL_CALL OInterfaceContainer::registerScriptEvent( sal_Int32 nIndex, const ScriptEventDescriptor& aScriptEvent ) throw(IllegalArgumentException, RuntimeException)
1192 ::osl::ClearableMutexGuard aGuard( m_rMutex );
1193 if ( m_xEventAttacher.is() )
1195 m_xEventAttacher->registerScriptEvent( nIndex, aScriptEvent );
1196 aGuard.clear();
1197 impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
1201 //------------------------------------------------------------------------
1202 void SAL_CALL OInterfaceContainer::registerScriptEvents( sal_Int32 nIndex, const Sequence< ScriptEventDescriptor >& aScriptEvents ) throw(IllegalArgumentException, RuntimeException)
1204 ::osl::ClearableMutexGuard aGuard( m_rMutex );
1205 if ( m_xEventAttacher.is() )
1207 m_xEventAttacher->registerScriptEvents( nIndex, aScriptEvents );
1208 aGuard.clear();
1209 impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
1213 //------------------------------------------------------------------------
1214 void SAL_CALL OInterfaceContainer::revokeScriptEvent( sal_Int32 nIndex, const OUString& aListenerType, const OUString& aEventMethod, const OUString& aRemoveListenerParam ) throw(IllegalArgumentException, RuntimeException)
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 Sequence< ScriptEventDescriptor > aReturn;
1245 if ( m_xEventAttacher.is() )
1247 aReturn = m_xEventAttacher->getScriptEvents( nIndex );
1248 if ( lcl_hasVbaEvents( aReturn ) )
1250 aReturn = lcl_stripVbaEvents( aReturn );
1253 return aReturn;
1256 //------------------------------------------------------------------------
1257 void SAL_CALL OInterfaceContainer::attach( sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any& aHelper ) throw(IllegalArgumentException, ServiceNotRegisteredException, RuntimeException)
1259 if ( m_xEventAttacher.is() )
1260 m_xEventAttacher->attach( nIndex, xObject, aHelper );
1263 //------------------------------------------------------------------------
1264 void SAL_CALL OInterfaceContainer::detach( sal_Int32 nIndex, const Reference< XInterface >& xObject ) throw(IllegalArgumentException, RuntimeException)
1266 if ( m_xEventAttacher.is() )
1267 m_xEventAttacher->detach( nIndex, xObject );
1270 //------------------------------------------------------------------------
1271 void SAL_CALL OInterfaceContainer::addScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException)
1273 if ( m_xEventAttacher.is() )
1274 m_xEventAttacher->addScriptListener( xListener );
1277 //------------------------------------------------------------------------
1278 void SAL_CALL OInterfaceContainer::removeScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException)
1280 if ( m_xEventAttacher.is() )
1281 m_xEventAttacher->removeScriptListener( xListener );
1284 //==================================================================
1285 //= OFormComponents
1286 //==================================================================
1287 //------------------------------------------------------------------------------
1288 Any SAL_CALL OFormComponents::queryAggregation(const Type& _rType) throw(RuntimeException)
1290 Any aReturn = OFormComponents_BASE::queryInterface(_rType);
1291 if (!aReturn.hasValue())
1293 aReturn = OInterfaceContainer::queryInterface(_rType);
1295 if (!aReturn.hasValue())
1296 aReturn = FormComponentsBase::queryAggregation(_rType);
1299 return aReturn;
1302 //------------------------------------------------------------------
1303 Sequence<Type> SAL_CALL OFormComponents::getTypes() throw(RuntimeException)
1305 return ::comphelper::concatSequences(OInterfaceContainer::getTypes(), FormComponentsBase::getTypes(), OFormComponents_BASE::getTypes());
1308 //------------------------------------------------------------------------------
1309 OFormComponents::OFormComponents(const Reference<XMultiServiceFactory>& _rxFactory)
1310 :FormComponentsBase( m_aMutex )
1311 ,OInterfaceContainer( _rxFactory, m_aMutex, XFormComponent::static_type() )
1312 ,OFormComponents_BASE()
1316 //------------------------------------------------------------------------------
1317 OFormComponents::OFormComponents( const OFormComponents& _cloneSource )
1318 :FormComponentsBase( m_aMutex )
1319 ,OInterfaceContainer( m_aMutex, _cloneSource )
1320 ,OFormComponents_BASE()
1324 //------------------------------------------------------------------------------
1325 OFormComponents::~OFormComponents()
1327 if (!FormComponentsBase::rBHelper.bDisposed)
1329 acquire();
1330 dispose();
1334 // OComponentHelper
1335 //------------------------------------------------------------------------------
1336 void OFormComponents::disposing()
1338 OInterfaceContainer::disposing();
1339 FormComponentsBase::disposing();
1340 m_xParent = NULL;
1343 //XChild
1344 //------------------------------------------------------------------------------
1345 void OFormComponents::setParent(const InterfaceRef& Parent) throw( NoSupportException, RuntimeException )
1347 ::osl::MutexGuard aGuard( m_aMutex );
1348 m_xParent = Parent;
1351 //------------------------------------------------------------------------------
1352 InterfaceRef OFormComponents::getParent() throw( RuntimeException )
1354 return m_xParent;
1357 //.........................................................................
1358 } // namespace frm
1359 //.........................................................................
1361 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */