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