Impress Remote 1.0.5, tag sdremote-1.0.5
[LibreOffice.git] / toolkit / source / controls / controlmodelcontainerbase.cxx
blobcfa436e5c58b82fee1ad75ee571db1994e0fb201
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <toolkit/controls/controlmodelcontainerbase.hxx>
22 #include <vcl/svapp.hxx>
23 #include <vcl/window.hxx>
24 #include <vcl/wall.hxx>
25 #include <osl/mutex.hxx>
26 #include <toolkit/helper/property.hxx>
27 #include <toolkit/helper/unopropertyarrayhelper.hxx>
28 #include <toolkit/controls/geometrycontrolmodel.hxx>
29 #include <toolkit/controls/unocontrols.hxx>
30 #include "toolkit/controls/formattedcontrol.hxx"
31 #include "toolkit/controls/roadmapcontrol.hxx"
32 #include "toolkit/controls/tkscrollbar.hxx"
33 #include "toolkit/controls/tabpagemodel.hxx"
34 #include <toolkit/controls/stdtabcontroller.hxx>
35 #include <com/sun/star/awt/PosSize.hpp>
36 #include <com/sun/star/awt/WindowAttribute.hpp>
37 #include <com/sun/star/resource/XStringResourceResolver.hpp>
38 #include <com/sun/star/graphic/XGraphicProvider.hpp>
39 #include <com/sun/star/lang/XInitialization.hpp>
40 #include <cppuhelper/typeprovider.hxx>
41 #include <tools/debug.hxx>
42 #include <tools/diagnose_ex.h>
43 #include <comphelper/processfactory.hxx>
44 #include <vcl/svapp.hxx>
45 #include <vcl/outdev.hxx>
46 #include <comphelper/types.hxx>
48 #include <comphelper/componentcontext.hxx>
49 #include <toolkit/helper/vclunohelper.hxx>
50 #include <toolkit/helper/tkresmgr.hxx>
51 #include <unotools/ucbstreamhelper.hxx>
52 #include <vcl/graph.hxx>
53 #include <vcl/image.hxx>
55 #include "tree/treecontrol.hxx"
56 #include "grid/gridcontrol.hxx"
57 #include <toolkit/controls/tabpagecontainer.hxx>
59 #include <boost/bind.hpp>
61 #include <map>
62 #include <algorithm>
63 #include <functional>
64 #include "tools/urlobj.hxx"
65 #include "osl/file.hxx"
66 #include "toolkit/controls/dialogcontrol.hxx"
68 using namespace ::com::sun::star;
69 using namespace ::com::sun::star::uno;
70 using namespace ::com::sun::star::awt;
71 using namespace ::com::sun::star::lang;
72 using namespace ::com::sun::star::container;
73 using namespace ::com::sun::star::beans;
74 using namespace ::com::sun::star::util;
75 using namespace toolkit;
77 #define PROPERTY_RESOURCERESOLVER ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ))
79 //HELPER
80 ::rtl::OUString getPhysicalLocation( const ::com::sun::star::uno::Any& rbase, const ::com::sun::star::uno::Any& rUrl );
82 struct LanguageDependentProp
84 const char* pPropName;
85 sal_Int32 nPropNameLength;
88 // ----------------------------------------------------------------------------
89 namespace
91 static const Sequence< ::rtl::OUString >& lcl_getLanguageDependentProperties()
93 static Sequence< ::rtl::OUString > s_aLanguageDependentProperties;
94 if ( s_aLanguageDependentProperties.getLength() == 0 )
96 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
97 if ( s_aLanguageDependentProperties.getLength() == 0 )
99 s_aLanguageDependentProperties.realloc( 2 );
100 s_aLanguageDependentProperties[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HelpText" ) );
101 s_aLanguageDependentProperties[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
102 // note: properties must be sorted
105 return s_aLanguageDependentProperties;
109 // ----------------------------------------------------------------------------
110 // functor for disposing a control model
111 struct DisposeControlModel : public ::std::unary_function< Reference< XControlModel >, void >
113 void operator()( Reference< XControlModel >& _rxModel )
117 ::comphelper::disposeComponent( _rxModel );
119 catch (const Exception&)
121 OSL_TRACE( "DisposeControlModel::(): caught an exception while disposing a component!" );
126 // ----------------------------------------------------------------------------
127 // functor for searching control model by name
128 struct FindControlModel : public ::std::unary_function< ControlModelContainerBase::UnoControlModelHolder, bool >
130 private:
131 const ::rtl::OUString& m_rName;
133 public:
134 FindControlModel( const ::rtl::OUString& _rName ) : m_rName( _rName ) { }
136 bool operator()( const ControlModelContainerBase::UnoControlModelHolder& _rCompare )
138 return ( _rCompare.second == m_rName ) ? true : false;
142 // ----------------------------------------------------------------------------
143 // functor for cloning a control model, and insertion into a target list
144 struct CloneControlModel : public ::std::unary_function< ControlModelContainerBase::UnoControlModelHolder, void >
146 private:
147 ControlModelContainerBase::UnoControlModelHolderList& m_rTargetList;
149 public:
150 CloneControlModel( ControlModelContainerBase::UnoControlModelHolderList& _rTargetList )
151 :m_rTargetList( _rTargetList )
155 void operator()( const ControlModelContainerBase::UnoControlModelHolder& _rSource )
157 // clone the source object
158 Reference< XCloneable > xCloneSource( _rSource.first, UNO_QUERY );
159 Reference< XControlModel > xClone( xCloneSource->createClone(), UNO_QUERY );
160 // add to target list
161 m_rTargetList.push_back( ControlModelContainerBase::UnoControlModelHolder( xClone, _rSource.second ) );
165 // ----------------------------------------------------------------------------
166 // functor for comparing a XControlModel with a given reference
167 struct CompareControlModel : public ::std::unary_function< ControlModelContainerBase::UnoControlModelHolder, bool >
169 private:
170 Reference< XControlModel > m_xReference;
171 public:
172 CompareControlModel( const Reference< XControlModel >& _rxReference ) : m_xReference( _rxReference ) { }
174 bool operator()( const ControlModelContainerBase::UnoControlModelHolder& _rCompare )
176 return ( _rCompare.first.get() == m_xReference.get() ) ? true : false;
180 // ----------------------------------------------------------------------------
181 static void lcl_throwIllegalArgumentException( )
182 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
183 throw IllegalArgumentException();
186 // ----------------------------------------------------------------------------
187 static void lcl_throwNoSuchElementException( )
188 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
189 throw NoSuchElementException();
192 // ----------------------------------------------------------------------------
193 static void lcl_throwElementExistException( )
194 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
195 throw ElementExistException();
198 // ----------------------------------------------------------------------------
199 static const ::rtl::OUString& getTabIndexPropertyName( )
201 static const ::rtl::OUString s_sTabIndexProperty( RTL_CONSTASCII_USTRINGPARAM( "TabIndex" ) );
202 return s_sTabIndexProperty;
205 // ----------------------------------------------------------------------------
206 static const ::rtl::OUString& getStepPropertyName( )
208 static const ::rtl::OUString s_sStepProperty( RTL_CONSTASCII_USTRINGPARAM( "Step" ) );
209 return s_sStepProperty;
212 // ----------------------------------------------------
213 // class ControlModelContainerBase
214 // ----------------------------------------------------
215 ControlModelContainerBase::ControlModelContainerBase( const Reference< XMultiServiceFactory >& i_factory )
216 :ControlModelContainer_IBase( i_factory )
217 ,maContainerListeners( *this )
218 ,maChangeListeners ( GetMutex() )
219 ,mbGroupsUpToDate( sal_False )
223 ControlModelContainerBase::ControlModelContainerBase( const ControlModelContainerBase& rModel )
224 : ControlModelContainer_IBase( rModel )
225 , maContainerListeners( *this )
226 , maChangeListeners ( GetMutex() )
227 , mbGroupsUpToDate( sal_False )
231 ControlModelContainerBase::~ControlModelContainerBase()
233 maModels.clear();
234 mbGroupsUpToDate = sal_False;
237 Any ControlModelContainerBase::ImplGetDefaultValue( sal_uInt16 nPropId ) const
239 Any aAny;
241 switch ( nPropId )
243 case BASEPROPERTY_DEFAULTCONTROL:
244 aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlDialog );
245 break;
246 default:
247 aAny = UnoControlModel::ImplGetDefaultValue( nPropId );
250 return aAny;
253 ::cppu::IPropertyArrayHelper& ControlModelContainerBase::getInfoHelper()
255 static UnoPropertyArrayHelper* pHelper = NULL;
256 if ( !pHelper )
258 Sequence<sal_Int32> aIDs = ImplGetPropertyIds();
259 pHelper = new UnoPropertyArrayHelper( aIDs );
261 return *pHelper;
264 void SAL_CALL ControlModelContainerBase::dispose( ) throw(RuntimeException)
266 // ====================================================================
267 // tell our listeners
269 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
271 EventObject aDisposeEvent;
272 aDisposeEvent.Source = static_cast< XAggregation* >( static_cast< ::cppu::OWeakAggObject* >( this ) );
274 maContainerListeners.disposeAndClear( aDisposeEvent );
275 maChangeListeners.disposeAndClear( aDisposeEvent );
278 // ====================================================================
279 // call the base class
280 UnoControlModel::dispose();
282 // ====================================================================
283 // dispose our child models
284 // for this, collect the models (we collect them from maModels, and this is modified when disposing children)
285 ::std::vector< Reference< XControlModel > > aChildModels( maModels.size() );
287 ::std::transform(
288 maModels.begin(), maModels.end(), // source range
289 aChildModels.begin(), // target location
290 ::boost::bind( &UnoControlModelHolder::first, _1 ) // operation to apply -> select the XControlModel part
293 // now dispose
294 ::std::for_each( aChildModels.begin(), aChildModels.end(), DisposeControlModel() );
295 aChildModels.clear();
297 mbGroupsUpToDate = sal_False;
300 // XMultiPropertySet
301 Reference< XPropertySetInfo > ControlModelContainerBase::getPropertySetInfo( ) throw(RuntimeException)
303 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
304 return xInfo;
306 void ControlModelContainerBase::Clone_Impl(ControlModelContainerBase& _rClone) const
308 // clone all children
309 ::std::for_each(
310 maModels.begin(), maModels.end(),
311 CloneControlModel( _rClone.maModels )
314 UnoControlModel* ControlModelContainerBase::Clone() const
316 // clone the container itself
317 ControlModelContainerBase* pClone = new ControlModelContainerBase( *this );
318 Clone_Impl(*pClone);
320 return pClone;
323 ControlModelContainerBase::UnoControlModelHolderList::iterator ControlModelContainerBase::ImplFindElement( const ::rtl::OUString& rName )
325 return ::std::find_if( maModels.begin(), maModels.end(), FindControlModel( rName ) );
328 // ::XMultiServiceFactory
329 Reference< XInterface > ControlModelContainerBase::createInstance( const ::rtl::OUString& aServiceSpecifier ) throw(Exception, RuntimeException)
331 SolarMutexGuard aGuard;
333 OGeometryControlModel_Base* pNewModel = NULL;
335 const Reference< XMultiServiceFactory > xFactory( maContext.getLegacyServiceFactory() );
336 if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlEditModel ) == 0 )
337 pNewModel = new OGeometryControlModel< UnoControlEditModel >( xFactory );
338 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFormattedFieldModel ) == 0 )
339 pNewModel = new OGeometryControlModel< UnoControlFormattedFieldModel >( xFactory );
340 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFileControlModel ) == 0 )
341 pNewModel = new OGeometryControlModel< UnoControlFileControlModel >( xFactory );
342 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlButtonModel ) == 0 )
343 pNewModel = new OGeometryControlModel< UnoControlButtonModel >( xFactory );
344 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlImageControlModel ) == 0 )
345 pNewModel = new OGeometryControlModel< UnoControlImageControlModel >( xFactory );
346 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRadioButtonModel ) == 0 )
347 pNewModel = new OGeometryControlModel< UnoControlRadioButtonModel >( xFactory );
348 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCheckBoxModel ) == 0 )
349 pNewModel = new OGeometryControlModel< UnoControlCheckBoxModel >( xFactory );
350 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedHyperlinkModel ) == 0 )
351 pNewModel = new OGeometryControlModel< UnoControlFixedHyperlinkModel >( xFactory );
352 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedTextModel ) == 0 )
353 pNewModel = new OGeometryControlModel< UnoControlFixedTextModel >( xFactory );
354 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlGroupBoxModel ) == 0 )
355 pNewModel = new OGeometryControlModel< UnoControlGroupBoxModel >( xFactory );
356 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlListBoxModel ) == 0 )
357 pNewModel = new OGeometryControlModel< UnoControlListBoxModel >( xFactory );
358 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlComboBoxModel ) == 0 )
359 pNewModel = new OGeometryControlModel< UnoControlComboBoxModel >( xFactory );
360 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlDateFieldModel ) == 0 )
361 pNewModel = new OGeometryControlModel< UnoControlDateFieldModel >( xFactory );
362 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlTimeFieldModel ) == 0 )
363 pNewModel = new OGeometryControlModel< UnoControlTimeFieldModel >( xFactory );
364 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlNumericFieldModel ) == 0 )
365 pNewModel = new OGeometryControlModel< UnoControlNumericFieldModel >( xFactory );
366 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCurrencyFieldModel ) == 0 )
367 pNewModel = new OGeometryControlModel< UnoControlCurrencyFieldModel >( xFactory );
368 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlPatternFieldModel ) == 0 )
369 pNewModel = new OGeometryControlModel< UnoControlPatternFieldModel >( xFactory );
370 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlProgressBarModel ) == 0 )
371 pNewModel = new OGeometryControlModel< UnoControlProgressBarModel >( xFactory );
372 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlScrollBarModel ) == 0 )
373 pNewModel = new OGeometryControlModel< UnoControlScrollBarModel >( xFactory );
374 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFixedLineModel ) == 0 )
375 pNewModel = new OGeometryControlModel< UnoControlFixedLineModel >( xFactory );
376 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRoadmapModel ) == 0 )
377 pNewModel = new OGeometryControlModel< UnoControlRoadmapModel >( xFactory );
378 else if ( aServiceSpecifier.compareToAscii( szServiceName_TreeControlModel ) == 0 )
379 pNewModel = new OGeometryControlModel< UnoTreeModel >( xFactory );
380 else if ( aServiceSpecifier.compareToAscii( szServiceName_GridControlModel ) == 0 )
381 pNewModel = new OGeometryControlModel< UnoGridModel >( xFactory );
382 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlTabPageContainerModel ) == 0 )
383 pNewModel = new OGeometryControlModel< UnoControlTabPageContainerModel >( xFactory );
384 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoMultiPageModel ) == 0 )
385 pNewModel = new OGeometryControlModel< UnoMultiPageModel >( xFactory );
386 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlTabPageModel ) == 0 )
387 pNewModel = new OGeometryControlModel< UnoControlTabPageModel >( xFactory );
388 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoPageModel ) == 0 )
389 pNewModel = new OGeometryControlModel< UnoPageModel >( xFactory );
390 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoFrameModel ) == 0 )
391 pNewModel = new OGeometryControlModel< UnoFrameModel >( xFactory );
393 if ( !pNewModel )
395 if ( xFactory.is() )
397 Reference< XInterface > xObject = xFactory->createInstance( aServiceSpecifier );
398 Reference< XServiceInfo > xSI( xObject, UNO_QUERY );
399 Reference< XCloneable > xCloneAccess( xSI, UNO_QUERY );
400 Reference< XAggregation > xAgg( xCloneAccess, UNO_QUERY );
401 if ( xAgg.is() )
403 if ( xSI->supportsService(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlModel"))) )
405 // release 3 of the 4 references we have to the object
406 xAgg.clear();
407 xSI.clear();
408 xObject.clear();
410 pNewModel = new OCommonGeometryControlModel( xCloneAccess, aServiceSpecifier );
416 Reference< XInterface > xNewModel = (::cppu::OWeakObject*)pNewModel;
417 return xNewModel;
420 Reference< XInterface > ControlModelContainerBase::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& i_arguments ) throw(Exception, RuntimeException)
422 const Reference< XInterface > xInstance( createInstance( ServiceSpecifier ) );
423 const Reference< XInitialization > xInstanceInit( xInstance, UNO_QUERY );
424 ENSURE_OR_RETURN( xInstanceInit.is(), "ControlModelContainerBase::createInstanceWithArguments: can't pass the arguments!", xInstance );
425 xInstanceInit->initialize( i_arguments );
426 return xInstance;
429 Sequence< ::rtl::OUString > ControlModelContainerBase::getAvailableServiceNames() throw(RuntimeException)
431 static Sequence< ::rtl::OUString >* pNamesSeq = NULL;
432 if ( !pNamesSeq )
434 pNamesSeq = new Sequence< ::rtl::OUString >( 26 );
435 ::rtl::OUString* pNames = pNamesSeq->getArray();
436 pNames[0] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlEditModel );
437 pNames[1] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFormattedFieldModel );
438 pNames[2] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFileControlModel );
439 pNames[3] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlButtonModel );
440 pNames[4] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlImageControlModel );
441 pNames[5] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRadioButtonModel );
442 pNames[6] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlCheckBoxModel );
443 pNames[7] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFixedTextModel );
444 pNames[8] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlGroupBoxModel );
445 pNames[9] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlListBoxModel );
446 pNames[10] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlComboBoxModel );
447 pNames[11] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlDateFieldModel );
448 pNames[12] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlTimeFieldModel );
449 pNames[13] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlNumericFieldModel );
450 pNames[14] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlCurrencyFieldModel );
451 pNames[15] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlPatternFieldModel );
452 pNames[16] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlProgressBarModel );
453 pNames[17] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlScrollBarModel );
454 pNames[18] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFixedLineModel );
455 pNames[19] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRoadmapModel );
456 pNames[20] = ::rtl::OUString::createFromAscii( szServiceName_TreeControlModel );
457 pNames[21] = ::rtl::OUString::createFromAscii( szServiceName_GridControlModel );
458 pNames[22] = ::rtl::OUString::createFromAscii( szServiceName_UnoControlTabPageContainerModel );
459 pNames[23] = ::rtl::OUString::createFromAscii( szServiceName_UnoControlTabPageModel );
460 pNames[24] = ::rtl::OUString::createFromAscii( szServiceName_UnoMultiPageModel );
461 pNames[25] = ::rtl::OUString::createFromAscii( szServiceName_UnoFrameModel );
463 return *pNamesSeq;
466 // XContainer
467 void ControlModelContainerBase::addContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException)
469 maContainerListeners.addInterface( l );
472 void ControlModelContainerBase::removeContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException)
474 maContainerListeners.removeInterface( l );
477 // XElementAcces
478 Type ControlModelContainerBase::getElementType() throw(RuntimeException)
480 Type aType = getCppuType( ( Reference< XControlModel>* ) NULL );
481 return aType;
484 sal_Bool ControlModelContainerBase::hasElements() throw(RuntimeException)
486 return !maModels.empty();
489 // XNameContainer, XNameReplace, XNameAccess
490 void ControlModelContainerBase::replaceByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
492 SolarMutexGuard aGuard;
494 Reference< XControlModel > xNewModel;
495 aElement >>= xNewModel;
496 if ( !xNewModel.is() )
497 lcl_throwIllegalArgumentException();
499 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
500 if ( maModels.end() == aElementPos )
501 lcl_throwNoSuchElementException();
502 // Dialog behaviour is to have all containee names unique ( MSO Userform is the same )
503 // With container controls you could have constructed an existing hierachy and are now
504 // add this to an existing container, in this case a name nested in the containment
505 // hierachy of the added control could contain a name clash, if we have access to the
506 // list of global names then recursively check for previously existing names ( we need
507 // to do this obviously before the 'this' objects container is updated
508 Reference< XNameContainer > xAllChildren( getPropertyValue( GetPropertyName( BASEPROPERTY_USERFORMCONTAINEES ) ), UNO_QUERY );
509 if ( xAllChildren.is() )
511 // remove old control ( and children ) from global list of containees
512 updateUserFormChildren( xAllChildren, aName, Remove, uno::Reference< XControlModel >() );
513 // Add new control ( and containees if they exist )
514 updateUserFormChildren( xAllChildren, aName, Insert, xNewModel );
516 // stop listening at the old model
517 stopControlListening( aElementPos->first );
518 Reference< XControlModel > xReplaced( aElementPos->first );
519 // remember the new model, and start listening
520 aElementPos->first = xNewModel;
521 startControlListening( xNewModel );
523 ContainerEvent aEvent;
524 aEvent.Source = *this;
525 aEvent.Element = aElement;
526 aEvent.ReplacedElement <<= xReplaced;
527 aEvent.Accessor <<= aName;
529 // notify the container listener
530 maContainerListeners.elementReplaced( aEvent );
532 // our "tab controller model" has potentially changed -> notify this
533 implNotifyTabModelChange( aName );
536 Any ControlModelContainerBase::getByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
538 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
539 if ( maModels.end() == aElementPos )
540 lcl_throwNoSuchElementException();
542 return makeAny( aElementPos->first );
545 Sequence< ::rtl::OUString > ControlModelContainerBase::getElementNames() throw(RuntimeException)
547 Sequence< ::rtl::OUString > aNames( maModels.size() );
549 ::std::transform(
550 maModels.begin(), maModels.end(), // source range
551 aNames.getArray(), // target range
552 ::boost::bind( &UnoControlModelHolder::second, _1 ) // operator to apply: select the second element (the name)
555 return aNames;
558 sal_Bool ControlModelContainerBase::hasByName( const ::rtl::OUString& aName ) throw(RuntimeException)
560 return maModels.end() != ImplFindElement( aName );
563 void ControlModelContainerBase::insertByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
565 SolarMutexGuard aGuard;
567 Reference< XControlModel > xM;
568 aElement >>= xM;
570 if ( xM.is() )
572 Reference< beans::XPropertySet > xProps( xM, UNO_QUERY );
573 if ( xProps.is() )
576 Reference< beans::XPropertySetInfo > xPropInfo = xProps.get()->getPropertySetInfo();
578 ::rtl::OUString sImageSourceProperty = GetPropertyName( BASEPROPERTY_IMAGEURL );
579 if ( xPropInfo.get()->hasPropertyByName( sImageSourceProperty ) && ImplHasProperty(BASEPROPERTY_DIALOGSOURCEURL) )
581 Any aUrl = xProps.get()->getPropertyValue( sImageSourceProperty );
583 ::rtl::OUString absoluteUrl =
584 getPhysicalLocation( getPropertyValue( GetPropertyName( BASEPROPERTY_DIALOGSOURCEURL ) ), aUrl );
586 aUrl <<= absoluteUrl;
588 xProps.get()->setPropertyValue( sImageSourceProperty , aUrl );
595 if ( aName.isEmpty() || !xM.is() )
596 lcl_throwIllegalArgumentException();
598 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
599 if ( maModels.end() != aElementPos )
600 lcl_throwElementExistException();
602 // Dialog behaviour is to have all containee names unique ( MSO Userform is the same )
603 // With container controls you could have constructed an existing hierachy and are now
604 // add this to an existing container, in this case a name nested in the containment
605 // hierachy of the added control could contain a name clash, if we have access to the
606 // list of global names then we need to recursively check for previously existing
607 // names ( we need to do this obviously before the 'this' objects container is updated
608 // remove old control ( and children ) from global list of containees
609 Reference< XNameContainer > xAllChildren( getPropertyValue( GetPropertyName( BASEPROPERTY_USERFORMCONTAINEES ) ), UNO_QUERY );
611 if ( xAllChildren.is() )
612 updateUserFormChildren( xAllChildren, aName, Insert, xM );
613 maModels.push_back( UnoControlModelHolder( xM, aName ) );
614 mbGroupsUpToDate = sal_False;
615 startControlListening( xM );
617 ContainerEvent aEvent;
618 aEvent.Source = *this;
619 aEvent.Element <<= aElement;
620 aEvent.Accessor <<= aName;
621 maContainerListeners.elementInserted( aEvent );
623 // our "tab controller model" has potentially changed -> notify this
624 implNotifyTabModelChange( aName );
627 void ControlModelContainerBase::removeByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
629 SolarMutexGuard aGuard;
631 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
632 if ( maModels.end() == aElementPos )
633 lcl_throwNoSuchElementException();
635 // Dialog behaviour is to have all containee names unique ( MSO Userform is the same )
636 // With container controls you could have constructed an existing hierachy and are now
637 // removing this control from an existing container, in this case all nested names in
638 // the containment hierachy of the control to be removed need to be removed from the global
639 // names cache ( we need to do this obviously before the 'this' objects container is updated )
640 Reference< XNameContainer > xAllChildren( getPropertyValue( GetPropertyName( BASEPROPERTY_USERFORMCONTAINEES ) ), UNO_QUERY );
641 if ( xAllChildren.is() )
642 updateUserFormChildren( xAllChildren, aName, Remove, uno::Reference< XControlModel >() );
644 ContainerEvent aEvent;
645 aEvent.Source = *this;
646 aEvent.Element <<= aElementPos->first;
647 aEvent.Accessor <<= aName;
648 maContainerListeners.elementRemoved( aEvent );
650 stopControlListening( aElementPos->first );
651 Reference< XPropertySet > xPS( aElementPos->first, UNO_QUERY );
652 maModels.erase( aElementPos );
653 mbGroupsUpToDate = sal_False;
655 if ( xPS.is() )
659 xPS->setPropertyValue( PROPERTY_RESOURCERESOLVER, makeAny( Reference< resource::XStringResourceResolver >() ) );
661 catch (const Exception&)
663 DBG_UNHANDLED_EXCEPTION();
667 // our "tab controller model" has potentially changed -> notify this
668 implNotifyTabModelChange( aName );
671 // ----------------------------------------------------------------------------
672 sal_Bool SAL_CALL ControlModelContainerBase::getGroupControl( ) throw (RuntimeException)
674 return sal_True;
677 // ----------------------------------------------------------------------------
678 void SAL_CALL ControlModelContainerBase::setGroupControl( sal_Bool ) throw (RuntimeException)
680 OSL_TRACE( "UnoControlDialogModel::setGroupControl: explicit grouping not supported" );
683 // ----------------------------------------------------------------------------
684 void SAL_CALL ControlModelContainerBase::setControlModels( const Sequence< Reference< XControlModel > >& _rControls ) throw (RuntimeException)
686 SolarMutexGuard aGuard;
688 // set the tab indexes according to the order of models in the sequence
689 const Reference< XControlModel >* pControls = _rControls.getConstArray( );
690 const Reference< XControlModel >* pControlsEnd = _rControls.getConstArray( ) + _rControls.getLength();
692 sal_Int16 nTabIndex = 1;
694 for ( ; pControls != pControlsEnd; ++pControls )
696 // look up the control in our own structure. This is to prevent invalid arguments
697 UnoControlModelHolderList::const_iterator aPos =
698 ::std::find_if(
699 maModels.begin(), maModels.end(),
700 CompareControlModel( *pControls )
702 if ( maModels.end() != aPos )
704 // okay, this is an existent model
705 // now set the TabIndex property (if applicable)
706 Reference< XPropertySet > xProps( aPos->first, UNO_QUERY );
707 Reference< XPropertySetInfo > xPSI;
708 if ( xProps.is() )
709 xPSI = xProps->getPropertySetInfo();
710 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
711 xProps->setPropertyValue( getTabIndexPropertyName(), makeAny( nTabIndex++ ) );
713 mbGroupsUpToDate = sal_False;
718 typedef ::std::multimap< sal_Int32, Reference< XControlModel >, ::std::less< sal_Int32 > > MapIndexToModel;
720 // ----------------------------------------------------------------------------
721 Sequence< Reference< XControlModel > > SAL_CALL ControlModelContainerBase::getControlModels( ) throw (RuntimeException)
723 SolarMutexGuard aGuard;
725 MapIndexToModel aSortedModels;
726 // will be the sorted container of all models which have a tab index property
727 ::std::vector< Reference< XControlModel > > aUnindexedModels;
728 // will be the container of all models which do not have a tab index property
730 UnoControlModelHolderList::const_iterator aLoop = maModels.begin();
731 for ( ; aLoop != maModels.end(); ++aLoop )
733 Reference< XControlModel > xModel( aLoop->first );
735 // see if the model has a TabIndex property
736 Reference< XPropertySet > xControlProps( xModel, UNO_QUERY );
737 Reference< XPropertySetInfo > xPSI;
738 if ( xControlProps.is() )
739 xPSI = xControlProps->getPropertySetInfo( );
740 DBG_ASSERT( xPSI.is(), "UnoControlDialogModel::getControlModels: invalid child model!" );
742 // has it?
743 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
744 { // yes
745 sal_Int32 nTabIndex = -1;
746 xControlProps->getPropertyValue( getTabIndexPropertyName() ) >>= nTabIndex;
748 aSortedModels.insert( MapIndexToModel::value_type( nTabIndex, xModel ) );
750 else if ( xModel.is() )
751 // no, it hasn't, but we have to include it, anyway
752 aUnindexedModels.push_back( xModel );
755 // okay, here we have a container of all our models, sorted by tab index,
756 // plus a container of "unindexed" models
757 // -> merge them
758 Sequence< Reference< XControlModel > > aReturn( aUnindexedModels.size() + aSortedModels.size() );
759 ::std::transform(
760 aSortedModels.begin(), aSortedModels.end(),
761 ::std::copy( aUnindexedModels.begin(), aUnindexedModels.end(), aReturn.getArray() ),
762 ::boost::bind( &MapIndexToModel::value_type::second, _1 )
765 return aReturn;
768 // ----------------------------------------------------------------------------
769 void SAL_CALL ControlModelContainerBase::setGroup( const Sequence< Reference< XControlModel > >&, const ::rtl::OUString& ) throw (RuntimeException)
771 // not supported. We have only implicit grouping:
772 // We only have a sequence of control models, and we _know_ (yes, that's a HACK relying on
773 // implementation details) that VCL does grouping according to the order of controls automatically
774 // At least VCL does this for all we're interested in: Radio buttons.
775 OSL_TRACE( "UnoControlDialogModel::setGroup: grouping not supported" );
778 ////----- XInitialization -------------------------------------------------------------------
779 void SAL_CALL ControlModelContainerBase::initialize (const Sequence<Any>& rArguments) throw (com::sun::star::uno::Exception, com::sun::star::uno::RuntimeException)
781 if ( rArguments.getLength() == 1 )
783 sal_Int16 nPageId = -1;
784 if ( !( rArguments[ 0 ] >>= nPageId ))
785 throw lang::IllegalArgumentException();
786 m_nTabPageId = nPageId;
788 else
789 m_nTabPageId = -1;
791 ::sal_Int16 SAL_CALL ControlModelContainerBase::getTabPageID() throw (::com::sun::star::uno::RuntimeException)
793 return m_nTabPageId;
795 ::sal_Bool SAL_CALL ControlModelContainerBase::getEnabled() throw (::com::sun::star::uno::RuntimeException)
797 return m_bEnabled;
799 void SAL_CALL ControlModelContainerBase::setEnabled( ::sal_Bool _enabled ) throw (::com::sun::star::uno::RuntimeException)
801 m_bEnabled = _enabled;
803 ::rtl::OUString SAL_CALL ControlModelContainerBase::getTitle() throw (::com::sun::star::uno::RuntimeException)
805 SolarMutexGuard aGuard;
806 Reference<XPropertySet> xThis(*this,UNO_QUERY);
807 ::rtl::OUString sTitle;
808 xThis->getPropertyValue(GetPropertyName(BASEPROPERTY_TITLE)) >>= sTitle;
809 return sTitle;
810 //return m_sTitle;
812 void SAL_CALL ControlModelContainerBase::setTitle( const ::rtl::OUString& _title ) throw (::com::sun::star::uno::RuntimeException)
814 SolarMutexGuard aGuard;
815 Reference<XPropertySet> xThis(*this,UNO_QUERY);
816 xThis->setPropertyValue(GetPropertyName(BASEPROPERTY_TITLE),makeAny(_title));
818 ::rtl::OUString SAL_CALL ControlModelContainerBase::getImageURL() throw (::com::sun::star::uno::RuntimeException)
820 return m_sImageURL;
822 void SAL_CALL ControlModelContainerBase::setImageURL( const ::rtl::OUString& _imageurl ) throw (::com::sun::star::uno::RuntimeException)
824 m_sImageURL = _imageurl;
826 ::rtl::OUString SAL_CALL ControlModelContainerBase::getToolTip() throw (::com::sun::star::uno::RuntimeException)
828 return m_sTooltip;
830 void SAL_CALL ControlModelContainerBase::setToolTip( const ::rtl::OUString& _tooltip ) throw (::com::sun::star::uno::RuntimeException)
832 m_sTooltip = _tooltip;
835 // ----------------------------------------------------------------------------
836 namespace
838 enum GroupingMachineState
840 eLookingForGroup,
841 eExpandingGroup
844 // ........................................................................
845 static sal_Int32 lcl_getDialogStep( const Reference< XControlModel >& _rxModel )
847 sal_Int32 nStep = 0;
850 Reference< XPropertySet > xModelProps( _rxModel, UNO_QUERY );
851 xModelProps->getPropertyValue( getStepPropertyName() ) >>= nStep;
853 catch (const Exception&)
855 OSL_TRACE( "lcl_getDialogStep: caught an exception while determining the dialog page!" );
857 return nStep;
861 // ----------------------------------------------------------------------------
862 sal_Int32 SAL_CALL ControlModelContainerBase::getGroupCount( ) throw (RuntimeException)
864 SolarMutexGuard aGuard;
866 implUpdateGroupStructure();
868 return maGroups.size();
871 // ----------------------------------------------------------------------------
872 void SAL_CALL ControlModelContainerBase::getGroup( sal_Int32 _nGroup, Sequence< Reference< XControlModel > >& _rGroup, ::rtl::OUString& _rName ) throw (RuntimeException)
874 SolarMutexGuard aGuard;
876 implUpdateGroupStructure();
878 if ( ( _nGroup < 0 ) || ( _nGroup >= (sal_Int32)maGroups.size() ) )
880 OSL_TRACE( "UnoControlDialogModel::getGroup: invalid argument and I am not allowed to throw an exception!" );
881 _rGroup.realloc( 0 );
882 _rName = ::rtl::OUString();
884 else
886 AllGroups::const_iterator aGroupPos = maGroups.begin() + _nGroup;
887 _rGroup.realloc( aGroupPos->size() );
888 // copy the models
889 ::std::copy( aGroupPos->begin(), aGroupPos->end(), _rGroup.getArray() );
890 // give the group a name
891 _rName = ::rtl::OUString::valueOf( _nGroup );
895 // ----------------------------------------------------------------------------
896 void SAL_CALL ControlModelContainerBase::getGroupByName( const ::rtl::OUString& _rName, Sequence< Reference< XControlModel > >& _rGroup ) throw (RuntimeException)
898 SolarMutexGuard aGuard;
900 ::rtl::OUString sDummyName;
901 getGroup( _rName.toInt32( ), _rGroup, sDummyName );
904 // ----------------------------------------------------------------------------
905 void SAL_CALL ControlModelContainerBase::addChangesListener( const Reference< XChangesListener >& _rxListener ) throw (RuntimeException)
907 maChangeListeners.addInterface( _rxListener );
910 // ----------------------------------------------------------------------------
911 void SAL_CALL ControlModelContainerBase::removeChangesListener( const Reference< XChangesListener >& _rxListener ) throw (RuntimeException)
913 maChangeListeners.removeInterface( _rxListener );
916 // ----------------------------------------------------------------------------
917 void ControlModelContainerBase::implNotifyTabModelChange( const ::rtl::OUString& _rAccessor )
919 // multiplex to our change listeners:
920 // the changes event
921 ChangesEvent aEvent;
922 aEvent.Source = *this;
923 aEvent.Base <<= aEvent.Source; // the "base of the changes root" is also ourself
924 aEvent.Changes.realloc( 1 ); // exactly one change
925 aEvent.Changes[ 0 ].Accessor <<= _rAccessor;
928 Sequence< Reference< XInterface > > aChangeListeners( maChangeListeners.getElements() );
929 const Reference< XInterface >* pListener = aChangeListeners.getConstArray();
930 const Reference< XInterface >* pListenerEnd = aChangeListeners.getConstArray() + aChangeListeners.getLength();
931 for ( ; pListener != pListenerEnd; ++pListener )
933 if ( pListener->is() )
934 static_cast< XChangesListener* >( pListener->get() )->changesOccurred( aEvent );
939 // ----------------------------------------------------------------------------
940 void ControlModelContainerBase::implUpdateGroupStructure()
942 if ( mbGroupsUpToDate )
943 // nothing to do
944 return;
946 // conditions for a group:
947 // * all elements of the group are radio buttons
948 // * all elements of the group are on the same dialog page
949 // * in the overall control order (determined by the tab index), all elements are subsequent
951 maGroups.clear();
953 Sequence< Reference< XControlModel > > aControlModels = getControlModels();
954 const Reference< XControlModel >* pControlModels = aControlModels.getConstArray();
955 const Reference< XControlModel >* pControlModelsEnd = pControlModels + aControlModels.getLength();
957 // in extreme we have as much groups as controls
958 maGroups.reserve( aControlModels.getLength() );
960 GroupingMachineState eState = eLookingForGroup; // the current state of our machine
961 Reference< XServiceInfo > xModelSI; // for checking for a radion button
962 AllGroups::iterator aCurrentGroup = maGroups.end(); // the group which we're currently building
963 sal_Int32 nCurrentGroupStep = -1; // the step which all controls of the current group belong to
964 sal_Bool bIsRadioButton; // is it a radio button?
966 #if OSL_DEBUG_LEVEL > 1
967 ::std::vector< ::rtl::OUString > aCurrentGroupLabels;
968 #endif
970 for ( ; pControlModels != pControlModelsEnd; ++pControlModels )
972 // we'll need this in every state
973 xModelSI = xModelSI.query( *pControlModels );
974 bIsRadioButton = xModelSI.is() && xModelSI->supportsService( ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRadioButtonModel ) );
976 switch ( eState )
978 case eLookingForGroup:
980 if ( !bIsRadioButton )
981 // this is no radio button -> still looking for the beginning of a group
982 continue;
983 // the current model is a radio button
984 // -> we found the beginning of a new group
985 // create the place for this group
986 size_t nGroups = maGroups.size();
987 maGroups.resize( nGroups + 1 );
988 aCurrentGroup = maGroups.begin() + nGroups;
989 // and add the (only, til now) member
990 aCurrentGroup->push_back( *pControlModels );
992 // get the step which all controls of this group now have to belong to
993 nCurrentGroupStep = lcl_getDialogStep( *pControlModels );
994 // new state: looking for further members
995 eState = eExpandingGroup;
997 #if OSL_DEBUG_LEVEL > 1
998 Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY );
999 ::rtl::OUString sLabel;
1000 if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Label")) ) )
1001 xModelProps->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Label")) ) >>= sLabel;
1002 aCurrentGroupLabels.push_back( sLabel );
1003 #endif
1005 break;
1007 case eExpandingGroup:
1009 if ( !bIsRadioButton )
1010 { // no radio button -> the group is done
1011 aCurrentGroup = maGroups.end();
1012 eState = eLookingForGroup;
1013 #if OSL_DEBUG_LEVEL > 1
1014 aCurrentGroupLabels.clear();
1015 #endif
1016 continue;
1019 // it is a radio button - is it on the proper page?
1020 const sal_Int32 nThisModelStep = lcl_getDialogStep( *pControlModels );
1021 if ( ( nThisModelStep == nCurrentGroupStep ) // the current button is on the same dialog page
1022 || ( 0 == nThisModelStep ) // the current button appears on all pages
1025 // -> it belongs to the same group
1026 aCurrentGroup->push_back( *pControlModels );
1027 // state still is eExpandingGroup - we're looking for further elements
1028 eState = eExpandingGroup;
1030 #if OSL_DEBUG_LEVEL > 1
1031 Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY );
1032 ::rtl::OUString sLabel;
1033 if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Label")) ) )
1034 xModelProps->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Label")) ) >>= sLabel;
1035 aCurrentGroupLabels.push_back( sLabel );
1036 #endif
1037 continue;
1040 // it's a radio button, but on a different page
1041 // -> we open a new group for it
1043 // close the old group
1044 aCurrentGroup = maGroups.end();
1045 #if OSL_DEBUG_LEVEL > 1
1046 aCurrentGroupLabels.clear();
1047 #endif
1049 // open a new group
1050 size_t nGroups = maGroups.size();
1051 maGroups.resize( nGroups + 1 );
1052 aCurrentGroup = maGroups.begin() + nGroups;
1053 // and add the (only, til now) member
1054 aCurrentGroup->push_back( *pControlModels );
1056 nCurrentGroupStep = nThisModelStep;
1058 // state is the same: we still are looking for further elements of the current group
1059 eState = eExpandingGroup;
1060 #if OSL_DEBUG_LEVEL > 1
1061 Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY );
1062 ::rtl::OUString sLabel;
1063 if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Label")) ) )
1064 xModelProps->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Label")) ) >>= sLabel;
1065 aCurrentGroupLabels.push_back( sLabel );
1066 #endif
1068 break;
1072 mbGroupsUpToDate = sal_True;
1075 // ----------------------------------------------------------------------------
1076 void SAL_CALL ControlModelContainerBase::propertyChange( const PropertyChangeEvent& _rEvent ) throw (RuntimeException)
1078 SolarMutexGuard aGuard;
1080 DBG_ASSERT( 0 == _rEvent.PropertyName.compareToAscii( "TabIndex" ),
1081 "UnoControlDialogModel::propertyChange: not listening for this property!" );
1083 // the accessor for the changed element
1084 ::rtl::OUString sAccessor;
1085 UnoControlModelHolderList::const_iterator aPos =
1086 ::std::find_if(
1087 maModels.begin(), maModels.end(),
1088 CompareControlModel( Reference< XControlModel >( _rEvent.Source, UNO_QUERY ) )
1090 OSL_ENSURE( maModels.end() != aPos, "UnoControlDialogModel::propertyChange: don't know this model!" );
1091 if ( maModels.end() != aPos )
1092 sAccessor = aPos->second;
1094 // our groups are not up-to-date
1095 mbGroupsUpToDate = sal_False;
1097 // notify
1098 implNotifyTabModelChange( sAccessor );
1101 // ----------------------------------------------------------------------------
1102 void SAL_CALL ControlModelContainerBase::disposing( const EventObject& /*rEvent*/ ) throw (RuntimeException)
1106 // ----------------------------------------------------------------------------
1107 void ControlModelContainerBase::startControlListening( const Reference< XControlModel >& _rxChildModel )
1109 SolarMutexGuard aGuard;
1111 Reference< XPropertySet > xModelProps( _rxChildModel, UNO_QUERY );
1112 Reference< XPropertySetInfo > xPSI;
1113 if ( xModelProps.is() )
1114 xPSI = xModelProps->getPropertySetInfo();
1116 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
1117 xModelProps->addPropertyChangeListener( getTabIndexPropertyName(), this );
1120 // ----------------------------------------------------------------------------
1121 void ControlModelContainerBase::stopControlListening( const Reference< XControlModel >& _rxChildModel )
1123 SolarMutexGuard aGuard;
1125 Reference< XPropertySet > xModelProps( _rxChildModel, UNO_QUERY );
1126 Reference< XPropertySetInfo > xPSI;
1127 if ( xModelProps.is() )
1128 xPSI = xModelProps->getPropertySetInfo();
1130 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
1131 xModelProps->removePropertyChangeListener( getTabIndexPropertyName(), this );
1134 // ============================================================================
1135 // = class ResourceListener
1136 // ============================================================================
1138 ResourceListener::ResourceListener(
1139 const Reference< util::XModifyListener >& rListener ) :
1140 OWeakObject(),
1141 m_xListener( rListener ),
1142 m_bListening( false )
1146 ResourceListener::~ResourceListener()
1150 // XInterface
1151 Any SAL_CALL ResourceListener::queryInterface( const Type& rType )
1152 throw ( RuntimeException )
1154 Any a = ::cppu::queryInterface(
1155 rType ,
1156 static_cast< XModifyListener* >( this ),
1157 static_cast< XEventListener* >( this ));
1159 if ( a.hasValue() )
1160 return a;
1162 return OWeakObject::queryInterface( rType );
1165 void SAL_CALL ResourceListener::acquire() throw ()
1167 OWeakObject::acquire();
1170 void SAL_CALL ResourceListener::release() throw ()
1172 OWeakObject::release();
1175 void ResourceListener::startListening(
1176 const Reference< resource::XStringResourceResolver >& rResource )
1178 Reference< util::XModifyBroadcaster > xModifyBroadcaster( rResource, UNO_QUERY );
1181 // --- SAFE ---
1182 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1183 bool bListening( m_bListening );
1184 bool bResourceSet( m_xResource.is() );
1185 aGuard.clear();
1186 // --- SAFE ---
1188 if ( bListening && bResourceSet )
1189 stopListening();
1191 // --- SAFE ---
1192 aGuard.reset();
1193 m_xResource = rResource;
1194 aGuard.clear();
1195 // --- SAFE ---
1198 Reference< util::XModifyListener > xThis( static_cast<OWeakObject*>( this ), UNO_QUERY );
1199 if ( xModifyBroadcaster.is() )
1203 xModifyBroadcaster->addModifyListener( xThis );
1205 // --- SAFE ---
1206 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1207 m_bListening = true;
1208 // --- SAFE ---
1210 catch (const RuntimeException&)
1212 throw;
1214 catch (const Exception&)
1220 void ResourceListener::stopListening()
1222 Reference< util::XModifyBroadcaster > xModifyBroadcaster;
1224 // --- SAFE ---
1225 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1226 if ( m_bListening && m_xResource.is() )
1227 xModifyBroadcaster = Reference< util::XModifyBroadcaster >( m_xResource, UNO_QUERY );
1228 aGuard.clear();
1229 // --- SAFE ---
1231 Reference< util::XModifyListener > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
1232 if ( xModifyBroadcaster.is() )
1236 // --- SAFE ---
1237 aGuard.reset();
1238 m_bListening = false;
1239 m_xResource.clear();
1240 aGuard.clear();
1241 // --- SAFE ---
1243 xModifyBroadcaster->removeModifyListener( xThis );
1245 catch (const RuntimeException&)
1247 throw;
1249 catch (const Exception&)
1255 // XModifyListener
1256 void SAL_CALL ResourceListener::modified(
1257 const lang::EventObject& aEvent )
1258 throw ( RuntimeException )
1260 Reference< util::XModifyListener > xListener;
1262 // --- SAFE ---
1263 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1264 xListener = m_xListener;
1265 aGuard.clear();
1266 // --- SAFE ---
1268 if ( xListener.is() )
1272 xListener->modified( aEvent );
1274 catch (const RuntimeException&)
1276 throw;
1278 catch (const Exception&)
1284 // XEventListener
1285 void SAL_CALL ResourceListener::disposing(
1286 const EventObject& Source )
1287 throw ( RuntimeException )
1289 Reference< lang::XEventListener > xListener;
1290 Reference< resource::XStringResourceResolver > xResource;
1292 // --- SAFE ---
1293 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1294 Reference< XInterface > xIfacRes( m_xResource, UNO_QUERY );
1295 Reference< XInterface > xIfacList( m_xListener, UNO_QUERY );
1296 aGuard.clear();
1297 // --- SAFE ---
1299 if ( Source.Source == xIfacRes )
1301 // --- SAFE ---
1302 aGuard.reset();
1303 m_bListening = false;
1304 xResource = m_xResource;
1305 xListener = Reference< lang::XEventListener >( m_xListener, UNO_QUERY );
1306 m_xResource.clear();
1307 aGuard.clear();
1308 // --- SAFE ---
1310 if ( xListener.is() )
1314 xListener->disposing( Source );
1316 catch (const RuntimeException&)
1318 throw;
1320 catch (const Exception&)
1325 else if ( Source.Source == xIfacList )
1327 // --- SAFE ---
1328 aGuard.reset();
1329 m_bListening = false;
1330 xListener = Reference< lang::XEventListener >( m_xListener, UNO_QUERY );
1331 xResource = m_xResource;
1332 m_xResource.clear();
1333 m_xListener.clear();
1334 aGuard.clear();
1335 // --- SAFE ---
1337 // Remove ourself as listener from resource resolver
1338 Reference< util::XModifyBroadcaster > xModifyBroadcaster( xResource, UNO_QUERY );
1339 Reference< util::XModifyListener > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
1340 if ( xModifyBroadcaster.is() )
1344 xModifyBroadcaster->removeModifyListener( xThis );
1346 catch (const RuntimeException&)
1348 throw;
1350 catch (const Exception&)
1357 //===============================================================
1358 // ----------------------------------------------------
1359 // class DialogContainerControl
1360 // ----------------------------------------------------
1361 ControlContainerBase::ControlContainerBase( const Reference< XMultiServiceFactory >& i_factory )
1362 :ContainerControl_IBase( i_factory )
1363 ,mbSizeModified(false)
1364 ,mbPosModified(false)
1366 maComponentInfos.nWidth = 280;
1367 maComponentInfos.nHeight = 400;
1368 mxListener = new ResourceListener( Reference< util::XModifyListener >(
1369 static_cast< OWeakObject* >( this ), UNO_QUERY ));
1372 ControlContainerBase::~ControlContainerBase()
1376 void ControlContainerBase::createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer > & rParentPeer ) throw(RuntimeException)
1378 SolarMutexGuard aGuard;
1379 UnoControlContainer::createPeer( rxToolkit, rParentPeer );
1382 void ControlContainerBase::ImplInsertControl( Reference< XControlModel >& rxModel, const ::rtl::OUString& rName )
1384 Reference< XPropertySet > xP( rxModel, UNO_QUERY );
1386 ::rtl::OUString aDefCtrl;
1387 xP->getPropertyValue( GetPropertyName( BASEPROPERTY_DEFAULTCONTROL ) ) >>= aDefCtrl;
1388 Reference < XControl > xCtrl;
1389 maContext.createComponent( aDefCtrl, xCtrl );
1391 DBG_ASSERT( xCtrl.is(), "ControlContainerBase::ImplInsertControl: could not create the control!" );
1392 if ( xCtrl.is() )
1394 xCtrl->setModel( rxModel );
1395 addControl( rName, xCtrl );
1396 // will implicitly call addingControl, where we can add the PropertiesChangeListener to the model
1397 // (which we formerly did herein)
1398 // 08.01.2001 - 96008 - fs@openoffice.org
1400 ImplSetPosSize( xCtrl );
1404 void ControlContainerBase::ImplRemoveControl( Reference< XControlModel >& rxModel )
1406 Sequence< Reference< XControl > > aControls = getControls();
1407 Reference< XControl > xCtrl = StdTabController::FindControl( aControls, rxModel );
1408 if ( xCtrl.is() )
1410 removeControl( xCtrl );
1413 Reference< XComponent > const xControlComp( xCtrl, UNO_QUERY_THROW );
1414 xControlComp->dispose();
1416 catch (const Exception&)
1418 DBG_UNHANDLED_EXCEPTION();
1423 void ControlContainerBase::ImplSetPosSize( Reference< XControl >& rxCtrl )
1425 Reference< XPropertySet > xP( rxCtrl->getModel(), UNO_QUERY );
1427 sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
1428 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) ) ) >>= nX;
1429 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) ) ) >>= nY;
1430 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ) ) >>= nWidth;
1431 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ) ) >>= nHeight;
1432 MapMode aMode( MAP_APPFONT );
1433 OutputDevice*pOutDev = Application::GetDefaultDevice();
1434 if ( pOutDev )
1436 ::Size aTmp( nX, nY );
1437 aTmp = pOutDev->LogicToPixel( aTmp, aMode );
1438 nX = aTmp.Width();
1439 nY = aTmp.Height();
1440 aTmp = ::Size( nWidth, nHeight );
1441 aTmp = pOutDev->LogicToPixel( aTmp, aMode );
1442 nWidth = aTmp.Width();
1443 nHeight = aTmp.Height();
1445 else
1447 Reference< XWindowPeer > xPeer = ImplGetCompatiblePeer( sal_True );
1448 Reference< XDevice > xD( xPeer, UNO_QUERY );
1450 SimpleFontMetric aFM;
1451 FontDescriptor aFD;
1452 Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_FONTDESCRIPTOR ) );
1453 aVal >>= aFD;
1454 if ( !aFD.StyleName.isEmpty() )
1456 Reference< XFont > xFont = xD->getFont( aFD );
1457 aFM = xFont->getFontMetric();
1459 else
1461 Reference< XGraphics > xG = xD->createGraphics();
1462 aFM = xG->getFontMetric();
1465 sal_Int16 nH = aFM.Ascent + aFM.Descent;
1466 sal_Int16 nW = nH/2; // calculate avarage width?!
1468 nX *= nW;
1469 nX /= 4;
1470 nWidth *= nW;
1471 nWidth /= 4;
1472 nY *= nH;
1473 nY /= 8;
1474 nHeight *= nH;
1475 nHeight /= 8;
1477 Reference < XWindow > xW( rxCtrl, UNO_QUERY );
1478 xW->setPosSize( nX, nY, nWidth, nHeight, PosSize::POSSIZE );
1481 void ControlContainerBase::dispose() throw(RuntimeException)
1483 EventObject aEvt;
1484 aEvt.Source = static_cast< ::cppu::OWeakObject* >( this );
1485 // Notify our listener helper about dispose
1486 // --- SAFE ---
1488 SolarMutexClearableGuard aGuard;
1489 Reference< XEventListener > xListener( mxListener, UNO_QUERY );
1490 mxListener.clear();
1491 aGuard.clear();
1492 // --- SAFE ---
1494 if ( xListener.is() )
1495 xListener->disposing( aEvt );
1496 UnoControlContainer::dispose();
1499 void SAL_CALL ControlContainerBase::disposing(
1500 const EventObject& Source )
1501 throw(RuntimeException)
1503 UnoControlContainer::disposing( Source );
1506 sal_Bool ControlContainerBase::setModel( const Reference< XControlModel >& rxModel ) throw(RuntimeException)
1508 SolarMutexGuard aGuard;
1510 // destroy the old tab controller, if existent
1511 if ( mxTabController.is() )
1513 mxTabController->setModel( NULL ); // just to be sure, should not be necessary
1514 removeTabController( mxTabController );
1515 ::comphelper::disposeComponent( mxTabController ); // just to be sure, should not be necessary
1516 mxTabController.clear();
1519 if ( getModel().is() )
1521 Sequence< Reference< XControl > > aControls = getControls();
1522 const Reference< XControl >* pCtrls = aControls.getConstArray();
1523 const Reference< XControl >* pCtrlsEnd = pCtrls + aControls.getLength();
1525 for ( ; pCtrls < pCtrlsEnd; ++pCtrls )
1526 removeControl( *pCtrls );
1527 // will implicitly call removingControl, which will remove the PropertyChangeListener
1528 // (which we formerly did herein)
1529 // 08.01.2001 - 96008 - fs@openoffice.org
1531 Reference< XContainer > xC( getModel(), UNO_QUERY );
1532 if ( xC.is() )
1533 xC->removeContainerListener( this );
1535 Reference< XChangesNotifier > xChangeNotifier( getModel(), UNO_QUERY );
1536 if ( xChangeNotifier.is() )
1537 xChangeNotifier->removeChangesListener( this );
1540 sal_Bool bRet = UnoControl::setModel( rxModel );
1542 if ( getModel().is() )
1544 Reference< XNameAccess > xNA( getModel(), UNO_QUERY );
1545 if ( xNA.is() )
1547 Sequence< ::rtl::OUString > aNames = xNA->getElementNames();
1548 const ::rtl::OUString* pNames = aNames.getConstArray();
1549 sal_uInt32 nCtrls = aNames.getLength();
1551 Reference< XControlModel > xCtrlModel;
1552 for( sal_uInt32 n = 0; n < nCtrls; ++n, ++pNames )
1554 xNA->getByName( *pNames ) >>= xCtrlModel;
1555 ImplInsertControl( xCtrlModel, *pNames );
1559 Reference< XContainer > xC( getModel(), UNO_QUERY );
1560 if ( xC.is() )
1561 xC->addContainerListener( this );
1563 Reference< XChangesNotifier > xChangeNotifier( getModel(), UNO_QUERY );
1564 if ( xChangeNotifier.is() )
1565 xChangeNotifier->addChangesListener( this );
1568 Reference< XTabControllerModel > xTabbing( getModel(), UNO_QUERY );
1569 if ( xTabbing.is() )
1571 mxTabController = new StdTabController;
1572 mxTabController->setModel( xTabbing );
1573 addTabController( mxTabController );
1575 ImplStartListingForResourceEvents();
1577 return bRet;
1579 void ControlContainerBase::setDesignMode( sal_Bool bOn ) throw(RuntimeException)
1581 SolarMutexGuard aGuard;
1583 UnoControl::setDesignMode( bOn );
1585 Sequence< Reference< XControl > > xCtrls = getControls();
1586 sal_Int32 nControls = xCtrls.getLength();
1587 Reference< XControl >* pControls = xCtrls.getArray();
1588 for ( sal_Int32 n = 0; n < nControls; n++ )
1589 pControls[n]->setDesignMode( bOn );
1591 // #109067# in design mode the tab controller is not notified about
1592 // tab index changes, therefore the tab order must be activated
1593 // when switching from design mode to live mode
1594 if ( mxTabController.is() && !bOn )
1595 mxTabController->activateTabOrder();
1598 void ControlContainerBase::elementInserted( const ContainerEvent& Event ) throw(RuntimeException)
1600 SolarMutexGuard aGuard;
1602 Reference< XControlModel > xModel;
1603 ::rtl::OUString aName;
1605 Event.Accessor >>= aName;
1606 Event.Element >>= xModel;
1607 ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementInserted: illegal element!" );
1610 ImplInsertControl( xModel, aName );
1612 catch (const RuntimeException&)
1614 throw;
1616 catch (const Exception&)
1618 DBG_UNHANDLED_EXCEPTION();
1622 void ControlContainerBase::elementRemoved( const ContainerEvent& Event ) throw(RuntimeException)
1624 SolarMutexGuard aGuard;
1626 Reference< XControlModel > xModel;
1627 Event.Element >>= xModel;
1628 ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementRemoved: illegal element!" );
1631 ImplRemoveControl( xModel );
1633 catch (const RuntimeException&)
1635 throw;
1637 catch (const Exception&)
1639 DBG_UNHANDLED_EXCEPTION();
1643 void ControlContainerBase::elementReplaced( const ContainerEvent& Event ) throw(RuntimeException)
1645 SolarMutexGuard aGuard;
1647 Reference< XControlModel > xModel;
1648 Event.ReplacedElement >>= xModel;
1651 OSL_ENSURE( xModel.is(), "ControlContainerBase::elementReplaced: invalid ReplacedElement!" );
1652 if ( xModel.is() )
1653 ImplRemoveControl( xModel );
1655 catch (const RuntimeException&)
1657 throw;
1659 catch (const Exception&)
1661 DBG_UNHANDLED_EXCEPTION();
1664 ::rtl::OUString aName;
1665 Event.Accessor >>= aName;
1666 Event.Element >>= xModel;
1667 ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementReplaced: invalid new element!" );
1670 ImplInsertControl( xModel, aName );
1672 catch (const RuntimeException&)
1674 throw;
1676 catch (const Exception&)
1678 DBG_UNHANDLED_EXCEPTION();
1682 // XPropertiesChangeListener
1683 void ControlContainerBase::ImplModelPropertiesChanged( const Sequence< PropertyChangeEvent >& rEvents ) throw(RuntimeException)
1685 if( !isDesignMode() && !mbCreatingCompatiblePeer )
1687 ::rtl::OUString s1( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) );
1688 ::rtl::OUString s2( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) );
1689 ::rtl::OUString s3( RTL_CONSTASCII_USTRINGPARAM( "Width" ) );
1690 ::rtl::OUString s4( RTL_CONSTASCII_USTRINGPARAM( "Height" ) );
1692 sal_Int32 nLen = rEvents.getLength();
1693 for( sal_Int32 i = 0; i < nLen; i++ )
1695 const PropertyChangeEvent& rEvt = rEvents.getConstArray()[i];
1696 Reference< XControlModel > xModel( rEvt.Source, UNO_QUERY );
1697 sal_Bool bOwnModel = (XControlModel*)xModel.get() == (XControlModel*)getModel().get();
1698 if ( ( rEvt.PropertyName == s1 ) ||
1699 ( rEvt.PropertyName == s2 ) ||
1700 ( rEvt.PropertyName == s3 ) ||
1701 ( rEvt.PropertyName == s4 ) )
1703 if ( bOwnModel )
1705 if ( !mbPosModified && !mbSizeModified )
1707 // Don't set new pos/size if we get new values from window listener
1708 Reference< XControl > xThis( (XAggregation*)(::cppu::OWeakAggObject*)this, UNO_QUERY );
1709 ImplSetPosSize( xThis );
1712 else
1714 Sequence<Reference<XControl> > aControlSequence(getControls());
1715 Reference<XControl> aControlRef( StdTabController::FindControl( aControlSequence, xModel ) );
1716 ImplSetPosSize( aControlRef );
1718 break;
1723 UnoControlContainer::ImplModelPropertiesChanged( rEvents );
1726 void ControlContainerBase::addingControl( const Reference< XControl >& _rxControl )
1728 SolarMutexGuard aGuard;
1729 UnoControlContainer::addingControl( _rxControl );
1731 if ( _rxControl.is() )
1733 Reference< XMultiPropertySet > xProps( _rxControl->getModel(), UNO_QUERY );
1734 if ( xProps.is() )
1736 Sequence< ::rtl::OUString > aNames( 4 );
1737 ::rtl::OUString* pNames = aNames.getArray();
1738 *pNames++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PositionX") );
1739 *pNames++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PositionY") );
1740 *pNames++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Width"));
1741 *pNames++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Height"));
1743 xProps->addPropertiesChangeListener( aNames, this );
1748 void ControlContainerBase::removingControl( const Reference< XControl >& _rxControl )
1750 SolarMutexGuard aGuard;
1751 UnoControlContainer::removingControl( _rxControl );
1753 if ( _rxControl.is() )
1755 Reference< XMultiPropertySet > xProps( _rxControl->getModel(), UNO_QUERY );
1756 if ( xProps.is() )
1757 xProps->removePropertiesChangeListener( this );
1762 void SAL_CALL ControlContainerBase::changesOccurred( const ChangesEvent& ) throw (RuntimeException)
1764 SolarMutexGuard aGuard;
1765 // a tab controller model may have changed
1767 // #109067# in design mode don't notify the tab controller
1768 // about tab index changes
1769 if ( mxTabController.is() && !mbDesignMode )
1770 mxTabController->activateTabOrder();
1772 static void lcl_ApplyResolverToNestedContainees( const Reference< resource::XStringResourceResolver >& xStringResourceResolver, const Reference< XControlContainer >& xContainer )
1774 rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER );
1776 Any xNewStringResourceResolver; xNewStringResourceResolver <<= xStringResourceResolver;
1778 Sequence< rtl::OUString > aPropNames(1);
1779 aPropNames[0] = aPropName;
1781 const Sequence< Reference< awt::XControl > > aSeq = xContainer->getControls();
1782 for ( sal_Int32 i = 0; i < aSeq.getLength(); i++ )
1784 Reference< XControl > xControl( aSeq[i] );
1785 Reference< XPropertySet > xPropertySet;
1787 if ( xControl.is() )
1788 xPropertySet = Reference< XPropertySet >( xControl->getModel(), UNO_QUERY );
1790 if ( !xPropertySet.is() )
1791 continue;
1795 Reference< resource::XStringResourceResolver > xCurrStringResourceResolver;
1796 Any aOldValue = xPropertySet->getPropertyValue( aPropName );
1797 if ( ( aOldValue >>= xCurrStringResourceResolver )
1798 && ( xStringResourceResolver == xCurrStringResourceResolver )
1801 Reference< XMultiPropertySet > xMultiPropSet( xPropertySet, UNO_QUERY );
1802 Reference< XPropertiesChangeListener > xListener( xPropertySet, UNO_QUERY );
1803 xMultiPropSet->firePropertiesChangeEvent( aPropNames, xListener );
1805 else
1806 xPropertySet->setPropertyValue( aPropName, xNewStringResourceResolver );
1808 catch (const Exception&)
1812 uno::Reference< XControlContainer > xNestedContainer( xControl, uno::UNO_QUERY );
1813 if ( xNestedContainer.is() )
1814 lcl_ApplyResolverToNestedContainees( xStringResourceResolver, xNestedContainer );
1819 void ControlContainerBase::ImplStartListingForResourceEvents()
1821 Reference< resource::XStringResourceResolver > xStringResourceResolver;
1823 ImplGetPropertyValue( PROPERTY_RESOURCERESOLVER ) >>= xStringResourceResolver;
1825 // Add our helper as listener to retrieve notifications about changes
1826 Reference< util::XModifyListener > rListener( mxListener );
1827 ResourceListener* pResourceListener = static_cast< ResourceListener* >( rListener.get() );
1829 // resource listener will stop listening if resolver reference is empty
1830 if ( pResourceListener )
1831 pResourceListener->startListening( xStringResourceResolver );
1832 ImplUpdateResourceResolver();
1835 void ControlContainerBase::ImplUpdateResourceResolver()
1837 rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER );
1838 Reference< resource::XStringResourceResolver > xStringResourceResolver;
1840 ImplGetPropertyValue( aPropName ) >>= xStringResourceResolver;
1841 if ( !xStringResourceResolver.is() )
1842 return;
1844 lcl_ApplyResolverToNestedContainees( xStringResourceResolver, this );
1846 // propagate resource resolver changes to language dependent props of the dialog
1847 Reference< XPropertySet > xPropertySet( getModel(), UNO_QUERY );
1848 if ( xPropertySet.is() )
1850 Reference< XMultiPropertySet > xMultiPropSet( xPropertySet, UNO_QUERY );
1851 Reference< XPropertiesChangeListener > xListener( xPropertySet, UNO_QUERY );
1852 xMultiPropSet->firePropertiesChangeEvent( lcl_getLanguageDependentProperties(), xListener );
1856 //// ----------------------------------------------------
1857 //// Helper Method to convert relative url to physical location
1858 //// ----------------------------------------------------
1860 ::rtl::OUString getPhysicalLocation( const ::com::sun::star::uno::Any& rbase, const ::com::sun::star::uno::Any& rUrl )
1863 ::rtl::OUString baseLocation;
1864 ::rtl::OUString url;
1866 rbase >>= baseLocation;
1867 rUrl >>= url;
1869 ::rtl::OUString absoluteURL( url );
1870 if ( !url.isEmpty() )
1872 INetURLObject urlObj(baseLocation);
1873 urlObj.removeSegment();
1874 baseLocation = urlObj.GetMainURL( INetURLObject::NO_DECODE );
1876 const INetURLObject protocolCheck( url );
1877 const INetProtocol protocol = protocolCheck.GetProtocol();
1878 if ( protocol == INET_PROT_NOT_VALID )
1880 ::rtl::OUString testAbsoluteURL;
1881 if ( ::osl::FileBase::E_None == ::osl::FileBase::getAbsoluteFileURL( baseLocation, url, testAbsoluteURL ) )
1882 absoluteURL = testAbsoluteURL;
1886 return absoluteURL;
1889 void
1890 ControlModelContainerBase::updateUserFormChildren( const Reference< XNameContainer >& xAllChildren, const rtl::OUString& aName, ChildOperation Operation, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& xTarget ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
1892 if ( Operation < Insert || Operation > Remove )
1893 throw IllegalArgumentException();
1895 if ( xAllChildren.is() )
1897 if ( Operation == Remove )
1899 Reference< XControlModel > xOldModel( xAllChildren->getByName( aName ), UNO_QUERY );
1900 xAllChildren->removeByName( aName );
1902 Reference< XNameContainer > xChildContainer( xOldModel, UNO_QUERY );
1903 if ( xChildContainer.is() )
1905 Reference< XPropertySet > xProps( xChildContainer, UNO_QUERY );
1906 // container control is being removed from this container, reset the
1907 // global list of containees
1908 if ( xProps.is() )
1909 xProps->setPropertyValue( GetPropertyName( BASEPROPERTY_USERFORMCONTAINEES ), uno::makeAny( uno::Reference< XNameContainer >() ) );
1910 Sequence< rtl::OUString > aChildNames = xChildContainer->getElementNames();
1911 for ( sal_Int32 index=0; index< aChildNames.getLength(); ++index )
1912 updateUserFormChildren( xAllChildren, aChildNames[ index ], Operation, Reference< XControlModel > () );
1915 else if ( Operation == Insert )
1917 xAllChildren->insertByName( aName, uno::makeAny( xTarget ) );
1918 Reference< XNameContainer > xChildContainer( xTarget, UNO_QUERY );
1919 if ( xChildContainer.is() )
1921 // container control is being added from this container, reset the
1922 // global list of containees to point to the correct global list
1923 Reference< XPropertySet > xProps( xChildContainer, UNO_QUERY );
1924 if ( xProps.is() )
1925 xProps->setPropertyValue( GetPropertyName( BASEPROPERTY_USERFORMCONTAINEES ), uno::makeAny( xAllChildren ) );
1926 Sequence< rtl::OUString > aChildNames = xChildContainer->getElementNames();
1927 for ( sal_Int32 index=0; index< aChildNames.getLength(); ++index )
1929 Reference< XControlModel > xChildTarget( xChildContainer->getByName( aChildNames[ index ] ), UNO_QUERY );
1930 updateUserFormChildren( xAllChildren, aChildNames[ index ], Operation, xChildTarget );
1935 else
1936 throw IllegalArgumentException();
1939 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */