| /************************************************************** | |
| * | |
| * Licensed to the Apache Software Foundation (ASF) under one | |
| * or more contributor license agreements. See the NOTICE file | |
| * distributed with this work for additional information | |
| * regarding copyright ownership. The ASF licenses this file | |
| * to you under the Apache License, Version 2.0 (the | |
| * "License"); you may not use this file except in compliance | |
| * with the License. You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, | |
| * software distributed under the License is distributed on an | |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| * KIND, either express or implied. See the License for the | |
| * specific language governing permissions and limitations | |
| * under the License. | |
| * | |
| *************************************************************/ | |
| // MARKER(update_precomp.py): autogen include statement, do not remove | |
| #include "precompiled_forms.hxx" | |
| #include "frm_resource.hrc" | |
| #include "frm_resource.hxx" | |
| #include "InterfaceContainer.hxx" | |
| #include "componenttools.hxx" | |
| #include "property.hrc" | |
| #include "services.hxx" | |
| #include <com/sun/star/beans/XPropertySet.hpp> | |
| #include <com/sun/star/container/XNamed.hpp> | |
| #include <com/sun/star/io/WrongFormatException.hpp> | |
| #include <com/sun/star/io/XMarkableStream.hpp> | |
| #include <com/sun/star/lang/XComponent.hpp> | |
| #include <com/sun/star/util/XCloneable.hpp> | |
| #include <com/sun/star/form/XForm.hpp> | |
| #include <comphelper/container.hxx> | |
| #include <comphelper/enumhelper.hxx> | |
| #include <comphelper/eventattachermgr.hxx> | |
| #include <comphelper/property.hxx> | |
| #include <comphelper/sequence.hxx> | |
| #include <comphelper/types.hxx> | |
| #include <cppuhelper/exc_hlp.hxx> | |
| #include <cppuhelper/queryinterface.hxx> | |
| #include <rtl/logfile.hxx> | |
| #include <tools/debug.hxx> | |
| #include <tools/diagnose_ex.h> | |
| #include <algorithm> | |
| #include <memory> | |
| //......................................................................... | |
| #include <com/sun/star/frame/XModel.hpp> | |
| #include <com/sun/star/document/XCodeNameQuery.hpp> | |
| #include <ooo/vba/XVBAToOOEventDescGen.hpp> | |
| #include <comphelper/processfactory.hxx> | |
| namespace frm | |
| { | |
| //......................................................................... | |
| using namespace ::com::sun::star::frame; | |
| using namespace ::com::sun::star::lang; | |
| using namespace ::com::sun::star::uno; | |
| using namespace ::com::sun::star::beans; | |
| using namespace ::com::sun::star::document; | |
| using namespace ::com::sun::star::container; | |
| using namespace ::com::sun::star::script; | |
| using namespace ::com::sun::star::io; | |
| using namespace ::com::sun::star::form; | |
| using namespace ::com::sun::star::util; | |
| namespace | |
| { | |
| //--------------------------------------------------------------------- | |
| static void lcl_throwIllegalArgumentException() | |
| { | |
| throw IllegalArgumentException(); | |
| } | |
| } | |
| bool | |
| lcl_hasVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents ) | |
| { | |
| const ScriptEventDescriptor* pDesc = sEvents.getConstArray(); | |
| const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() ); | |
| for ( ; pDesc != pEnd; ++pDesc ) | |
| { | |
| if ( pDesc->ScriptType.equals( rtl::OUString::createFromAscii( "VBAInterop" ) ) ) | |
| return true; | |
| } | |
| return false; | |
| } | |
| Sequence< ScriptEventDescriptor > | |
| lcl_stripVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents ) | |
| { | |
| Sequence< ScriptEventDescriptor > sStripped( sEvents.getLength() ); | |
| const ScriptEventDescriptor* pDesc = sEvents.getConstArray(); | |
| const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() ); | |
| sal_Int32 nCopied = 0; | |
| for ( ; pDesc != pEnd; ++pDesc ) | |
| { | |
| if ( !pDesc->ScriptType.equals( rtl::OUString::createFromAscii( "VBAInterop" ) ) ) | |
| { | |
| sStripped[ nCopied++ ] = *pDesc; | |
| } | |
| } | |
| if ( nCopied ) | |
| sStripped.realloc( nCopied ); | |
| return sStripped; | |
| } | |
| void OInterfaceContainer::impl_addVbEvents_nolck_nothrow( const sal_Int32 i_nIndex ) | |
| { | |
| // we are dealing with form controls | |
| try | |
| { | |
| do | |
| { | |
| Reference< XModel > xDoc( getXModel( static_cast< XContainer *> ( this ) ) ); | |
| if ( !xDoc.is() ) | |
| break; | |
| Reference< XMultiServiceFactory > xDocFac( xDoc, UNO_QUERY_THROW ); | |
| Reference< XCodeNameQuery > xNameQuery( xDocFac->createInstance( rtl::OUString::createFromAscii( "ooo.vba.VBACodeNameProvider" ) ), UNO_QUERY ); | |
| if ( !xNameQuery.is() ) | |
| break; | |
| ::osl::MutexGuard aGuard( m_rMutex ); | |
| bool hasVBABindings = lcl_hasVbaEvents( m_xEventAttacher->getScriptEvents( i_nIndex ) ); | |
| if ( hasVBABindings ) | |
| break; | |
| Reference< XInterface > xElement( getByIndex( i_nIndex ) , UNO_QUERY_THROW ); | |
| Reference< XForm > xElementAsForm( xElement, UNO_QUERY ); | |
| if ( xElementAsForm.is() ) | |
| break; | |
| ::rtl::OUString sCodeName( xNameQuery->getCodeNameForObject( xElement ) ); | |
| Reference< XPropertySet > xProps( xElement, UNO_QUERY_THROW ); | |
| ::rtl::OUString sServiceName; | |
| xProps->getPropertyValue( rtl::OUString::createFromAscii("DefaultControl" ) ) >>= sServiceName; | |
| Reference< ooo::vba::XVBAToOOEventDescGen > xDescSupplier( m_xServiceFactory->createInstance( rtl::OUString::createFromAscii( "ooo.vba.VBAToOOEventDesc" ) ), UNO_QUERY_THROW ); | |
| Sequence< ScriptEventDescriptor > vbaEvents = xDescSupplier->getEventDescriptions( m_xServiceFactory->createInstance( sServiceName ), sCodeName ); | |
| // register the vba script events | |
| m_xEventAttacher->registerScriptEvents( i_nIndex, vbaEvents ); | |
| } | |
| while ( false ); | |
| } | |
| catch ( const ServiceNotRegisteredException& ) | |
| { | |
| // silence this, not all document types support the ooo.vba.VBACodeNameProvider service | |
| } | |
| catch( const Exception& ) | |
| { | |
| DBG_UNHANDLED_EXCEPTION(); | |
| } | |
| } | |
| //================================================================== | |
| //= ElementDescription | |
| //================================================================== | |
| //------------------------------------------------------------------ | |
| ElementDescription::ElementDescription( ) | |
| { | |
| } | |
| //------------------------------------------------------------------ | |
| ElementDescription::~ElementDescription() | |
| { | |
| } | |
| //================================================================== | |
| //= OInterfaceContainer | |
| //================================================================== | |
| //------------------------------------------------------------------ | |
| OInterfaceContainer::OInterfaceContainer( | |
| const Reference<XMultiServiceFactory>& _rxFactory, | |
| ::osl::Mutex& _rMutex, | |
| const Type& _rElementType) | |
| :OInterfaceContainer_BASE() | |
| ,m_rMutex(_rMutex) | |
| ,m_aContainerListeners(_rMutex) | |
| ,m_aElementType(_rElementType) | |
| ,m_xServiceFactory(_rxFactory) | |
| { | |
| impl_createEventAttacher_nothrow(); | |
| } | |
| //------------------------------------------------------------------------------ | |
| OInterfaceContainer::OInterfaceContainer( ::osl::Mutex& _rMutex, const OInterfaceContainer& _cloneSource ) | |
| :OInterfaceContainer_BASE() | |
| ,m_rMutex( _rMutex ) | |
| ,m_aContainerListeners( _rMutex ) | |
| ,m_aElementType( _cloneSource.m_aElementType ) | |
| ,m_xServiceFactory( _cloneSource.m_xServiceFactory ) | |
| { | |
| impl_createEventAttacher_nothrow(); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OInterfaceContainer::clonedFrom( const OInterfaceContainer& _cloneSource ) | |
| { | |
| try | |
| { | |
| const Reference< XIndexAccess > xSourceHierarchy( const_cast< OInterfaceContainer* >( &_cloneSource ) ); | |
| const sal_Int32 nCount = xSourceHierarchy->getCount(); | |
| for ( sal_Int32 i=0; i<nCount; ++i ) | |
| { | |
| Reference< XCloneable > xCloneable( xSourceHierarchy->getByIndex( i ), UNO_QUERY_THROW ); | |
| Reference< XInterface > xClone( xCloneable->createClone() ); | |
| insertByIndex( i, makeAny( xClone ) ); | |
| } | |
| } | |
| catch( const Exception& ) | |
| { | |
| throw WrappedTargetException( | |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not clone the given interface hierarchy." ) ), | |
| static_cast< XIndexContainer* >( const_cast< OInterfaceContainer* >( &_cloneSource ) ), | |
| ::cppu::getCaughtException() | |
| ); | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OInterfaceContainer::impl_createEventAttacher_nothrow() | |
| { | |
| try | |
| { | |
| m_xEventAttacher.set( ::comphelper::createEventAttacherManager( m_xServiceFactory ), UNO_SET_THROW ); | |
| } | |
| catch( const Exception& ) | |
| { | |
| DBG_UNHANDLED_EXCEPTION(); | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| OInterfaceContainer::~OInterfaceContainer() | |
| { | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OInterfaceContainer::disposing() | |
| { | |
| // dispose all elements | |
| for (sal_Int32 i = m_aItems.size(); i > 0; --i) | |
| { | |
| Reference<XPropertySet> xSet(m_aItems[i - 1], UNO_QUERY); | |
| if (xSet.is()) | |
| xSet->removePropertyChangeListener(PROPERTY_NAME, this); | |
| // revoke event knittings | |
| if ( m_xEventAttacher.is() ) | |
| { | |
| Reference< XInterface > xIfc( xSet, UNO_QUERY ); | |
| m_xEventAttacher->detach( i - 1, xIfc ); | |
| m_xEventAttacher->removeEntry( i - 1 ); | |
| } | |
| Reference<XComponent> xComponent(xSet, UNO_QUERY); | |
| if (xComponent.is()) | |
| xComponent->dispose(); | |
| } | |
| m_aMap.clear(); | |
| m_aItems.clear(); | |
| EventObject aEvt(static_cast<XContainer*>(this)); | |
| m_aContainerListeners.disposeAndClear(aEvt); | |
| } | |
| // XPersistObject | |
| //------------------------------------------------------------------------------ | |
| namespace | |
| { | |
| //.......................................................................... | |
| void lcl_saveEvents( ::std::vector< Sequence< ScriptEventDescriptor > >& _rSave, | |
| const Reference< XEventAttacherManager >& _rxManager, const sal_Int32 _nItemCount ) | |
| { | |
| OSL_ENSURE( _rxManager.is(), "lcl_saveEvents: invalid event attacher manager!" ); | |
| if ( !_rxManager.is() ) | |
| return; | |
| // reserve the space needed | |
| _rSave.reserve( _nItemCount ); | |
| // copy the events | |
| for (sal_Int32 i=0; i<_nItemCount; ++i) | |
| _rSave.push_back(_rxManager->getScriptEvents( i )); | |
| } | |
| //.......................................................................... | |
| void lcl_restoreEvents( const ::std::vector< Sequence< ScriptEventDescriptor > >& _rSave, | |
| const Reference< XEventAttacherManager >& _rxManager ) | |
| { | |
| OSL_ENSURE( _rxManager.is(), "lcl_restoreEvents: invalid event attacher manager!" ); | |
| if ( !_rxManager.is() ) | |
| return; | |
| ::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aLoop = _rSave.begin(); | |
| ::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aEnd = _rSave.end(); | |
| for ( sal_Int32 i=0; aLoop != aEnd; ++aLoop, ++i ) | |
| { | |
| _rxManager->revokeScriptEvents( i ); | |
| _rxManager->registerScriptEvents( i, *aLoop ); | |
| } | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::writeEvents(const Reference<XObjectOutputStream>& _rxOutStream) | |
| { | |
| // We're writing a document in SO 5.2 format (or even from earlier versions) | |
| // -> convert the events from the new runtime format to the format of the 5.2 files | |
| // but before, remember the current script events set for our children | |
| ::std::vector< Sequence< ScriptEventDescriptor > > aSave; | |
| if ( m_xEventAttacher.is() ) | |
| lcl_saveEvents( aSave, m_xEventAttacher, m_aItems.size() ); | |
| transformEvents( efVersionSO5x ); | |
| try | |
| { | |
| Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY); | |
| sal_Int32 nMark = xMark->createMark(); | |
| sal_Int32 nObjLen = 0; | |
| _rxOutStream->writeLong(nObjLen); | |
| Reference<XPersistObject> xScripts(m_xEventAttacher, UNO_QUERY); | |
| if (xScripts.is()) | |
| xScripts->write(_rxOutStream); | |
| // feststellen der Laenge | |
| nObjLen = xMark->offsetToMark(nMark) - 4; | |
| xMark->jumpToMark(nMark); | |
| _rxOutStream->writeLong(nObjLen); | |
| xMark->jumpToFurthest(); | |
| xMark->deleteMark(nMark); | |
| } | |
| catch( const Exception& ) | |
| { | |
| // restore the events | |
| if ( m_xEventAttacher.is() ) | |
| lcl_restoreEvents( aSave, m_xEventAttacher ); | |
| throw; | |
| } | |
| // restore the events | |
| if ( m_xEventAttacher.is() ) | |
| lcl_restoreEvents( aSave, m_xEventAttacher ); | |
| } | |
| //------------------------------------------------------------------------------ | |
| struct TransformEventTo52Format : public ::std::unary_function< ScriptEventDescriptor, void > | |
| { | |
| void operator()( ScriptEventDescriptor& _rDescriptor ) | |
| { | |
| if ( 0 == _rDescriptor.ScriptType.compareToAscii( "StarBasic" ) ) | |
| { // it's a starbasic macro | |
| sal_Int32 nPrefixLength = _rDescriptor.ScriptCode.indexOf( ':' ); | |
| if ( 0 <= nPrefixLength ) | |
| { // the macro name does not already contain a : | |
| #ifdef DBG_UTIL | |
| const ::rtl::OUString sPrefix = _rDescriptor.ScriptCode.copy( 0, nPrefixLength ); | |
| DBG_ASSERT( 0 == sPrefix.compareToAscii( "document" ) | |
| || 0 == sPrefix.compareToAscii( "application" ), | |
| "TransformEventTo52Format: invalid (unknown) prefix!" ); | |
| #endif | |
| // cut the prefix | |
| _rDescriptor.ScriptCode = _rDescriptor.ScriptCode.copy( nPrefixLength + 1 ); | |
| } | |
| } | |
| } | |
| }; | |
| //------------------------------------------------------------------------------ | |
| struct TransformEventTo60Format : public ::std::unary_function< ScriptEventDescriptor, void > | |
| { | |
| void operator()( ScriptEventDescriptor& _rDescriptor ) | |
| { | |
| if ( 0 == _rDescriptor.ScriptType.compareToAscii( "StarBasic" ) ) | |
| { // it's a starbasic macro | |
| if ( _rDescriptor.ScriptCode.indexOf( ':' ) < 0 ) | |
| { // the macro name does not already contain a : | |
| // -> default the type to "document" | |
| ::rtl::OUString sNewScriptCode( RTL_CONSTASCII_USTRINGPARAM( "document:" ) ); | |
| sNewScriptCode += _rDescriptor.ScriptCode; | |
| _rDescriptor.ScriptCode = sNewScriptCode; | |
| } | |
| } | |
| } | |
| }; | |
| //------------------------------------------------------------------------------ | |
| void OInterfaceContainer::transformEvents( const EventFormat _eTargetFormat ) | |
| { | |
| OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::transformEvents: no event attacher manager!" ); | |
| if ( !m_xEventAttacher.is() ) | |
| return; | |
| try | |
| { | |
| // loop through all our children | |
| sal_Int32 nItems = m_aItems.size(); | |
| Sequence< ScriptEventDescriptor > aChildEvents; | |
| for (sal_Int32 i=0; i<nItems; ++i) | |
| { | |
| // get the script events for this object | |
| aChildEvents = m_xEventAttacher->getScriptEvents( i ); | |
| if ( aChildEvents.getLength() ) | |
| { | |
| // the "iterators" for the events for this child | |
| ScriptEventDescriptor* pChildEvents = aChildEvents.getArray(); | |
| ScriptEventDescriptor* pChildEventsEnd = pChildEvents + aChildEvents.getLength(); | |
| // do the transformation | |
| if ( efVersionSO6x == _eTargetFormat ) | |
| ::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo60Format() ); | |
| else | |
| ::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo52Format() ); | |
| // revoke the script events | |
| m_xEventAttacher->revokeScriptEvents( i ); | |
| // and re-register them | |
| m_xEventAttacher->registerScriptEvents( i, aChildEvents ); | |
| } | |
| } | |
| } | |
| catch( const Exception& ) | |
| { | |
| DBG_UNHANDLED_EXCEPTION(); | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::readEvents(const Reference<XObjectInputStream>& _rxInStream) | |
| { | |
| ::osl::MutexGuard aGuard( m_rMutex ); | |
| // Scripting Info lesen | |
| Reference<XMarkableStream> xMark(_rxInStream, UNO_QUERY); | |
| sal_Int32 nObjLen = _rxInStream->readLong(); | |
| if (nObjLen) | |
| { | |
| sal_Int32 nMark = xMark->createMark(); | |
| Reference<XPersistObject> xObj(m_xEventAttacher, UNO_QUERY); | |
| if (xObj.is()) | |
| xObj->read(_rxInStream); | |
| xMark->jumpToMark(nMark); | |
| _rxInStream->skipBytes(nObjLen); | |
| xMark->deleteMark(nMark); | |
| } | |
| // Attachement lesen | |
| if ( m_xEventAttacher.is() ) | |
| { | |
| OInterfaceArray::const_iterator aAttach = m_aItems.begin(); | |
| OInterfaceArray::const_iterator aAttachEnd = m_aItems.end(); | |
| for ( sal_Int32 i=0; aAttach != aAttachEnd; ++aAttach, ++i ) | |
| { | |
| Reference< XInterface > xAsIFace( *aAttach, UNO_QUERY ); // important to normalize this .... | |
| Reference< XPropertySet > xAsSet( xAsIFace, UNO_QUERY ); | |
| m_xEventAttacher->attach( i, xAsIFace, makeAny( xAsSet ) ); | |
| } | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::write( const Reference< XObjectOutputStream >& _rxOutStream ) throw(IOException, RuntimeException) | |
| { | |
| ::osl::MutexGuard aGuard( m_rMutex ); | |
| sal_Int32 nLen = m_aItems.size(); | |
| // schreiben der laenge | |
| _rxOutStream->writeLong(nLen); | |
| if (nLen) | |
| { | |
| // 1. Version | |
| _rxOutStream->writeShort(0x0001); | |
| // 2. Objekte | |
| for (sal_Int32 i = 0; i < nLen; i++) | |
| { | |
| Reference<XPersistObject> xObj(m_aItems[i], UNO_QUERY); | |
| if (xObj.is()) | |
| _rxOutStream->writeObject(xObj); | |
| else | |
| { | |
| // ::com::sun::star::chaos::Error | |
| } | |
| } | |
| // 3. Scripts | |
| writeEvents(_rxOutStream); | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| namespace | |
| { | |
| Reference< XPersistObject > lcl_createPlaceHolder( const Reference< XMultiServiceFactory >& _rxORB ) | |
| { | |
| Reference< XPersistObject > xObject( _rxORB->createInstance( FRM_COMPONENT_HIDDENCONTROL ), UNO_QUERY ); | |
| DBG_ASSERT( xObject.is(), "lcl_createPlaceHolder: could not create a substitute for the unknown object!" ); | |
| if ( xObject.is() ) | |
| { | |
| // set some properties describing what we did | |
| Reference< XPropertySet > xObjProps( xObject, UNO_QUERY ); | |
| if ( xObject.is() ) | |
| { | |
| try | |
| { | |
| xObjProps->setPropertyValue( PROPERTY_NAME, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_NAME ) ) ); | |
| xObjProps->setPropertyValue( PROPERTY_TAG, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_EPXPLAIN ) ) ); | |
| } | |
| catch(Exception&) | |
| { | |
| } | |
| } | |
| } | |
| return xObject; | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::read( const Reference< XObjectInputStream >& _rxInStream ) throw(IOException, RuntimeException) | |
| { | |
| ::osl::MutexGuard aGuard( m_rMutex ); | |
| // after ::read the object is expected to be in the state it was when ::write was called, so we have | |
| // to empty ourself here | |
| // FS - 71598 - 12.01.00 | |
| while (getCount()) | |
| removeByIndex(0); | |
| // Schreibt nur in Abhaengigkeit der Laenge | |
| sal_Int32 nLen = _rxInStream->readLong(); | |
| if (nLen) | |
| { | |
| // 1. Version | |
| sal_uInt16 nVersion = _rxInStream->readShort(); (void)nVersion; | |
| // 2. Objekte | |
| for (sal_Int32 i = 0; i < nLen; i++) | |
| { | |
| Reference<XPersistObject> xObj; | |
| try | |
| { | |
| xObj = _rxInStream->readObject(); | |
| } | |
| catch(WrongFormatException& e) | |
| { | |
| (void)e; // make compiler happy | |
| // the object could not be read | |
| // create a object (so the readEvents below will assign the events to the right controls) | |
| xObj = lcl_createPlaceHolder( m_xServiceFactory ); | |
| if ( !xObj.is() ) | |
| // couldn't handle it | |
| throw; | |
| // 72133 - 09.02.00 - FS | |
| } | |
| catch(Exception&) | |
| { | |
| // unsere Map leeren | |
| while (!m_aItems.empty()) | |
| removeElementsNoEvents(0); | |
| // und die Exception nach aussen | |
| throw; | |
| } | |
| if ( xObj.is() ) | |
| { | |
| Reference< XPropertySet > xElement( xObj, UNO_QUERY ); | |
| try | |
| { | |
| implInsert( | |
| m_aItems.size(), // position | |
| xElement, // element to insert | |
| sal_False, // no event attacher manager handling | |
| NULL, // not yet approved - let implInsert do it | |
| sal_True // fire the event | |
| ); | |
| } | |
| catch( const Exception& ) | |
| { | |
| DBG_ERROR( "OInterfaceContainerHelper::read: reading succeeded, but not inserting!" ); | |
| // create a placeholder | |
| xElement = xElement.query( lcl_createPlaceHolder( m_xServiceFactory ) ); | |
| if ( !xElement.is() ) | |
| // couldn't handle it | |
| throw; | |
| // insert the placeholder | |
| implInsert( m_aItems.size(), xElement, sal_False, NULL, sal_True ); | |
| } | |
| } | |
| } | |
| readEvents(_rxInStream); | |
| } | |
| else | |
| { | |
| try | |
| { | |
| m_xEventAttacher = ::comphelper::createEventAttacherManager( m_xServiceFactory ); | |
| OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::read: could not create an event attacher manager!" ); | |
| } | |
| catch( const Exception& ) | |
| { | |
| DBG_UNHANDLED_EXCEPTION(); | |
| } | |
| } | |
| } | |
| // XContainer | |
| //------------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::addContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException ) | |
| { | |
| m_aContainerListeners.addInterface(_rxListener); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::removeContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException ) | |
| { | |
| m_aContainerListeners.removeInterface(_rxListener); | |
| } | |
| // XEventListener | |
| //------------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::disposing(const EventObject& _rSource) throw( RuntimeException ) | |
| { | |
| ::osl::MutexGuard aGuard( m_rMutex ); | |
| Reference< XInterface > xSource( _rSource.Source, UNO_QUERY ); | |
| // normalized source | |
| OInterfaceArray::iterator j; | |
| for ( j = m_aItems.begin(); j != m_aItems.end(); ++j ) | |
| { | |
| DBG_ASSERT( j->get() == Reference< XInterface >( *j, UNO_QUERY ).get(), | |
| "OInterfaceContainer::disposing: vector element not normalized!" ); | |
| if ( xSource.get() == j->get() ) | |
| // found the element | |
| break; | |
| } | |
| if ( m_aItems.end() != j ) | |
| { | |
| m_aItems.erase(j); | |
| // look up in, and erase from, m_aMap, too | |
| OInterfaceMap::iterator i = m_aMap.begin(); | |
| while ( i != m_aMap.end() ) | |
| { | |
| DBG_ASSERT( i->second.get() == Reference< XInterface >( i->second, UNO_QUERY ).get(), | |
| "OInterfaceContainer::disposing: map element not normalized!" ); | |
| if ( i->second.get() == xSource.get() ) | |
| { | |
| // found it | |
| m_aMap.erase(i); | |
| break; | |
| } | |
| ++i; | |
| DBG_ASSERT( i != m_aMap.end(), "OInterfaceContainer::disposing: inconsistency: the element was in m_aItems, but not in m_aMap!" ); | |
| } | |
| } | |
| } | |
| // XPropertyChangeListener | |
| //------------------------------------------------------------------------------ | |
| void OInterfaceContainer::propertyChange(const PropertyChangeEvent& evt) | |
| throw (::com::sun::star::uno::RuntimeException) { | |
| if (evt.PropertyName == PROPERTY_NAME) | |
| { | |
| ::osl::MutexGuard aGuard( m_rMutex ); | |
| OInterfaceMap::iterator i = ::std::find(m_aMap.begin(), m_aMap.end(), | |
| ::std::pair<const ::rtl::OUString, InterfaceRef >(::comphelper::getString(evt.OldValue),evt.Source)); | |
| if (i != m_aMap.end()) | |
| { | |
| InterfaceRef xCorrectType((*i).second); | |
| m_aMap.erase(i); | |
| m_aMap.insert(::std::pair<const ::rtl::OUString, InterfaceRef >(::comphelper::getString(evt.NewValue),xCorrectType)); | |
| } | |
| } | |
| } | |
| // XElementAccess | |
| //------------------------------------------------------------------------------ | |
| sal_Bool SAL_CALL OInterfaceContainer::hasElements() throw( RuntimeException ) | |
| { | |
| return !m_aMap.empty(); | |
| } | |
| //------------------------------------------------------------------------------ | |
| Type SAL_CALL OInterfaceContainer::getElementType() throw(RuntimeException) | |
| { | |
| return m_aElementType; | |
| } | |
| // XEnumerationAccess | |
| //------------------------------------------------------------------------------ | |
| Reference<XEnumeration> SAL_CALL OInterfaceContainer::createEnumeration() throw( RuntimeException ) | |
| { | |
| ::osl::MutexGuard aGuard( m_rMutex ); | |
| return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this)); | |
| } | |
| // XNameAccess | |
| //------------------------------------------------------------------------------ | |
| Any SAL_CALL OInterfaceContainer::getByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException) | |
| { | |
| ::std::pair <OInterfaceMap::iterator, | |
| OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName); | |
| if (aPair.first == aPair.second) | |
| throw NoSuchElementException(); | |
| return (*aPair.first).second->queryInterface( m_aElementType ); | |
| } | |
| //------------------------------------------------------------------------------ | |
| StringSequence SAL_CALL OInterfaceContainer::getElementNames() throw(RuntimeException) | |
| { | |
| StringSequence aNameList(m_aItems.size()); | |
| ::rtl::OUString* pStringArray = aNameList.getArray(); | |
| for (OInterfaceMap::const_iterator i = m_aMap.begin(); i != m_aMap.end(); ++i, ++pStringArray) | |
| { | |
| *pStringArray = (*i).first; | |
| } | |
| return aNameList; | |
| } | |
| //------------------------------------------------------------------------------ | |
| sal_Bool SAL_CALL OInterfaceContainer::hasByName( const ::rtl::OUString& _rName ) throw(RuntimeException) | |
| { | |
| ::std::pair <OInterfaceMap::iterator, | |
| OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName); | |
| return aPair.first != aPair.second; | |
| } | |
| // XIndexAccess | |
| //------------------------------------------------------------------------------ | |
| sal_Int32 OInterfaceContainer::getCount() throw( RuntimeException ) | |
| { | |
| return m_aItems.size(); | |
| } | |
| //------------------------------------------------------------------------------ | |
| Any OInterfaceContainer::getByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) | |
| { | |
| if (_nIndex < 0 || (_nIndex >= (sal_Int32)m_aItems.size())) | |
| throw IndexOutOfBoundsException(); | |
| return m_aItems[_nIndex]->queryInterface( m_aElementType ); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OInterfaceContainer::approveNewElement( const Reference< XPropertySet >& _rxObject, ElementDescription* _pElement ) | |
| { | |
| // it has to be non-NULL | |
| if ( !_rxObject.is() ) | |
| throw IllegalArgumentException(FRM_RES_STRING(RID_STR_NEED_NON_NULL_OBJECT), static_cast<XContainer*>(this), 1); | |
| // it has to support our element type interface | |
| Any aCorrectType = _rxObject->queryInterface( m_aElementType ); | |
| if ( !aCorrectType.hasValue() ) | |
| lcl_throwIllegalArgumentException(); | |
| // it has to have a "Name" property | |
| if ( !hasProperty( PROPERTY_NAME, _rxObject ) ) | |
| lcl_throwIllegalArgumentException(); | |
| // it has to be a child, and it must not have a parent already | |
| Reference< XChild > xChild( _rxObject, UNO_QUERY ); | |
| if ( !xChild.is() || xChild->getParent().is() ) | |
| { | |
| #ifdef FS_PRIV_DEBUG | |
| ::rtl::OUString sChildName, sParentName; | |
| Reference< XNamed > xNamed( xChild, UNO_QUERY ); | |
| if ( xNamed.is() ) | |
| sChildName = xNamed->getName(); | |
| if ( xChild.is() ) | |
| { | |
| xNamed = xNamed.query( xChild->getParent() ); | |
| if ( xNamed.is() ) | |
| sParentName = xNamed->getName(); | |
| } | |
| #endif | |
| lcl_throwIllegalArgumentException(); | |
| } | |
| // passed all tests. cache the information we have so far | |
| DBG_ASSERT( _pElement, "OInterfaceContainer::approveNewElement: invalid event descriptor!" ); | |
| if ( _pElement ) | |
| { | |
| _pElement->xPropertySet = _rxObject; | |
| _pElement->xChild = xChild; | |
| _pElement->aElementTypeInterface = aCorrectType; | |
| _pElement->xInterface = Reference< XInterface >( _rxObject, UNO_QUERY ); // normalized XInterface | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OInterfaceContainer::implInsert(sal_Int32 _nIndex, const Reference< XPropertySet >& _rxElement, | |
| sal_Bool _bEvents, ElementDescription* _pApprovalResult, sal_Bool _bFire ) throw( IllegalArgumentException ) | |
| { | |
| const bool bHandleEvents = _bEvents && m_xEventAttacher.is(); | |
| // SYNCHRONIZED -----> | |
| ::osl::ClearableMutexGuard aGuard( m_rMutex ); | |
| ::std::auto_ptr< ElementDescription > aAutoDeleteMetaData; | |
| ElementDescription* pElementMetaData = _pApprovalResult; | |
| if ( !pElementMetaData ) | |
| { // not yet approved by the caller -> do ourself | |
| pElementMetaData = createElementMetaData(); | |
| DBG_ASSERT( pElementMetaData, "OInterfaceContainer::implInsert: createElementMetaData returned nonsense!" ); | |
| // ensure that the meta data structure will be deleted later on | |
| aAutoDeleteMetaData = ::std::auto_ptr< ElementDescription >( pElementMetaData ); | |
| // will throw an exception if necessary | |
| approveNewElement( _rxElement, pElementMetaData ); | |
| } | |
| // approveNewElement (no matter if called here or outside) has ensure that all relevant interfaces | |
| // exist | |
| // set the name, and add as change listener for the name | |
| ::rtl::OUString sName; | |
| _rxElement->getPropertyValue(PROPERTY_NAME) >>= sName; | |
| _rxElement->addPropertyChangeListener(PROPERTY_NAME, this); | |
| // insert the object into our internal structures | |
| if (_nIndex > (sal_Int32)m_aItems.size()) // ermitteln des tatsaechlichen Indexs | |
| { | |
| _nIndex = m_aItems.size(); | |
| m_aItems.push_back( pElementMetaData->xInterface ); | |
| } | |
| else | |
| m_aItems.insert( m_aItems.begin() + _nIndex, pElementMetaData->xInterface ); | |
| m_aMap.insert( ::std::pair< const ::rtl::OUString, InterfaceRef >( sName, pElementMetaData->xInterface ) ); | |
| // announce ourself as parent to the new element | |
| pElementMetaData->xChild->setParent(static_cast<XContainer*>(this)); | |
| // handle the events | |
| if ( bHandleEvents ) | |
| { | |
| m_xEventAttacher->insertEntry(_nIndex); | |
| m_xEventAttacher->attach( _nIndex, pElementMetaData->xInterface, makeAny( _rxElement ) ); | |
| } | |
| // notify derived classes | |
| implInserted( pElementMetaData ); | |
| aGuard.clear(); | |
| // <----- SYNCHRONIZED | |
| // insert faked VBA events? | |
| if ( bHandleEvents ) | |
| { | |
| Reference< XEventAttacherManager > xMgr ( pElementMetaData->xInterface, UNO_QUERY ); | |
| if ( xMgr.is() ) | |
| { | |
| OInterfaceContainer* pIfcMgr = dynamic_cast< OInterfaceContainer* >( xMgr.get() ); | |
| sal_Int32 nLen = pIfcMgr->getCount(); | |
| for ( sal_Int32 i = 0; (i < nLen) && pIfcMgr ; ++i ) | |
| { | |
| // add fake events to the control at index i | |
| pIfcMgr->impl_addVbEvents_nolck_nothrow( i ); | |
| } | |
| } | |
| else | |
| { | |
| // add fake events to the control at index i | |
| impl_addVbEvents_nolck_nothrow( _nIndex ); | |
| } | |
| } | |
| // fire the notification about the change | |
| if ( _bFire ) | |
| { | |
| // notify listeners | |
| ContainerEvent aEvt; | |
| aEvt.Source = static_cast<XContainer*>(this); | |
| aEvt.Accessor <<= _nIndex; | |
| aEvt.Element = pElementMetaData->aElementTypeInterface; | |
| aGuard.clear(); | |
| m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvt ); | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OInterfaceContainer::removeElementsNoEvents(sal_Int32 nIndex) | |
| { | |
| OInterfaceArray::iterator i = m_aItems.begin() + nIndex; | |
| InterfaceRef xElement(*i); | |
| OInterfaceMap::iterator j = m_aMap.begin(); | |
| while (j != m_aMap.end() && (*j).second != xElement) ++j; | |
| m_aItems.erase(i); | |
| m_aMap.erase(j); | |
| Reference<XPropertySet> xSet(xElement, UNO_QUERY); | |
| if (xSet.is()) | |
| xSet->removePropertyChangeListener(PROPERTY_NAME, this); | |
| Reference<XChild> xChild(xElement, UNO_QUERY); | |
| if (xChild.is()) | |
| xChild->setParent(InterfaceRef ()); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OInterfaceContainer::implInserted( const ElementDescription* /*_pElement*/ ) | |
| { | |
| // not inrerested in | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OInterfaceContainer::implRemoved( const InterfaceRef& /*_rxObject*/ ) | |
| { | |
| // not inrerested in | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OInterfaceContainer::impl_replacedElement( const ContainerEvent& _rEvent, ::osl::ClearableMutexGuard& _rInstanceLock ) | |
| { | |
| _rInstanceLock.clear(); | |
| m_aContainerListeners.notifyEach( &XContainerListener::elementReplaced, _rEvent ); | |
| } | |
| // XIndexContainer | |
| //------------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::insertByIndex( sal_Int32 _nIndex, const Any& _rElement ) throw(IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException) | |
| { | |
| Reference< XPropertySet > xElement; | |
| _rElement >>= xElement; | |
| implInsert( _nIndex, xElement, sal_True /* event handling */ , NULL /* not yet approved */ , sal_True /* notification */ ); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OInterfaceContainer::implReplaceByIndex( const sal_Int32 _nIndex, const Any& _rNewElement, ::osl::ClearableMutexGuard& _rClearBeforeNotify ) | |
| { | |
| OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implReplaceByIndex: precondition not met (index)!" ); | |
| // approve the new object | |
| ::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() ); | |
| DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::implReplaceByIndex: createElementMetaData returned nonsense!" ); | |
| { | |
| Reference< XPropertySet > xElementProps; | |
| _rNewElement >>= xElementProps; | |
| approveNewElement( xElementProps, aElementMetaData.get() ); | |
| } | |
| // get the old element | |
| InterfaceRef xOldElement( m_aItems[ _nIndex ] ); | |
| DBG_ASSERT( xOldElement.get() == Reference< XInterface >( xOldElement, UNO_QUERY ).get(), | |
| "OInterfaceContainer::implReplaceByIndex: elements should be held normalized!" ); | |
| // locate the old element in the map | |
| OInterfaceMap::iterator j = m_aMap.begin(); | |
| while ( ( j != m_aMap.end() ) && ( j->second.get() != xOldElement.get() ) ) | |
| ++j; | |
| // remove event knittings | |
| if ( m_xEventAttacher.is() ) | |
| { | |
| InterfaceRef xNormalized( xOldElement, UNO_QUERY ); | |
| m_xEventAttacher->detach( _nIndex, xNormalized ); | |
| m_xEventAttacher->removeEntry( _nIndex ); | |
| } | |
| // don't listen for property changes anymore | |
| Reference<XPropertySet> xSet( xOldElement, UNO_QUERY ); | |
| if (xSet.is()) | |
| xSet->removePropertyChangeListener(PROPERTY_NAME, this); | |
| // give the old element a new (void) parent | |
| Reference<XChild> xChild(xOldElement, UNO_QUERY); | |
| if (xChild.is()) | |
| xChild->setParent(InterfaceRef ()); | |
| // remove the old one | |
| m_aMap.erase(j); | |
| // examine the new element | |
| ::rtl::OUString sName; | |
| DBG_ASSERT( aElementMetaData.get()->xPropertySet.is(), "OInterfaceContainer::implReplaceByIndex: what did approveNewElement do?" ); | |
| aElementMetaData.get()->xPropertySet->getPropertyValue(PROPERTY_NAME) >>= sName; | |
| aElementMetaData.get()->xPropertySet->addPropertyChangeListener(PROPERTY_NAME, this); | |
| // insert the new one | |
| m_aMap.insert( ::std::pair<const ::rtl::OUString, InterfaceRef >( sName, aElementMetaData.get()->xInterface ) ); | |
| m_aItems[ _nIndex ] = aElementMetaData.get()->xInterface; | |
| aElementMetaData.get()->xChild->setParent(static_cast<XContainer*>(this)); | |
| if ( m_xEventAttacher.is() ) | |
| { | |
| m_xEventAttacher->insertEntry( _nIndex ); | |
| m_xEventAttacher->attach( _nIndex, aElementMetaData.get()->xInterface, makeAny( aElementMetaData.get()->xPropertySet ) ); | |
| } | |
| ContainerEvent aReplaceEvent; | |
| aReplaceEvent.Source = static_cast< XContainer* >( this ); | |
| aReplaceEvent.Accessor <<= _nIndex; | |
| aReplaceEvent.Element = aElementMetaData.get()->xInterface->queryInterface( m_aElementType ); | |
| aReplaceEvent.ReplacedElement = xOldElement->queryInterface( m_aElementType ); | |
| impl_replacedElement( aReplaceEvent, _rClearBeforeNotify ); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OInterfaceContainer::implCheckIndex( const sal_Int32 _nIndex ) SAL_THROW( ( ::com::sun::star::lang::IndexOutOfBoundsException ) ) | |
| { | |
| if (_nIndex < 0 || _nIndex >= (sal_Int32)m_aItems.size()) | |
| throw IndexOutOfBoundsException(); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::replaceByIndex(sal_Int32 _nIndex, const Any& Element) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) | |
| { | |
| ::osl::ClearableMutexGuard aGuard( m_rMutex ); | |
| // check the index | |
| implCheckIndex( _nIndex ); | |
| // do the replace | |
| implReplaceByIndex( _nIndex, Element, aGuard ); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void OInterfaceContainer::implRemoveByIndex( const sal_Int32 _nIndex, ::osl::ClearableMutexGuard& _rClearBeforeNotify ) | |
| { | |
| OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implRemoveByIndex: precondition not met (index)!" ); | |
| OInterfaceArray::iterator i = m_aItems.begin() + _nIndex; | |
| InterfaceRef xElement(*i); | |
| OInterfaceMap::iterator j = m_aMap.begin(); | |
| while (j != m_aMap.end() && (*j).second != xElement) ++j; | |
| m_aItems.erase(i); | |
| m_aMap.erase(j); | |
| // remove event knittings | |
| if ( m_xEventAttacher.is() ) | |
| { | |
| InterfaceRef xNormalized( xElement, UNO_QUERY ); | |
| m_xEventAttacher->detach( _nIndex, xNormalized ); | |
| m_xEventAttacher->removeEntry( _nIndex ); | |
| } | |
| Reference<XPropertySet> xSet(xElement, UNO_QUERY); | |
| if (xSet.is()) | |
| xSet->removePropertyChangeListener(PROPERTY_NAME, this); | |
| Reference<XChild> xChild(xElement, UNO_QUERY); | |
| if (xChild.is()) | |
| xChild->setParent(InterfaceRef ()); | |
| // notify derived classes | |
| implRemoved(xElement); | |
| // notify listeners | |
| ContainerEvent aEvt; | |
| aEvt.Source = static_cast<XContainer*>(this); | |
| aEvt.Element = xElement->queryInterface( m_aElementType ); | |
| aEvt.Accessor <<= _nIndex; | |
| _rClearBeforeNotify.clear(); | |
| m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvt ); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::removeByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) | |
| { | |
| ::osl::ClearableMutexGuard aGuard( m_rMutex ); | |
| // check the index | |
| implCheckIndex( _nIndex ); | |
| // do the removal | |
| implRemoveByIndex( _nIndex, aGuard ); | |
| } | |
| //------------------------------------------------------------------------ | |
| ElementDescription* OInterfaceContainer::createElementMetaData( ) | |
| { | |
| return new ElementDescription; | |
| } | |
| //------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::insertByName(const ::rtl::OUString& _rName, const Any& _rElement) throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException ) | |
| { | |
| Reference< XPropertySet > xElementProps; | |
| ::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() ); | |
| DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::insertByName: createElementMetaData returned nonsense!" ); | |
| // ensure the correct name of the element | |
| try | |
| { | |
| _rElement >>= xElementProps; | |
| approveNewElement( xElementProps, aElementMetaData.get() ); | |
| xElementProps->setPropertyValue( PROPERTY_NAME, makeAny( _rName ) ); | |
| } | |
| catch( const IllegalArgumentException& ) | |
| { | |
| throw; // allowed to leave | |
| } | |
| catch( const ElementExistException& ) | |
| { | |
| throw; // allowed to leave | |
| } | |
| catch( const Exception& ) | |
| { | |
| DBG_ERROR( "OInterfaceContainer::insertByName: caught an exception!" ); | |
| } | |
| implInsert( m_aItems.size(), xElementProps, sal_True, aElementMetaData.get(), sal_True ); | |
| } | |
| //------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::replaceByName(const ::rtl::OUString& Name, const Any& Element) throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException ) | |
| { | |
| ::osl::ClearableMutexGuard aGuard( m_rMutex ); | |
| ::std::pair <OInterfaceMap::iterator, | |
| OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name); | |
| if (aPair.first == aPair.second) | |
| throw NoSuchElementException(); | |
| if (Element.getValueType().getTypeClass() != TypeClass_INTERFACE) | |
| lcl_throwIllegalArgumentException(); | |
| Reference<XPropertySet> xSet; | |
| Element >>= xSet; | |
| if (xSet.is()) | |
| { | |
| if (!hasProperty(PROPERTY_NAME, xSet)) | |
| lcl_throwIllegalArgumentException(); | |
| xSet->setPropertyValue(PROPERTY_NAME, makeAny(Name)); | |
| } | |
| // determine the element pos | |
| sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin(); | |
| implReplaceByIndex( nPos, Element, aGuard ); | |
| } | |
| //------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::removeByName(const ::rtl::OUString& Name) throw( NoSuchElementException, WrappedTargetException, RuntimeException ) | |
| { | |
| ::osl::MutexGuard aGuard( m_rMutex ); | |
| ::std::pair <OInterfaceMap::iterator, | |
| OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name); | |
| if (aPair.first == aPair.second) | |
| throw NoSuchElementException(); | |
| sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin(); | |
| removeByIndex(nPos); | |
| } | |
| // XEventAttacherManager | |
| //------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::registerScriptEvent( sal_Int32 nIndex, const ScriptEventDescriptor& aScriptEvent ) throw(IllegalArgumentException, RuntimeException) | |
| { | |
| ::osl::ClearableMutexGuard aGuard( m_rMutex ); | |
| if ( m_xEventAttacher.is() ) | |
| { | |
| m_xEventAttacher->registerScriptEvent( nIndex, aScriptEvent ); | |
| aGuard.clear(); | |
| impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events | |
| } | |
| } | |
| //------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::registerScriptEvents( sal_Int32 nIndex, const Sequence< ScriptEventDescriptor >& aScriptEvents ) throw(IllegalArgumentException, RuntimeException) | |
| { | |
| ::osl::ClearableMutexGuard aGuard( m_rMutex ); | |
| if ( m_xEventAttacher.is() ) | |
| { | |
| m_xEventAttacher->registerScriptEvents( nIndex, aScriptEvents ); | |
| aGuard.clear(); | |
| impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events | |
| } | |
| } | |
| //------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::revokeScriptEvent( sal_Int32 nIndex, const ::rtl::OUString& aListenerType, const ::rtl::OUString& aEventMethod, const ::rtl::OUString& aRemoveListenerParam ) throw(IllegalArgumentException, RuntimeException) | |
| { | |
| if ( m_xEventAttacher.is() ) | |
| m_xEventAttacher->revokeScriptEvent( nIndex, aListenerType, aEventMethod, aRemoveListenerParam ); | |
| } | |
| //------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::revokeScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException) | |
| { | |
| if ( m_xEventAttacher.is() ) | |
| m_xEventAttacher->revokeScriptEvents( nIndex ); | |
| } | |
| //------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::insertEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException) | |
| { | |
| if ( m_xEventAttacher.is() ) | |
| m_xEventAttacher->insertEntry( nIndex ); | |
| } | |
| //------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::removeEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException) | |
| { | |
| if ( m_xEventAttacher.is() ) | |
| m_xEventAttacher->removeEntry( nIndex ); | |
| } | |
| //------------------------------------------------------------------------ | |
| Sequence< ScriptEventDescriptor > SAL_CALL OInterfaceContainer::getScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException) | |
| { | |
| Sequence< ScriptEventDescriptor > aReturn; | |
| if ( m_xEventAttacher.is() ) | |
| { | |
| aReturn = m_xEventAttacher->getScriptEvents( nIndex ); | |
| if ( lcl_hasVbaEvents( aReturn ) ) | |
| { | |
| aReturn = lcl_stripVbaEvents( aReturn ); | |
| } | |
| } | |
| return aReturn; | |
| } | |
| //------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::attach( sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any& aHelper ) throw(IllegalArgumentException, ServiceNotRegisteredException, RuntimeException) | |
| { | |
| if ( m_xEventAttacher.is() ) | |
| m_xEventAttacher->attach( nIndex, xObject, aHelper ); | |
| } | |
| //------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::detach( sal_Int32 nIndex, const Reference< XInterface >& xObject ) throw(IllegalArgumentException, RuntimeException) | |
| { | |
| if ( m_xEventAttacher.is() ) | |
| m_xEventAttacher->detach( nIndex, xObject ); | |
| } | |
| //------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::addScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException) | |
| { | |
| if ( m_xEventAttacher.is() ) | |
| m_xEventAttacher->addScriptListener( xListener ); | |
| } | |
| //------------------------------------------------------------------------ | |
| void SAL_CALL OInterfaceContainer::removeScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException) | |
| { | |
| if ( m_xEventAttacher.is() ) | |
| m_xEventAttacher->removeScriptListener( xListener ); | |
| } | |
| //================================================================== | |
| //= OFormComponents | |
| //================================================================== | |
| //------------------------------------------------------------------------------ | |
| Any SAL_CALL OFormComponents::queryAggregation(const Type& _rType) throw(RuntimeException) | |
| { | |
| Any aReturn = OFormComponents_BASE::queryInterface(_rType); | |
| if (!aReturn.hasValue()) | |
| { | |
| aReturn = OInterfaceContainer::queryInterface(_rType); | |
| if (!aReturn.hasValue()) | |
| aReturn = FormComponentsBase::queryAggregation(_rType); | |
| } | |
| return aReturn; | |
| } | |
| //------------------------------------------------------------------ | |
| Sequence<Type> SAL_CALL OFormComponents::getTypes() throw(RuntimeException) | |
| { | |
| return ::comphelper::concatSequences(OInterfaceContainer::getTypes(), FormComponentsBase::getTypes(), OFormComponents_BASE::getTypes()); | |
| } | |
| //------------------------------------------------------------------------------ | |
| OFormComponents::OFormComponents(const Reference<XMultiServiceFactory>& _rxFactory) | |
| :FormComponentsBase( m_aMutex ) | |
| ,OInterfaceContainer( _rxFactory, m_aMutex, XFormComponent::static_type() ) | |
| ,OFormComponents_BASE() | |
| { | |
| } | |
| //------------------------------------------------------------------------------ | |
| OFormComponents::OFormComponents( const OFormComponents& _cloneSource ) | |
| :FormComponentsBase( m_aMutex ) | |
| ,OInterfaceContainer( m_aMutex, _cloneSource ) | |
| ,OFormComponents_BASE() | |
| { | |
| } | |
| //------------------------------------------------------------------------------ | |
| OFormComponents::~OFormComponents() | |
| { | |
| if (!FormComponentsBase::rBHelper.bDisposed) | |
| { | |
| acquire(); | |
| dispose(); | |
| } | |
| } | |
| // OComponentHelper | |
| //------------------------------------------------------------------------------ | |
| void OFormComponents::disposing() | |
| { | |
| OInterfaceContainer::disposing(); | |
| FormComponentsBase::disposing(); | |
| m_xParent = NULL; | |
| } | |
| //XChild | |
| //------------------------------------------------------------------------------ | |
| void OFormComponents::setParent(const InterfaceRef& Parent) throw( NoSupportException, RuntimeException ) | |
| { | |
| ::osl::MutexGuard aGuard( m_aMutex ); | |
| m_xParent = Parent; | |
| } | |
| //------------------------------------------------------------------------------ | |
| InterfaceRef OFormComponents::getParent() throw( RuntimeException ) | |
| { | |
| return m_xParent; | |
| } | |
| //......................................................................... | |
| } // namespace frm | |
| //......................................................................... | |