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