xref: /trunk/main/toolkit/source/controls/unocontrolcontainer.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_toolkit.hxx"
30 
31 
32 #include <com/sun/star/awt/XVclContainerPeer.hpp>
33 #include <com/sun/star/beans/XPropertyChangeListener.hpp>
34 
35 #include <cppuhelper/typeprovider.hxx>
36 #include <cppuhelper/implbase1.hxx>
37 #include <rtl/memory.h>
38 #include <rtl/uuid.h>
39 
40 #include <toolkit/controls/unocontrolcontainer.hxx>
41 #include <toolkit/helper/property.hxx>
42 #include <toolkit/helper/servicenames.hxx>
43 #include <comphelper/sequence.hxx>
44 
45 #include <tools/debug.hxx>
46 #include <tools/list.hxx>
47 #include <vcl/svapp.hxx>
48 #include <vcl/window.hxx>
49 
50 #include <limits>
51 #include <map>
52 #include <boost/shared_ptr.hpp>
53 
54 using namespace ::com::sun::star;
55 
56 extern WorkWindow* lcl_GetDefaultWindow();
57 
58 //  ----------------------------------------------------
59 //  class UnoControlHolder
60 //  ----------------------------------------------------
61 struct UnoControlHolder
62 {
63     uno::Reference< awt::XControl > mxControl;
64     ::rtl::OUString                 msName;
65 
66 public:
67     UnoControlHolder( const ::rtl::OUString& rName, const uno::Reference< awt::XControl > & rControl )
68     :   mxControl( rControl ),
69         msName( rName )
70     {
71     }
72 
73     inline const ::rtl::OUString&                   getName() const { return msName; }
74     inline const uno::Reference< awt::XControl >&   getControl() const { return mxControl; }
75 };
76 
77 //DECLARE_LIST( UnoControlHolderList, UnoControlHolder* );
78 
79 class UnoControlHolderList
80 {
81 public:
82     typedef sal_Int32                                       ControlIdentifier;
83 private:
84     typedef ::boost::shared_ptr< UnoControlHolder >         ControlInfo;
85     typedef ::std::map< ControlIdentifier, ControlInfo >    ControlMap;
86 
87 private:
88     ControlMap  maControls;
89 
90 public:
91     UnoControlHolderList();
92     ~UnoControlHolderList();
93 
94     /** adds a control with the given name to the list
95         @param _rxControl
96             the control to add. Must not be <NULL/>
97         @param _pBName
98             the name of the control, or <NULL/> if an automatic name should be generated
99         @return
100             the identifier of the newly added control
101     */
102     ControlIdentifier   addControl( const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pName );
103 
104     /** returns the number of controls in the list
105     */
106     inline size_t       size() const { return maControls.size(); }
107 
108     /** determines whether or not the list is empty
109     */
110     inline bool         empty() const { return maControls.empty(); }
111 
112     /** retrieves all controls currently in the list
113         @return
114             the number of controls in the list
115     */
116     size_t  getControls( uno::Sequence< uno::Reference< awt::XControl > >& _out_rControls ) const;
117 
118     /** retrieves all identifiers of all controls currently in the list
119         @return
120             the number of controls in the list
121     */
122     size_t  getIdentifiers( uno::Sequence< sal_Int32 >& _out_rIdentifiers ) const;
123 
124     /** returns the first control which is registered under the given name
125     */
126     uno::Reference< awt::XControl >
127             getControlForName( const ::rtl::OUString& _rName ) const;
128 
129     /** returns the identifier which a control is registered for, or -1 if the control
130             isn't registered
131     */
132     ControlIdentifier
133             getControlIdentifier( const uno::Reference< awt::XControl >& _rxControl );
134 
135     /** retrieves the control for a given id
136         @param _nIdentifier
137             the identifier for the control
138         @param _out_rxControl
139             takes the XControl upon successful return
140         @return
141             <TRUE/> if and only if a control with the given id is part of the list
142     */
143     bool    getControlForIdentifier( ControlIdentifier _nIdentifier, uno::Reference< awt::XControl >& _out_rxControl ) const;
144 
145     /** removes a control from the list, given by id
146         @param _nId
147             The identifier of the control to remove.
148     */
149     void    removeControlById( ControlIdentifier _nId );
150 
151     /** replaces a control from the list with another one
152         @param _nId
153             The identifier of the control to replace
154         @param _rxNewControl
155             the new control to put into the list
156     */
157     void    replaceControlById( ControlIdentifier _nId, const uno::Reference< awt::XControl >& _rxNewControl );
158 
159 private:
160     /** adds a control
161     @param _rxControl
162         the control to add to the container
163     @param _pName
164         pointer to the name of the control. Might be <NULL/>, in this case, a name is generated.
165     @return
166         the identifier of the newly inserted control
167     */
168     ControlIdentifier impl_addControl(
169         const uno::Reference< awt::XControl >& _rxControl,
170         const ::rtl::OUString*  _pName
171     );
172 
173     /** finds a free identifier
174         @throw uno::RuntimeException
175             if no free identifier can be found
176     */
177     ControlIdentifier impl_getFreeIdentifier_throw();
178 
179     /** finds a free name
180         @throw uno::RuntimeException
181             if no free name can be found
182     */
183     ::rtl::OUString impl_getFreeName_throw();
184 };
185 
186 //------------------------------------------------------------------------
187 UnoControlHolderList::UnoControlHolderList()
188 {
189 }
190 
191 //------------------------------------------------------------------------
192 UnoControlHolderList::~UnoControlHolderList()
193 {
194 }
195 
196 //------------------------------------------------------------------------
197 UnoControlHolderList::ControlIdentifier UnoControlHolderList::addControl( const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pName )
198 {
199     return impl_addControl( _rxControl, _pName );
200 }
201 
202 //------------------------------------------------------------------------
203 size_t UnoControlHolderList::getControls( uno::Sequence< uno::Reference< awt::XControl > >& _out_rControls ) const
204 {
205     _out_rControls.realloc( maControls.size() );
206     uno::Reference< awt::XControl >* pControls = _out_rControls.getArray();
207     for (   ControlMap::const_iterator loop = maControls.begin();
208             loop != maControls.end();
209             ++loop, ++pControls
210         )
211         *pControls = loop->second->getControl();
212     return maControls.size();
213 }
214 
215 //------------------------------------------------------------------------
216 size_t UnoControlHolderList::getIdentifiers( uno::Sequence< sal_Int32 >& _out_rIdentifiers ) const
217 {
218     _out_rIdentifiers.realloc( maControls.size() );
219     sal_Int32* pIndentifiers = _out_rIdentifiers.getArray();
220     for (   ControlMap::const_iterator loop = maControls.begin();
221             loop != maControls.end();
222             ++loop, ++pIndentifiers
223         )
224         *pIndentifiers = loop->first;
225     return maControls.size();
226 }
227 
228 //------------------------------------------------------------------------
229 uno::Reference< awt::XControl > UnoControlHolderList::getControlForName( const ::rtl::OUString& _rName ) const
230 {
231     for (   ControlMap::const_iterator loop = maControls.begin();
232             loop != maControls.end();
233             ++loop
234         )
235         if ( loop->second->getName() == _rName )
236             return loop->second->getControl();
237     return uno::Reference< awt::XControl >();
238 }
239 
240 //------------------------------------------------------------------------
241 UnoControlHolderList::ControlIdentifier UnoControlHolderList::getControlIdentifier( const uno::Reference< awt::XControl >& _rxControl )
242 {
243     for (   ControlMap::iterator loop = maControls.begin();
244             loop != maControls.end();
245             ++loop
246         )
247     {
248         if ( loop->second->getControl().get() == _rxControl.get() )
249             return loop->first;
250     }
251     return -1;
252 }
253 
254 //------------------------------------------------------------------------
255 bool UnoControlHolderList::getControlForIdentifier( UnoControlHolderList::ControlIdentifier _nIdentifier, uno::Reference< awt::XControl >& _out_rxControl ) const
256 {
257     ControlMap::const_iterator pos = maControls.find( _nIdentifier );
258     if ( pos == maControls.end() )
259         return false;
260     _out_rxControl = pos->second->getControl();
261     return true;
262 }
263 
264 //------------------------------------------------------------------------
265 void UnoControlHolderList::removeControlById( UnoControlHolderList::ControlIdentifier _nId )
266 {
267     ControlMap::iterator pos = maControls.find( _nId );
268     DBG_ASSERT( pos != maControls.end(), "UnoControlHolderList::removeControlById: invalid id!" );
269     if ( pos == maControls.end() )
270         return;
271 
272     maControls.erase( pos );
273 }
274 
275 //------------------------------------------------------------------------
276 void UnoControlHolderList::replaceControlById( ControlIdentifier _nId, const uno::Reference< awt::XControl >& _rxNewControl )
277 {
278     DBG_ASSERT( _rxNewControl.is(), "UnoControlHolderList::replaceControlById: invalid new control!" );
279 
280     ControlMap::iterator pos = maControls.find( _nId );
281     DBG_ASSERT( pos != maControls.end(), "UnoControlHolderList::replaceControlById: invalid id!" );
282     if ( pos == maControls.end() )
283         return;
284 
285     pos->second.reset( new UnoControlHolder( pos->second->getName(), _rxNewControl ) );
286 }
287 
288 //------------------------------------------------------------------------
289 UnoControlHolderList::ControlIdentifier UnoControlHolderList::impl_addControl( const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pName )
290 {
291     DBG_ASSERT( _rxControl.is(), "UnoControlHolderList::impl_addControl: invalid control!" );
292 
293     ::rtl::OUString sName = _pName ? *_pName : impl_getFreeName_throw();
294     sal_Int32 nId = impl_getFreeIdentifier_throw();
295 
296     maControls[ nId ] = ControlInfo( new UnoControlHolder( sName, _rxControl ) );
297     return nId;
298 }
299 
300 //------------------------------------------------------------------------
301 UnoControlHolderList::ControlIdentifier UnoControlHolderList::impl_getFreeIdentifier_throw()
302 {
303     for ( ControlIdentifier candidateId = 0; candidateId < ::std::numeric_limits< ControlIdentifier >::max(); ++candidateId )
304     {
305         ControlMap::const_iterator existent = maControls.find( candidateId );
306         if ( existent == maControls.end() )
307             return candidateId;
308     }
309     throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "out of identifiers" ) ), NULL );
310 }
311 
312 //------------------------------------------------------------------------
313 ::rtl::OUString UnoControlHolderList::impl_getFreeName_throw()
314 {
315     ::rtl::OUString name( RTL_CONSTASCII_USTRINGPARAM( "control_" ) );
316     for ( ControlIdentifier candidateId = 0; candidateId < ::std::numeric_limits< ControlIdentifier >::max(); ++candidateId )
317     {
318         ::rtl::OUString candidateName( name + ::rtl::OUString::valueOf( candidateId ) );
319         ControlMap::const_iterator loop = maControls.begin();
320         for ( ; loop != maControls.end(); ++loop )
321         {
322             if ( loop->second->getName() == candidateName )
323                 break;
324         }
325         if ( loop == maControls.end() )
326             return candidateName;
327     }
328     throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "out of identifiers" ) ), NULL );
329 }
330 //  ----------------------------------------------------
331 //  Function to set the controls' visibility according
332 //  to the dialog's "Step" property
333 //  ----------------------------------------------------
334 void implUpdateVisibility
335 (
336     sal_Int32 nDialogStep,
337     uno::Reference< awt::XControlContainer > xControlContainer
338 )
339 {
340     uno::Sequence< uno::Reference< awt::XControl > >
341         aCtrls = xControlContainer->getControls();
342     const uno::Reference< awt::XControl >* pCtrls = aCtrls.getConstArray();
343     sal_uInt32 nCtrls = aCtrls.getLength();
344     sal_Bool bCompleteVisible = (nDialogStep == 0);
345     for( sal_uInt32 n = 0; n < nCtrls; n++ )
346     {
347         uno::Reference< awt::XControl > xControl = pCtrls[ n ];
348 
349         sal_Bool bVisible = bCompleteVisible;
350         if( !bVisible )
351         {
352             uno::Reference< awt::XControlModel > xModel( xControl->getModel() );
353             uno::Reference< beans::XPropertySet > xPSet
354                 ( xModel, uno::UNO_QUERY );
355             uno::Reference< beans::XPropertySetInfo >
356                 xInfo = xPSet->getPropertySetInfo();
357             ::rtl::OUString aPropName(RTL_CONSTASCII_USTRINGPARAM( "Step" ) );
358             sal_Int32 nControlStep = 0;
359             if ( xInfo->hasPropertyByName( aPropName ) )
360             {
361                 uno::Any aVal = xPSet->getPropertyValue( aPropName );
362                 aVal >>= nControlStep;
363             }
364             bVisible = (nControlStep == 0) || (nControlStep == nDialogStep);
365         }
366 
367         uno::Reference< awt::XWindow> xWindow
368             ( xControl, uno::UNO_QUERY );
369         if( xWindow.is() )
370             xWindow->setVisible( bVisible );
371     }
372 }
373 
374 
375 //  ----------------------------------------------------
376 //  class DialogStepChangedListener
377 //  ----------------------------------------------------
378 typedef ::cppu::WeakImplHelper1< beans::XPropertyChangeListener > PropertyChangeListenerHelper;
379 
380 class DialogStepChangedListener: public PropertyChangeListenerHelper
381 {
382 private:
383     uno::Reference< awt::XControlContainer > mxControlContainer;
384 
385 public:
386     DialogStepChangedListener( uno::Reference< awt::XControlContainer > xControlContainer )
387         : mxControlContainer( xControlContainer ) {}
388 
389     // XEventListener
390     virtual void SAL_CALL disposing( const  lang::EventObject& Source ) throw( uno::RuntimeException);
391 
392     // XPropertyChangeListener
393     virtual void SAL_CALL propertyChange( const  beans::PropertyChangeEvent& evt ) throw( uno::RuntimeException);
394 
395 };
396 
397 void SAL_CALL DialogStepChangedListener::disposing( const  lang::EventObject& /*_rSource*/)
398     throw( uno::RuntimeException)
399 {
400     mxControlContainer.clear();
401 }
402 
403 void SAL_CALL DialogStepChangedListener::propertyChange( const  beans::PropertyChangeEvent& evt )
404     throw( uno::RuntimeException)
405 {
406     // evt.PropertyName HAS to be "Step" because we only use the listener for that
407     sal_Int32 nDialogStep = 0;
408     evt.NewValue >>= nDialogStep;
409     implUpdateVisibility( nDialogStep, mxControlContainer );
410 }
411 
412 //  ----------------------------------------------------
413 //  class UnoControlContainer
414 //  ----------------------------------------------------
415 UnoControlContainer::UnoControlContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& i_factory )
416     :UnoControlContainer_Base( i_factory )
417     ,maCListeners( *this )
418 {
419     mpControls = new UnoControlHolderList;
420 }
421 
422 UnoControlContainer::UnoControlContainer( const uno::Reference< lang::XMultiServiceFactory >& i_factory, const uno::Reference< awt::XWindowPeer >& xP )
423     :UnoControlContainer_Base( i_factory )
424     ,maCListeners( *this )
425 {
426     setPeer( xP );
427     mbDisposePeer = sal_False;
428     mpControls = new UnoControlHolderList;
429 }
430 
431 UnoControlContainer::~UnoControlContainer()
432 {
433     DELETEZ( mpControls );
434 }
435 
436 void UnoControlContainer::ImplActivateTabControllers()
437 {
438     sal_uInt32 nCount = maTabControllers.getLength();
439     for ( sal_uInt32 n = 0; n < nCount; n++ )
440     {
441         maTabControllers.getArray()[n]->setContainer( this );
442         maTabControllers.getArray()[n]->activateTabOrder();
443     }
444 }
445 
446 // lang::XComponent
447 void UnoControlContainer::dispose(  ) throw(uno::RuntimeException)
448 {
449     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
450 
451     lang::EventObject aDisposeEvent;
452     aDisposeEvent.Source = static_cast< uno::XAggregation* >( this );
453 
454     // DG: zuerst der Welt mitteilen, dass der Container wegfliegt. Dieses ist um einiges
455     // schneller wenn die Welt sowohl an den Controls als auch am Container horcht
456     maDisposeListeners.disposeAndClear( aDisposeEvent );
457     maCListeners.disposeAndClear( aDisposeEvent );
458 
459 
460     uno::Sequence< uno::Reference< awt::XControl > > aCtrls = getControls();
461     uno::Reference< awt::XControl >* pCtrls = aCtrls.getArray();
462     uno::Reference< awt::XControl >* pCtrlsEnd = pCtrls + aCtrls.getLength();
463 
464     for( ; pCtrls < pCtrlsEnd; ++pCtrls )
465     {
466         removingControl( *pCtrls );
467         // Control wegwerfen
468         (*pCtrls)->dispose();
469     }
470 
471 
472     // alle Strukturen entfernen
473     DELETEZ( mpControls );
474     mpControls = new UnoControlHolderList;
475 
476     UnoControlBase::dispose();
477 }
478 
479 // lang::XEventListener
480 void UnoControlContainer::disposing( const lang::EventObject& _rEvt ) throw(uno::RuntimeException)
481 {
482     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
483 
484     uno::Reference< awt::XControl >  xControl( _rEvt.Source, uno::UNO_QUERY );
485     if ( xControl.is() )
486         removeControl( xControl );
487 
488     UnoControlBase::disposing( _rEvt );
489 }
490 
491 // container::XContainer
492 void UnoControlContainer::addContainerListener( const uno::Reference< container::XContainerListener >& rxListener ) throw(uno::RuntimeException)
493 {
494     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
495 
496     maCListeners.addInterface( rxListener );
497 }
498 
499 void UnoControlContainer::removeContainerListener( const uno::Reference< container::XContainerListener >& rxListener ) throw(uno::RuntimeException)
500 {
501     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
502 
503     maCListeners.removeInterface( rxListener );
504 }
505 
506 
507 ::sal_Int32 SAL_CALL UnoControlContainer::insert( const uno::Any& _rElement ) throw (lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
508 {
509     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
510 
511     uno::Reference< awt::XControl > xControl;
512     if ( !( _rElement >>= xControl ) || !xControl.is() )
513         throw lang::IllegalArgumentException(
514             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Elements must support the XControl interface." ) ),
515             *this,
516             1
517         );
518 
519     return impl_addControl( xControl, NULL );
520 }
521 
522 void SAL_CALL UnoControlContainer::removeByIdentifier( ::sal_Int32 _nIdentifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
523 {
524     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
525 
526     uno::Reference< awt::XControl > xControl;
527     if ( !mpControls->getControlForIdentifier( _nIdentifier, xControl ) )
528         throw container::NoSuchElementException(
529             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "There is no element with the given identifier." ) ),
530             *this
531         );
532 
533     impl_removeControl( _nIdentifier, xControl, NULL );
534 }
535 
536 void SAL_CALL UnoControlContainer::replaceByIdentifer( ::sal_Int32 _nIdentifier, const uno::Any& _rElement ) throw (lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
537 {
538     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
539 
540     uno::Reference< awt::XControl > xExistentControl;
541     if ( !mpControls->getControlForIdentifier( _nIdentifier, xExistentControl ) )
542         throw container::NoSuchElementException(
543             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "There is no element with the given identifier." ) ),
544             *this
545         );
546 
547     uno::Reference< awt::XControl > xNewControl;
548     if ( !( _rElement >>= xNewControl ) )
549         throw lang::IllegalArgumentException(
550             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Elements must support the XControl interface." ) ),
551             *this,
552             1
553         );
554 
555     removingControl( xExistentControl );
556 
557     mpControls->replaceControlById( _nIdentifier, xNewControl );
558 
559     addingControl( xNewControl );
560 
561     impl_createControlPeerIfNecessary( xNewControl );
562 
563     if ( maCListeners.getLength() )
564     {
565         container::ContainerEvent aEvent;
566         aEvent.Source = *this;
567         aEvent.Accessor <<= _nIdentifier;
568         aEvent.Element <<= xNewControl;
569         aEvent.ReplacedElement <<= xExistentControl;
570         maCListeners.elementReplaced( aEvent );
571     }
572 }
573 
574 uno::Any SAL_CALL UnoControlContainer::getByIdentifier( ::sal_Int32 _nIdentifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
575 {
576     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
577 
578     uno::Reference< awt::XControl > xControl;
579     if ( !mpControls->getControlForIdentifier( _nIdentifier, xControl ) )
580         throw container::NoSuchElementException();
581     return uno::makeAny( xControl );
582 }
583 
584 uno::Sequence< ::sal_Int32 > SAL_CALL UnoControlContainer::getIdentifiers(  ) throw (uno::RuntimeException)
585 {
586     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
587 
588     uno::Sequence< ::sal_Int32 > aIdentifiers;
589     mpControls->getIdentifiers( aIdentifiers );
590     return aIdentifiers;
591 }
592 
593 // container::XElementAccess
594 uno::Type SAL_CALL UnoControlContainer::getElementType(  ) throw (uno::RuntimeException)
595 {
596     return awt::XControlModel::static_type();
597 }
598 
599 ::sal_Bool SAL_CALL UnoControlContainer::hasElements(  ) throw (uno::RuntimeException)
600 {
601     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
602     return !mpControls->empty();
603 }
604 
605 // awt::XControlContainer
606 void UnoControlContainer::setStatusText( const ::rtl::OUString& rStatusText ) throw(uno::RuntimeException)
607 {
608     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
609 
610     // In der Parenthierarchie nach unten gehen
611     uno::Reference< awt::XControlContainer >  xContainer( mxContext, uno::UNO_QUERY );
612     if( xContainer.is() )
613         xContainer->setStatusText( rStatusText );
614 }
615 
616 uno::Sequence< uno::Reference< awt::XControl > > UnoControlContainer::getControls(  ) throw(uno::RuntimeException)
617 {
618     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
619     uno::Sequence< uno::Reference< awt::XControl > > aControls;
620     mpControls->getControls( aControls );
621     return aControls;
622 }
623 
624 uno::Reference< awt::XControl > UnoControlContainer::getControl( const ::rtl::OUString& rName ) throw(uno::RuntimeException)
625 {
626     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
627     return mpControls->getControlForName( rName );
628 }
629 
630 void UnoControlContainer::addingControl( const uno::Reference< awt::XControl >& _rxControl )
631 {
632     if ( _rxControl.is() )
633     {
634         uno::Reference< uno::XInterface > xThis;
635         OWeakAggObject::queryInterface( ::getCppuType( static_cast< uno::Reference< uno::XInterface >* >( NULL ) ) ) >>= xThis;
636 
637         _rxControl->setContext( xThis );
638         _rxControl->addEventListener( this );
639     }
640 }
641 
642 void UnoControlContainer::impl_createControlPeerIfNecessary( const uno::Reference< awt::XControl >& _rxControl )
643 {
644     OSL_PRECOND( _rxControl.is(), "UnoControlContainer::impl_createControlPeerIfNecessary: invalid control, this will crash!" );
645 
646     // if the container already has a peer, then also create a peer for the control
647     uno::Reference< awt::XWindowPeer > xMyPeer( getPeer() );
648 
649     if( xMyPeer.is() )
650     {
651         _rxControl->createPeer( NULL, xMyPeer );
652         ImplActivateTabControllers();
653     }
654 
655 }
656 
657 sal_Int32 UnoControlContainer::impl_addControl( const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pName )
658 {
659     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
660     UnoControlHolderList::ControlIdentifier id = mpControls->addControl( _rxControl, _pName );
661 
662     addingControl( _rxControl );
663 
664     impl_createControlPeerIfNecessary( _rxControl );
665 
666     if ( maCListeners.getLength() )
667     {
668         container::ContainerEvent aEvent;
669         aEvent.Source = *this;
670         _pName ? ( aEvent.Accessor <<= *_pName ) : ( aEvent.Accessor <<= (sal_Int32)id );
671         aEvent.Element <<= _rxControl;
672         maCListeners.elementInserted( aEvent );
673     }
674 
675     return id;
676 }
677 
678 void UnoControlContainer::addControl( const ::rtl::OUString& rName, const uno::Reference< awt::XControl >& rControl ) throw(uno::RuntimeException)
679 {
680     if ( rControl.is() )
681         impl_addControl( rControl, &rName );
682 }
683 
684 void UnoControlContainer::removingControl( const uno::Reference< awt::XControl >& _rxControl )
685 {
686     if ( _rxControl.is() )
687     {
688         _rxControl->removeEventListener( this );
689         _rxControl->setContext( NULL );
690     }
691 }
692 
693 void UnoControlContainer::impl_removeControl( sal_Int32 _nId, const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pNameAccessor )
694 {
695 #ifdef DBG_UTIL
696     {
697         uno::Reference< awt::XControl > xControl;
698         bool bHas = mpControls->getControlForIdentifier( _nId, xControl );
699         DBG_ASSERT( bHas && xControl == _rxControl, "UnoControlContainer::impl_removeControl: inconsistency in the parameters!" );
700     }
701 #endif
702     removingControl( _rxControl );
703 
704     mpControls->removeControlById( _nId );
705 
706     if ( maCListeners.getLength() )
707     {
708         container::ContainerEvent aEvent;
709         aEvent.Source = *this;
710         _pNameAccessor ? ( aEvent.Accessor <<= *_pNameAccessor ) : ( aEvent.Accessor <<= _nId );
711         aEvent.Element <<= _rxControl;
712         maCListeners.elementRemoved( aEvent );
713     }
714 }
715 
716 void UnoControlContainer::removeControl( const uno::Reference< awt::XControl >& _rxControl ) throw(uno::RuntimeException)
717 {
718     if ( _rxControl.is() )
719     {
720         ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
721 
722         UnoControlHolderList::ControlIdentifier id = mpControls->getControlIdentifier( _rxControl );
723         if ( id != -1 )
724             impl_removeControl( id, _rxControl, NULL );
725     }
726 }
727 
728 
729 
730 // awt::XUnoControlContainer
731 void UnoControlContainer::setTabControllers( const uno::Sequence< uno::Reference< awt::XTabController > >& TabControllers ) throw(uno::RuntimeException)
732 {
733     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
734 
735     maTabControllers = TabControllers;
736 }
737 
738 uno::Sequence< uno::Reference< awt::XTabController > > UnoControlContainer::getTabControllers(  ) throw(uno::RuntimeException)
739 {
740     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
741 
742     return maTabControllers;
743 }
744 
745 void UnoControlContainer::addTabController( const uno::Reference< awt::XTabController >& TabController ) throw(uno::RuntimeException)
746 {
747     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
748 
749     sal_uInt32 nCount = maTabControllers.getLength();
750     maTabControllers.realloc( nCount + 1 );
751     maTabControllers[ nCount ] = TabController;
752 }
753 
754 void UnoControlContainer::removeTabController( const uno::Reference< awt::XTabController >& TabController ) throw(uno::RuntimeException)
755 {
756     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
757 
758     sal_uInt32 nCount = maTabControllers.getLength();
759     const uno::Reference< awt::XTabController >* pLoop = maTabControllers.getConstArray();
760     for ( sal_uInt32 n = 0; n < nCount; ++n, ++pLoop )
761     {
762         if( pLoop->get() == TabController.get() )
763         {
764             ::comphelper::removeElementAt( maTabControllers, n );
765             break;
766         }
767     }
768 }
769 
770 // awt::XControl
771 void UnoControlContainer::createPeer( const uno::Reference< awt::XToolkit >& rxToolkit, const uno::Reference< awt::XWindowPeer >& rParent ) throw(uno::RuntimeException)
772 {
773     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
774 
775     if( !getPeer().is() )
776     {
777         sal_Bool bVis = maComponentInfos.bVisible;
778         if( bVis )
779             UnoControl::setVisible( sal_False );
780         // eigenes Peer erzeugen
781         UnoControl::createPeer( rxToolkit, rParent );
782 
783         // alle Peers der Childs erzeugen
784         if ( !mbCreatingCompatiblePeer )
785         {
786             // Evaluate "Step" property
787             uno::Reference< awt::XControlModel > xModel( getModel() );
788             uno::Reference< beans::XPropertySet > xPSet
789                 ( xModel, uno::UNO_QUERY );
790             uno::Reference< beans::XPropertySetInfo >
791                 xInfo = xPSet->getPropertySetInfo();
792             ::rtl::OUString aPropName(RTL_CONSTASCII_USTRINGPARAM( "Step" ) );
793             if ( xInfo->hasPropertyByName( aPropName ) )
794             {
795                 ::com::sun::star::uno::Any aVal = xPSet->getPropertyValue( aPropName );
796                 sal_Int32 nDialogStep = 0;
797                 aVal >>= nDialogStep;
798                 uno::Reference< awt::XControlContainer > xContainer =
799                     SAL_STATIC_CAST( awt::XControlContainer*, this );
800                 implUpdateVisibility( nDialogStep, xContainer );
801 
802                 uno::Reference< beans::XPropertyChangeListener > xListener =
803                     SAL_STATIC_CAST( beans::XPropertyChangeListener*,
804                         new DialogStepChangedListener( xContainer ) );
805                 xPSet->addPropertyChangeListener( aPropName, xListener );
806             }
807 
808             uno::Sequence< uno::Reference< awt::XControl > > aCtrls = getControls();
809             sal_uInt32 nCtrls = aCtrls.getLength();
810             for( sal_uInt32 n = 0; n < nCtrls; n++ )
811                 aCtrls.getArray()[n]->createPeer( rxToolkit, getPeer() );
812 
813             uno::Reference< awt::XVclContainerPeer >  xC( getPeer(), uno::UNO_QUERY );
814             OSL_ENSURE(xC.is(),"Peer isn't valid. Please check!");
815 
816             xC->enableDialogControl( sal_True );
817             ImplActivateTabControllers();
818         }
819 
820         if( bVis && !isDesignMode() )
821             UnoControl::setVisible( sal_True );
822     }
823 }
824 
825 
826 // awt::XWindow
827 void UnoControlContainer::setVisible( sal_Bool bVisible ) throw(uno::RuntimeException)
828 {
829     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
830 
831     UnoControl::setVisible( bVisible );
832     if( !mxContext.is() && bVisible )
833         // Es ist ein TopWindow, also automatisch anzeigen
834         createPeer( uno::Reference< awt::XToolkit > (), uno::Reference< awt::XWindowPeer > () );
835 }
836 
837 
838 
839