1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 //____________________________________________________________________________________________________________
31 //____________________________________________________________________________________________________________
33 #include "basecontainercontrol.hxx"
35 //____________________________________________________________________________________________________________
36 // includes of other projects
37 //____________________________________________________________________________________________________________
38 #include <cppuhelper/typeprovider.hxx>
40 //____________________________________________________________________________________________________________
41 // includes of my own project
42 //____________________________________________________________________________________________________________
44 //____________________________________________________________________________________________________________
46 //____________________________________________________________________________________________________________
48 using namespace ::cppu
;
49 using namespace ::osl
;
50 using namespace ::rtl
;
51 using namespace ::com::sun::star::uno
;
52 using namespace ::com::sun::star::lang
;
53 using namespace ::com::sun::star::awt
;
54 using namespace ::com::sun::star::container
;
56 namespace unocontrols
{
58 //____________________________________________________________________________________________________________
60 //____________________________________________________________________________________________________________
62 BaseContainerControl::BaseContainerControl( const Reference
< XMultiServiceFactory
>& xFactory
)
63 : BaseControl ( xFactory
)
64 , m_aListeners ( m_aMutex
)
68 BaseContainerControl::~BaseContainerControl()
73 //____________________________________________________________________________________________________________
75 //____________________________________________________________________________________________________________
77 Any SAL_CALL
BaseContainerControl::queryInterface( const Type
& rType
) throw( RuntimeException
)
80 // Don't use mutex or guard in this method!!! Is a method of XInterface.
82 Reference
< XInterface
> xDel
= BaseControl::impl_getDelegator();
83 if ( xDel
.is() == sal_True
)
85 // If an delegator exist, forward question to his queryInterface.
86 // Delegator will ask his own queryAggregation!
87 aReturn
= xDel
->queryInterface( rType
);
91 // If an delegator unknown, forward question to own queryAggregation.
92 aReturn
= queryAggregation( rType
);
98 //____________________________________________________________________________________________________________
100 //____________________________________________________________________________________________________________
102 Sequence
< Type
> SAL_CALL
BaseContainerControl::getTypes() throw( RuntimeException
)
104 // Optimize this method !
105 // We initialize a static variable only one time. And we don't must use a mutex at every call!
106 // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
107 static OTypeCollection
* pTypeCollection
= NULL
;
109 if ( pTypeCollection
== NULL
)
111 // Ready for multithreading; get global mutex for first call of this method only! see before
112 MutexGuard
aGuard( Mutex::getGlobalMutex() );
114 // Control these pointer again ... it can be, that another instance will be faster then these!
115 if ( pTypeCollection
== NULL
)
117 // Create a static typecollection ...
118 static OTypeCollection
aTypeCollection ( ::getCppuType(( const Reference
< XControlModel
>*)NULL
) ,
119 ::getCppuType(( const Reference
< XControlContainer
>*)NULL
) ,
120 BaseControl::getTypes()
122 // ... and set his address to static pointer!
123 pTypeCollection
= &aTypeCollection
;
127 return pTypeCollection
->getTypes();
130 //____________________________________________________________________________________________________________
132 //____________________________________________________________________________________________________________
134 Any SAL_CALL
BaseContainerControl::queryAggregation( const Type
& aType
) throw( RuntimeException
)
136 // Ask for my own supported interfaces ...
137 // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
138 Any
aReturn ( ::cppu::queryInterface( aType
,
139 static_cast< XControlModel
* > ( this ) ,
140 static_cast< XControlContainer
* > ( this )
144 // If searched interface supported by this class ...
145 if ( aReturn
.hasValue() == sal_True
)
147 // ... return this information.
152 // Else; ... ask baseclass for interfaces!
153 return BaseControl::queryAggregation( aType
);
157 //____________________________________________________________________________________________________________
159 //____________________________________________________________________________________________________________
161 void SAL_CALL
BaseContainerControl::createPeer( const Reference
< XToolkit
>& xToolkit
,
162 const Reference
< XWindowPeer
>& xParent
) throw( RuntimeException
)
164 if ( getPeer().is() == sal_False
)
167 BaseControl::createPeer( xToolkit
, xParent
);
169 // create peers at all children
170 Sequence
< Reference
< XControl
> > seqControlList
= getControls();
171 sal_uInt32 nControls
= seqControlList
.getLength();
173 for ( sal_uInt32 n
=0; n
<nControls
; n
++ )
175 seqControlList
.getArray()[n
]->createPeer( xToolkit
, getPeer() );
178 // activate new tab order
179 impl_activateTabControllers();
184 //____________________________________________________________________________________________________________
186 //____________________________________________________________________________________________________________
188 sal_Bool SAL_CALL
BaseContainerControl::setModel( const Reference
< XControlModel
>& ) throw( RuntimeException
)
190 // This object has NO model.
194 //____________________________________________________________________________________________________________
196 //____________________________________________________________________________________________________________
198 Reference
< XControlModel
> SAL_CALL
BaseContainerControl::getModel() throw( RuntimeException
)
200 // This object has NO model.
201 // return (XControlModel*)this ;
202 return Reference
< XControlModel
>();
205 //____________________________________________________________________________________________________________
207 //____________________________________________________________________________________________________________
209 void SAL_CALL
BaseContainerControl::dispose() throw( RuntimeException
)
211 // Tell everything that this container is now gone.
212 // It's faster if you listen to both the control and the container.
214 // Ready for multithreading
215 MutexGuard
aGuard( m_aMutex
);
218 EventObject aObject
;
220 aObject
.Source
= Reference
< XComponent
> ( (XControlContainer
*)this, UNO_QUERY
);
221 m_aListeners
.disposeAndClear( aObject
);
224 Sequence
< Reference
< XControl
> > seqCtrls
= getControls();
225 Reference
< XControl
> * pCtrls
= seqCtrls
.getArray();
226 sal_uInt32 nCtrls
= seqCtrls
.getLength();
227 size_t nMaxCount
= maControlInfoList
.size();
230 for ( nCount
= 0; nCount
< nMaxCount
; ++nCount
)
232 delete maControlInfoList
[ nCount
];
234 maControlInfoList
.clear();
236 for ( nCount
= 0; nCount
< nCtrls
; ++nCount
)
238 pCtrls
[ nCount
] -> removeEventListener ( static_cast< XEventListener
* >( static_cast< XWindowListener
* >( this ) ) ) ;
239 pCtrls
[ nCount
] -> dispose ( ) ;
243 BaseControl::dispose();
246 //____________________________________________________________________________________________________________
248 //____________________________________________________________________________________________________________
250 void SAL_CALL
BaseContainerControl::disposing( const EventObject
& rEvent
) throw( RuntimeException
)
252 Reference
< XControl
> xControl( rEvent
.Source
, UNO_QUERY
);
254 // "removeControl" remove only, when control is an active control
255 removeControl( xControl
);
258 //____________________________________________________________________________________________________________
260 //____________________________________________________________________________________________________________
262 void SAL_CALL
BaseContainerControl::addControl ( const OUString
& rName
, const Reference
< XControl
> & rControl
) throw( RuntimeException
)
264 if ( !rControl
.is () )
267 // take memory for new item
268 IMPL_ControlInfo
* pNewControl
= new IMPL_ControlInfo
;
270 if (pNewControl
!=(IMPL_ControlInfo
*)0)
272 // Ready for multithreading
273 MutexGuard
aGuard (m_aMutex
) ;
276 pNewControl
->sName
= rName
;
277 pNewControl
->xControl
= rControl
;
279 // and insert in list
280 maControlInfoList
.push_back( pNewControl
) ;
282 // initialize new control
283 pNewControl
->xControl
->setContext ( (OWeakObject
*)this ) ;
284 pNewControl
->xControl
->addEventListener ( static_cast< XEventListener
* >( static_cast< XWindowListener
* >( this ) ) ) ;
286 // when container has a peer ...
289 // .. then create a peer on child
290 pNewControl
->xControl
->createPeer ( getPeer()->getToolkit(), getPeer() ) ;
291 impl_activateTabControllers () ;
294 // Send message to all listener
295 OInterfaceContainerHelper
* pInterfaceContainer
= m_aListeners
.getContainer( ::getCppuType((const Reference
< XContainerListener
>*)0) ) ;
297 if (pInterfaceContainer
)
300 ContainerEvent aEvent
;
302 aEvent
.Source
= *this ;
303 aEvent
.Element
<<= rControl
;
306 OInterfaceIteratorHelper
aIterator (*pInterfaceContainer
) ;
309 while ( aIterator
.hasMoreElements() )
311 ((XContainerListener
*)aIterator
.next())->elementInserted (aEvent
) ;
317 //____________________________________________________________________________________________________________
319 //____________________________________________________________________________________________________________
321 void SAL_CALL
BaseContainerControl::addContainerListener ( const Reference
< XContainerListener
> & rListener
) throw( RuntimeException
)
323 // Ready for multithreading
324 MutexGuard
aGuard ( m_aMutex
) ;
326 m_aListeners
.addInterface ( ::getCppuType((const Reference
< XContainerListener
>*)0), rListener
) ;
329 //____________________________________________________________________________________________________________
331 //____________________________________________________________________________________________________________
333 void SAL_CALL
BaseContainerControl::removeControl ( const Reference
< XControl
> & rControl
) throw( RuntimeException
)
337 // Ready for multithreading
338 MutexGuard
aGuard (m_aMutex
) ;
340 size_t nControls
= maControlInfoList
.size();
342 for ( size_t n
= 0; n
< nControls
; n
++ )
344 // Search for right control
345 IMPL_ControlInfo
* pControl
= maControlInfoList
[ n
] ;
346 if ( rControl
== pControl
->xControl
)
348 //.is it found ... remove listener from control
349 pControl
->xControl
->removeEventListener (static_cast< XEventListener
* >( static_cast< XWindowListener
* >( this ) )) ;
350 pControl
->xControl
->setContext ( Reference
< XInterface
> () ) ;
354 ::std::vector
<IMPL_ControlInfo
*>::iterator itr
= maControlInfoList
.begin();
355 ::std::advance(itr
, n
);
356 maControlInfoList
.erase(itr
);
358 // Send message to all other listener
359 OInterfaceContainerHelper
* pInterfaceContainer
= m_aListeners
.getContainer( ::getCppuType((const Reference
< XContainerListener
>*)0) ) ;
361 if (pInterfaceContainer
)
363 ContainerEvent aEvent
;
365 aEvent
.Source
= *this ;
366 aEvent
.Element
<<= rControl
;
368 OInterfaceIteratorHelper
aIterator (*pInterfaceContainer
) ;
370 while ( aIterator
.hasMoreElements() )
372 ((XContainerListener
*)aIterator
.next())->elementRemoved (aEvent
) ;
382 //____________________________________________________________________________________________________________
384 //____________________________________________________________________________________________________________
386 void SAL_CALL
BaseContainerControl::removeContainerListener ( const Reference
< XContainerListener
> & rListener
) throw( RuntimeException
)
388 // Ready for multithreading
389 MutexGuard
aGuard ( m_aMutex
) ;
391 m_aListeners
.removeInterface ( ::getCppuType((const Reference
< XContainerListener
>*)0), rListener
) ;
394 //____________________________________________________________________________________________________________
396 //____________________________________________________________________________________________________________
398 void SAL_CALL
BaseContainerControl::setStatusText ( const OUString
& rStatusText
) throw( RuntimeException
)
400 // go down to each parent
401 Reference
< XControlContainer
> xContainer ( getContext(), UNO_QUERY
) ;
403 if ( xContainer
.is () )
405 xContainer
->setStatusText ( rStatusText
) ;
409 //____________________________________________________________________________________________________________
411 //____________________________________________________________________________________________________________
413 Reference
< XControl
> SAL_CALL
BaseContainerControl::getControl ( const OUString
& rName
) throw( RuntimeException
)
415 // Ready for multithreading
416 MutexGuard
aGuard ( Mutex::getGlobalMutex() ) ;
418 Reference
< XControl
> xRetControl
= Reference
< XControl
> ();
419 size_t nControls
= maControlInfoList
.size();
421 // Search for right control
422 for( size_t nCount
= 0; nCount
< nControls
; ++nCount
)
424 IMPL_ControlInfo
* pSearchControl
= maControlInfoList
[ nCount
];
426 if ( pSearchControl
->sName
== rName
)
428 // We have found it ...
429 // Break operation and return.
430 return pSearchControl
->xControl
;
434 // We have not found it ... return NULL.
435 return Reference
< XControl
> () ;
438 //____________________________________________________________________________________________________________
440 //____________________________________________________________________________________________________________
442 Sequence
< Reference
< XControl
> > SAL_CALL
BaseContainerControl::getControls () throw( RuntimeException
)
444 // Ready for multithreading
445 MutexGuard
aGuard ( Mutex::getGlobalMutex() ) ;
447 size_t nControls
= maControlInfoList
.size();
449 Sequence
< Reference
< XControl
> > aDescriptor ( nControls
) ;
450 Reference
< XControl
> * pDestination
= aDescriptor
.getArray () ;
452 // Copy controls to sequence
453 for( nCount
= 0; nCount
< nControls
; ++nCount
)
455 IMPL_ControlInfo
* pCopyControl
= maControlInfoList
[ nCount
];
456 pDestination
[ nCount
] = pCopyControl
->xControl
;
463 //____________________________________________________________________________________________________________
464 // XUnoControlContainer
465 //____________________________________________________________________________________________________________
467 void SAL_CALL
BaseContainerControl::addTabController ( const Reference
< XTabController
> & rTabController
) throw( RuntimeException
)
469 // Ready for multithreading
470 MutexGuard
aGuard (m_aMutex
) ;
472 sal_uInt32 nOldCount
= m_xTabControllerList
.getLength () ;
473 Sequence
< Reference
< XTabController
> > aNewList ( nOldCount
+ 1 ) ;
474 sal_uInt32 nCount
= 0 ;
476 // Copy old elements of sequence to new list.
477 for ( nCount
= 0; nCount
< nOldCount
; ++nCount
)
479 aNewList
.getArray () [nCount
] = m_xTabControllerList
.getConstArray () [nCount
] ;
482 // Add new controller
483 aNewList
.getArray () [nOldCount
] = rTabController
;
485 // change old and new list
486 m_xTabControllerList
= aNewList
;
489 //____________________________________________________________________________________________________________
490 // XUnoControlContainer
491 //____________________________________________________________________________________________________________
493 void SAL_CALL
BaseContainerControl::removeTabController ( const Reference
< XTabController
> & rTabController
) throw( RuntimeException
)
495 // Ready for multithreading
496 MutexGuard
aGuard (m_aMutex
) ;
498 sal_uInt32 nMaxCount
= m_xTabControllerList
.getLength () ;
499 sal_uInt32 nCount
= 0 ;
501 // Search right tabcontroller ...
502 for ( nCount
= 0; nCount
< nMaxCount
; ++nCount
)
504 if ( m_xTabControllerList
.getConstArray () [nCount
] == rTabController
)
506 // ... if is it found ... remove it from list.
507 m_xTabControllerList
.getArray()[ nCount
] = Reference
< XTabController
>() ;
513 //____________________________________________________________________________________________________________
514 // XUnoControlContainer
515 //____________________________________________________________________________________________________________
517 void SAL_CALL
BaseContainerControl::setTabControllers ( const Sequence
< Reference
< XTabController
> >& rTabControllers
) throw( RuntimeException
)
519 // Ready for multithreading
520 MutexGuard
aGuard (m_aMutex
) ;
522 m_xTabControllerList
= rTabControllers
;
525 Sequence
<Reference
< XTabController
> > SAL_CALL
BaseContainerControl::getTabControllers () throw( RuntimeException
)
527 // Ready for multithreading
528 MutexGuard
aGuard (m_aMutex
) ;
530 return m_xTabControllerList
;
533 //____________________________________________________________________________________________________________
535 //____________________________________________________________________________________________________________
537 void SAL_CALL
BaseContainerControl::setVisible ( sal_Bool bVisible
) throw( RuntimeException
)
539 // override baseclass definition
540 BaseControl::setVisible ( bVisible
) ;
542 // is it a top window ?
543 if ( !getContext().is() && bVisible
)
545 // then show it automaticly
546 createPeer ( Reference
< XToolkit
> (), Reference
< XWindowPeer
> () ) ;
550 //____________________________________________________________________________________________________________
552 //____________________________________________________________________________________________________________
554 WindowDescriptor
* BaseContainerControl::impl_getWindowDescriptor ( const Reference
< XWindowPeer
> & rParentPeer
)
556 // - used from "createPeer()" to set the values of an WindowDescriptor !!!
557 // - if you will change the descriptor-values, you must override thid virtuell function
558 // - the caller must release the memory for this dynamical descriptor !!!
560 WindowDescriptor
* aDescriptor
= new WindowDescriptor
;
562 aDescriptor
->Type
= WindowClass_CONTAINER
;
563 aDescriptor
->WindowServiceName
= "window" ;
564 aDescriptor
->ParentIndex
= -1 ;
565 aDescriptor
->Parent
= rParentPeer
;
566 aDescriptor
->Bounds
= getPosSize () ;
567 aDescriptor
->WindowAttributes
= 0 ;
572 //____________________________________________________________________________________________________________
574 //____________________________________________________________________________________________________________
576 void BaseContainerControl::impl_paint ( sal_Int32
/*nX*/, sal_Int32
/*nY*/, const Reference
< XGraphics
> & /*rGraphics*/ )
581 for ( size_t n = maControlInfoList.size(); n; )
583 ControlInfo* pSearchControl = maControlInfoList[ --n ];
584 pSearchControl->xControl->paint ( nX, nY, rGraphics ) ;
590 //____________________________________________________________________________________________________________
592 //____________________________________________________________________________________________________________
594 void BaseContainerControl::impl_activateTabControllers ()
596 // Ready for multithreading
597 MutexGuard
aGuard (m_aMutex
) ;
599 sal_uInt32 nMaxCount
= m_xTabControllerList
.getLength () ;
600 sal_uInt32 nCount
= 0 ;
602 for ( nCount
= 0; nCount
< nMaxCount
; ++nCount
)
604 m_xTabControllerList
.getArray () [nCount
]->setContainer ( this ) ;
605 m_xTabControllerList
.getArray () [nCount
]->activateTabOrder ( ) ;
609 //____________________________________________________________________________________________________________
611 //____________________________________________________________________________________________________________
613 void BaseContainerControl::impl_cleanMemory ()
615 // Get count of listitems.
616 size_t nMaxCount
= maControlInfoList
.size();
620 for ( nCount
= 0; nCount
< nMaxCount
; ++nCount
)
622 // Delete everytime first element of list!
623 // We count from 0 to MAX, where "MAX=count of items" BEFORE we delete some elements!
624 // If we use "GetObject ( nCount )" ... it can be, that we have an index greater then count of current elements!
626 IMPL_ControlInfo
* pSearchControl
= maControlInfoList
[ nCount
];
627 delete pSearchControl
;
630 // Delete list himself.
631 maControlInfoList
.clear ();
634 } // namespace unocontrols
636 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */