xref: /AOO41X/main/UnoControls/source/base/basecontainercontrol.cxx (revision 0b4ced1d4e3a9bc987eae61b8e131e5e85d0fb11)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 //____________________________________________________________________________________________________________
25 //  my own includes
26 //____________________________________________________________________________________________________________
27 
28 #include "basecontainercontrol.hxx"
29 
30 //____________________________________________________________________________________________________________
31 //  includes of other projects
32 //____________________________________________________________________________________________________________
33 #include <cppuhelper/typeprovider.hxx>
34 
35 //____________________________________________________________________________________________________________
36 //  includes of my own project
37 //____________________________________________________________________________________________________________
38 
39 //____________________________________________________________________________________________________________
40 //  namespaces
41 //____________________________________________________________________________________________________________
42 
43 using namespace ::cppu                      ;
44 using namespace ::osl                       ;
45 using namespace ::rtl                       ;
46 using namespace ::com::sun::star::uno       ;
47 using namespace ::com::sun::star::lang      ;
48 using namespace ::com::sun::star::awt       ;
49 using namespace ::com::sun::star::container ;
50 
51 namespace unocontrols{
52 
53 //____________________________________________________________________________________________________________
54 //  construct/destruct
55 //____________________________________________________________________________________________________________
56 
BaseContainerControl(const Reference<XMultiServiceFactory> & xFactory)57 BaseContainerControl::BaseContainerControl( const Reference< XMultiServiceFactory >& xFactory )
58     : BaseControl   ( xFactory  )
59     , m_aListeners  ( m_aMutex  )
60 {
61     // initialize info list for controls
62     m_pControlInfoList = new IMPL_ControlInfoList ;
63 }
64 
~BaseContainerControl()65 BaseContainerControl::~BaseContainerControl()
66 {
67     impl_cleanMemory();
68 }
69 
70 //____________________________________________________________________________________________________________
71 //  XInterface
72 //____________________________________________________________________________________________________________
73 
queryInterface(const Type & rType)74 Any SAL_CALL BaseContainerControl::queryInterface( const Type& rType ) throw( RuntimeException )
75 {
76     // Attention:
77     //  Don't use mutex or guard in this method!!! Is a method of XInterface.
78     Any aReturn ;
79     Reference< XInterface > xDel = BaseControl::impl_getDelegator();
80     if ( xDel.is() == sal_True )
81     {
82         // If an delegator exist, forward question to his queryInterface.
83         // Delegator will ask his own queryAggregation!
84         aReturn = xDel->queryInterface( rType );
85     }
86     else
87     {
88         // If an delegator unknown, forward question to own queryAggregation.
89         aReturn = queryAggregation( rType );
90     }
91 
92     return aReturn ;
93 }
94 
95 //____________________________________________________________________________________________________________
96 //  XTypeProvider
97 //____________________________________________________________________________________________________________
98 
getTypes()99 Sequence< Type > SAL_CALL BaseContainerControl::getTypes() throw( RuntimeException )
100 {
101     // Optimize this method !
102     // We initialize a static variable only one time. And we don't must use a mutex at every call!
103     // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
104     static OTypeCollection* pTypeCollection = NULL ;
105 
106     if ( pTypeCollection == NULL )
107     {
108         // Ready for multithreading; get global mutex for first call of this method only! see before
109         MutexGuard aGuard( Mutex::getGlobalMutex() );
110 
111         // Control these pointer again ... it can be, that another instance will be faster then these!
112         if ( pTypeCollection == NULL )
113         {
114             // Create a static typecollection ...
115             static OTypeCollection aTypeCollection  (   ::getCppuType(( const Reference< XControlModel      >*)NULL )   ,
116                                                         ::getCppuType(( const Reference< XControlContainer  >*)NULL )   ,
117                                                         BaseControl::getTypes()
118                                                     );
119             // ... and set his address to static pointer!
120             pTypeCollection = &aTypeCollection ;
121         }
122     }
123 
124     return pTypeCollection->getTypes();
125 }
126 
127 //____________________________________________________________________________________________________________
128 //  XAggregation
129 //____________________________________________________________________________________________________________
130 
queryAggregation(const Type & aType)131 Any SAL_CALL BaseContainerControl::queryAggregation( const Type& aType ) throw( RuntimeException )
132 {
133     // Ask for my own supported interfaces ...
134     // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
135     Any aReturn ( ::cppu::queryInterface(   aType                                       ,
136                                             static_cast< XControlModel*     > ( this )  ,
137                                             static_cast< XControlContainer* > ( this )
138                                         )
139                 );
140 
141     // If searched interface supported by this class ...
142     if ( aReturn.hasValue() == sal_True )
143     {
144         // ... return this information.
145         return aReturn ;
146     }
147     else
148     {
149         // Else; ... ask baseclass for interfaces!
150         return BaseControl::queryAggregation( aType );
151     }
152 }
153 
154 //____________________________________________________________________________________________________________
155 //  XControl
156 //____________________________________________________________________________________________________________
157 
createPeer(const Reference<XToolkit> & xToolkit,const Reference<XWindowPeer> & xParent)158 void SAL_CALL BaseContainerControl::createPeer( const   Reference< XToolkit >&      xToolkit    ,
159                                                 const   Reference< XWindowPeer >&   xParent     ) throw( RuntimeException )
160 {
161     if ( getPeer().is() == sal_False )
162     {
163         // create own peer
164         BaseControl::createPeer( xToolkit, xParent );
165 
166         // create peers at all childs
167         Sequence< Reference< XControl > >   seqControlList  = getControls();
168         sal_uInt32                          nControls       = seqControlList.getLength();
169 
170         for ( sal_uInt32 n=0; n<nControls; n++ )
171         {
172             seqControlList.getArray()[n]->createPeer( xToolkit, getPeer() );
173         }
174 
175         // activate new tab order
176         impl_activateTabControllers();
177 
178 /*
179         Reference< XVclContainerPeer > xC;
180         mxPeer->queryInterface( ::getCppuType((const Reference< XVclContainerPeer >*)0), xC );
181         xC->enableDialogControl( sal_True );
182 */
183 
184     }
185 }
186 
187 //____________________________________________________________________________________________________________
188 //  XControl
189 //____________________________________________________________________________________________________________
190 
setModel(const Reference<XControlModel> &)191 sal_Bool SAL_CALL BaseContainerControl::setModel( const Reference< XControlModel >& ) throw( RuntimeException )
192 {
193     // This object has NO model.
194     return sal_False ;
195 }
196 
197 //____________________________________________________________________________________________________________
198 //  XControl
199 //____________________________________________________________________________________________________________
200 
getModel()201 Reference< XControlModel > SAL_CALL BaseContainerControl::getModel() throw( RuntimeException )
202 {
203     // This object has NO model.
204     // return (XControlModel*)this ;
205     return Reference< XControlModel >();
206 }
207 
208 //____________________________________________________________________________________________________________
209 //  XComponent
210 //____________________________________________________________________________________________________________
211 
dispose()212 void SAL_CALL BaseContainerControl::dispose() throw( RuntimeException )
213 {
214     // Zuerst der Welt mitteilen, da� der Container wegfliegt. Dieses ist um einiges
215     // schneller wenn die Welt sowohl an den Controls als auch am Container horcht
216 
217     // Ready for multithreading
218     MutexGuard aGuard( m_aMutex );
219 
220     // remove listeners
221     EventObject aObject ;
222 
223     aObject.Source = Reference< XComponent > ( (XControlContainer*)this, UNO_QUERY );
224     m_aListeners.disposeAndClear( aObject );
225 
226     // remove controls
227     Sequence< Reference< XControl > >   seqCtrls    =   getControls();
228     Reference< XControl > *             pCtrls      =   seqCtrls.getArray();
229     sal_uInt32                          nCtrls      =   seqCtrls.getLength();
230     sal_uInt32                          nMaxCount   =   m_pControlInfoList->Count();
231     sal_uInt32                          nCount      =   0;
232 
233     for ( nCount = 0; nCount < nMaxCount; ++nCount )
234     {
235         delete m_pControlInfoList->GetObject( 0 );
236     }
237     m_pControlInfoList->Clear();
238 
239 
240     for ( nCount = 0; nCount < nCtrls; ++nCount )
241     {
242         pCtrls [ nCount ] -> removeEventListener    ( static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ) ) ;
243         pCtrls [ nCount ] -> dispose                (       ) ;
244     }
245 
246     // call baseclass
247     BaseControl::dispose();
248 }
249 
250 //____________________________________________________________________________________________________________
251 //  XEventListener
252 //____________________________________________________________________________________________________________
253 
disposing(const EventObject & rEvent)254 void SAL_CALL BaseContainerControl::disposing( const EventObject& rEvent ) throw( RuntimeException )
255 {
256     Reference< XControl > xControl( rEvent.Source, UNO_QUERY );
257 
258     // "removeControl" remove only, when control is an active control
259     removeControl( xControl );
260 }
261 
262 //____________________________________________________________________________________________________________
263 //  XControlContainer
264 //____________________________________________________________________________________________________________
265 
addControl(const OUString & rName,const Reference<XControl> & rControl)266 void SAL_CALL BaseContainerControl::addControl ( const OUString& rName, const Reference< XControl > & rControl ) throw( RuntimeException )
267 {
268     if ( !rControl.is () )
269         return;
270 
271     // take memory for new item
272     IMPL_ControlInfo* pNewControl = new IMPL_ControlInfo ;
273 
274     if (pNewControl!=(IMPL_ControlInfo*)0)
275     {
276         // Ready for multithreading
277         MutexGuard aGuard (m_aMutex) ;
278 
279         // set control
280         pNewControl->sName      = rName     ;
281         pNewControl->xControl   = rControl  ;
282 
283         // and insert in list
284         m_pControlInfoList->Insert ( pNewControl, LIST_APPEND ) ;
285 
286         // initialize new control
287         pNewControl->xControl->setContext       ( (OWeakObject*)this    ) ;
288         pNewControl->xControl->addEventListener ( static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ) ) ;
289 
290         // when container has a peer ...
291         if (getPeer().is())
292         {
293             // .. then create a peer on child
294             pNewControl->xControl->createPeer ( getPeer()->getToolkit(), getPeer() ) ;
295             impl_activateTabControllers () ;
296         }
297 
298         // Send message to all listener
299         OInterfaceContainerHelper* pInterfaceContainer = m_aListeners.getContainer( ::getCppuType((const Reference< XContainerListener >*)0) ) ;
300 
301         if (pInterfaceContainer)
302         {
303             // Build event
304             ContainerEvent  aEvent ;
305 
306             aEvent.Source   = *this     ;
307             aEvent.Element <<= rControl ;
308 
309             // Get all listener
310             OInterfaceIteratorHelper    aIterator (*pInterfaceContainer) ;
311 
312             // Send event
313             while ( aIterator.hasMoreElements() )
314             {
315                 ((XContainerListener*)aIterator.next())->elementInserted (aEvent) ;
316             }
317         }
318     }
319 }
320 
321 //____________________________________________________________________________________________________________
322 //  XControlContainer
323 //____________________________________________________________________________________________________________
324 
addContainerListener(const Reference<XContainerListener> & rListener)325 void SAL_CALL BaseContainerControl::addContainerListener ( const Reference< XContainerListener > & rListener ) throw( RuntimeException )
326 {
327     // Ready for multithreading
328     MutexGuard aGuard ( m_aMutex ) ;
329 
330     m_aListeners.addInterface ( ::getCppuType((const Reference< XContainerListener >*)0), rListener ) ;
331 }
332 
333 //____________________________________________________________________________________________________________
334 //  XControlContainer
335 //____________________________________________________________________________________________________________
336 
removeControl(const Reference<XControl> & rControl)337 void SAL_CALL BaseContainerControl::removeControl ( const Reference< XControl > & rControl ) throw( RuntimeException )
338 {
339     if ( rControl.is() )
340     {
341         // Ready for multithreading
342         MutexGuard aGuard (m_aMutex) ;
343 
344         sal_uInt32 nControls = m_pControlInfoList->Count () ;
345 
346         for ( sal_uInt32 n=0; n<nControls; n++ )
347         {
348             // Search for right control
349             IMPL_ControlInfo* pControl = m_pControlInfoList->GetObject (n) ;
350             if ( rControl == pControl->xControl )
351             {
352                 //.is it found ... remove listener from control
353                 pControl->xControl->removeEventListener (static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) )) ;
354                 pControl->xControl->setContext          ( Reference< XInterface >  ()   ) ;
355 
356                 // ... free memory
357                 delete pControl ;
358                 m_pControlInfoList->Remove (n) ;
359 
360                 // Send message to all other listener
361                 OInterfaceContainerHelper * pInterfaceContainer = m_aListeners.getContainer( ::getCppuType((const Reference< XContainerListener >*)0) ) ;
362 
363                 if (pInterfaceContainer)
364                 {
365                     ContainerEvent  aEvent ;
366 
367                     aEvent.Source    = *this    ;
368                     aEvent.Element <<= rControl ;
369 
370                     OInterfaceIteratorHelper    aIterator (*pInterfaceContainer) ;
371 
372                     while ( aIterator.hasMoreElements() )
373                     {
374                         ((XContainerListener*)aIterator.next())->elementRemoved (aEvent) ;
375                     }
376                 }
377                 // Break "for" !
378                 break ;
379             }
380         }
381     }
382 }
383 
384 //____________________________________________________________________________________________________________
385 //  XControlContainer
386 //____________________________________________________________________________________________________________
387 
removeContainerListener(const Reference<XContainerListener> & rListener)388 void SAL_CALL BaseContainerControl::removeContainerListener ( const Reference< XContainerListener > & rListener ) throw( RuntimeException )
389 {
390     // Ready for multithreading
391     MutexGuard aGuard ( m_aMutex ) ;
392 
393     m_aListeners.removeInterface ( ::getCppuType((const Reference< XContainerListener >*)0), rListener ) ;
394 }
395 
396 //____________________________________________________________________________________________________________
397 //  XControlContainer
398 //____________________________________________________________________________________________________________
399 
setStatusText(const OUString & rStatusText)400 void SAL_CALL BaseContainerControl::setStatusText ( const OUString& rStatusText ) throw( RuntimeException )
401 {
402     // go down to each parent
403     Reference< XControlContainer >  xContainer ( getContext(), UNO_QUERY ) ;
404 
405     if ( xContainer.is () )
406     {
407         xContainer->setStatusText ( rStatusText ) ;
408     }
409 }
410 
411 //____________________________________________________________________________________________________________
412 //  XControlContainer
413 //____________________________________________________________________________________________________________
414 
getControl(const OUString & rName)415 Reference< XControl > SAL_CALL BaseContainerControl::getControl ( const OUString& rName ) throw( RuntimeException )
416 {
417     // Ready for multithreading
418     MutexGuard  aGuard ( Mutex::getGlobalMutex() ) ;
419 
420     Reference< XControl >  xRetControl  =   Reference< XControl >       () ;
421     sal_uInt32              nControls   =   m_pControlInfoList->Count   () ;
422 
423     // Search for right control
424     for( sal_uInt32 nCount = 0; nCount < nControls; ++nCount )
425     {
426         IMPL_ControlInfo* pSearchControl = m_pControlInfoList->GetObject ( nCount ) ;
427 
428         if ( pSearchControl->sName == rName )
429         {
430             // We have found it ...
431             // Break operation and return.
432             return pSearchControl->xControl ;
433         }
434     }
435 
436     // We have not found it ... return NULL.
437     return Reference< XControl >  () ;
438 }
439 
440 //____________________________________________________________________________________________________________
441 //  XControlContainer
442 //____________________________________________________________________________________________________________
443 
getControls()444 Sequence< Reference< XControl > > SAL_CALL BaseContainerControl::getControls () throw( RuntimeException )
445 {
446     // Ready for multithreading
447     MutexGuard  aGuard ( Mutex::getGlobalMutex() ) ;
448 
449     sal_uInt32                          nControls       = m_pControlInfoList->Count ()  ;
450     Sequence< Reference< XControl > >   aDescriptor     ( nControls )                   ;
451     Reference< XControl > *             pDestination    = aDescriptor.getArray ()       ;
452     sal_uInt32                          nCount          = 0                             ;
453 
454     // Copy controls to sequence
455     for( nCount = 0; nCount < nControls; ++nCount )
456     {
457         IMPL_ControlInfo* pCopyControl = m_pControlInfoList->GetObject ( nCount ) ;
458         pDestination [ nCount ] = pCopyControl->xControl ;
459     }
460 
461     // Return sequence
462     return aDescriptor ;
463 }
464 
465 //____________________________________________________________________________________________________________
466 //  XUnoControlContainer
467 //____________________________________________________________________________________________________________
468 
addTabController(const Reference<XTabController> & rTabController)469 void SAL_CALL BaseContainerControl::addTabController ( const Reference< XTabController > & rTabController ) throw( RuntimeException )
470 {
471     // Ready for multithreading
472     MutexGuard aGuard (m_aMutex) ;
473 
474     sal_uInt32                                  nOldCount   = m_xTabControllerList.getLength () ;
475     Sequence< Reference< XTabController >  >    aNewList    ( nOldCount + 1 )                   ;
476     sal_uInt32                                  nCount      = 0                                 ;
477 
478     // Copy old elements of sequence to new list.
479     for ( nCount = 0; nCount < nOldCount; ++nCount )
480     {
481         aNewList.getArray () [nCount] = m_xTabControllerList.getConstArray () [nCount] ;
482     }
483 
484     // Add new controller
485     aNewList.getArray () [nOldCount] = rTabController ;
486 
487     // change old and new list
488     m_xTabControllerList = aNewList ;
489 }
490 
491 //____________________________________________________________________________________________________________
492 //  XUnoControlContainer
493 //____________________________________________________________________________________________________________
494 
removeTabController(const Reference<XTabController> & rTabController)495 void SAL_CALL BaseContainerControl::removeTabController ( const Reference< XTabController > & rTabController ) throw( RuntimeException )
496 {
497     // Ready for multithreading
498     MutexGuard aGuard (m_aMutex) ;
499 
500     sal_uInt32  nMaxCount   = m_xTabControllerList.getLength () ;
501     sal_uInt32  nCount      = 0                                 ;
502 
503     // Search right tabcontroller ...
504     for ( nCount = 0; nCount < nMaxCount; ++nCount )
505     {
506         if ( m_xTabControllerList.getConstArray () [nCount] == rTabController )
507         {
508             // ... if is it found ... remove it from list.
509             m_xTabControllerList.getArray()[ nCount ] = Reference< XTabController >() ;
510             break ;
511         }
512     }
513 }
514 
515 //____________________________________________________________________________________________________________
516 //  XUnoControlContainer
517 //____________________________________________________________________________________________________________
518 
setTabControllers(const Sequence<Reference<XTabController>> & rTabControllers)519 void SAL_CALL BaseContainerControl::setTabControllers ( const Sequence< Reference< XTabController >  >& rTabControllers ) throw( RuntimeException )
520 {
521     // Ready for multithreading
522     MutexGuard aGuard (m_aMutex) ;
523 
524     m_xTabControllerList = rTabControllers ;
525 }
526 
getTabControllers()527 Sequence<Reference< XTabController > > SAL_CALL BaseContainerControl::getTabControllers () throw( RuntimeException )
528 {
529     // Ready for multithreading
530     MutexGuard aGuard (m_aMutex) ;
531 
532     return m_xTabControllerList ;
533 }
534 
535 //____________________________________________________________________________________________________________
536 //  XWindow
537 //____________________________________________________________________________________________________________
538 
setVisible(sal_Bool bVisible)539 void SAL_CALL BaseContainerControl::setVisible ( sal_Bool bVisible ) throw( RuntimeException )
540 {
541     // override baseclass definition
542     BaseControl::setVisible ( bVisible ) ;
543 
544     // is it a top window ?
545     if ( !getContext().is() && bVisible )
546     {
547         // then show it automaticly
548         createPeer ( Reference< XToolkit > (), Reference< XWindowPeer > () ) ;
549     }
550 }
551 
552 //____________________________________________________________________________________________________________
553 //  protected method
554 //____________________________________________________________________________________________________________
555 
impl_getWindowDescriptor(const Reference<XWindowPeer> & rParentPeer)556 WindowDescriptor* BaseContainerControl::impl_getWindowDescriptor ( const Reference< XWindowPeer > & rParentPeer )
557 {
558     // - used from "createPeer()" to set the values of an WindowDescriptor !!!
559     // - if you will change the descriptor-values, you must override thid virtuell function
560     // - the caller must release the memory for this dynamical descriptor !!!
561 
562     WindowDescriptor    *   aDescriptor = new WindowDescriptor ;
563 
564     aDescriptor->Type               = WindowClass_CONTAINER                             ;
565     aDescriptor->WindowServiceName  = OUString(RTL_CONSTASCII_USTRINGPARAM("window"))   ;
566     aDescriptor->ParentIndex        = -1                                                ;
567     aDescriptor->Parent             = rParentPeer                                       ;
568     aDescriptor->Bounds             = getPosSize ()                                     ;
569     aDescriptor->WindowAttributes   = 0                                                 ;
570 
571     return aDescriptor ;
572 }
573 
574 //____________________________________________________________________________________________________________
575 //  protected method
576 //____________________________________________________________________________________________________________
577 
impl_paint(sal_Int32,sal_Int32,const Reference<XGraphics> &)578 void BaseContainerControl::impl_paint ( sal_Int32 /*nX*/, sal_Int32 /*nY*/, const Reference< XGraphics > & /*rGraphics*/ )
579 {
580 /*
581     if (rGraphics.is())
582     {
583         for ( sal_uInt32 n=m_pControlInfoList->Count(); n; )
584         {
585             ControlInfo* pSearchControl = m_pControlInfoList->GetObject (--n) ;
586 
587             pSearchControl->xControl->paint ( nX, nY, rGraphics ) ;
588         }
589     }
590 */
591 }
592 
593 //____________________________________________________________________________________________________________
594 //  private method
595 //____________________________________________________________________________________________________________
596 
impl_activateTabControllers()597 void BaseContainerControl::impl_activateTabControllers ()
598 {
599     // Ready for multithreading
600     MutexGuard aGuard (m_aMutex) ;
601 
602     sal_uInt32  nMaxCount   =   m_xTabControllerList.getLength ()   ;
603     sal_uInt32  nCount      =   0                                   ;
604 
605     for ( nCount = 0; nCount < nMaxCount; ++nCount )
606     {
607         m_xTabControllerList.getArray () [nCount]->setContainer     ( this  ) ;
608         m_xTabControllerList.getArray () [nCount]->activateTabOrder (       ) ;
609     }
610 }
611 
612 //____________________________________________________________________________________________________________
613 //  private method
614 //____________________________________________________________________________________________________________
615 
impl_cleanMemory()616 void BaseContainerControl::impl_cleanMemory ()
617 {
618     // Get count of listitems.
619     sal_uInt32  nMaxCount   =   m_pControlInfoList->Count ()    ;
620     sal_uInt32  nCount      =   0                               ;
621 
622     // Delete all items.
623     for ( nCount = 0; nCount < nMaxCount; ++nCount )
624     {
625         // Delete everytime first element of list!
626         // We count from 0 to MAX, where "MAX=count of items" BEFORE we delete some elements!
627         // If we use "GetObject ( nCount )" ... it can be, that we have an index greater then count of current elements!
628 
629         IMPL_ControlInfo* pSearchControl = m_pControlInfoList->GetObject ( 0 ) ;
630         delete pSearchControl ;
631     }
632 
633     // Delete list himself.
634     m_pControlInfoList->Clear () ;
635     delete m_pControlInfoList ;
636 }
637 
638 } // namespace unocontrols
639