1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 //____________________________________________________________________________________________________________
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 //____________________________________________________________________________________________________________
40 //____________________________________________________________________________________________________________
42 BaseContainerControl::BaseContainerControl( const Reference
< XComponentContext
>& rxContext
)
43 : BaseControl ( rxContext
)
44 , m_aListeners ( m_aMutex
)
48 BaseContainerControl::~BaseContainerControl()
53 //____________________________________________________________________________________________________________
55 //____________________________________________________________________________________________________________
57 Any SAL_CALL
BaseContainerControl::queryInterface( const Type
& rType
) throw( RuntimeException
)
60 // Don't use mutex or guard in this method!!! Is a method of XInterface.
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
);
71 // If an delegator unknown, forward question to own queryAggregation.
72 aReturn
= queryAggregation( rType
);
78 //____________________________________________________________________________________________________________
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 //____________________________________________________________________________________________________________
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.
132 // Else; ... ask baseclass for interfaces!
133 return BaseControl::queryAggregation( aType
);
137 //____________________________________________________________________________________________________________
139 //____________________________________________________________________________________________________________
141 void SAL_CALL
BaseContainerControl::createPeer( const Reference
< XToolkit
>& xToolkit
,
142 const Reference
< XWindowPeer
>& xParent
) throw( RuntimeException
)
144 if ( getPeer().is() == sal_False
)
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 //____________________________________________________________________________________________________________
166 //____________________________________________________________________________________________________________
168 sal_Bool SAL_CALL
BaseContainerControl::setModel( const Reference
< XControlModel
>& ) throw( RuntimeException
)
170 // This object has NO model.
174 //____________________________________________________________________________________________________________
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 //____________________________________________________________________________________________________________
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
);
198 EventObject aObject
;
200 aObject
.Source
= Reference
< XComponent
> ( (XControlContainer
*)this, UNO_QUERY
);
201 m_aListeners
.disposeAndClear( aObject
);
204 Sequence
< Reference
< XControl
> > seqCtrls
= getControls();
205 Reference
< XControl
> * pCtrls
= seqCtrls
.getArray();
206 sal_uInt32 nCtrls
= seqCtrls
.getLength();
207 size_t nMaxCount
= maControlInfoList
.size();
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 ( ) ;
223 BaseControl::dispose();
226 //____________________________________________________________________________________________________________
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 //____________________________________________________________________________________________________________
240 //____________________________________________________________________________________________________________
242 void SAL_CALL
BaseContainerControl::addControl ( const OUString
& rName
, const Reference
< XControl
> & rControl
) throw( RuntimeException
)
244 if ( !rControl
.is () )
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
) ;
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 ...
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
)
280 ContainerEvent aEvent
;
282 aEvent
.Source
= *this ;
283 aEvent
.Element
<<= rControl
;
286 OInterfaceIteratorHelper
aIterator (*pInterfaceContainer
) ;
289 while ( aIterator
.hasMoreElements() )
291 ((XContainerListener
*)aIterator
.next())->elementInserted (aEvent
) ;
297 //____________________________________________________________________________________________________________
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 //____________________________________________________________________________________________________________
311 //____________________________________________________________________________________________________________
313 void SAL_CALL
BaseContainerControl::removeControl ( const Reference
< XControl
> & rControl
) throw( RuntimeException
)
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
> () ) ;
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
) ;
362 //____________________________________________________________________________________________________________
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 //____________________________________________________________________________________________________________
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 //____________________________________________________________________________________________________________
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 //____________________________________________________________________________________________________________
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();
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
;
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
>() ;
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 //____________________________________________________________________________________________________________
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 //____________________________________________________________________________________________________________
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 ;
552 //____________________________________________________________________________________________________________
554 //____________________________________________________________________________________________________________
556 void BaseContainerControl::impl_paint ( sal_Int32
/*nX*/, sal_Int32
/*nY*/, const Reference
< XGraphics
> & /*rGraphics*/ )
560 //____________________________________________________________________________________________________________
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 //____________________________________________________________________________________________________________
581 //____________________________________________________________________________________________________________
583 void BaseContainerControl::impl_cleanMemory ()
585 // Get count of listitems.
586 size_t nMaxCount
= maControlInfoList
.size();
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: */