LCOV - code coverage report
Current view: top level - forms/source/misc - InterfaceContainer.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 412 593 69.5 %
Date: 2015-06-13 12:38:46 Functions: 57 72 79.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11