merge the formfield patch from ooo-build
[ooovba.git] / UnoControls / source / base / basecontainercontrol.cxx
blobc8167900887dbb862ca34dfab2e71c2bdd0d0a4c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: basecontainercontrol.cxx,v $
10 * $Revision: 1.6 $
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 //____________________________________________________________________________________________________________
32 // my own includes
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 //____________________________________________________________________________________________________________
47 // namespaces
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 //____________________________________________________________________________________________________________
61 // construct/destruct
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()
74 impl_cleanMemory();
77 //____________________________________________________________________________________________________________
78 // XInterface
79 //____________________________________________________________________________________________________________
81 Any SAL_CALL BaseContainerControl::queryInterface( const Type& rType ) throw( RuntimeException )
83 // Attention:
84 // Don't use mutex or guard in this method!!! Is a method of XInterface.
85 Any aReturn ;
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 );
93 else
95 // If an delegator unknown, forward question to own queryAggregation.
96 aReturn = queryAggregation( rType );
99 return aReturn ;
102 //____________________________________________________________________________________________________________
103 // XTypeProvider
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 //____________________________________________________________________________________________________________
135 // XAggregation
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.
152 return aReturn ;
154 else
156 // Else; ... ask baseclass for interfaces!
157 return BaseControl::queryAggregation( aType );
161 //____________________________________________________________________________________________________________
162 // XControl
163 //____________________________________________________________________________________________________________
165 void SAL_CALL BaseContainerControl::createPeer( const Reference< XToolkit >& xToolkit ,
166 const Reference< XWindowPeer >& xParent ) throw( RuntimeException )
168 if ( getPeer().is() == sal_False )
170 // create own peer
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 //____________________________________________________________________________________________________________
195 // XControl
196 //____________________________________________________________________________________________________________
198 sal_Bool SAL_CALL BaseContainerControl::setModel( const Reference< XControlModel >& ) throw( RuntimeException )
200 // This object has NO model.
201 return sal_False ;
204 //____________________________________________________________________________________________________________
205 // XControl
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 //____________________________________________________________________________________________________________
216 // XComponent
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 );
227 // remove listeners
228 EventObject aObject ;
230 aObject.Source = Reference< XComponent > ( (XControlContainer*)this, UNO_QUERY );
231 m_aListeners.disposeAndClear( aObject );
233 // remove controls
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 ( ) ;
253 // call baseclass
254 BaseControl::dispose();
257 //____________________________________________________________________________________________________________
258 // XEventListener
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 //____________________________________________________________________________________________________________
270 // XControlContainer
271 //____________________________________________________________________________________________________________
273 void SAL_CALL BaseContainerControl::addControl ( const OUString& rName, const Reference< XControl > & rControl ) throw( RuntimeException )
275 if ( !rControl.is () )
276 return;
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) ;
286 // set control
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 ...
298 if (getPeer().is())
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)
310 // Build event
311 ContainerEvent aEvent ;
313 aEvent.Source = *this ;
314 aEvent.Element <<= rControl ;
316 // Get all listener
317 OInterfaceIteratorHelper aIterator (*pInterfaceContainer) ;
319 // Send event
320 while ( aIterator.hasMoreElements() )
322 ((XContainerListener*)aIterator.next())->elementInserted (aEvent) ;
328 //____________________________________________________________________________________________________________
329 // XControlContainer
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 //____________________________________________________________________________________________________________
341 // XControlContainer
342 //____________________________________________________________________________________________________________
344 void SAL_CALL BaseContainerControl::removeControl ( const Reference< XControl > & rControl ) throw( RuntimeException )
346 if ( rControl.is() )
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 > () ) ;
363 // ... free memory
364 delete pControl ;
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) ;
384 // Break "for" !
385 break ;
391 //____________________________________________________________________________________________________________
392 // XControlContainer
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 //____________________________________________________________________________________________________________
404 // XControlContainer
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 //____________________________________________________________________________________________________________
419 // XControlContainer
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 //____________________________________________________________________________________________________________
448 // XControlContainer
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 ;
468 // Return sequence
469 return aDescriptor ;
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 >() ;
517 break ;
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 //____________________________________________________________________________________________________________
543 // XWindow
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 //____________________________________________________________________________________________________________
560 // protected method
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 ;
578 return aDescriptor ;
581 //____________________________________________________________________________________________________________
582 // protected method
583 //____________________________________________________________________________________________________________
585 void BaseContainerControl::impl_paint ( sal_Int32 /*nX*/, sal_Int32 /*nY*/, const Reference< XGraphics > & /*rGraphics*/ )
588 if (rGraphics.is())
590 for ( sal_uInt32 n=m_pControlInfoList->Count(); n; )
592 ControlInfo* pSearchControl = m_pControlInfoList->GetObject (--n) ;
594 pSearchControl->xControl->paint ( nX, nY, rGraphics ) ;
600 //____________________________________________________________________________________________________________
601 // private method
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 //____________________________________________________________________________________________________________
620 // private method
621 //____________________________________________________________________________________________________________
623 void BaseContainerControl::impl_cleanMemory ()
625 // Get count of listitems.
626 sal_uInt32 nMaxCount = m_pControlInfoList->Count () ;
627 sal_uInt32 nCount = 0 ;
629 // Delete all items.
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