bump product version to 4.1.6.2
[LibreOffice.git] / UnoControls / source / base / basecontainercontrol.cxx
blob2ef9a9e6e1deab7aa9c8989017c4914be01e81ca
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "basecontainercontrol.hxx"
22 #include <cppuhelper/typeprovider.hxx>
24 //____________________________________________________________________________________________________________
25 // namespaces
26 //____________________________________________________________________________________________________________
28 using namespace ::cppu ;
29 using namespace ::osl ;
30 using namespace ::rtl ;
31 using namespace ::com::sun::star::uno ;
32 using namespace ::com::sun::star::lang ;
33 using namespace ::com::sun::star::awt ;
34 using namespace ::com::sun::star::container ;
36 namespace unocontrols{
38 //____________________________________________________________________________________________________________
39 // construct/destruct
40 //____________________________________________________________________________________________________________
42 BaseContainerControl::BaseContainerControl( const Reference< XComponentContext >& rxContext )
43 : BaseControl ( rxContext )
44 , m_aListeners ( m_aMutex )
48 BaseContainerControl::~BaseContainerControl()
50 impl_cleanMemory();
53 //____________________________________________________________________________________________________________
54 // XInterface
55 //____________________________________________________________________________________________________________
57 Any SAL_CALL BaseContainerControl::queryInterface( const Type& rType ) throw( RuntimeException )
59 // Attention:
60 // Don't use mutex or guard in this method!!! Is a method of XInterface.
61 Any aReturn ;
62 Reference< XInterface > xDel = BaseControl::impl_getDelegator();
63 if ( xDel.is() == sal_True )
65 // If an delegator exist, forward question to his queryInterface.
66 // Delegator will ask his own queryAggregation!
67 aReturn = xDel->queryInterface( rType );
69 else
71 // If an delegator unknown, forward question to own queryAggregation.
72 aReturn = queryAggregation( rType );
75 return aReturn ;
78 //____________________________________________________________________________________________________________
79 // XTypeProvider
80 //____________________________________________________________________________________________________________
82 Sequence< Type > SAL_CALL BaseContainerControl::getTypes() throw( RuntimeException )
84 // Optimize this method !
85 // We initialize a static variable only one time. And we don't must use a mutex at every call!
86 // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
87 static OTypeCollection* pTypeCollection = NULL ;
89 if ( pTypeCollection == NULL )
91 // Ready for multithreading; get global mutex for first call of this method only! see before
92 MutexGuard aGuard( Mutex::getGlobalMutex() );
94 // Control these pointer again ... it can be, that another instance will be faster then these!
95 if ( pTypeCollection == NULL )
97 // Create a static typecollection ...
98 static OTypeCollection aTypeCollection ( ::getCppuType(( const Reference< XControlModel >*)NULL ) ,
99 ::getCppuType(( const Reference< XControlContainer >*)NULL ) ,
100 BaseControl::getTypes()
102 // ... and set his address to static pointer!
103 pTypeCollection = &aTypeCollection ;
107 return pTypeCollection->getTypes();
110 //____________________________________________________________________________________________________________
111 // XAggregation
112 //____________________________________________________________________________________________________________
114 Any SAL_CALL BaseContainerControl::queryAggregation( const Type& aType ) throw( RuntimeException )
116 // Ask for my own supported interfaces ...
117 // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
118 Any aReturn ( ::cppu::queryInterface( aType ,
119 static_cast< XControlModel* > ( this ) ,
120 static_cast< XControlContainer* > ( this )
124 // If searched interface supported by this class ...
125 if ( aReturn.hasValue() == sal_True )
127 // ... return this information.
128 return aReturn ;
130 else
132 // Else; ... ask baseclass for interfaces!
133 return BaseControl::queryAggregation( aType );
137 //____________________________________________________________________________________________________________
138 // XControl
139 //____________________________________________________________________________________________________________
141 void SAL_CALL BaseContainerControl::createPeer( const Reference< XToolkit >& xToolkit ,
142 const Reference< XWindowPeer >& xParent ) throw( RuntimeException )
144 if ( getPeer().is() == sal_False )
146 // create own peer
147 BaseControl::createPeer( xToolkit, xParent );
149 // create peers at all children
150 Sequence< Reference< XControl > > seqControlList = getControls();
151 sal_uInt32 nControls = seqControlList.getLength();
153 for ( sal_uInt32 n=0; n<nControls; n++ )
155 seqControlList.getArray()[n]->createPeer( xToolkit, getPeer() );
158 // activate new tab order
159 impl_activateTabControllers();
164 //____________________________________________________________________________________________________________
165 // XControl
166 //____________________________________________________________________________________________________________
168 sal_Bool SAL_CALL BaseContainerControl::setModel( const Reference< XControlModel >& ) throw( RuntimeException )
170 // This object has NO model.
171 return sal_False ;
174 //____________________________________________________________________________________________________________
175 // XControl
176 //____________________________________________________________________________________________________________
178 Reference< XControlModel > SAL_CALL BaseContainerControl::getModel() throw( RuntimeException )
180 // This object has NO model.
181 // return (XControlModel*)this ;
182 return Reference< XControlModel >();
185 //____________________________________________________________________________________________________________
186 // XComponent
187 //____________________________________________________________________________________________________________
189 void SAL_CALL BaseContainerControl::dispose() throw( RuntimeException )
191 // Tell everything that this container is now gone.
192 // It's faster if you listen to both the control and the container.
194 // Ready for multithreading
195 MutexGuard aGuard( m_aMutex );
197 // remove listeners
198 EventObject aObject ;
200 aObject.Source = Reference< XComponent > ( (XControlContainer*)this, UNO_QUERY );
201 m_aListeners.disposeAndClear( aObject );
203 // remove controls
204 Sequence< Reference< XControl > > seqCtrls = getControls();
205 Reference< XControl > * pCtrls = seqCtrls.getArray();
206 sal_uInt32 nCtrls = seqCtrls.getLength();
207 size_t nMaxCount = maControlInfoList.size();
208 size_t nCount = 0;
210 for ( nCount = 0; nCount < nMaxCount; ++nCount )
212 delete maControlInfoList[ nCount ];
214 maControlInfoList.clear();
216 for ( nCount = 0; nCount < nCtrls; ++nCount )
218 pCtrls [ nCount ] -> removeEventListener ( static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ) ) ;
219 pCtrls [ nCount ] -> dispose ( ) ;
222 // call baseclass
223 BaseControl::dispose();
226 //____________________________________________________________________________________________________________
227 // XEventListener
228 //____________________________________________________________________________________________________________
230 void SAL_CALL BaseContainerControl::disposing( const EventObject& rEvent ) throw( RuntimeException )
232 Reference< XControl > xControl( rEvent.Source, UNO_QUERY );
234 // "removeControl" remove only, when control is an active control
235 removeControl( xControl );
238 //____________________________________________________________________________________________________________
239 // XControlContainer
240 //____________________________________________________________________________________________________________
242 void SAL_CALL BaseContainerControl::addControl ( const OUString& rName, const Reference< XControl > & rControl ) throw( RuntimeException )
244 if ( !rControl.is () )
245 return;
247 // take memory for new item
248 IMPL_ControlInfo* pNewControl = new IMPL_ControlInfo ;
250 if (pNewControl!=(IMPL_ControlInfo*)0)
252 // Ready for multithreading
253 MutexGuard aGuard (m_aMutex) ;
255 // set control
256 pNewControl->sName = rName ;
257 pNewControl->xControl = rControl ;
259 // and insert in list
260 maControlInfoList.push_back( pNewControl ) ;
262 // initialize new control
263 pNewControl->xControl->setContext ( (OWeakObject*)this ) ;
264 pNewControl->xControl->addEventListener ( static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ) ) ;
266 // when container has a peer ...
267 if (getPeer().is())
269 // .. then create a peer on child
270 pNewControl->xControl->createPeer ( getPeer()->getToolkit(), getPeer() ) ;
271 impl_activateTabControllers () ;
274 // Send message to all listener
275 OInterfaceContainerHelper* pInterfaceContainer = m_aListeners.getContainer( ::getCppuType((const Reference< XContainerListener >*)0) ) ;
277 if (pInterfaceContainer)
279 // Build event
280 ContainerEvent aEvent ;
282 aEvent.Source = *this ;
283 aEvent.Element <<= rControl ;
285 // Get all listener
286 OInterfaceIteratorHelper aIterator (*pInterfaceContainer) ;
288 // Send event
289 while ( aIterator.hasMoreElements() )
291 ((XContainerListener*)aIterator.next())->elementInserted (aEvent) ;
297 //____________________________________________________________________________________________________________
298 // XControlContainer
299 //____________________________________________________________________________________________________________
301 void SAL_CALL BaseContainerControl::addContainerListener ( const Reference< XContainerListener > & rListener ) throw( RuntimeException )
303 // Ready for multithreading
304 MutexGuard aGuard ( m_aMutex ) ;
306 m_aListeners.addInterface ( ::getCppuType((const Reference< XContainerListener >*)0), rListener ) ;
309 //____________________________________________________________________________________________________________
310 // XControlContainer
311 //____________________________________________________________________________________________________________
313 void SAL_CALL BaseContainerControl::removeControl ( const Reference< XControl > & rControl ) throw( RuntimeException )
315 if ( rControl.is() )
317 // Ready for multithreading
318 MutexGuard aGuard (m_aMutex) ;
320 size_t nControls = maControlInfoList.size();
322 for ( size_t n = 0; n < nControls; n++ )
324 // Search for right control
325 IMPL_ControlInfo* pControl = maControlInfoList[ n ] ;
326 if ( rControl == pControl->xControl )
328 //.is it found ... remove listener from control
329 pControl->xControl->removeEventListener (static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) )) ;
330 pControl->xControl->setContext ( Reference< XInterface > () ) ;
332 // ... free memory
333 delete pControl ;
334 ::std::vector<IMPL_ControlInfo*>::iterator itr = maControlInfoList.begin();
335 ::std::advance(itr, n);
336 maControlInfoList.erase(itr);
338 // Send message to all other listener
339 OInterfaceContainerHelper * pInterfaceContainer = m_aListeners.getContainer( ::getCppuType((const Reference< XContainerListener >*)0) ) ;
341 if (pInterfaceContainer)
343 ContainerEvent aEvent ;
345 aEvent.Source = *this ;
346 aEvent.Element <<= rControl ;
348 OInterfaceIteratorHelper aIterator (*pInterfaceContainer) ;
350 while ( aIterator.hasMoreElements() )
352 ((XContainerListener*)aIterator.next())->elementRemoved (aEvent) ;
355 // Break "for" !
356 break ;
362 //____________________________________________________________________________________________________________
363 // XControlContainer
364 //____________________________________________________________________________________________________________
366 void SAL_CALL BaseContainerControl::removeContainerListener ( const Reference< XContainerListener > & rListener ) throw( RuntimeException )
368 // Ready for multithreading
369 MutexGuard aGuard ( m_aMutex ) ;
371 m_aListeners.removeInterface ( ::getCppuType((const Reference< XContainerListener >*)0), rListener ) ;
374 //____________________________________________________________________________________________________________
375 // XControlContainer
376 //____________________________________________________________________________________________________________
378 void SAL_CALL BaseContainerControl::setStatusText ( const OUString& rStatusText ) throw( RuntimeException )
380 // go down to each parent
381 Reference< XControlContainer > xContainer ( getContext(), UNO_QUERY ) ;
383 if ( xContainer.is () )
385 xContainer->setStatusText ( rStatusText ) ;
389 //____________________________________________________________________________________________________________
390 // XControlContainer
391 //____________________________________________________________________________________________________________
393 Reference< XControl > SAL_CALL BaseContainerControl::getControl ( const OUString& rName ) throw( RuntimeException )
395 // Ready for multithreading
396 MutexGuard aGuard ( Mutex::getGlobalMutex() ) ;
398 Reference< XControl > xRetControl = Reference< XControl > ();
399 size_t nControls = maControlInfoList.size();
401 // Search for right control
402 for( size_t nCount = 0; nCount < nControls; ++nCount )
404 IMPL_ControlInfo* pSearchControl = maControlInfoList[ nCount ];
406 if ( pSearchControl->sName == rName )
408 // We have found it ...
409 // Break operation and return.
410 return pSearchControl->xControl ;
414 // We have not found it ... return NULL.
415 return Reference< XControl > () ;
418 //____________________________________________________________________________________________________________
419 // XControlContainer
420 //____________________________________________________________________________________________________________
422 Sequence< Reference< XControl > > SAL_CALL BaseContainerControl::getControls () throw( RuntimeException )
424 // Ready for multithreading
425 MutexGuard aGuard ( Mutex::getGlobalMutex() ) ;
427 size_t nControls = maControlInfoList.size();
428 size_t nCount = 0;
429 Sequence< Reference< XControl > > aDescriptor ( nControls ) ;
430 Reference< XControl > * pDestination = aDescriptor.getArray () ;
432 // Copy controls to sequence
433 for( nCount = 0; nCount < nControls; ++nCount )
435 IMPL_ControlInfo* pCopyControl = maControlInfoList[ nCount ];
436 pDestination [ nCount ] = pCopyControl->xControl ;
439 // Return sequence
440 return aDescriptor ;
443 //____________________________________________________________________________________________________________
444 // XUnoControlContainer
445 //____________________________________________________________________________________________________________
447 void SAL_CALL BaseContainerControl::addTabController ( const Reference< XTabController > & rTabController ) throw( RuntimeException )
449 // Ready for multithreading
450 MutexGuard aGuard (m_aMutex) ;
452 sal_uInt32 nOldCount = m_xTabControllerList.getLength () ;
453 Sequence< Reference< XTabController > > aNewList ( nOldCount + 1 ) ;
454 sal_uInt32 nCount = 0 ;
456 // Copy old elements of sequence to new list.
457 for ( nCount = 0; nCount < nOldCount; ++nCount )
459 aNewList.getArray () [nCount] = m_xTabControllerList.getConstArray () [nCount] ;
462 // Add new controller
463 aNewList.getArray () [nOldCount] = rTabController ;
465 // change old and new list
466 m_xTabControllerList = aNewList ;
469 //____________________________________________________________________________________________________________
470 // XUnoControlContainer
471 //____________________________________________________________________________________________________________
473 void SAL_CALL BaseContainerControl::removeTabController ( const Reference< XTabController > & rTabController ) throw( RuntimeException )
475 // Ready for multithreading
476 MutexGuard aGuard (m_aMutex) ;
478 sal_uInt32 nMaxCount = m_xTabControllerList.getLength () ;
479 sal_uInt32 nCount = 0 ;
481 // Search right tabcontroller ...
482 for ( nCount = 0; nCount < nMaxCount; ++nCount )
484 if ( m_xTabControllerList.getConstArray () [nCount] == rTabController )
486 // ... if is it found ... remove it from list.
487 m_xTabControllerList.getArray()[ nCount ] = Reference< XTabController >() ;
488 break ;
493 //____________________________________________________________________________________________________________
494 // XUnoControlContainer
495 //____________________________________________________________________________________________________________
497 void SAL_CALL BaseContainerControl::setTabControllers ( const Sequence< Reference< XTabController > >& rTabControllers ) throw( RuntimeException )
499 // Ready for multithreading
500 MutexGuard aGuard (m_aMutex) ;
502 m_xTabControllerList = rTabControllers ;
505 Sequence<Reference< XTabController > > SAL_CALL BaseContainerControl::getTabControllers () throw( RuntimeException )
507 // Ready for multithreading
508 MutexGuard aGuard (m_aMutex) ;
510 return m_xTabControllerList ;
513 //____________________________________________________________________________________________________________
514 // XWindow
515 //____________________________________________________________________________________________________________
517 void SAL_CALL BaseContainerControl::setVisible ( sal_Bool bVisible ) throw( RuntimeException )
519 // override baseclass definition
520 BaseControl::setVisible ( bVisible ) ;
522 // is it a top window ?
523 if ( !getContext().is() && bVisible )
525 // then show it automaticly
526 createPeer ( Reference< XToolkit > (), Reference< XWindowPeer > () ) ;
530 //____________________________________________________________________________________________________________
531 // protected method
532 //____________________________________________________________________________________________________________
534 WindowDescriptor* BaseContainerControl::impl_getWindowDescriptor ( const Reference< XWindowPeer > & rParentPeer )
536 // - used from "createPeer()" to set the values of an WindowDescriptor !!!
537 // - if you will change the descriptor-values, you must override thid virtuell function
538 // - the caller must release the memory for this dynamical descriptor !!!
540 WindowDescriptor * aDescriptor = new WindowDescriptor ;
542 aDescriptor->Type = WindowClass_CONTAINER ;
543 aDescriptor->WindowServiceName = "window" ;
544 aDescriptor->ParentIndex = -1 ;
545 aDescriptor->Parent = rParentPeer ;
546 aDescriptor->Bounds = getPosSize () ;
547 aDescriptor->WindowAttributes = 0 ;
549 return aDescriptor ;
552 //____________________________________________________________________________________________________________
553 // protected method
554 //____________________________________________________________________________________________________________
556 void BaseContainerControl::impl_paint ( sal_Int32 /*nX*/, sal_Int32 /*nY*/, const Reference< XGraphics > & /*rGraphics*/ )
560 //____________________________________________________________________________________________________________
561 // private method
562 //____________________________________________________________________________________________________________
564 void BaseContainerControl::impl_activateTabControllers ()
566 // Ready for multithreading
567 MutexGuard aGuard (m_aMutex) ;
569 sal_uInt32 nMaxCount = m_xTabControllerList.getLength () ;
570 sal_uInt32 nCount = 0 ;
572 for ( nCount = 0; nCount < nMaxCount; ++nCount )
574 m_xTabControllerList.getArray () [nCount]->setContainer ( this ) ;
575 m_xTabControllerList.getArray () [nCount]->activateTabOrder ( ) ;
579 //____________________________________________________________________________________________________________
580 // private method
581 //____________________________________________________________________________________________________________
583 void BaseContainerControl::impl_cleanMemory ()
585 // Get count of listitems.
586 size_t nMaxCount = maControlInfoList.size();
587 size_t nCount = 0;
589 // Delete all items.
590 for ( nCount = 0; nCount < nMaxCount; ++nCount )
592 // Delete everytime first element of list!
593 // We count from 0 to MAX, where "MAX=count of items" BEFORE we delete some elements!
594 // If we use "GetObject ( nCount )" ... it can be, that we have an index greater then count of current elements!
596 IMPL_ControlInfo* pSearchControl = maControlInfoList[ nCount ];
597 delete pSearchControl;
600 // Delete list himself.
601 maControlInfoList.clear ();
604 } // namespace unocontrols
606 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */