Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / UnoControls / source / base / basecontainercontrol.cxx
blobf219b3f5d108482dbe3b93e82fc873c8b8d10d64
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 //____________________________________________________________________________________________________________
30 // my own includes
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 //____________________________________________________________________________________________________________
45 // namespaces
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 //____________________________________________________________________________________________________________
59 // construct/destruct
60 //____________________________________________________________________________________________________________
62 BaseContainerControl::BaseContainerControl( const Reference< XMultiServiceFactory >& xFactory )
63 : BaseControl ( xFactory )
64 , m_aListeners ( m_aMutex )
68 BaseContainerControl::~BaseContainerControl()
70 impl_cleanMemory();
73 //____________________________________________________________________________________________________________
74 // XInterface
75 //____________________________________________________________________________________________________________
77 Any SAL_CALL BaseContainerControl::queryInterface( const Type& rType ) throw( RuntimeException )
79 // Attention:
80 // Don't use mutex or guard in this method!!! Is a method of XInterface.
81 Any aReturn ;
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 );
89 else
91 // If an delegator unknown, forward question to own queryAggregation.
92 aReturn = queryAggregation( rType );
95 return aReturn ;
98 //____________________________________________________________________________________________________________
99 // XTypeProvider
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 //____________________________________________________________________________________________________________
131 // XAggregation
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.
148 return aReturn ;
150 else
152 // Else; ... ask baseclass for interfaces!
153 return BaseControl::queryAggregation( aType );
157 //____________________________________________________________________________________________________________
158 // XControl
159 //____________________________________________________________________________________________________________
161 void SAL_CALL BaseContainerControl::createPeer( const Reference< XToolkit >& xToolkit ,
162 const Reference< XWindowPeer >& xParent ) throw( RuntimeException )
164 if ( getPeer().is() == sal_False )
166 // create own peer
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 //____________________________________________________________________________________________________________
185 // XControl
186 //____________________________________________________________________________________________________________
188 sal_Bool SAL_CALL BaseContainerControl::setModel( const Reference< XControlModel >& ) throw( RuntimeException )
190 // This object has NO model.
191 return sal_False ;
194 //____________________________________________________________________________________________________________
195 // XControl
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 //____________________________________________________________________________________________________________
206 // XComponent
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 );
217 // remove listeners
218 EventObject aObject ;
220 aObject.Source = Reference< XComponent > ( (XControlContainer*)this, UNO_QUERY );
221 m_aListeners.disposeAndClear( aObject );
223 // remove controls
224 Sequence< Reference< XControl > > seqCtrls = getControls();
225 Reference< XControl > * pCtrls = seqCtrls.getArray();
226 sal_uInt32 nCtrls = seqCtrls.getLength();
227 size_t nMaxCount = maControlInfoList.size();
228 size_t nCount = 0;
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 ( ) ;
242 // call baseclass
243 BaseControl::dispose();
246 //____________________________________________________________________________________________________________
247 // XEventListener
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 //____________________________________________________________________________________________________________
259 // XControlContainer
260 //____________________________________________________________________________________________________________
262 void SAL_CALL BaseContainerControl::addControl ( const OUString& rName, const Reference< XControl > & rControl ) throw( RuntimeException )
264 if ( !rControl.is () )
265 return;
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) ;
275 // set control
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 ...
287 if (getPeer().is())
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)
299 // Build event
300 ContainerEvent aEvent ;
302 aEvent.Source = *this ;
303 aEvent.Element <<= rControl ;
305 // Get all listener
306 OInterfaceIteratorHelper aIterator (*pInterfaceContainer) ;
308 // Send event
309 while ( aIterator.hasMoreElements() )
311 ((XContainerListener*)aIterator.next())->elementInserted (aEvent) ;
317 //____________________________________________________________________________________________________________
318 // XControlContainer
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 //____________________________________________________________________________________________________________
330 // XControlContainer
331 //____________________________________________________________________________________________________________
333 void SAL_CALL BaseContainerControl::removeControl ( const Reference< XControl > & rControl ) throw( RuntimeException )
335 if ( rControl.is() )
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 > () ) ;
352 // ... free memory
353 delete pControl ;
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) ;
375 // Break "for" !
376 break ;
382 //____________________________________________________________________________________________________________
383 // XControlContainer
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 //____________________________________________________________________________________________________________
395 // XControlContainer
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 //____________________________________________________________________________________________________________
410 // XControlContainer
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 //____________________________________________________________________________________________________________
439 // XControlContainer
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();
448 size_t nCount = 0;
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 ;
459 // Return sequence
460 return aDescriptor ;
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 >() ;
508 break ;
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 //____________________________________________________________________________________________________________
534 // XWindow
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 //____________________________________________________________________________________________________________
551 // protected method
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 ;
569 return aDescriptor ;
572 //____________________________________________________________________________________________________________
573 // protected method
574 //____________________________________________________________________________________________________________
576 void BaseContainerControl::impl_paint ( sal_Int32 /*nX*/, sal_Int32 /*nY*/, const Reference< XGraphics > & /*rGraphics*/ )
579 if (rGraphics.is())
581 for ( size_t n = maControlInfoList.size(); n; )
583 ControlInfo* pSearchControl = maControlInfoList[ --n ];
584 pSearchControl->xControl->paint ( nX, nY, rGraphics ) ;
590 //____________________________________________________________________________________________________________
591 // private method
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 //____________________________________________________________________________________________________________
610 // private method
611 //____________________________________________________________________________________________________________
613 void BaseContainerControl::impl_cleanMemory ()
615 // Get count of listitems.
616 size_t nMaxCount = maControlInfoList.size();
617 size_t nCount = 0;
619 // Delete all items.
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: */