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 ) 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 ) 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) 632 { 633 m_aContainerListeners.addInterface(_rxListener); 634 } 635 636 //------------------------------------------------------------------------------ 637 void SAL_CALL OInterfaceContainer::removeContainerListener(const Reference<XContainerListener>& _rxListener) 638 { 639 m_aContainerListeners.removeInterface(_rxListener); 640 } 641 642 // XEventListener 643 //------------------------------------------------------------------------------ 644 void SAL_CALL OInterfaceContainer::disposing(const EventObject& _rSource) 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 if (evt.PropertyName == PROPERTY_NAME) 691 { 692 ::osl::MutexGuard aGuard( m_rMutex ); 693 OInterfaceMap::iterator i = ::std::find(m_aMap.begin(), m_aMap.end(), 694 ::std::pair<const ::rtl::OUString, InterfaceRef >(::comphelper::getString(evt.OldValue),evt.Source)); 695 if (i != m_aMap.end()) 696 { 697 InterfaceRef xCorrectType((*i).second); 698 m_aMap.erase(i); 699 m_aMap.insert(::std::pair<const ::rtl::OUString, InterfaceRef >(::comphelper::getString(evt.NewValue),xCorrectType)); 700 } 701 } 702 } 703 704 // XElementAccess 705 //------------------------------------------------------------------------------ 706 sal_Bool SAL_CALL OInterfaceContainer::hasElements() 707 { 708 return !m_aMap.empty(); 709 } 710 711 //------------------------------------------------------------------------------ 712 Type SAL_CALL OInterfaceContainer::getElementType() 713 { 714 return m_aElementType; 715 } 716 717 // XEnumerationAccess 718 //------------------------------------------------------------------------------ 719 Reference<XEnumeration> SAL_CALL OInterfaceContainer::createEnumeration() 720 { 721 ::osl::MutexGuard aGuard( m_rMutex ); 722 return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this)); 723 } 724 725 // XNameAccess 726 //------------------------------------------------------------------------------ 727 Any SAL_CALL OInterfaceContainer::getByName( const ::rtl::OUString& _rName ) 728 { 729 ::std::pair <OInterfaceMap::iterator, 730 OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName); 731 732 if (aPair.first == aPair.second) 733 throw NoSuchElementException(); 734 735 return (*aPair.first).second->queryInterface( m_aElementType ); 736 } 737 738 //------------------------------------------------------------------------------ 739 StringSequence SAL_CALL OInterfaceContainer::getElementNames() 740 { 741 StringSequence aNameList(m_aItems.size()); 742 ::rtl::OUString* pStringArray = aNameList.getArray(); 743 744 for (OInterfaceMap::const_iterator i = m_aMap.begin(); i != m_aMap.end(); ++i, ++pStringArray) 745 { 746 *pStringArray = (*i).first; 747 } 748 return aNameList; 749 } 750 751 //------------------------------------------------------------------------------ 752 sal_Bool SAL_CALL OInterfaceContainer::hasByName( const ::rtl::OUString& _rName ) 753 { 754 ::std::pair <OInterfaceMap::iterator, 755 OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName); 756 return aPair.first != aPair.second; 757 } 758 759 // XIndexAccess 760 //------------------------------------------------------------------------------ 761 sal_Int32 OInterfaceContainer::getCount() 762 { 763 return m_aItems.size(); 764 } 765 766 //------------------------------------------------------------------------------ 767 Any OInterfaceContainer::getByIndex(sal_Int32 _nIndex) 768 { 769 if (_nIndex < 0 || (_nIndex >= (sal_Int32)m_aItems.size())) 770 throw IndexOutOfBoundsException(); 771 772 return m_aItems[_nIndex]->queryInterface( m_aElementType ); 773 } 774 775 //------------------------------------------------------------------------------ 776 void OInterfaceContainer::approveNewElement( const Reference< XPropertySet >& _rxObject, ElementDescription* _pElement ) 777 { 778 // it has to be non-NULL 779 if ( !_rxObject.is() ) 780 throw IllegalArgumentException(FRM_RES_STRING(RID_STR_NEED_NON_NULL_OBJECT), static_cast<XContainer*>(this), 1); 781 782 // it has to support our element type interface 783 Any aCorrectType = _rxObject->queryInterface( m_aElementType ); 784 if ( !aCorrectType.hasValue() ) 785 lcl_throwIllegalArgumentException(); 786 787 // it has to have a "Name" property 788 if ( !hasProperty( PROPERTY_NAME, _rxObject ) ) 789 lcl_throwIllegalArgumentException(); 790 791 // it has to be a child, and it must not have a parent already 792 Reference< XChild > xChild( _rxObject, UNO_QUERY ); 793 if ( !xChild.is() || xChild->getParent().is() ) 794 { 795 #ifdef FS_PRIV_DEBUG 796 ::rtl::OUString sChildName, sParentName; 797 Reference< XNamed > xNamed( xChild, UNO_QUERY ); 798 if ( xNamed.is() ) 799 sChildName = xNamed->getName(); 800 if ( xChild.is() ) 801 { 802 xNamed = xNamed.query( xChild->getParent() ); 803 if ( xNamed.is() ) 804 sParentName = xNamed->getName(); 805 } 806 #endif 807 lcl_throwIllegalArgumentException(); 808 } 809 810 // passed all tests. cache the information we have so far 811 DBG_ASSERT( _pElement, "OInterfaceContainer::approveNewElement: invalid event descriptor!" ); 812 if ( _pElement ) 813 { 814 _pElement->xPropertySet = _rxObject; 815 _pElement->xChild = xChild; 816 _pElement->aElementTypeInterface = aCorrectType; 817 _pElement->xInterface = Reference< XInterface >( _rxObject, UNO_QUERY ); // normalized XInterface 818 } 819 } 820 821 //------------------------------------------------------------------------------ 822 void OInterfaceContainer::implInsert(sal_Int32 _nIndex, const Reference< XPropertySet >& _rxElement, 823 sal_Bool _bEvents, ElementDescription* _pApprovalResult, sal_Bool _bFire ) 824 { 825 const bool bHandleEvents = _bEvents && m_xEventAttacher.is(); 826 827 // SYNCHRONIZED -----> 828 ::osl::ClearableMutexGuard aGuard( m_rMutex ); 829 830 ::std::auto_ptr< ElementDescription > aAutoDeleteMetaData; 831 ElementDescription* pElementMetaData = _pApprovalResult; 832 if ( !pElementMetaData ) 833 { // not yet approved by the caller -> do ourself 834 pElementMetaData = createElementMetaData(); 835 DBG_ASSERT( pElementMetaData, "OInterfaceContainer::implInsert: createElementMetaData returned nonsense!" ); 836 837 // ensure that the meta data structure will be deleted later on 838 aAutoDeleteMetaData = ::std::auto_ptr< ElementDescription >( pElementMetaData ); 839 840 // will throw an exception if necessary 841 approveNewElement( _rxElement, pElementMetaData ); 842 } 843 844 845 // approveNewElement (no matter if called here or outside) has ensure that all relevant interfaces 846 // exist 847 848 // set the name, and add as change listener for the name 849 ::rtl::OUString sName; 850 _rxElement->getPropertyValue(PROPERTY_NAME) >>= sName; 851 _rxElement->addPropertyChangeListener(PROPERTY_NAME, this); 852 853 // insert the object into our internal structures 854 if (_nIndex > (sal_Int32)m_aItems.size()) // ermitteln des tatsaechlichen Indexs 855 { 856 _nIndex = m_aItems.size(); 857 m_aItems.push_back( pElementMetaData->xInterface ); 858 } 859 else 860 m_aItems.insert( m_aItems.begin() + _nIndex, pElementMetaData->xInterface ); 861 862 m_aMap.insert( ::std::pair< const ::rtl::OUString, InterfaceRef >( sName, pElementMetaData->xInterface ) ); 863 864 // announce ourself as parent to the new element 865 pElementMetaData->xChild->setParent(static_cast<XContainer*>(this)); 866 867 // handle the events 868 if ( bHandleEvents ) 869 { 870 m_xEventAttacher->insertEntry(_nIndex); 871 m_xEventAttacher->attach( _nIndex, pElementMetaData->xInterface, makeAny( _rxElement ) ); 872 } 873 874 // notify derived classes 875 implInserted( pElementMetaData ); 876 877 aGuard.clear(); 878 // <----- SYNCHRONIZED 879 880 // insert faked VBA events? 881 if ( bHandleEvents ) 882 { 883 Reference< XEventAttacherManager > xMgr ( pElementMetaData->xInterface, UNO_QUERY ); 884 if ( xMgr.is() ) 885 { 886 OInterfaceContainer* pIfcMgr = dynamic_cast< OInterfaceContainer* >( xMgr.get() ); 887 sal_Int32 nLen = pIfcMgr->getCount(); 888 for ( sal_Int32 i = 0; (i < nLen) && pIfcMgr ; ++i ) 889 { 890 // add fake events to the control at index i 891 pIfcMgr->impl_addVbEvents_nolck_nothrow( i ); 892 } 893 } 894 else 895 { 896 // add fake events to the control at index i 897 impl_addVbEvents_nolck_nothrow( _nIndex ); 898 } 899 } 900 901 // fire the notification about the change 902 if ( _bFire ) 903 { 904 // notify listeners 905 ContainerEvent aEvt; 906 aEvt.Source = static_cast<XContainer*>(this); 907 aEvt.Accessor <<= _nIndex; 908 aEvt.Element = pElementMetaData->aElementTypeInterface; 909 910 aGuard.clear(); 911 m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvt ); 912 } 913 } 914 915 //------------------------------------------------------------------------------ 916 void OInterfaceContainer::removeElementsNoEvents(sal_Int32 nIndex) 917 { 918 OInterfaceArray::iterator i = m_aItems.begin() + nIndex; 919 InterfaceRef xElement(*i); 920 921 OInterfaceMap::iterator j = m_aMap.begin(); 922 while (j != m_aMap.end() && (*j).second != xElement) ++j; 923 924 m_aItems.erase(i); 925 m_aMap.erase(j); 926 927 Reference<XPropertySet> xSet(xElement, UNO_QUERY); 928 if (xSet.is()) 929 xSet->removePropertyChangeListener(PROPERTY_NAME, this); 930 931 Reference<XChild> xChild(xElement, UNO_QUERY); 932 if (xChild.is()) 933 xChild->setParent(InterfaceRef ()); 934 } 935 936 //------------------------------------------------------------------------------ 937 void OInterfaceContainer::implInserted( const ElementDescription* /*_pElement*/ ) 938 { 939 // not inrerested in 940 } 941 942 //------------------------------------------------------------------------------ 943 void OInterfaceContainer::implRemoved( const InterfaceRef& /*_rxObject*/ ) 944 { 945 // not inrerested in 946 } 947 948 //------------------------------------------------------------------------------ 949 void OInterfaceContainer::impl_replacedElement( const ContainerEvent& _rEvent, ::osl::ClearableMutexGuard& _rInstanceLock ) 950 { 951 _rInstanceLock.clear(); 952 m_aContainerListeners.notifyEach( &XContainerListener::elementReplaced, _rEvent ); 953 } 954 955 // XIndexContainer 956 //------------------------------------------------------------------------------ 957 void SAL_CALL OInterfaceContainer::insertByIndex( sal_Int32 _nIndex, const Any& _rElement ) 958 { 959 Reference< XPropertySet > xElement; 960 _rElement >>= xElement; 961 implInsert( _nIndex, xElement, sal_True /* event handling */ , NULL /* not yet approved */ , sal_True /* notification */ ); 962 } 963 964 //------------------------------------------------------------------------------ 965 void OInterfaceContainer::implReplaceByIndex( const sal_Int32 _nIndex, const Any& _rNewElement, ::osl::ClearableMutexGuard& _rClearBeforeNotify ) 966 { 967 OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implReplaceByIndex: precondition not met (index)!" ); 968 969 // approve the new object 970 ::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() ); 971 DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::implReplaceByIndex: createElementMetaData returned nonsense!" ); 972 { 973 Reference< XPropertySet > xElementProps; 974 _rNewElement >>= xElementProps; 975 approveNewElement( xElementProps, aElementMetaData.get() ); 976 } 977 978 // get the old element 979 InterfaceRef xOldElement( m_aItems[ _nIndex ] ); 980 DBG_ASSERT( xOldElement.get() == Reference< XInterface >( xOldElement, UNO_QUERY ).get(), 981 "OInterfaceContainer::implReplaceByIndex: elements should be held normalized!" ); 982 983 // locate the old element in the map 984 OInterfaceMap::iterator j = m_aMap.begin(); 985 while ( ( j != m_aMap.end() ) && ( j->second.get() != xOldElement.get() ) ) 986 ++j; 987 988 // remove event knittings 989 if ( m_xEventAttacher.is() ) 990 { 991 InterfaceRef xNormalized( xOldElement, UNO_QUERY ); 992 m_xEventAttacher->detach( _nIndex, xNormalized ); 993 m_xEventAttacher->removeEntry( _nIndex ); 994 } 995 996 // don't listen for property changes anymore 997 Reference<XPropertySet> xSet( xOldElement, UNO_QUERY ); 998 if (xSet.is()) 999 xSet->removePropertyChangeListener(PROPERTY_NAME, this); 1000 1001 // give the old element a new (void) parent 1002 Reference<XChild> xChild(xOldElement, UNO_QUERY); 1003 if (xChild.is()) 1004 xChild->setParent(InterfaceRef ()); 1005 1006 // remove the old one 1007 m_aMap.erase(j); 1008 1009 // examine the new element 1010 ::rtl::OUString sName; 1011 DBG_ASSERT( aElementMetaData.get()->xPropertySet.is(), "OInterfaceContainer::implReplaceByIndex: what did approveNewElement do?" ); 1012 1013 aElementMetaData.get()->xPropertySet->getPropertyValue(PROPERTY_NAME) >>= sName; 1014 aElementMetaData.get()->xPropertySet->addPropertyChangeListener(PROPERTY_NAME, this); 1015 1016 // insert the new one 1017 m_aMap.insert( ::std::pair<const ::rtl::OUString, InterfaceRef >( sName, aElementMetaData.get()->xInterface ) ); 1018 m_aItems[ _nIndex ] = aElementMetaData.get()->xInterface; 1019 1020 aElementMetaData.get()->xChild->setParent(static_cast<XContainer*>(this)); 1021 1022 if ( m_xEventAttacher.is() ) 1023 { 1024 m_xEventAttacher->insertEntry( _nIndex ); 1025 m_xEventAttacher->attach( _nIndex, aElementMetaData.get()->xInterface, makeAny( aElementMetaData.get()->xPropertySet ) ); 1026 } 1027 1028 ContainerEvent aReplaceEvent; 1029 aReplaceEvent.Source = static_cast< XContainer* >( this ); 1030 aReplaceEvent.Accessor <<= _nIndex; 1031 aReplaceEvent.Element = aElementMetaData.get()->xInterface->queryInterface( m_aElementType ); 1032 aReplaceEvent.ReplacedElement = xOldElement->queryInterface( m_aElementType ); 1033 1034 impl_replacedElement( aReplaceEvent, _rClearBeforeNotify ); 1035 } 1036 1037 //------------------------------------------------------------------------------ 1038 void OInterfaceContainer::implCheckIndex( const sal_Int32 _nIndex ) 1039 { 1040 if (_nIndex < 0 || _nIndex >= (sal_Int32)m_aItems.size()) 1041 throw IndexOutOfBoundsException(); 1042 } 1043 1044 //------------------------------------------------------------------------------ 1045 void SAL_CALL OInterfaceContainer::replaceByIndex(sal_Int32 _nIndex, const Any& Element) 1046 { 1047 ::osl::ClearableMutexGuard aGuard( m_rMutex ); 1048 // check the index 1049 implCheckIndex( _nIndex ); 1050 // do the replace 1051 implReplaceByIndex( _nIndex, Element, aGuard ); 1052 } 1053 1054 //------------------------------------------------------------------------------ 1055 void OInterfaceContainer::implRemoveByIndex( const sal_Int32 _nIndex, ::osl::ClearableMutexGuard& _rClearBeforeNotify ) 1056 { 1057 OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implRemoveByIndex: precondition not met (index)!" ); 1058 1059 OInterfaceArray::iterator i = m_aItems.begin() + _nIndex; 1060 InterfaceRef xElement(*i); 1061 1062 OInterfaceMap::iterator j = m_aMap.begin(); 1063 while (j != m_aMap.end() && (*j).second != xElement) ++j; 1064 1065 m_aItems.erase(i); 1066 m_aMap.erase(j); 1067 1068 // remove event knittings 1069 if ( m_xEventAttacher.is() ) 1070 { 1071 InterfaceRef xNormalized( xElement, UNO_QUERY ); 1072 m_xEventAttacher->detach( _nIndex, xNormalized ); 1073 m_xEventAttacher->removeEntry( _nIndex ); 1074 } 1075 1076 Reference<XPropertySet> xSet(xElement, UNO_QUERY); 1077 if (xSet.is()) 1078 xSet->removePropertyChangeListener(PROPERTY_NAME, this); 1079 1080 Reference<XChild> xChild(xElement, UNO_QUERY); 1081 if (xChild.is()) 1082 xChild->setParent(InterfaceRef ()); 1083 1084 // notify derived classes 1085 implRemoved(xElement); 1086 1087 // notify listeners 1088 ContainerEvent aEvt; 1089 aEvt.Source = static_cast<XContainer*>(this); 1090 aEvt.Element = xElement->queryInterface( m_aElementType ); 1091 aEvt.Accessor <<= _nIndex; 1092 1093 _rClearBeforeNotify.clear(); 1094 m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvt ); 1095 } 1096 1097 //------------------------------------------------------------------------------ 1098 void SAL_CALL OInterfaceContainer::removeByIndex(sal_Int32 _nIndex) 1099 { 1100 ::osl::ClearableMutexGuard aGuard( m_rMutex ); 1101 // check the index 1102 implCheckIndex( _nIndex ); 1103 // do the removal 1104 implRemoveByIndex( _nIndex, aGuard ); 1105 } 1106 1107 //------------------------------------------------------------------------ 1108 ElementDescription* OInterfaceContainer::createElementMetaData( ) 1109 { 1110 return new ElementDescription; 1111 } 1112 1113 //------------------------------------------------------------------------ 1114 void SAL_CALL OInterfaceContainer::insertByName(const ::rtl::OUString& _rName, const Any& _rElement) 1115 { 1116 Reference< XPropertySet > xElementProps; 1117 1118 ::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() ); 1119 DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::insertByName: createElementMetaData returned nonsense!" ); 1120 1121 // ensure the correct name of the element 1122 try 1123 { 1124 _rElement >>= xElementProps; 1125 approveNewElement( xElementProps, aElementMetaData.get() ); 1126 1127 xElementProps->setPropertyValue( PROPERTY_NAME, makeAny( _rName ) ); 1128 } 1129 catch( const IllegalArgumentException& ) 1130 { 1131 throw; // allowed to leave 1132 } 1133 catch( const ElementExistException& ) 1134 { 1135 throw; // allowed to leave 1136 } 1137 catch( const Exception& ) 1138 { 1139 DBG_ERROR( "OInterfaceContainer::insertByName: caught an exception!" ); 1140 } 1141 implInsert( m_aItems.size(), xElementProps, sal_True, aElementMetaData.get(), sal_True ); 1142 } 1143 1144 //------------------------------------------------------------------------ 1145 void SAL_CALL OInterfaceContainer::replaceByName(const ::rtl::OUString& Name, const Any& Element) 1146 { 1147 ::osl::ClearableMutexGuard aGuard( m_rMutex ); 1148 ::std::pair <OInterfaceMap::iterator, 1149 OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name); 1150 if (aPair.first == aPair.second) 1151 throw NoSuchElementException(); 1152 1153 if (Element.getValueType().getTypeClass() != TypeClass_INTERFACE) 1154 lcl_throwIllegalArgumentException(); 1155 1156 Reference<XPropertySet> xSet; 1157 Element >>= xSet; 1158 if (xSet.is()) 1159 { 1160 if (!hasProperty(PROPERTY_NAME, xSet)) 1161 lcl_throwIllegalArgumentException(); 1162 1163 xSet->setPropertyValue(PROPERTY_NAME, makeAny(Name)); 1164 } 1165 1166 // determine the element pos 1167 sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin(); 1168 1169 implReplaceByIndex( nPos, Element, aGuard ); 1170 } 1171 1172 //------------------------------------------------------------------------ 1173 void SAL_CALL OInterfaceContainer::removeByName(const ::rtl::OUString& Name) 1174 { 1175 ::osl::MutexGuard aGuard( m_rMutex ); 1176 ::std::pair <OInterfaceMap::iterator, 1177 OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name); 1178 if (aPair.first == aPair.second) 1179 throw NoSuchElementException(); 1180 1181 sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin(); 1182 removeByIndex(nPos); 1183 } 1184 1185 1186 // XEventAttacherManager 1187 //------------------------------------------------------------------------ 1188 void SAL_CALL OInterfaceContainer::registerScriptEvent( sal_Int32 nIndex, const ScriptEventDescriptor& aScriptEvent ) 1189 { 1190 ::osl::ClearableMutexGuard aGuard( m_rMutex ); 1191 if ( m_xEventAttacher.is() ) 1192 { 1193 m_xEventAttacher->registerScriptEvent( nIndex, aScriptEvent ); 1194 aGuard.clear(); 1195 impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events 1196 } 1197 } 1198 1199 //------------------------------------------------------------------------ 1200 void SAL_CALL OInterfaceContainer::registerScriptEvents( sal_Int32 nIndex, const Sequence< ScriptEventDescriptor >& aScriptEvents ) 1201 { 1202 ::osl::ClearableMutexGuard aGuard( m_rMutex ); 1203 if ( m_xEventAttacher.is() ) 1204 { 1205 m_xEventAttacher->registerScriptEvents( nIndex, aScriptEvents ); 1206 aGuard.clear(); 1207 impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events 1208 } 1209 } 1210 1211 //------------------------------------------------------------------------ 1212 void SAL_CALL OInterfaceContainer::revokeScriptEvent( sal_Int32 nIndex, const ::rtl::OUString& aListenerType, const ::rtl::OUString& aEventMethod, const ::rtl::OUString& aRemoveListenerParam ) 1213 { 1214 if ( m_xEventAttacher.is() ) 1215 m_xEventAttacher->revokeScriptEvent( nIndex, aListenerType, aEventMethod, aRemoveListenerParam ); 1216 } 1217 1218 //------------------------------------------------------------------------ 1219 void SAL_CALL OInterfaceContainer::revokeScriptEvents( sal_Int32 nIndex ) 1220 { 1221 if ( m_xEventAttacher.is() ) 1222 m_xEventAttacher->revokeScriptEvents( nIndex ); 1223 } 1224 1225 //------------------------------------------------------------------------ 1226 void SAL_CALL OInterfaceContainer::insertEntry( sal_Int32 nIndex ) 1227 { 1228 if ( m_xEventAttacher.is() ) 1229 m_xEventAttacher->insertEntry( nIndex ); 1230 } 1231 1232 //------------------------------------------------------------------------ 1233 void SAL_CALL OInterfaceContainer::removeEntry( sal_Int32 nIndex ) 1234 { 1235 if ( m_xEventAttacher.is() ) 1236 m_xEventAttacher->removeEntry( nIndex ); 1237 } 1238 1239 //------------------------------------------------------------------------ 1240 Sequence< ScriptEventDescriptor > SAL_CALL OInterfaceContainer::getScriptEvents( sal_Int32 nIndex ) 1241 { 1242 Sequence< ScriptEventDescriptor > aReturn; 1243 if ( m_xEventAttacher.is() ) 1244 { 1245 aReturn = m_xEventAttacher->getScriptEvents( nIndex ); 1246 if ( lcl_hasVbaEvents( aReturn ) ) 1247 { 1248 aReturn = lcl_stripVbaEvents( aReturn ); 1249 } 1250 } 1251 return aReturn; 1252 } 1253 1254 //------------------------------------------------------------------------ 1255 void SAL_CALL OInterfaceContainer::attach( sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any& aHelper ) 1256 { 1257 if ( m_xEventAttacher.is() ) 1258 m_xEventAttacher->attach( nIndex, xObject, aHelper ); 1259 } 1260 1261 //------------------------------------------------------------------------ 1262 void SAL_CALL OInterfaceContainer::detach( sal_Int32 nIndex, const Reference< XInterface >& xObject ) 1263 { 1264 if ( m_xEventAttacher.is() ) 1265 m_xEventAttacher->detach( nIndex, xObject ); 1266 } 1267 1268 //------------------------------------------------------------------------ 1269 void SAL_CALL OInterfaceContainer::addScriptListener( const Reference< XScriptListener >& xListener ) 1270 { 1271 if ( m_xEventAttacher.is() ) 1272 m_xEventAttacher->addScriptListener( xListener ); 1273 } 1274 1275 //------------------------------------------------------------------------ 1276 void SAL_CALL OInterfaceContainer::removeScriptListener( const Reference< XScriptListener >& xListener ) 1277 { 1278 if ( m_xEventAttacher.is() ) 1279 m_xEventAttacher->removeScriptListener( xListener ); 1280 } 1281 1282 //================================================================== 1283 //= OFormComponents 1284 //================================================================== 1285 //------------------------------------------------------------------------------ 1286 Any SAL_CALL OFormComponents::queryAggregation(const Type& _rType) 1287 { 1288 Any aReturn = OFormComponents_BASE::queryInterface(_rType); 1289 if (!aReturn.hasValue()) 1290 { 1291 aReturn = OInterfaceContainer::queryInterface(_rType); 1292 1293 if (!aReturn.hasValue()) 1294 aReturn = FormComponentsBase::queryAggregation(_rType); 1295 } 1296 1297 return aReturn; 1298 } 1299 1300 //------------------------------------------------------------------ 1301 Sequence<Type> SAL_CALL OFormComponents::getTypes() 1302 { 1303 return ::comphelper::concatSequences(OInterfaceContainer::getTypes(), FormComponentsBase::getTypes(), OFormComponents_BASE::getTypes()); 1304 } 1305 1306 //------------------------------------------------------------------------------ 1307 OFormComponents::OFormComponents(const Reference<XMultiServiceFactory>& _rxFactory) 1308 :FormComponentsBase( m_aMutex ) 1309 ,OInterfaceContainer( _rxFactory, m_aMutex, XFormComponent::static_type() ) 1310 ,OFormComponents_BASE() 1311 { 1312 } 1313 1314 //------------------------------------------------------------------------------ 1315 OFormComponents::OFormComponents( const OFormComponents& _cloneSource ) 1316 :FormComponentsBase( m_aMutex ) 1317 ,OInterfaceContainer( m_aMutex, _cloneSource ) 1318 ,OFormComponents_BASE() 1319 { 1320 } 1321 1322 //------------------------------------------------------------------------------ 1323 OFormComponents::~OFormComponents() 1324 { 1325 if (!FormComponentsBase::rBHelper.bDisposed) 1326 { 1327 acquire(); 1328 dispose(); 1329 } 1330 } 1331 1332 // OComponentHelper 1333 //------------------------------------------------------------------------------ 1334 void OFormComponents::disposing() 1335 { 1336 OInterfaceContainer::disposing(); 1337 FormComponentsBase::disposing(); 1338 m_xParent = NULL; 1339 } 1340 1341 //XChild 1342 //------------------------------------------------------------------------------ 1343 void OFormComponents::setParent(const InterfaceRef& Parent) 1344 { 1345 ::osl::MutexGuard aGuard( m_aMutex ); 1346 m_xParent = Parent; 1347 } 1348 1349 //------------------------------------------------------------------------------ 1350 InterfaceRef OFormComponents::getParent() 1351 { 1352 return m_xParent; 1353 } 1354 1355 //......................................................................... 1356 } // namespace frm 1357 //......................................................................... 1358