1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_toolkit.hxx" 30 31 32 #include <com/sun/star/awt/XVclContainerPeer.hpp> 33 #include <com/sun/star/beans/XPropertyChangeListener.hpp> 34 35 #include <cppuhelper/typeprovider.hxx> 36 #include <cppuhelper/implbase1.hxx> 37 #include <rtl/memory.h> 38 #include <rtl/uuid.h> 39 40 #include <toolkit/controls/unocontrolcontainer.hxx> 41 #include <toolkit/helper/property.hxx> 42 #include <toolkit/helper/servicenames.hxx> 43 #include <comphelper/sequence.hxx> 44 45 #include <tools/debug.hxx> 46 #include <tools/list.hxx> 47 #include <vcl/svapp.hxx> 48 #include <vcl/window.hxx> 49 50 #include <limits> 51 #include <map> 52 #include <boost/shared_ptr.hpp> 53 54 using namespace ::com::sun::star; 55 56 extern WorkWindow* lcl_GetDefaultWindow(); 57 58 // ---------------------------------------------------- 59 // class UnoControlHolder 60 // ---------------------------------------------------- 61 struct UnoControlHolder 62 { 63 uno::Reference< awt::XControl > mxControl; 64 ::rtl::OUString msName; 65 66 public: 67 UnoControlHolder( const ::rtl::OUString& rName, const uno::Reference< awt::XControl > & rControl ) 68 : mxControl( rControl ), 69 msName( rName ) 70 { 71 } 72 73 inline const ::rtl::OUString& getName() const { return msName; } 74 inline const uno::Reference< awt::XControl >& getControl() const { return mxControl; } 75 }; 76 77 //DECLARE_LIST( UnoControlHolderList, UnoControlHolder* ); 78 79 class UnoControlHolderList 80 { 81 public: 82 typedef sal_Int32 ControlIdentifier; 83 private: 84 typedef ::boost::shared_ptr< UnoControlHolder > ControlInfo; 85 typedef ::std::map< ControlIdentifier, ControlInfo > ControlMap; 86 87 private: 88 ControlMap maControls; 89 90 public: 91 UnoControlHolderList(); 92 ~UnoControlHolderList(); 93 94 /** adds a control with the given name to the list 95 @param _rxControl 96 the control to add. Must not be <NULL/> 97 @param _pBName 98 the name of the control, or <NULL/> if an automatic name should be generated 99 @return 100 the identifier of the newly added control 101 */ 102 ControlIdentifier addControl( const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pName ); 103 104 /** returns the number of controls in the list 105 */ 106 inline size_t size() const { return maControls.size(); } 107 108 /** determines whether or not the list is empty 109 */ 110 inline bool empty() const { return maControls.empty(); } 111 112 /** retrieves all controls currently in the list 113 @return 114 the number of controls in the list 115 */ 116 size_t getControls( uno::Sequence< uno::Reference< awt::XControl > >& _out_rControls ) const; 117 118 /** retrieves all identifiers of all controls currently in the list 119 @return 120 the number of controls in the list 121 */ 122 size_t getIdentifiers( uno::Sequence< sal_Int32 >& _out_rIdentifiers ) const; 123 124 /** returns the first control which is registered under the given name 125 */ 126 uno::Reference< awt::XControl > 127 getControlForName( const ::rtl::OUString& _rName ) const; 128 129 /** returns the identifier which a control is registered for, or -1 if the control 130 isn't registered 131 */ 132 ControlIdentifier 133 getControlIdentifier( const uno::Reference< awt::XControl >& _rxControl ); 134 135 /** retrieves the control for a given id 136 @param _nIdentifier 137 the identifier for the control 138 @param _out_rxControl 139 takes the XControl upon successful return 140 @return 141 <TRUE/> if and only if a control with the given id is part of the list 142 */ 143 bool getControlForIdentifier( ControlIdentifier _nIdentifier, uno::Reference< awt::XControl >& _out_rxControl ) const; 144 145 /** removes a control from the list, given by id 146 @param _nId 147 The identifier of the control to remove. 148 */ 149 void removeControlById( ControlIdentifier _nId ); 150 151 /** replaces a control from the list with another one 152 @param _nId 153 The identifier of the control to replace 154 @param _rxNewControl 155 the new control to put into the list 156 */ 157 void replaceControlById( ControlIdentifier _nId, const uno::Reference< awt::XControl >& _rxNewControl ); 158 159 private: 160 /** adds a control 161 @param _rxControl 162 the control to add to the container 163 @param _pName 164 pointer to the name of the control. Might be <NULL/>, in this case, a name is generated. 165 @return 166 the identifier of the newly inserted control 167 */ 168 ControlIdentifier impl_addControl( 169 const uno::Reference< awt::XControl >& _rxControl, 170 const ::rtl::OUString* _pName 171 ); 172 173 /** finds a free identifier 174 @throw uno::RuntimeException 175 if no free identifier can be found 176 */ 177 ControlIdentifier impl_getFreeIdentifier_throw(); 178 179 /** finds a free name 180 @throw uno::RuntimeException 181 if no free name can be found 182 */ 183 ::rtl::OUString impl_getFreeName_throw(); 184 }; 185 186 //------------------------------------------------------------------------ 187 UnoControlHolderList::UnoControlHolderList() 188 { 189 } 190 191 //------------------------------------------------------------------------ 192 UnoControlHolderList::~UnoControlHolderList() 193 { 194 } 195 196 //------------------------------------------------------------------------ 197 UnoControlHolderList::ControlIdentifier UnoControlHolderList::addControl( const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pName ) 198 { 199 return impl_addControl( _rxControl, _pName ); 200 } 201 202 //------------------------------------------------------------------------ 203 size_t UnoControlHolderList::getControls( uno::Sequence< uno::Reference< awt::XControl > >& _out_rControls ) const 204 { 205 _out_rControls.realloc( maControls.size() ); 206 uno::Reference< awt::XControl >* pControls = _out_rControls.getArray(); 207 for ( ControlMap::const_iterator loop = maControls.begin(); 208 loop != maControls.end(); 209 ++loop, ++pControls 210 ) 211 *pControls = loop->second->getControl(); 212 return maControls.size(); 213 } 214 215 //------------------------------------------------------------------------ 216 size_t UnoControlHolderList::getIdentifiers( uno::Sequence< sal_Int32 >& _out_rIdentifiers ) const 217 { 218 _out_rIdentifiers.realloc( maControls.size() ); 219 sal_Int32* pIndentifiers = _out_rIdentifiers.getArray(); 220 for ( ControlMap::const_iterator loop = maControls.begin(); 221 loop != maControls.end(); 222 ++loop, ++pIndentifiers 223 ) 224 *pIndentifiers = loop->first; 225 return maControls.size(); 226 } 227 228 //------------------------------------------------------------------------ 229 uno::Reference< awt::XControl > UnoControlHolderList::getControlForName( const ::rtl::OUString& _rName ) const 230 { 231 for ( ControlMap::const_iterator loop = maControls.begin(); 232 loop != maControls.end(); 233 ++loop 234 ) 235 if ( loop->second->getName() == _rName ) 236 return loop->second->getControl(); 237 return uno::Reference< awt::XControl >(); 238 } 239 240 //------------------------------------------------------------------------ 241 UnoControlHolderList::ControlIdentifier UnoControlHolderList::getControlIdentifier( const uno::Reference< awt::XControl >& _rxControl ) 242 { 243 for ( ControlMap::iterator loop = maControls.begin(); 244 loop != maControls.end(); 245 ++loop 246 ) 247 { 248 if ( loop->second->getControl().get() == _rxControl.get() ) 249 return loop->first; 250 } 251 return -1; 252 } 253 254 //------------------------------------------------------------------------ 255 bool UnoControlHolderList::getControlForIdentifier( UnoControlHolderList::ControlIdentifier _nIdentifier, uno::Reference< awt::XControl >& _out_rxControl ) const 256 { 257 ControlMap::const_iterator pos = maControls.find( _nIdentifier ); 258 if ( pos == maControls.end() ) 259 return false; 260 _out_rxControl = pos->second->getControl(); 261 return true; 262 } 263 264 //------------------------------------------------------------------------ 265 void UnoControlHolderList::removeControlById( UnoControlHolderList::ControlIdentifier _nId ) 266 { 267 ControlMap::iterator pos = maControls.find( _nId ); 268 DBG_ASSERT( pos != maControls.end(), "UnoControlHolderList::removeControlById: invalid id!" ); 269 if ( pos == maControls.end() ) 270 return; 271 272 maControls.erase( pos ); 273 } 274 275 //------------------------------------------------------------------------ 276 void UnoControlHolderList::replaceControlById( ControlIdentifier _nId, const uno::Reference< awt::XControl >& _rxNewControl ) 277 { 278 DBG_ASSERT( _rxNewControl.is(), "UnoControlHolderList::replaceControlById: invalid new control!" ); 279 280 ControlMap::iterator pos = maControls.find( _nId ); 281 DBG_ASSERT( pos != maControls.end(), "UnoControlHolderList::replaceControlById: invalid id!" ); 282 if ( pos == maControls.end() ) 283 return; 284 285 pos->second.reset( new UnoControlHolder( pos->second->getName(), _rxNewControl ) ); 286 } 287 288 //------------------------------------------------------------------------ 289 UnoControlHolderList::ControlIdentifier UnoControlHolderList::impl_addControl( const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pName ) 290 { 291 DBG_ASSERT( _rxControl.is(), "UnoControlHolderList::impl_addControl: invalid control!" ); 292 293 ::rtl::OUString sName = _pName ? *_pName : impl_getFreeName_throw(); 294 sal_Int32 nId = impl_getFreeIdentifier_throw(); 295 296 maControls[ nId ] = ControlInfo( new UnoControlHolder( sName, _rxControl ) ); 297 return nId; 298 } 299 300 //------------------------------------------------------------------------ 301 UnoControlHolderList::ControlIdentifier UnoControlHolderList::impl_getFreeIdentifier_throw() 302 { 303 for ( ControlIdentifier candidateId = 0; candidateId < ::std::numeric_limits< ControlIdentifier >::max(); ++candidateId ) 304 { 305 ControlMap::const_iterator existent = maControls.find( candidateId ); 306 if ( existent == maControls.end() ) 307 return candidateId; 308 } 309 throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "out of identifiers" ) ), NULL ); 310 } 311 312 //------------------------------------------------------------------------ 313 ::rtl::OUString UnoControlHolderList::impl_getFreeName_throw() 314 { 315 ::rtl::OUString name( RTL_CONSTASCII_USTRINGPARAM( "control_" ) ); 316 for ( ControlIdentifier candidateId = 0; candidateId < ::std::numeric_limits< ControlIdentifier >::max(); ++candidateId ) 317 { 318 ::rtl::OUString candidateName( name + ::rtl::OUString::valueOf( candidateId ) ); 319 ControlMap::const_iterator loop = maControls.begin(); 320 for ( ; loop != maControls.end(); ++loop ) 321 { 322 if ( loop->second->getName() == candidateName ) 323 break; 324 } 325 if ( loop == maControls.end() ) 326 return candidateName; 327 } 328 throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "out of identifiers" ) ), NULL ); 329 } 330 // ---------------------------------------------------- 331 // Function to set the controls' visibility according 332 // to the dialog's "Step" property 333 // ---------------------------------------------------- 334 void implUpdateVisibility 335 ( 336 sal_Int32 nDialogStep, 337 uno::Reference< awt::XControlContainer > xControlContainer 338 ) 339 { 340 uno::Sequence< uno::Reference< awt::XControl > > 341 aCtrls = xControlContainer->getControls(); 342 const uno::Reference< awt::XControl >* pCtrls = aCtrls.getConstArray(); 343 sal_uInt32 nCtrls = aCtrls.getLength(); 344 sal_Bool bCompleteVisible = (nDialogStep == 0); 345 for( sal_uInt32 n = 0; n < nCtrls; n++ ) 346 { 347 uno::Reference< awt::XControl > xControl = pCtrls[ n ]; 348 349 sal_Bool bVisible = bCompleteVisible; 350 if( !bVisible ) 351 { 352 uno::Reference< awt::XControlModel > xModel( xControl->getModel() ); 353 uno::Reference< beans::XPropertySet > xPSet 354 ( xModel, uno::UNO_QUERY ); 355 uno::Reference< beans::XPropertySetInfo > 356 xInfo = xPSet->getPropertySetInfo(); 357 ::rtl::OUString aPropName(RTL_CONSTASCII_USTRINGPARAM( "Step" ) ); 358 sal_Int32 nControlStep = 0; 359 if ( xInfo->hasPropertyByName( aPropName ) ) 360 { 361 uno::Any aVal = xPSet->getPropertyValue( aPropName ); 362 aVal >>= nControlStep; 363 } 364 bVisible = (nControlStep == 0) || (nControlStep == nDialogStep); 365 } 366 367 uno::Reference< awt::XWindow> xWindow 368 ( xControl, uno::UNO_QUERY ); 369 if( xWindow.is() ) 370 xWindow->setVisible( bVisible ); 371 } 372 } 373 374 375 // ---------------------------------------------------- 376 // class DialogStepChangedListener 377 // ---------------------------------------------------- 378 typedef ::cppu::WeakImplHelper1< beans::XPropertyChangeListener > PropertyChangeListenerHelper; 379 380 class DialogStepChangedListener: public PropertyChangeListenerHelper 381 { 382 private: 383 uno::Reference< awt::XControlContainer > mxControlContainer; 384 385 public: 386 DialogStepChangedListener( uno::Reference< awt::XControlContainer > xControlContainer ) 387 : mxControlContainer( xControlContainer ) {} 388 389 // XEventListener 390 virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw( uno::RuntimeException); 391 392 // XPropertyChangeListener 393 virtual void SAL_CALL propertyChange( const beans::PropertyChangeEvent& evt ) throw( uno::RuntimeException); 394 395 }; 396 397 void SAL_CALL DialogStepChangedListener::disposing( const lang::EventObject& /*_rSource*/) 398 throw( uno::RuntimeException) 399 { 400 mxControlContainer.clear(); 401 } 402 403 void SAL_CALL DialogStepChangedListener::propertyChange( const beans::PropertyChangeEvent& evt ) 404 throw( uno::RuntimeException) 405 { 406 // evt.PropertyName HAS to be "Step" because we only use the listener for that 407 sal_Int32 nDialogStep = 0; 408 evt.NewValue >>= nDialogStep; 409 implUpdateVisibility( nDialogStep, mxControlContainer ); 410 } 411 412 // ---------------------------------------------------- 413 // class UnoControlContainer 414 // ---------------------------------------------------- 415 UnoControlContainer::UnoControlContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& i_factory ) 416 :UnoControlContainer_Base( i_factory ) 417 ,maCListeners( *this ) 418 { 419 mpControls = new UnoControlHolderList; 420 } 421 422 UnoControlContainer::UnoControlContainer( const uno::Reference< lang::XMultiServiceFactory >& i_factory, const uno::Reference< awt::XWindowPeer >& xP ) 423 :UnoControlContainer_Base( i_factory ) 424 ,maCListeners( *this ) 425 { 426 setPeer( xP ); 427 mbDisposePeer = sal_False; 428 mpControls = new UnoControlHolderList; 429 } 430 431 UnoControlContainer::~UnoControlContainer() 432 { 433 DELETEZ( mpControls ); 434 } 435 436 void UnoControlContainer::ImplActivateTabControllers() 437 { 438 sal_uInt32 nCount = maTabControllers.getLength(); 439 for ( sal_uInt32 n = 0; n < nCount; n++ ) 440 { 441 maTabControllers.getArray()[n]->setContainer( this ); 442 maTabControllers.getArray()[n]->activateTabOrder(); 443 } 444 } 445 446 // lang::XComponent 447 void UnoControlContainer::dispose( ) throw(uno::RuntimeException) 448 { 449 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 450 451 lang::EventObject aDisposeEvent; 452 aDisposeEvent.Source = static_cast< uno::XAggregation* >( this ); 453 454 // DG: zuerst der Welt mitteilen, dass der Container wegfliegt. Dieses ist um einiges 455 // schneller wenn die Welt sowohl an den Controls als auch am Container horcht 456 maDisposeListeners.disposeAndClear( aDisposeEvent ); 457 maCListeners.disposeAndClear( aDisposeEvent ); 458 459 460 uno::Sequence< uno::Reference< awt::XControl > > aCtrls = getControls(); 461 uno::Reference< awt::XControl >* pCtrls = aCtrls.getArray(); 462 uno::Reference< awt::XControl >* pCtrlsEnd = pCtrls + aCtrls.getLength(); 463 464 for( ; pCtrls < pCtrlsEnd; ++pCtrls ) 465 { 466 removingControl( *pCtrls ); 467 // Control wegwerfen 468 (*pCtrls)->dispose(); 469 } 470 471 472 // alle Strukturen entfernen 473 DELETEZ( mpControls ); 474 mpControls = new UnoControlHolderList; 475 476 UnoControlBase::dispose(); 477 } 478 479 // lang::XEventListener 480 void UnoControlContainer::disposing( const lang::EventObject& _rEvt ) throw(uno::RuntimeException) 481 { 482 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 483 484 uno::Reference< awt::XControl > xControl( _rEvt.Source, uno::UNO_QUERY ); 485 if ( xControl.is() ) 486 removeControl( xControl ); 487 488 UnoControlBase::disposing( _rEvt ); 489 } 490 491 // container::XContainer 492 void UnoControlContainer::addContainerListener( const uno::Reference< container::XContainerListener >& rxListener ) throw(uno::RuntimeException) 493 { 494 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 495 496 maCListeners.addInterface( rxListener ); 497 } 498 499 void UnoControlContainer::removeContainerListener( const uno::Reference< container::XContainerListener >& rxListener ) throw(uno::RuntimeException) 500 { 501 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 502 503 maCListeners.removeInterface( rxListener ); 504 } 505 506 507 ::sal_Int32 SAL_CALL UnoControlContainer::insert( const uno::Any& _rElement ) throw (lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException) 508 { 509 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 510 511 uno::Reference< awt::XControl > xControl; 512 if ( !( _rElement >>= xControl ) || !xControl.is() ) 513 throw lang::IllegalArgumentException( 514 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Elements must support the XControl interface." ) ), 515 *this, 516 1 517 ); 518 519 return impl_addControl( xControl, NULL ); 520 } 521 522 void SAL_CALL UnoControlContainer::removeByIdentifier( ::sal_Int32 _nIdentifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 523 { 524 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 525 526 uno::Reference< awt::XControl > xControl; 527 if ( !mpControls->getControlForIdentifier( _nIdentifier, xControl ) ) 528 throw container::NoSuchElementException( 529 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "There is no element with the given identifier." ) ), 530 *this 531 ); 532 533 impl_removeControl( _nIdentifier, xControl, NULL ); 534 } 535 536 void SAL_CALL UnoControlContainer::replaceByIdentifer( ::sal_Int32 _nIdentifier, const uno::Any& _rElement ) throw (lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 537 { 538 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 539 540 uno::Reference< awt::XControl > xExistentControl; 541 if ( !mpControls->getControlForIdentifier( _nIdentifier, xExistentControl ) ) 542 throw container::NoSuchElementException( 543 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "There is no element with the given identifier." ) ), 544 *this 545 ); 546 547 uno::Reference< awt::XControl > xNewControl; 548 if ( !( _rElement >>= xNewControl ) ) 549 throw lang::IllegalArgumentException( 550 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Elements must support the XControl interface." ) ), 551 *this, 552 1 553 ); 554 555 removingControl( xExistentControl ); 556 557 mpControls->replaceControlById( _nIdentifier, xNewControl ); 558 559 addingControl( xNewControl ); 560 561 impl_createControlPeerIfNecessary( xNewControl ); 562 563 if ( maCListeners.getLength() ) 564 { 565 container::ContainerEvent aEvent; 566 aEvent.Source = *this; 567 aEvent.Accessor <<= _nIdentifier; 568 aEvent.Element <<= xNewControl; 569 aEvent.ReplacedElement <<= xExistentControl; 570 maCListeners.elementReplaced( aEvent ); 571 } 572 } 573 574 uno::Any SAL_CALL UnoControlContainer::getByIdentifier( ::sal_Int32 _nIdentifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 575 { 576 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 577 578 uno::Reference< awt::XControl > xControl; 579 if ( !mpControls->getControlForIdentifier( _nIdentifier, xControl ) ) 580 throw container::NoSuchElementException(); 581 return uno::makeAny( xControl ); 582 } 583 584 uno::Sequence< ::sal_Int32 > SAL_CALL UnoControlContainer::getIdentifiers( ) throw (uno::RuntimeException) 585 { 586 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 587 588 uno::Sequence< ::sal_Int32 > aIdentifiers; 589 mpControls->getIdentifiers( aIdentifiers ); 590 return aIdentifiers; 591 } 592 593 // container::XElementAccess 594 uno::Type SAL_CALL UnoControlContainer::getElementType( ) throw (uno::RuntimeException) 595 { 596 return awt::XControlModel::static_type(); 597 } 598 599 ::sal_Bool SAL_CALL UnoControlContainer::hasElements( ) throw (uno::RuntimeException) 600 { 601 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 602 return !mpControls->empty(); 603 } 604 605 // awt::XControlContainer 606 void UnoControlContainer::setStatusText( const ::rtl::OUString& rStatusText ) throw(uno::RuntimeException) 607 { 608 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 609 610 // In der Parenthierarchie nach unten gehen 611 uno::Reference< awt::XControlContainer > xContainer( mxContext, uno::UNO_QUERY ); 612 if( xContainer.is() ) 613 xContainer->setStatusText( rStatusText ); 614 } 615 616 uno::Sequence< uno::Reference< awt::XControl > > UnoControlContainer::getControls( ) throw(uno::RuntimeException) 617 { 618 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 619 uno::Sequence< uno::Reference< awt::XControl > > aControls; 620 mpControls->getControls( aControls ); 621 return aControls; 622 } 623 624 uno::Reference< awt::XControl > UnoControlContainer::getControl( const ::rtl::OUString& rName ) throw(uno::RuntimeException) 625 { 626 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 627 return mpControls->getControlForName( rName ); 628 } 629 630 void UnoControlContainer::addingControl( const uno::Reference< awt::XControl >& _rxControl ) 631 { 632 if ( _rxControl.is() ) 633 { 634 uno::Reference< uno::XInterface > xThis; 635 OWeakAggObject::queryInterface( ::getCppuType( static_cast< uno::Reference< uno::XInterface >* >( NULL ) ) ) >>= xThis; 636 637 _rxControl->setContext( xThis ); 638 _rxControl->addEventListener( this ); 639 } 640 } 641 642 void UnoControlContainer::impl_createControlPeerIfNecessary( const uno::Reference< awt::XControl >& _rxControl ) 643 { 644 OSL_PRECOND( _rxControl.is(), "UnoControlContainer::impl_createControlPeerIfNecessary: invalid control, this will crash!" ); 645 646 // if the container already has a peer, then also create a peer for the control 647 uno::Reference< awt::XWindowPeer > xMyPeer( getPeer() ); 648 649 if( xMyPeer.is() ) 650 { 651 _rxControl->createPeer( NULL, xMyPeer ); 652 ImplActivateTabControllers(); 653 } 654 655 } 656 657 sal_Int32 UnoControlContainer::impl_addControl( const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pName ) 658 { 659 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 660 UnoControlHolderList::ControlIdentifier id = mpControls->addControl( _rxControl, _pName ); 661 662 addingControl( _rxControl ); 663 664 impl_createControlPeerIfNecessary( _rxControl ); 665 666 if ( maCListeners.getLength() ) 667 { 668 container::ContainerEvent aEvent; 669 aEvent.Source = *this; 670 _pName ? ( aEvent.Accessor <<= *_pName ) : ( aEvent.Accessor <<= (sal_Int32)id ); 671 aEvent.Element <<= _rxControl; 672 maCListeners.elementInserted( aEvent ); 673 } 674 675 return id; 676 } 677 678 void UnoControlContainer::addControl( const ::rtl::OUString& rName, const uno::Reference< awt::XControl >& rControl ) throw(uno::RuntimeException) 679 { 680 if ( rControl.is() ) 681 impl_addControl( rControl, &rName ); 682 } 683 684 void UnoControlContainer::removingControl( const uno::Reference< awt::XControl >& _rxControl ) 685 { 686 if ( _rxControl.is() ) 687 { 688 _rxControl->removeEventListener( this ); 689 _rxControl->setContext( NULL ); 690 } 691 } 692 693 void UnoControlContainer::impl_removeControl( sal_Int32 _nId, const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pNameAccessor ) 694 { 695 #ifdef DBG_UTIL 696 { 697 uno::Reference< awt::XControl > xControl; 698 bool bHas = mpControls->getControlForIdentifier( _nId, xControl ); 699 DBG_ASSERT( bHas && xControl == _rxControl, "UnoControlContainer::impl_removeControl: inconsistency in the parameters!" ); 700 } 701 #endif 702 removingControl( _rxControl ); 703 704 mpControls->removeControlById( _nId ); 705 706 if ( maCListeners.getLength() ) 707 { 708 container::ContainerEvent aEvent; 709 aEvent.Source = *this; 710 _pNameAccessor ? ( aEvent.Accessor <<= *_pNameAccessor ) : ( aEvent.Accessor <<= _nId ); 711 aEvent.Element <<= _rxControl; 712 maCListeners.elementRemoved( aEvent ); 713 } 714 } 715 716 void UnoControlContainer::removeControl( const uno::Reference< awt::XControl >& _rxControl ) throw(uno::RuntimeException) 717 { 718 if ( _rxControl.is() ) 719 { 720 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 721 722 UnoControlHolderList::ControlIdentifier id = mpControls->getControlIdentifier( _rxControl ); 723 if ( id != -1 ) 724 impl_removeControl( id, _rxControl, NULL ); 725 } 726 } 727 728 729 730 // awt::XUnoControlContainer 731 void UnoControlContainer::setTabControllers( const uno::Sequence< uno::Reference< awt::XTabController > >& TabControllers ) throw(uno::RuntimeException) 732 { 733 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 734 735 maTabControllers = TabControllers; 736 } 737 738 uno::Sequence< uno::Reference< awt::XTabController > > UnoControlContainer::getTabControllers( ) throw(uno::RuntimeException) 739 { 740 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 741 742 return maTabControllers; 743 } 744 745 void UnoControlContainer::addTabController( const uno::Reference< awt::XTabController >& TabController ) throw(uno::RuntimeException) 746 { 747 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 748 749 sal_uInt32 nCount = maTabControllers.getLength(); 750 maTabControllers.realloc( nCount + 1 ); 751 maTabControllers[ nCount ] = TabController; 752 } 753 754 void UnoControlContainer::removeTabController( const uno::Reference< awt::XTabController >& TabController ) throw(uno::RuntimeException) 755 { 756 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 757 758 sal_uInt32 nCount = maTabControllers.getLength(); 759 const uno::Reference< awt::XTabController >* pLoop = maTabControllers.getConstArray(); 760 for ( sal_uInt32 n = 0; n < nCount; ++n, ++pLoop ) 761 { 762 if( pLoop->get() == TabController.get() ) 763 { 764 ::comphelper::removeElementAt( maTabControllers, n ); 765 break; 766 } 767 } 768 } 769 770 // awt::XControl 771 void UnoControlContainer::createPeer( const uno::Reference< awt::XToolkit >& rxToolkit, const uno::Reference< awt::XWindowPeer >& rParent ) throw(uno::RuntimeException) 772 { 773 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 774 775 if( !getPeer().is() ) 776 { 777 sal_Bool bVis = maComponentInfos.bVisible; 778 if( bVis ) 779 UnoControl::setVisible( sal_False ); 780 // eigenes Peer erzeugen 781 UnoControl::createPeer( rxToolkit, rParent ); 782 783 // alle Peers der Childs erzeugen 784 if ( !mbCreatingCompatiblePeer ) 785 { 786 // Evaluate "Step" property 787 uno::Reference< awt::XControlModel > xModel( getModel() ); 788 uno::Reference< beans::XPropertySet > xPSet 789 ( xModel, uno::UNO_QUERY ); 790 uno::Reference< beans::XPropertySetInfo > 791 xInfo = xPSet->getPropertySetInfo(); 792 ::rtl::OUString aPropName(RTL_CONSTASCII_USTRINGPARAM( "Step" ) ); 793 if ( xInfo->hasPropertyByName( aPropName ) ) 794 { 795 ::com::sun::star::uno::Any aVal = xPSet->getPropertyValue( aPropName ); 796 sal_Int32 nDialogStep = 0; 797 aVal >>= nDialogStep; 798 uno::Reference< awt::XControlContainer > xContainer = 799 SAL_STATIC_CAST( awt::XControlContainer*, this ); 800 implUpdateVisibility( nDialogStep, xContainer ); 801 802 uno::Reference< beans::XPropertyChangeListener > xListener = 803 SAL_STATIC_CAST( beans::XPropertyChangeListener*, 804 new DialogStepChangedListener( xContainer ) ); 805 xPSet->addPropertyChangeListener( aPropName, xListener ); 806 } 807 808 uno::Sequence< uno::Reference< awt::XControl > > aCtrls = getControls(); 809 sal_uInt32 nCtrls = aCtrls.getLength(); 810 for( sal_uInt32 n = 0; n < nCtrls; n++ ) 811 aCtrls.getArray()[n]->createPeer( rxToolkit, getPeer() ); 812 813 uno::Reference< awt::XVclContainerPeer > xC( getPeer(), uno::UNO_QUERY ); 814 OSL_ENSURE(xC.is(),"Peer isn't valid. Please check!"); 815 816 xC->enableDialogControl( sal_True ); 817 ImplActivateTabControllers(); 818 } 819 820 if( bVis && !isDesignMode() ) 821 UnoControl::setVisible( sal_True ); 822 } 823 } 824 825 826 // awt::XWindow 827 void UnoControlContainer::setVisible( sal_Bool bVisible ) throw(uno::RuntimeException) 828 { 829 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 830 831 UnoControl::setVisible( bVisible ); 832 if( !mxContext.is() && bVisible ) 833 // Es ist ein TopWindow, also automatisch anzeigen 834 createPeer( uno::Reference< awt::XToolkit > (), uno::Reference< awt::XWindowPeer > () ); 835 } 836 837 838 839