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 //____________________________________________________________________________________________________________ 25 // my own includes 26 //____________________________________________________________________________________________________________ 27 28 #include "basecontainercontrol.hxx" 29 30 //____________________________________________________________________________________________________________ 31 // includes of other projects 32 //____________________________________________________________________________________________________________ 33 #include <cppuhelper/typeprovider.hxx> 34 35 //____________________________________________________________________________________________________________ 36 // includes of my own project 37 //____________________________________________________________________________________________________________ 38 39 //____________________________________________________________________________________________________________ 40 // namespaces 41 //____________________________________________________________________________________________________________ 42 43 using namespace ::cppu ; 44 using namespace ::osl ; 45 using namespace ::rtl ; 46 using namespace ::com::sun::star::uno ; 47 using namespace ::com::sun::star::lang ; 48 using namespace ::com::sun::star::awt ; 49 using namespace ::com::sun::star::container ; 50 51 namespace unocontrols{ 52 53 //____________________________________________________________________________________________________________ 54 // construct/destruct 55 //____________________________________________________________________________________________________________ 56 57 BaseContainerControl::BaseContainerControl( const Reference< XMultiServiceFactory >& xFactory ) 58 : BaseControl ( xFactory ) 59 , m_aListeners ( m_aMutex ) 60 { 61 // initialize info list for controls 62 m_pControlInfoList = new IMPL_ControlInfoList ; 63 } 64 65 BaseContainerControl::~BaseContainerControl() 66 { 67 impl_cleanMemory(); 68 } 69 70 //____________________________________________________________________________________________________________ 71 // XInterface 72 //____________________________________________________________________________________________________________ 73 74 Any SAL_CALL BaseContainerControl::queryInterface( const Type& rType ) throw( RuntimeException ) 75 { 76 // Attention: 77 // Don't use mutex or guard in this method!!! Is a method of XInterface. 78 Any aReturn ; 79 Reference< XInterface > xDel = BaseControl::impl_getDelegator(); 80 if ( xDel.is() == sal_True ) 81 { 82 // If an delegator exist, forward question to his queryInterface. 83 // Delegator will ask his own queryAggregation! 84 aReturn = xDel->queryInterface( rType ); 85 } 86 else 87 { 88 // If an delegator unknown, forward question to own queryAggregation. 89 aReturn = queryAggregation( rType ); 90 } 91 92 return aReturn ; 93 } 94 95 //____________________________________________________________________________________________________________ 96 // XTypeProvider 97 //____________________________________________________________________________________________________________ 98 99 Sequence< Type > SAL_CALL BaseContainerControl::getTypes() throw( RuntimeException ) 100 { 101 // Optimize this method ! 102 // We initialize a static variable only one time. And we don't must use a mutex at every call! 103 // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL! 104 static OTypeCollection* pTypeCollection = NULL ; 105 106 if ( pTypeCollection == NULL ) 107 { 108 // Ready for multithreading; get global mutex for first call of this method only! see before 109 MutexGuard aGuard( Mutex::getGlobalMutex() ); 110 111 // Control these pointer again ... it can be, that another instance will be faster then these! 112 if ( pTypeCollection == NULL ) 113 { 114 // Create a static typecollection ... 115 static OTypeCollection aTypeCollection ( ::getCppuType(( const Reference< XControlModel >*)NULL ) , 116 ::getCppuType(( const Reference< XControlContainer >*)NULL ) , 117 BaseControl::getTypes() 118 ); 119 // ... and set his address to static pointer! 120 pTypeCollection = &aTypeCollection ; 121 } 122 } 123 124 return pTypeCollection->getTypes(); 125 } 126 127 //____________________________________________________________________________________________________________ 128 // XAggregation 129 //____________________________________________________________________________________________________________ 130 131 Any SAL_CALL BaseContainerControl::queryAggregation( const Type& aType ) throw( RuntimeException ) 132 { 133 // Ask for my own supported interfaces ... 134 // Attention: XTypeProvider and XInterface are supported by OComponentHelper! 135 Any aReturn ( ::cppu::queryInterface( aType , 136 static_cast< XControlModel* > ( this ) , 137 static_cast< XControlContainer* > ( this ) 138 ) 139 ); 140 141 // If searched interface supported by this class ... 142 if ( aReturn.hasValue() == sal_True ) 143 { 144 // ... return this information. 145 return aReturn ; 146 } 147 else 148 { 149 // Else; ... ask baseclass for interfaces! 150 return BaseControl::queryAggregation( aType ); 151 } 152 } 153 154 //____________________________________________________________________________________________________________ 155 // XControl 156 //____________________________________________________________________________________________________________ 157 158 void SAL_CALL BaseContainerControl::createPeer( const Reference< XToolkit >& xToolkit , 159 const Reference< XWindowPeer >& xParent ) throw( RuntimeException ) 160 { 161 if ( getPeer().is() == sal_False ) 162 { 163 // create own peer 164 BaseControl::createPeer( xToolkit, xParent ); 165 166 // create peers at all childs 167 Sequence< Reference< XControl > > seqControlList = getControls(); 168 sal_uInt32 nControls = seqControlList.getLength(); 169 170 for ( sal_uInt32 n=0; n<nControls; n++ ) 171 { 172 seqControlList.getArray()[n]->createPeer( xToolkit, getPeer() ); 173 } 174 175 // activate new tab order 176 impl_activateTabControllers(); 177 178 /* 179 Reference< XVclContainerPeer > xC; 180 mxPeer->queryInterface( ::getCppuType((const Reference< XVclContainerPeer >*)0), xC ); 181 xC->enableDialogControl( sal_True ); 182 */ 183 184 } 185 } 186 187 //____________________________________________________________________________________________________________ 188 // XControl 189 //____________________________________________________________________________________________________________ 190 191 sal_Bool SAL_CALL BaseContainerControl::setModel( const Reference< XControlModel >& ) throw( RuntimeException ) 192 { 193 // This object has NO model. 194 return sal_False ; 195 } 196 197 //____________________________________________________________________________________________________________ 198 // XControl 199 //____________________________________________________________________________________________________________ 200 201 Reference< XControlModel > SAL_CALL BaseContainerControl::getModel() throw( RuntimeException ) 202 { 203 // This object has NO model. 204 // return (XControlModel*)this ; 205 return Reference< XControlModel >(); 206 } 207 208 //____________________________________________________________________________________________________________ 209 // XComponent 210 //____________________________________________________________________________________________________________ 211 212 void SAL_CALL BaseContainerControl::dispose() throw( RuntimeException ) 213 { 214 // Zuerst der Welt mitteilen, da� der Container wegfliegt. Dieses ist um einiges 215 // schneller wenn die Welt sowohl an den Controls als auch am Container horcht 216 217 // Ready for multithreading 218 MutexGuard aGuard( m_aMutex ); 219 220 // remove listeners 221 EventObject aObject ; 222 223 aObject.Source = Reference< XComponent > ( (XControlContainer*)this, UNO_QUERY ); 224 m_aListeners.disposeAndClear( aObject ); 225 226 // remove controls 227 Sequence< Reference< XControl > > seqCtrls = getControls(); 228 Reference< XControl > * pCtrls = seqCtrls.getArray(); 229 sal_uInt32 nCtrls = seqCtrls.getLength(); 230 sal_uInt32 nMaxCount = m_pControlInfoList->Count(); 231 sal_uInt32 nCount = 0; 232 233 for ( nCount = 0; nCount < nMaxCount; ++nCount ) 234 { 235 delete m_pControlInfoList->GetObject( 0 ); 236 } 237 m_pControlInfoList->Clear(); 238 239 240 for ( nCount = 0; nCount < nCtrls; ++nCount ) 241 { 242 pCtrls [ nCount ] -> removeEventListener ( static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ) ) ; 243 pCtrls [ nCount ] -> dispose ( ) ; 244 } 245 246 // call baseclass 247 BaseControl::dispose(); 248 } 249 250 //____________________________________________________________________________________________________________ 251 // XEventListener 252 //____________________________________________________________________________________________________________ 253 254 void SAL_CALL BaseContainerControl::disposing( const EventObject& rEvent ) throw( RuntimeException ) 255 { 256 Reference< XControl > xControl( rEvent.Source, UNO_QUERY ); 257 258 // "removeControl" remove only, when control is an active control 259 removeControl( xControl ); 260 } 261 262 //____________________________________________________________________________________________________________ 263 // XControlContainer 264 //____________________________________________________________________________________________________________ 265 266 void SAL_CALL BaseContainerControl::addControl ( const OUString& rName, const Reference< XControl > & rControl ) throw( RuntimeException ) 267 { 268 if ( !rControl.is () ) 269 return; 270 271 // take memory for new item 272 IMPL_ControlInfo* pNewControl = new IMPL_ControlInfo ; 273 274 if (pNewControl!=(IMPL_ControlInfo*)0) 275 { 276 // Ready for multithreading 277 MutexGuard aGuard (m_aMutex) ; 278 279 // set control 280 pNewControl->sName = rName ; 281 pNewControl->xControl = rControl ; 282 283 // and insert in list 284 m_pControlInfoList->Insert ( pNewControl, LIST_APPEND ) ; 285 286 // initialize new control 287 pNewControl->xControl->setContext ( (OWeakObject*)this ) ; 288 pNewControl->xControl->addEventListener ( static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ) ) ; 289 290 // when container has a peer ... 291 if (getPeer().is()) 292 { 293 // .. then create a peer on child 294 pNewControl->xControl->createPeer ( getPeer()->getToolkit(), getPeer() ) ; 295 impl_activateTabControllers () ; 296 } 297 298 // Send message to all listener 299 OInterfaceContainerHelper* pInterfaceContainer = m_aListeners.getContainer( ::getCppuType((const Reference< XContainerListener >*)0) ) ; 300 301 if (pInterfaceContainer) 302 { 303 // Build event 304 ContainerEvent aEvent ; 305 306 aEvent.Source = *this ; 307 aEvent.Element <<= rControl ; 308 309 // Get all listener 310 OInterfaceIteratorHelper aIterator (*pInterfaceContainer) ; 311 312 // Send event 313 while ( aIterator.hasMoreElements() ) 314 { 315 ((XContainerListener*)aIterator.next())->elementInserted (aEvent) ; 316 } 317 } 318 } 319 } 320 321 //____________________________________________________________________________________________________________ 322 // XControlContainer 323 //____________________________________________________________________________________________________________ 324 325 void SAL_CALL BaseContainerControl::addContainerListener ( const Reference< XContainerListener > & rListener ) throw( RuntimeException ) 326 { 327 // Ready for multithreading 328 MutexGuard aGuard ( m_aMutex ) ; 329 330 m_aListeners.addInterface ( ::getCppuType((const Reference< XContainerListener >*)0), rListener ) ; 331 } 332 333 //____________________________________________________________________________________________________________ 334 // XControlContainer 335 //____________________________________________________________________________________________________________ 336 337 void SAL_CALL BaseContainerControl::removeControl ( const Reference< XControl > & rControl ) throw( RuntimeException ) 338 { 339 if ( rControl.is() ) 340 { 341 // Ready for multithreading 342 MutexGuard aGuard (m_aMutex) ; 343 344 sal_uInt32 nControls = m_pControlInfoList->Count () ; 345 346 for ( sal_uInt32 n=0; n<nControls; n++ ) 347 { 348 // Search for right control 349 IMPL_ControlInfo* pControl = m_pControlInfoList->GetObject (n) ; 350 if ( rControl == pControl->xControl ) 351 { 352 //.is it found ... remove listener from control 353 pControl->xControl->removeEventListener (static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) )) ; 354 pControl->xControl->setContext ( Reference< XInterface > () ) ; 355 356 // ... free memory 357 delete pControl ; 358 m_pControlInfoList->Remove (n) ; 359 360 // Send message to all other listener 361 OInterfaceContainerHelper * pInterfaceContainer = m_aListeners.getContainer( ::getCppuType((const Reference< XContainerListener >*)0) ) ; 362 363 if (pInterfaceContainer) 364 { 365 ContainerEvent aEvent ; 366 367 aEvent.Source = *this ; 368 aEvent.Element <<= rControl ; 369 370 OInterfaceIteratorHelper aIterator (*pInterfaceContainer) ; 371 372 while ( aIterator.hasMoreElements() ) 373 { 374 ((XContainerListener*)aIterator.next())->elementRemoved (aEvent) ; 375 } 376 } 377 // Break "for" ! 378 break ; 379 } 380 } 381 } 382 } 383 384 //____________________________________________________________________________________________________________ 385 // XControlContainer 386 //____________________________________________________________________________________________________________ 387 388 void SAL_CALL BaseContainerControl::removeContainerListener ( const Reference< XContainerListener > & rListener ) throw( RuntimeException ) 389 { 390 // Ready for multithreading 391 MutexGuard aGuard ( m_aMutex ) ; 392 393 m_aListeners.removeInterface ( ::getCppuType((const Reference< XContainerListener >*)0), rListener ) ; 394 } 395 396 //____________________________________________________________________________________________________________ 397 // XControlContainer 398 //____________________________________________________________________________________________________________ 399 400 void SAL_CALL BaseContainerControl::setStatusText ( const OUString& rStatusText ) throw( RuntimeException ) 401 { 402 // go down to each parent 403 Reference< XControlContainer > xContainer ( getContext(), UNO_QUERY ) ; 404 405 if ( xContainer.is () ) 406 { 407 xContainer->setStatusText ( rStatusText ) ; 408 } 409 } 410 411 //____________________________________________________________________________________________________________ 412 // XControlContainer 413 //____________________________________________________________________________________________________________ 414 415 Reference< XControl > SAL_CALL BaseContainerControl::getControl ( const OUString& rName ) throw( RuntimeException ) 416 { 417 // Ready for multithreading 418 MutexGuard aGuard ( Mutex::getGlobalMutex() ) ; 419 420 Reference< XControl > xRetControl = Reference< XControl > () ; 421 sal_uInt32 nControls = m_pControlInfoList->Count () ; 422 423 // Search for right control 424 for( sal_uInt32 nCount = 0; nCount < nControls; ++nCount ) 425 { 426 IMPL_ControlInfo* pSearchControl = m_pControlInfoList->GetObject ( nCount ) ; 427 428 if ( pSearchControl->sName == rName ) 429 { 430 // We have found it ... 431 // Break operation and return. 432 return pSearchControl->xControl ; 433 } 434 } 435 436 // We have not found it ... return NULL. 437 return Reference< XControl > () ; 438 } 439 440 //____________________________________________________________________________________________________________ 441 // XControlContainer 442 //____________________________________________________________________________________________________________ 443 444 Sequence< Reference< XControl > > SAL_CALL BaseContainerControl::getControls () throw( RuntimeException ) 445 { 446 // Ready for multithreading 447 MutexGuard aGuard ( Mutex::getGlobalMutex() ) ; 448 449 sal_uInt32 nControls = m_pControlInfoList->Count () ; 450 Sequence< Reference< XControl > > aDescriptor ( nControls ) ; 451 Reference< XControl > * pDestination = aDescriptor.getArray () ; 452 sal_uInt32 nCount = 0 ; 453 454 // Copy controls to sequence 455 for( nCount = 0; nCount < nControls; ++nCount ) 456 { 457 IMPL_ControlInfo* pCopyControl = m_pControlInfoList->GetObject ( nCount ) ; 458 pDestination [ nCount ] = pCopyControl->xControl ; 459 } 460 461 // Return sequence 462 return aDescriptor ; 463 } 464 465 //____________________________________________________________________________________________________________ 466 // XUnoControlContainer 467 //____________________________________________________________________________________________________________ 468 469 void SAL_CALL BaseContainerControl::addTabController ( const Reference< XTabController > & rTabController ) throw( RuntimeException ) 470 { 471 // Ready for multithreading 472 MutexGuard aGuard (m_aMutex) ; 473 474 sal_uInt32 nOldCount = m_xTabControllerList.getLength () ; 475 Sequence< Reference< XTabController > > aNewList ( nOldCount + 1 ) ; 476 sal_uInt32 nCount = 0 ; 477 478 // Copy old elements of sequence to new list. 479 for ( nCount = 0; nCount < nOldCount; ++nCount ) 480 { 481 aNewList.getArray () [nCount] = m_xTabControllerList.getConstArray () [nCount] ; 482 } 483 484 // Add new controller 485 aNewList.getArray () [nOldCount] = rTabController ; 486 487 // change old and new list 488 m_xTabControllerList = aNewList ; 489 } 490 491 //____________________________________________________________________________________________________________ 492 // XUnoControlContainer 493 //____________________________________________________________________________________________________________ 494 495 void SAL_CALL BaseContainerControl::removeTabController ( const Reference< XTabController > & rTabController ) throw( RuntimeException ) 496 { 497 // Ready for multithreading 498 MutexGuard aGuard (m_aMutex) ; 499 500 sal_uInt32 nMaxCount = m_xTabControllerList.getLength () ; 501 sal_uInt32 nCount = 0 ; 502 503 // Search right tabcontroller ... 504 for ( nCount = 0; nCount < nMaxCount; ++nCount ) 505 { 506 if ( m_xTabControllerList.getConstArray () [nCount] == rTabController ) 507 { 508 // ... if is it found ... remove it from list. 509 m_xTabControllerList.getArray()[ nCount ] = Reference< XTabController >() ; 510 break ; 511 } 512 } 513 } 514 515 //____________________________________________________________________________________________________________ 516 // XUnoControlContainer 517 //____________________________________________________________________________________________________________ 518 519 void SAL_CALL BaseContainerControl::setTabControllers ( const Sequence< Reference< XTabController > >& rTabControllers ) throw( RuntimeException ) 520 { 521 // Ready for multithreading 522 MutexGuard aGuard (m_aMutex) ; 523 524 m_xTabControllerList = rTabControllers ; 525 } 526 527 Sequence<Reference< XTabController > > SAL_CALL BaseContainerControl::getTabControllers () throw( RuntimeException ) 528 { 529 // Ready for multithreading 530 MutexGuard aGuard (m_aMutex) ; 531 532 return m_xTabControllerList ; 533 } 534 535 //____________________________________________________________________________________________________________ 536 // XWindow 537 //____________________________________________________________________________________________________________ 538 539 void SAL_CALL BaseContainerControl::setVisible ( sal_Bool bVisible ) throw( RuntimeException ) 540 { 541 // override baseclass definition 542 BaseControl::setVisible ( bVisible ) ; 543 544 // is it a top window ? 545 if ( !getContext().is() && bVisible ) 546 { 547 // then show it automaticly 548 createPeer ( Reference< XToolkit > (), Reference< XWindowPeer > () ) ; 549 } 550 } 551 552 //____________________________________________________________________________________________________________ 553 // protected method 554 //____________________________________________________________________________________________________________ 555 556 WindowDescriptor* BaseContainerControl::impl_getWindowDescriptor ( const Reference< XWindowPeer > & rParentPeer ) 557 { 558 // - used from "createPeer()" to set the values of an WindowDescriptor !!! 559 // - if you will change the descriptor-values, you must override thid virtuell function 560 // - the caller must release the memory for this dynamical descriptor !!! 561 562 WindowDescriptor * aDescriptor = new WindowDescriptor ; 563 564 aDescriptor->Type = WindowClass_CONTAINER ; 565 aDescriptor->WindowServiceName = OUString(RTL_CONSTASCII_USTRINGPARAM("window")) ; 566 aDescriptor->ParentIndex = -1 ; 567 aDescriptor->Parent = rParentPeer ; 568 aDescriptor->Bounds = getPosSize () ; 569 aDescriptor->WindowAttributes = 0 ; 570 571 return aDescriptor ; 572 } 573 574 //____________________________________________________________________________________________________________ 575 // protected method 576 //____________________________________________________________________________________________________________ 577 578 void BaseContainerControl::impl_paint ( sal_Int32 /*nX*/, sal_Int32 /*nY*/, const Reference< XGraphics > & /*rGraphics*/ ) 579 { 580 /* 581 if (rGraphics.is()) 582 { 583 for ( sal_uInt32 n=m_pControlInfoList->Count(); n; ) 584 { 585 ControlInfo* pSearchControl = m_pControlInfoList->GetObject (--n) ; 586 587 pSearchControl->xControl->paint ( nX, nY, rGraphics ) ; 588 } 589 } 590 */ 591 } 592 593 //____________________________________________________________________________________________________________ 594 // private method 595 //____________________________________________________________________________________________________________ 596 597 void BaseContainerControl::impl_activateTabControllers () 598 { 599 // Ready for multithreading 600 MutexGuard aGuard (m_aMutex) ; 601 602 sal_uInt32 nMaxCount = m_xTabControllerList.getLength () ; 603 sal_uInt32 nCount = 0 ; 604 605 for ( nCount = 0; nCount < nMaxCount; ++nCount ) 606 { 607 m_xTabControllerList.getArray () [nCount]->setContainer ( this ) ; 608 m_xTabControllerList.getArray () [nCount]->activateTabOrder ( ) ; 609 } 610 } 611 612 //____________________________________________________________________________________________________________ 613 // private method 614 //____________________________________________________________________________________________________________ 615 616 void BaseContainerControl::impl_cleanMemory () 617 { 618 // Get count of listitems. 619 sal_uInt32 nMaxCount = m_pControlInfoList->Count () ; 620 sal_uInt32 nCount = 0 ; 621 622 // Delete all items. 623 for ( nCount = 0; nCount < nMaxCount; ++nCount ) 624 { 625 // Delete everytime first element of list! 626 // We count from 0 to MAX, where "MAX=count of items" BEFORE we delete some elements! 627 // If we use "GetObject ( nCount )" ... it can be, that we have an index greater then count of current elements! 628 629 IMPL_ControlInfo* pSearchControl = m_pControlInfoList->GetObject ( 0 ) ; 630 delete pSearchControl ; 631 } 632 633 // Delete list himself. 634 m_pControlInfoList->Clear () ; 635 delete m_pControlInfoList ; 636 } 637 638 } // namespace unocontrols 639