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