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