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