1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: basecontainercontrol.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 //____________________________________________________________________________________________________________
33 //____________________________________________________________________________________________________________
35 #include "basecontainercontrol.hxx"
37 //____________________________________________________________________________________________________________
38 // includes of other projects
39 //____________________________________________________________________________________________________________
40 #include <cppuhelper/typeprovider.hxx>
42 //____________________________________________________________________________________________________________
43 // includes of my own project
44 //____________________________________________________________________________________________________________
46 //____________________________________________________________________________________________________________
48 //____________________________________________________________________________________________________________
50 using namespace ::cppu
;
51 using namespace ::osl
;
52 using namespace ::rtl
;
53 using namespace ::com::sun::star::uno
;
54 using namespace ::com::sun::star::lang
;
55 using namespace ::com::sun::star::awt
;
56 using namespace ::com::sun::star::container
;
58 namespace unocontrols
{
60 //____________________________________________________________________________________________________________
62 //____________________________________________________________________________________________________________
64 BaseContainerControl::BaseContainerControl( const Reference
< XMultiServiceFactory
>& xFactory
)
65 : BaseControl ( xFactory
)
66 , m_aListeners ( m_aMutex
)
68 // initialize info list for controls
69 m_pControlInfoList
= new IMPL_ControlInfoList
;
72 BaseContainerControl::~BaseContainerControl()
77 //____________________________________________________________________________________________________________
79 //____________________________________________________________________________________________________________
81 Any SAL_CALL
BaseContainerControl::queryInterface( const Type
& rType
) throw( RuntimeException
)
84 // Don't use mutex or guard in this method!!! Is a method of XInterface.
86 Reference
< XInterface
> xDel
= BaseControl::impl_getDelegator();
87 if ( xDel
.is() == sal_True
)
89 // If an delegator exist, forward question to his queryInterface.
90 // Delegator will ask his own queryAggregation!
91 aReturn
= xDel
->queryInterface( rType
);
95 // If an delegator unknown, forward question to own queryAggregation.
96 aReturn
= queryAggregation( rType
);
102 //____________________________________________________________________________________________________________
104 //____________________________________________________________________________________________________________
106 Sequence
< Type
> SAL_CALL
BaseContainerControl::getTypes() throw( RuntimeException
)
108 // Optimize this method !
109 // We initialize a static variable only one time. And we don't must use a mutex at every call!
110 // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
111 static OTypeCollection
* pTypeCollection
= NULL
;
113 if ( pTypeCollection
== NULL
)
115 // Ready for multithreading; get global mutex for first call of this method only! see before
116 MutexGuard
aGuard( Mutex::getGlobalMutex() );
118 // Control these pointer again ... it can be, that another instance will be faster then these!
119 if ( pTypeCollection
== NULL
)
121 // Create a static typecollection ...
122 static OTypeCollection
aTypeCollection ( ::getCppuType(( const Reference
< XControlModel
>*)NULL
) ,
123 ::getCppuType(( const Reference
< XControlContainer
>*)NULL
) ,
124 BaseControl::getTypes()
126 // ... and set his address to static pointer!
127 pTypeCollection
= &aTypeCollection
;
131 return pTypeCollection
->getTypes();
134 //____________________________________________________________________________________________________________
136 //____________________________________________________________________________________________________________
138 Any SAL_CALL
BaseContainerControl::queryAggregation( const Type
& aType
) throw( RuntimeException
)
140 // Ask for my own supported interfaces ...
141 // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
142 Any
aReturn ( ::cppu::queryInterface( aType
,
143 static_cast< XControlModel
* > ( this ) ,
144 static_cast< XControlContainer
* > ( this )
148 // If searched interface supported by this class ...
149 if ( aReturn
.hasValue() == sal_True
)
151 // ... return this information.
156 // Else; ... ask baseclass for interfaces!
157 return BaseControl::queryAggregation( aType
);
161 //____________________________________________________________________________________________________________
163 //____________________________________________________________________________________________________________
165 void SAL_CALL
BaseContainerControl::createPeer( const Reference
< XToolkit
>& xToolkit
,
166 const Reference
< XWindowPeer
>& xParent
) throw( RuntimeException
)
168 if ( getPeer().is() == sal_False
)
171 BaseControl::createPeer( xToolkit
, xParent
);
173 // create peers at all childs
174 Sequence
< Reference
< XControl
> > seqControlList
= getControls();
175 sal_uInt32 nControls
= seqControlList
.getLength();
177 for ( sal_uInt32 n
=0; n
<nControls
; n
++ )
179 seqControlList
.getArray()[n
]->createPeer( xToolkit
, getPeer() );
182 // activate new tab order
183 impl_activateTabControllers();
186 Reference< XVclContainerPeer > xC;
187 mxPeer->queryInterface( ::getCppuType((const Reference< XVclContainerPeer >*)0), xC );
188 xC->enableDialogControl( sal_True );
194 //____________________________________________________________________________________________________________
196 //____________________________________________________________________________________________________________
198 sal_Bool SAL_CALL
BaseContainerControl::setModel( const Reference
< XControlModel
>& ) throw( RuntimeException
)
200 // This object has NO model.
204 //____________________________________________________________________________________________________________
206 //____________________________________________________________________________________________________________
208 Reference
< XControlModel
> SAL_CALL
BaseContainerControl::getModel() throw( RuntimeException
)
210 // This object has NO model.
211 // return (XControlModel*)this ;
212 return Reference
< XControlModel
>();
215 //____________________________________________________________________________________________________________
217 //____________________________________________________________________________________________________________
219 void SAL_CALL
BaseContainerControl::dispose() throw( RuntimeException
)
221 // Zuerst der Welt mitteilen, da� der Container wegfliegt. Dieses ist um einiges
222 // schneller wenn die Welt sowohl an den Controls als auch am Container horcht
224 // Ready for multithreading
225 MutexGuard
aGuard( m_aMutex
);
228 EventObject aObject
;
230 aObject
.Source
= Reference
< XComponent
> ( (XControlContainer
*)this, UNO_QUERY
);
231 m_aListeners
.disposeAndClear( aObject
);
234 Sequence
< Reference
< XControl
> > seqCtrls
= getControls();
235 Reference
< XControl
> * pCtrls
= seqCtrls
.getArray();
236 sal_uInt32 nCtrls
= seqCtrls
.getLength();
237 sal_uInt32 nMaxCount
= m_pControlInfoList
->Count();
238 sal_uInt32 nCount
= 0;
240 for ( nCount
= 0; nCount
< nMaxCount
; ++nCount
)
242 delete m_pControlInfoList
->GetObject( 0 );
244 m_pControlInfoList
->Clear();
247 for ( nCount
= 0; nCount
< nCtrls
; ++nCount
)
249 pCtrls
[ nCount
] -> removeEventListener ( static_cast< XEventListener
* >( static_cast< XWindowListener
* >( this ) ) ) ;
250 pCtrls
[ nCount
] -> dispose ( ) ;
254 BaseControl::dispose();
257 //____________________________________________________________________________________________________________
259 //____________________________________________________________________________________________________________
261 void SAL_CALL
BaseContainerControl::disposing( const EventObject
& rEvent
) throw( RuntimeException
)
263 Reference
< XControl
> xControl( rEvent
.Source
, UNO_QUERY
);
265 // "removeControl" remove only, when control is an active control
266 removeControl( xControl
);
269 //____________________________________________________________________________________________________________
271 //____________________________________________________________________________________________________________
273 void SAL_CALL
BaseContainerControl::addControl ( const OUString
& rName
, const Reference
< XControl
> & rControl
) throw( RuntimeException
)
275 if ( !rControl
.is () )
278 // take memory for new item
279 IMPL_ControlInfo
* pNewControl
= new IMPL_ControlInfo
;
281 if (pNewControl
!=(IMPL_ControlInfo
*)0)
283 // Ready for multithreading
284 MutexGuard
aGuard (m_aMutex
) ;
287 pNewControl
->sName
= rName
;
288 pNewControl
->xControl
= rControl
;
290 // and insert in list
291 m_pControlInfoList
->Insert ( pNewControl
, LIST_APPEND
) ;
293 // initialize new control
294 pNewControl
->xControl
->setContext ( (OWeakObject
*)this ) ;
295 pNewControl
->xControl
->addEventListener ( static_cast< XEventListener
* >( static_cast< XWindowListener
* >( this ) ) ) ;
297 // when container has a peer ...
300 // .. then create a peer on child
301 pNewControl
->xControl
->createPeer ( getPeer()->getToolkit(), getPeer() ) ;
302 impl_activateTabControllers () ;
305 // Send message to all listener
306 OInterfaceContainerHelper
* pInterfaceContainer
= m_aListeners
.getContainer( ::getCppuType((const Reference
< XContainerListener
>*)0) ) ;
308 if (pInterfaceContainer
)
311 ContainerEvent aEvent
;
313 aEvent
.Source
= *this ;
314 aEvent
.Element
<<= rControl
;
317 OInterfaceIteratorHelper
aIterator (*pInterfaceContainer
) ;
320 while ( aIterator
.hasMoreElements() )
322 ((XContainerListener
*)aIterator
.next())->elementInserted (aEvent
) ;
328 //____________________________________________________________________________________________________________
330 //____________________________________________________________________________________________________________
332 void SAL_CALL
BaseContainerControl::addContainerListener ( const Reference
< XContainerListener
> & rListener
) throw( RuntimeException
)
334 // Ready for multithreading
335 MutexGuard
aGuard ( m_aMutex
) ;
337 m_aListeners
.addInterface ( ::getCppuType((const Reference
< XContainerListener
>*)0), rListener
) ;
340 //____________________________________________________________________________________________________________
342 //____________________________________________________________________________________________________________
344 void SAL_CALL
BaseContainerControl::removeControl ( const Reference
< XControl
> & rControl
) throw( RuntimeException
)
348 // Ready for multithreading
349 MutexGuard
aGuard (m_aMutex
) ;
351 sal_uInt32 nControls
= m_pControlInfoList
->Count () ;
353 for ( sal_uInt32 n
=0; n
<nControls
; n
++ )
355 // Search for right control
356 IMPL_ControlInfo
* pControl
= m_pControlInfoList
->GetObject (n
) ;
357 if ( rControl
== pControl
->xControl
)
359 //.is it found ... remove listener from control
360 pControl
->xControl
->removeEventListener (static_cast< XEventListener
* >( static_cast< XWindowListener
* >( this ) )) ;
361 pControl
->xControl
->setContext ( Reference
< XInterface
> () ) ;
365 m_pControlInfoList
->Remove (n
) ;
367 // Send message to all other listener
368 OInterfaceContainerHelper
* pInterfaceContainer
= m_aListeners
.getContainer( ::getCppuType((const Reference
< XContainerListener
>*)0) ) ;
370 if (pInterfaceContainer
)
372 ContainerEvent aEvent
;
374 aEvent
.Source
= *this ;
375 aEvent
.Element
<<= rControl
;
377 OInterfaceIteratorHelper
aIterator (*pInterfaceContainer
) ;
379 while ( aIterator
.hasMoreElements() )
381 ((XContainerListener
*)aIterator
.next())->elementRemoved (aEvent
) ;
391 //____________________________________________________________________________________________________________
393 //____________________________________________________________________________________________________________
395 void SAL_CALL
BaseContainerControl::removeContainerListener ( const Reference
< XContainerListener
> & rListener
) throw( RuntimeException
)
397 // Ready for multithreading
398 MutexGuard
aGuard ( m_aMutex
) ;
400 m_aListeners
.removeInterface ( ::getCppuType((const Reference
< XContainerListener
>*)0), rListener
) ;
403 //____________________________________________________________________________________________________________
405 //____________________________________________________________________________________________________________
407 void SAL_CALL
BaseContainerControl::setStatusText ( const OUString
& rStatusText
) throw( RuntimeException
)
409 // go down to each parent
410 Reference
< XControlContainer
> xContainer ( getContext(), UNO_QUERY
) ;
412 if ( xContainer
.is () )
414 xContainer
->setStatusText ( rStatusText
) ;
418 //____________________________________________________________________________________________________________
420 //____________________________________________________________________________________________________________
422 Reference
< XControl
> SAL_CALL
BaseContainerControl::getControl ( const OUString
& rName
) throw( RuntimeException
)
424 // Ready for multithreading
425 MutexGuard
aGuard ( Mutex::getGlobalMutex() ) ;
427 Reference
< XControl
> xRetControl
= Reference
< XControl
> () ;
428 sal_uInt32 nControls
= m_pControlInfoList
->Count () ;
430 // Search for right control
431 for( sal_uInt32 nCount
= 0; nCount
< nControls
; ++nCount
)
433 IMPL_ControlInfo
* pSearchControl
= m_pControlInfoList
->GetObject ( nCount
) ;
435 if ( pSearchControl
->sName
== rName
)
437 // We have found it ...
438 // Break operation and return.
439 return pSearchControl
->xControl
;
443 // We have not found it ... return NULL.
444 return Reference
< XControl
> () ;
447 //____________________________________________________________________________________________________________
449 //____________________________________________________________________________________________________________
451 Sequence
< Reference
< XControl
> > SAL_CALL
BaseContainerControl::getControls () throw( RuntimeException
)
453 // Ready for multithreading
454 MutexGuard
aGuard ( Mutex::getGlobalMutex() ) ;
456 sal_uInt32 nControls
= m_pControlInfoList
->Count () ;
457 Sequence
< Reference
< XControl
> > aDescriptor ( nControls
) ;
458 Reference
< XControl
> * pDestination
= aDescriptor
.getArray () ;
459 sal_uInt32 nCount
= 0 ;
461 // Copy controls to sequence
462 for( nCount
= 0; nCount
< nControls
; ++nCount
)
464 IMPL_ControlInfo
* pCopyControl
= m_pControlInfoList
->GetObject ( nCount
) ;
465 pDestination
[ nCount
] = pCopyControl
->xControl
;
472 //____________________________________________________________________________________________________________
473 // XUnoControlContainer
474 //____________________________________________________________________________________________________________
476 void SAL_CALL
BaseContainerControl::addTabController ( const Reference
< XTabController
> & rTabController
) throw( RuntimeException
)
478 // Ready for multithreading
479 MutexGuard
aGuard (m_aMutex
) ;
481 sal_uInt32 nOldCount
= m_xTabControllerList
.getLength () ;
482 Sequence
< Reference
< XTabController
> > aNewList ( nOldCount
+ 1 ) ;
483 sal_uInt32 nCount
= 0 ;
485 // Copy old elements of sequence to new list.
486 for ( nCount
= 0; nCount
< nOldCount
; ++nCount
)
488 aNewList
.getArray () [nCount
] = m_xTabControllerList
.getConstArray () [nCount
] ;
491 // Add new controller
492 aNewList
.getArray () [nOldCount
] = rTabController
;
494 // change old and new list
495 m_xTabControllerList
= aNewList
;
498 //____________________________________________________________________________________________________________
499 // XUnoControlContainer
500 //____________________________________________________________________________________________________________
502 void SAL_CALL
BaseContainerControl::removeTabController ( const Reference
< XTabController
> & rTabController
) throw( RuntimeException
)
504 // Ready for multithreading
505 MutexGuard
aGuard (m_aMutex
) ;
507 sal_uInt32 nMaxCount
= m_xTabControllerList
.getLength () ;
508 sal_uInt32 nCount
= 0 ;
510 // Search right tabcontroller ...
511 for ( nCount
= 0; nCount
< nMaxCount
; ++nCount
)
513 if ( m_xTabControllerList
.getConstArray () [nCount
] == rTabController
)
515 // ... if is it found ... remove it from list.
516 m_xTabControllerList
.getArray()[ nCount
] = Reference
< XTabController
>() ;
522 //____________________________________________________________________________________________________________
523 // XUnoControlContainer
524 //____________________________________________________________________________________________________________
526 void SAL_CALL
BaseContainerControl::setTabControllers ( const Sequence
< Reference
< XTabController
> >& rTabControllers
) throw( RuntimeException
)
528 // Ready for multithreading
529 MutexGuard
aGuard (m_aMutex
) ;
531 m_xTabControllerList
= rTabControllers
;
534 Sequence
<Reference
< XTabController
> > SAL_CALL
BaseContainerControl::getTabControllers () throw( RuntimeException
)
536 // Ready for multithreading
537 MutexGuard
aGuard (m_aMutex
) ;
539 return m_xTabControllerList
;
542 //____________________________________________________________________________________________________________
544 //____________________________________________________________________________________________________________
546 void SAL_CALL
BaseContainerControl::setVisible ( sal_Bool bVisible
) throw( RuntimeException
)
548 // override baseclass definition
549 BaseControl::setVisible ( bVisible
) ;
551 // is it a top window ?
552 if ( !getContext().is() && bVisible
)
554 // then show it automaticly
555 createPeer ( Reference
< XToolkit
> (), Reference
< XWindowPeer
> () ) ;
559 //____________________________________________________________________________________________________________
561 //____________________________________________________________________________________________________________
563 WindowDescriptor
* BaseContainerControl::impl_getWindowDescriptor ( const Reference
< XWindowPeer
> & rParentPeer
)
565 // - used from "createPeer()" to set the values of an WindowDescriptor !!!
566 // - if you will change the descriptor-values, you must override thid virtuell function
567 // - the caller must release the memory for this dynamical descriptor !!!
569 WindowDescriptor
* aDescriptor
= new WindowDescriptor
;
571 aDescriptor
->Type
= WindowClass_CONTAINER
;
572 aDescriptor
->WindowServiceName
= OUString(RTL_CONSTASCII_USTRINGPARAM("window")) ;
573 aDescriptor
->ParentIndex
= -1 ;
574 aDescriptor
->Parent
= rParentPeer
;
575 aDescriptor
->Bounds
= getPosSize () ;
576 aDescriptor
->WindowAttributes
= 0 ;
581 //____________________________________________________________________________________________________________
583 //____________________________________________________________________________________________________________
585 void BaseContainerControl::impl_paint ( sal_Int32
/*nX*/, sal_Int32
/*nY*/, const Reference
< XGraphics
> & /*rGraphics*/ )
590 for ( sal_uInt32 n=m_pControlInfoList->Count(); n; )
592 ControlInfo* pSearchControl = m_pControlInfoList->GetObject (--n) ;
594 pSearchControl->xControl->paint ( nX, nY, rGraphics ) ;
600 //____________________________________________________________________________________________________________
602 //____________________________________________________________________________________________________________
604 void BaseContainerControl::impl_activateTabControllers ()
606 // Ready for multithreading
607 MutexGuard
aGuard (m_aMutex
) ;
609 sal_uInt32 nMaxCount
= m_xTabControllerList
.getLength () ;
610 sal_uInt32 nCount
= 0 ;
612 for ( nCount
= 0; nCount
< nMaxCount
; ++nCount
)
614 m_xTabControllerList
.getArray () [nCount
]->setContainer ( this ) ;
615 m_xTabControllerList
.getArray () [nCount
]->activateTabOrder ( ) ;
619 //____________________________________________________________________________________________________________
621 //____________________________________________________________________________________________________________
623 void BaseContainerControl::impl_cleanMemory ()
625 // Get count of listitems.
626 sal_uInt32 nMaxCount
= m_pControlInfoList
->Count () ;
627 sal_uInt32 nCount
= 0 ;
630 for ( nCount
= 0; nCount
< nMaxCount
; ++nCount
)
632 // Delete everytime first element of list!
633 // We count from 0 to MAX, where "MAX=count of items" BEFORE we delete some elements!
634 // If we use "GetObject ( nCount )" ... it can be, that we have an index greater then count of current elements!
636 IMPL_ControlInfo
* pSearchControl
= m_pControlInfoList
->GetObject ( 0 ) ;
637 delete pSearchControl
;
640 // Delete list himself.
641 m_pControlInfoList
->Clear () ;
642 delete m_pControlInfoList
;
645 } // namespace unocontrols