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