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