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

Generated by: LCOV version 1.10