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