1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_toolkit.hxx"
26
27 #include <toolkit/controls/controlmodelcontainerbase.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/window.hxx>
30 #include <vcl/wall.hxx>
31 #include <vos/mutex.hxx>
32 #include <toolkit/helper/property.hxx>
33 #include <toolkit/helper/unopropertyarrayhelper.hxx>
34 #include <toolkit/controls/geometrycontrolmodel.hxx>
35 #include <toolkit/controls/unocontrols.hxx>
36 #include "toolkit/controls/formattedcontrol.hxx"
37 #include "toolkit/controls/roadmapcontrol.hxx"
38 #include "toolkit/controls/tkscrollbar.hxx"
39 #include "toolkit/controls/tabpagemodel.hxx"
40 #include <toolkit/controls/stdtabcontroller.hxx>
41 #include <com/sun/star/awt/PosSize.hpp>
42 #include <com/sun/star/awt/WindowAttribute.hpp>
43 #include <com/sun/star/resource/XStringResourceResolver.hpp>
44 #include <com/sun/star/graphic/XGraphicProvider.hpp>
45 #include <com/sun/star/lang/XInitialization.hpp>
46 #include <tools/list.hxx>
47 #include <cppuhelper/typeprovider.hxx>
48 #include <tools/debug.hxx>
49 #include <tools/diagnose_ex.h>
50 #include <comphelper/processfactory.hxx>
51 #include <vcl/svapp.hxx>
52 #include <vcl/outdev.hxx>
53 #include <comphelper/types.hxx>
54
55 #include <comphelper/componentcontext.hxx>
56 #include <toolkit/helper/vclunohelper.hxx>
57 #include <toolkit/helper/tkresmgr.hxx>
58 #include <unotools/ucbstreamhelper.hxx>
59 #include <vcl/graph.hxx>
60 #include <vcl/image.hxx>
61
62 #include "tree/treecontrol.hxx"
63 #include "grid/gridcontrol.hxx"
64 #include <toolkit/controls/tabpagecontainer.hxx>
65
66 #include <map>
67 #include <algorithm>
68 #include <functional>
69 #include "tools/urlobj.hxx"
70 #include "osl/file.hxx"
71
72 using namespace ::com::sun::star;
73 using namespace ::com::sun::star::uno;
74 using namespace ::com::sun::star::awt;
75 using namespace ::com::sun::star::lang;
76 using namespace ::com::sun::star::container;
77 using namespace ::com::sun::star::beans;
78 using namespace ::com::sun::star::util;
79 using namespace toolkit;
80
81 #define PROPERTY_RESOURCERESOLVER ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ))
82
83 //HELPER
84 ::rtl::OUString getPhysicalLocation( const ::com::sun::star::uno::Any& rbase, const ::com::sun::star::uno::Any& rUrl );
85
86 struct LanguageDependentProp
87 {
88 const char* pPropName;
89 sal_Int32 nPropNameLength;
90 };
91
92 // ----------------------------------------------------------------------------
93 namespace
94 {
lcl_getLanguageDependentProperties()95 static const Sequence< ::rtl::OUString >& lcl_getLanguageDependentProperties()
96 {
97 static Sequence< ::rtl::OUString > s_aLanguageDependentProperties;
98 if ( s_aLanguageDependentProperties.getLength() == 0 )
99 {
100 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
101 if ( s_aLanguageDependentProperties.getLength() == 0 )
102 {
103 s_aLanguageDependentProperties.realloc( 2 );
104 s_aLanguageDependentProperties[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HelpText" ) );
105 s_aLanguageDependentProperties[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
106 // note: properties must be sorted
107 }
108 }
109 return s_aLanguageDependentProperties;
110 }
111 }
112
113 // ----------------------------------------------------------------------------
114 // functor for disposing a control model
115 struct DisposeControlModel : public ::std::unary_function< Reference< XControlModel >, void >
116 {
operator ()DisposeControlModel117 void operator()( Reference< XControlModel >& _rxModel )
118 {
119 try
120 {
121 ::comphelper::disposeComponent( _rxModel );
122 }
123 catch( const Exception& )
124 {
125 DBG_ERROR( "DisposeControlModel::(): caught an exception while disposing a component!" );
126 }
127 }
128 };
129
130 // ----------------------------------------------------------------------------
131 // functor for searching control model by name
132 struct FindControlModel : public ::std::unary_function< ControlModelContainerBase::UnoControlModelHolder, bool >
133 {
134 private:
135 const ::rtl::OUString& m_rName;
136
137 public:
FindControlModelFindControlModel138 FindControlModel( const ::rtl::OUString& _rName ) : m_rName( _rName ) { }
139
operator ()FindControlModel140 bool operator()( const ControlModelContainerBase::UnoControlModelHolder& _rCompare )
141 {
142 return ( _rCompare.second == m_rName ) ? true : false;
143 }
144 };
145
146 // ----------------------------------------------------------------------------
147 // functor for cloning a control model, and insertion into a target list
148 struct CloneControlModel : public ::std::unary_function< ControlModelContainerBase::UnoControlModelHolder, void >
149 {
150 private:
151 ControlModelContainerBase::UnoControlModelHolderList& m_rTargetList;
152
153 public:
CloneControlModelCloneControlModel154 CloneControlModel( ControlModelContainerBase::UnoControlModelHolderList& _rTargetList )
155 :m_rTargetList( _rTargetList )
156 {
157 }
158
operator ()CloneControlModel159 void operator()( const ControlModelContainerBase::UnoControlModelHolder& _rSource )
160 {
161 // clone the source object
162 Reference< XCloneable > xCloneSource( _rSource.first, UNO_QUERY );
163 Reference< XControlModel > xClone( xCloneSource->createClone(), UNO_QUERY );
164 // add to target list
165 m_rTargetList.push_back( ControlModelContainerBase::UnoControlModelHolder( xClone, _rSource.second ) );
166 }
167 };
168
169 // ----------------------------------------------------------------------------
170 // functor for comparing a XControlModel with a given reference
171 struct CompareControlModel : public ::std::unary_function< ControlModelContainerBase::UnoControlModelHolder, bool >
172 {
173 private:
174 Reference< XControlModel > m_xReference;
175 public:
CompareControlModelCompareControlModel176 CompareControlModel( const Reference< XControlModel >& _rxReference ) : m_xReference( _rxReference ) { }
177
operator ()CompareControlModel178 bool operator()( const ControlModelContainerBase::UnoControlModelHolder& _rCompare )
179 {
180 return ( _rCompare.first.get() == m_xReference.get() ) ? true : false;
181 }
182 };
183
184 // ----------------------------------------------------------------------------
lcl_throwIllegalArgumentException()185 static void lcl_throwIllegalArgumentException( )
186 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
187 throw IllegalArgumentException();
188 }
189
190 // ----------------------------------------------------------------------------
lcl_throwNoSuchElementException()191 static void lcl_throwNoSuchElementException( )
192 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
193 throw NoSuchElementException();
194 }
195
196 // ----------------------------------------------------------------------------
lcl_throwElementExistException()197 static void lcl_throwElementExistException( )
198 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
199 throw ElementExistException();
200 }
201
202 // ----------------------------------------------------------------------------
getTabIndexPropertyName()203 static const ::rtl::OUString& getTabIndexPropertyName( )
204 {
205 static const ::rtl::OUString s_sTabIndexProperty( RTL_CONSTASCII_USTRINGPARAM( "TabIndex" ) );
206 return s_sTabIndexProperty;
207 }
208
209 // ----------------------------------------------------------------------------
getStepPropertyName()210 static const ::rtl::OUString& getStepPropertyName( )
211 {
212 static const ::rtl::OUString s_sStepProperty( RTL_CONSTASCII_USTRINGPARAM( "Step" ) );
213 return s_sStepProperty;
214 }
215
216 // ----------------------------------------------------
217 // class ControlModelContainerBase
218 // ----------------------------------------------------
ControlModelContainerBase(const Reference<XMultiServiceFactory> & i_factory)219 ControlModelContainerBase::ControlModelContainerBase( const Reference< XMultiServiceFactory >& i_factory )
220 :ControlModelContainer_IBase( i_factory )
221 ,maContainerListeners( *this )
222 ,maChangeListeners ( GetMutex() )
223 ,mbGroupsUpToDate( sal_False )
224 ,m_bEnabled( sal_True )
225 {
226 }
227
ControlModelContainerBase(const ControlModelContainerBase & rModel)228 ControlModelContainerBase::ControlModelContainerBase( const ControlModelContainerBase& rModel )
229 : ControlModelContainer_IBase( rModel )
230 , maContainerListeners( *this )
231 , maChangeListeners ( GetMutex() )
232 , mbGroupsUpToDate( sal_False )
233 {
234 }
235
~ControlModelContainerBase()236 ControlModelContainerBase::~ControlModelContainerBase()
237 {
238 maModels.clear();
239 mbGroupsUpToDate = sal_False;
240 }
241
ImplGetDefaultValue(sal_uInt16 nPropId) const242 Any ControlModelContainerBase::ImplGetDefaultValue( sal_uInt16 nPropId ) const
243 {
244 Any aAny;
245
246 switch ( nPropId )
247 {
248 case BASEPROPERTY_DEFAULTCONTROL:
249 aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlDialog );
250 break;
251 default:
252 aAny = UnoControlModel::ImplGetDefaultValue( nPropId );
253 }
254
255 return aAny;
256 }
257
getInfoHelper()258 ::cppu::IPropertyArrayHelper& ControlModelContainerBase::getInfoHelper()
259 {
260 static UnoPropertyArrayHelper* pHelper = NULL;
261 if ( !pHelper )
262 {
263 Sequence<sal_Int32> aIDs = ImplGetPropertyIds();
264 pHelper = new UnoPropertyArrayHelper( aIDs );
265 }
266 return *pHelper;
267 }
268
dispose()269 void SAL_CALL ControlModelContainerBase::dispose( )
270 {
271 // ====================================================================
272 // tell our listeners
273 {
274 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
275
276 EventObject aDisposeEvent;
277 aDisposeEvent.Source = static_cast< XAggregation* >( static_cast< ::cppu::OWeakAggObject* >( this ) );
278
279 maContainerListeners.disposeAndClear( aDisposeEvent );
280 maChangeListeners.disposeAndClear( aDisposeEvent );
281 }
282
283 // ====================================================================
284 // call the base class
285 UnoControlModel::dispose();
286
287 // ====================================================================
288 // dispose our child models
289 // for this, collect the models (we collect them from maModels, and this is modified when disposing children)
290 ::std::vector< Reference< XControlModel > > aChildModels( maModels.size() );
291
292 ::std::transform(
293 maModels.begin(), maModels.end(), // source range
294 aChildModels.begin(), // target location
295 ::std::select1st< UnoControlModelHolder >( ) // operation to apply -> select the XControlModel part
296 );
297
298 // now dispose
299 ::std::for_each( aChildModels.begin(), aChildModels.end(), DisposeControlModel() );
300 aChildModels.clear();
301
302 mbGroupsUpToDate = sal_False;
303 }
304
305 // XMultiPropertySet
getPropertySetInfo()306 Reference< XPropertySetInfo > ControlModelContainerBase::getPropertySetInfo( )
307 {
308 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
309 return xInfo;
310 }
Clone_Impl(ControlModelContainerBase & _rClone) const311 void ControlModelContainerBase::Clone_Impl(ControlModelContainerBase& _rClone) const
312 {
313 // clone all children
314 ::std::for_each(
315 maModels.begin(), maModels.end(),
316 CloneControlModel( _rClone.maModels )
317 );
318 }
Clone() const319 UnoControlModel* ControlModelContainerBase::Clone() const
320 {
321 // clone the container itself
322 ControlModelContainerBase* pClone = new ControlModelContainerBase( *this );
323 Clone_Impl(*pClone);
324
325 return pClone;
326 }
327
ImplFindElement(const::rtl::OUString & rName)328 ControlModelContainerBase::UnoControlModelHolderList::iterator ControlModelContainerBase::ImplFindElement( const ::rtl::OUString& rName )
329 {
330 return ::std::find_if( maModels.begin(), maModels.end(), FindControlModel( rName ) );
331 }
332
333 // ::XMultiServiceFactory
createInstance(const::rtl::OUString & aServiceSpecifier)334 Reference< XInterface > ControlModelContainerBase::createInstance( const ::rtl::OUString& aServiceSpecifier )
335 {
336 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
337
338 OGeometryControlModel_Base* pNewModel = NULL;
339
340 const Reference< XMultiServiceFactory > xFactory( maContext.getLegacyServiceFactory() );
341 if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlEditModel ) == 0 )
342 pNewModel = new OGeometryControlModel< UnoControlEditModel >( xFactory );
343 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFormattedFieldModel ) == 0 )
344 pNewModel = new OGeometryControlModel< UnoControlFormattedFieldModel >( xFactory );
345 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFileControlModel ) == 0 )
346 pNewModel = new OGeometryControlModel< UnoControlFileControlModel >( xFactory );
347 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlButtonModel ) == 0 )
348 pNewModel = new OGeometryControlModel< UnoControlButtonModel >( xFactory );
349 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlImageControlModel ) == 0 )
350 pNewModel = new OGeometryControlModel< UnoControlImageControlModel >( xFactory );
351 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRadioButtonModel ) == 0 )
352 pNewModel = new OGeometryControlModel< UnoControlRadioButtonModel >( xFactory );
353 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCheckBoxModel ) == 0 )
354 pNewModel = new OGeometryControlModel< UnoControlCheckBoxModel >( xFactory );
355 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedHyperlinkModel ) == 0 )
356 pNewModel = new OGeometryControlModel< UnoControlFixedHyperlinkModel >( xFactory );
357 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedTextModel ) == 0 )
358 pNewModel = new OGeometryControlModel< UnoControlFixedTextModel >( xFactory );
359 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlGroupBoxModel ) == 0 )
360 pNewModel = new OGeometryControlModel< UnoControlGroupBoxModel >( xFactory );
361 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlListBoxModel ) == 0 )
362 pNewModel = new OGeometryControlModel< UnoControlListBoxModel >( xFactory );
363 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlComboBoxModel ) == 0 )
364 pNewModel = new OGeometryControlModel< UnoControlComboBoxModel >( xFactory );
365 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlDateFieldModel ) == 0 )
366 pNewModel = new OGeometryControlModel< UnoControlDateFieldModel >( xFactory );
367 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlTimeFieldModel ) == 0 )
368 pNewModel = new OGeometryControlModel< UnoControlTimeFieldModel >( xFactory );
369 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlNumericFieldModel ) == 0 )
370 pNewModel = new OGeometryControlModel< UnoControlNumericFieldModel >( xFactory );
371 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCurrencyFieldModel ) == 0 )
372 pNewModel = new OGeometryControlModel< UnoControlCurrencyFieldModel >( xFactory );
373 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlPatternFieldModel ) == 0 )
374 pNewModel = new OGeometryControlModel< UnoControlPatternFieldModel >( xFactory );
375 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlProgressBarModel ) == 0 )
376 pNewModel = new OGeometryControlModel< UnoControlProgressBarModel >( xFactory );
377 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlScrollBarModel ) == 0 )
378 pNewModel = new OGeometryControlModel< UnoControlScrollBarModel >( xFactory );
379 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFixedLineModel ) == 0 )
380 pNewModel = new OGeometryControlModel< UnoControlFixedLineModel >( xFactory );
381 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRoadmapModel ) == 0 )
382 pNewModel = new OGeometryControlModel< UnoControlRoadmapModel >( xFactory );
383 else if ( aServiceSpecifier.compareToAscii( szServiceName_TreeControlModel ) == 0 )
384 pNewModel = new OGeometryControlModel< UnoTreeModel >( xFactory );
385 else if ( aServiceSpecifier.compareToAscii( szServiceName_GridControlModel ) == 0 )
386 pNewModel = new OGeometryControlModel< UnoGridModel >( xFactory );
387 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlTabPageContainerModel ) == 0 )
388 pNewModel = new OGeometryControlModel< UnoControlTabPageContainerModel >( xFactory );
389 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlTabPageModel ) == 0 )
390 pNewModel = new OGeometryControlModel< UnoControlTabPageModel >( xFactory );
391
392 if ( !pNewModel )
393 {
394 if ( xFactory.is() )
395 {
396 Reference< XInterface > xObject = xFactory->createInstance( aServiceSpecifier );
397 Reference< XServiceInfo > xSI( xObject, UNO_QUERY );
398 Reference< XCloneable > xCloneAccess( xSI, UNO_QUERY );
399 Reference< XAggregation > xAgg( xCloneAccess, UNO_QUERY );
400 if ( xAgg.is() )
401 {
402 if ( xSI->supportsService( ::rtl::OUString::createFromAscii( "com.sun.star.awt.UnoControlModel" ) ) )
403 {
404 // release 3 of the 4 references we have to the object
405 xAgg.clear();
406 xSI.clear();
407 xObject.clear();
408
409 pNewModel = new OCommonGeometryControlModel( xCloneAccess, aServiceSpecifier );
410 }
411 }
412 }
413 }
414
415 Reference< XInterface > xNewModel = (::cppu::OWeakObject*)pNewModel;
416 return xNewModel;
417 }
418
createInstanceWithArguments(const::rtl::OUString & ServiceSpecifier,const Sequence<Any> & i_arguments)419 Reference< XInterface > ControlModelContainerBase::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& i_arguments )
420 {
421 const Reference< XInterface > xInstance( createInstance( ServiceSpecifier ) );
422 const Reference< XInitialization > xInstanceInit( xInstance, UNO_QUERY );
423 ENSURE_OR_RETURN( xInstanceInit.is(), "ControlModelContainerBase::createInstanceWithArguments: can't pass the arguments!", xInstance );
424 xInstanceInit->initialize( i_arguments );
425 return xInstance;
426 }
427
getAvailableServiceNames()428 Sequence< ::rtl::OUString > ControlModelContainerBase::getAvailableServiceNames()
429 {
430 static Sequence< ::rtl::OUString >* pNamesSeq = NULL;
431 if ( !pNamesSeq )
432 {
433 pNamesSeq = new Sequence< ::rtl::OUString >( 24 );
434 ::rtl::OUString* pNames = pNamesSeq->getArray();
435 pNames[0] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlEditModel );
436 pNames[1] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFormattedFieldModel );
437 pNames[2] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFileControlModel );
438 pNames[3] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlButtonModel );
439 pNames[4] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlImageControlModel );
440 pNames[5] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRadioButtonModel );
441 pNames[6] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlCheckBoxModel );
442 pNames[7] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFixedTextModel );
443 pNames[8] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlGroupBoxModel );
444 pNames[9] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlListBoxModel );
445 pNames[10] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlComboBoxModel );
446 pNames[11] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlDateFieldModel );
447 pNames[12] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlTimeFieldModel );
448 pNames[13] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlNumericFieldModel );
449 pNames[14] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlCurrencyFieldModel );
450 pNames[15] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlPatternFieldModel );
451 pNames[16] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlProgressBarModel );
452 pNames[17] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlScrollBarModel );
453 pNames[18] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFixedLineModel );
454 pNames[19] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRoadmapModel );
455 pNames[20] = ::rtl::OUString::createFromAscii( szServiceName_TreeControlModel );
456 pNames[21] = ::rtl::OUString::createFromAscii( szServiceName_GridControlModel );
457 pNames[22] = ::rtl::OUString::createFromAscii( szServiceName_UnoControlTabPageContainerModel );
458 pNames[23] = ::rtl::OUString::createFromAscii( szServiceName_UnoControlTabPageModel );
459 }
460 return *pNamesSeq;
461 }
462
463 // XContainer
addContainerListener(const Reference<XContainerListener> & l)464 void ControlModelContainerBase::addContainerListener( const Reference< XContainerListener >& l )
465 {
466 maContainerListeners.addInterface( l );
467 }
468
removeContainerListener(const Reference<XContainerListener> & l)469 void ControlModelContainerBase::removeContainerListener( const Reference< XContainerListener >& l )
470 {
471 maContainerListeners.removeInterface( l );
472 }
473
474 // XElementAcces
getElementType()475 Type ControlModelContainerBase::getElementType()
476 {
477 Type aType = getCppuType( ( Reference< XControlModel>* ) NULL );
478 return aType;
479 }
480
hasElements()481 sal_Bool ControlModelContainerBase::hasElements()
482 {
483 return !maModels.empty();
484 }
485
486 // XNameContainer, XNameReplace, XNameAccess
replaceByName(const::rtl::OUString & aName,const Any & aElement)487 void ControlModelContainerBase::replaceByName( const ::rtl::OUString& aName, const Any& aElement )
488 {
489 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
490
491 Reference< XControlModel > xNewModel;
492 aElement >>= xNewModel;
493 if ( !xNewModel.is() )
494 lcl_throwIllegalArgumentException();
495
496 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
497 if ( maModels.end() == aElementPos )
498 lcl_throwNoSuchElementException();
499
500 // stop listening at the old model
501 stopControlListening( aElementPos->first );
502 Reference< XControlModel > xReplaced( aElementPos->first );
503 // remember the new model, and start listening
504 aElementPos->first = xNewModel;
505 startControlListening( xNewModel );
506
507 ContainerEvent aEvent;
508 aEvent.Source = *this;
509 aEvent.Element = aElement;
510 aEvent.ReplacedElement <<= xReplaced;
511 aEvent.Accessor <<= aName;
512
513 // notify the container listener
514 maContainerListeners.elementReplaced( aEvent );
515
516 // our "tab controller model" has potentially changed -> notify this
517 implNotifyTabModelChange( aName );
518 }
519
getByName(const::rtl::OUString & aName)520 Any ControlModelContainerBase::getByName( const ::rtl::OUString& aName )
521 {
522 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
523 if ( maModels.end() == aElementPos )
524 lcl_throwNoSuchElementException();
525
526 return makeAny( aElementPos->first );
527 }
528
getElementNames()529 Sequence< ::rtl::OUString > ControlModelContainerBase::getElementNames()
530 {
531 Sequence< ::rtl::OUString > aNames( maModels.size() );
532
533 ::std::transform(
534 maModels.begin(), maModels.end(), // source range
535 aNames.getArray(), // target range
536 ::std::select2nd< UnoControlModelHolder >() // operator to apply: select the second element (the name)
537 );
538
539 return aNames;
540 }
541
hasByName(const::rtl::OUString & aName)542 sal_Bool ControlModelContainerBase::hasByName( const ::rtl::OUString& aName )
543 {
544 return maModels.end() != ImplFindElement( aName );
545 }
546
insertByName(const::rtl::OUString & aName,const Any & aElement)547 void ControlModelContainerBase::insertByName( const ::rtl::OUString& aName, const Any& aElement )
548 {
549 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
550
551 Reference< XControlModel > xM;
552 aElement >>= xM;
553
554 if ( xM.is() )
555 {
556 Reference< beans::XPropertySet > xProps( xM, UNO_QUERY );
557 if ( xProps.is() )
558 {
559
560 Reference< beans::XPropertySetInfo > xPropInfo = xProps.get()->getPropertySetInfo();
561
562 ::rtl::OUString sImageSourceProperty = GetPropertyName( BASEPROPERTY_IMAGEURL );
563 if ( xPropInfo.get()->hasPropertyByName( sImageSourceProperty ) && ImplHasProperty(BASEPROPERTY_DIALOGSOURCEURL) )
564 {
565 Any aUrl = xProps.get()->getPropertyValue( sImageSourceProperty );
566
567 ::rtl::OUString absoluteUrl =
568 getPhysicalLocation( getPropertyValue( GetPropertyName( BASEPROPERTY_DIALOGSOURCEURL ) ), aUrl );
569
570 aUrl <<= absoluteUrl;
571
572 xProps.get()->setPropertyValue( sImageSourceProperty , aUrl );
573 }
574 }
575 }
576
577
578
579 if ( !aName.getLength() || !xM.is() )
580 lcl_throwIllegalArgumentException();
581
582 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
583 if ( maModels.end() != aElementPos )
584 lcl_throwElementExistException();
585
586 maModels.push_back( UnoControlModelHolder( xM, aName ) );
587 mbGroupsUpToDate = sal_False;
588 startControlListening( xM );
589
590 ContainerEvent aEvent;
591 aEvent.Source = *this;
592 aEvent.Element <<= aElement;
593 aEvent.Accessor <<= aName;
594 maContainerListeners.elementInserted( aEvent );
595
596 // our "tab controller model" has potentially changed -> notify this
597 implNotifyTabModelChange( aName );
598 }
599
removeByName(const::rtl::OUString & aName)600 void ControlModelContainerBase::removeByName( const ::rtl::OUString& aName )
601 {
602 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
603
604 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
605 if ( maModels.end() == aElementPos )
606 lcl_throwNoSuchElementException();
607
608 ContainerEvent aEvent;
609 aEvent.Source = *this;
610 aEvent.Element <<= aElementPos->first;
611 aEvent.Accessor <<= aName;
612 maContainerListeners.elementRemoved( aEvent );
613
614 stopControlListening( aElementPos->first );
615 Reference< XPropertySet > xPS( aElementPos->first, UNO_QUERY );
616 maModels.erase( aElementPos );
617 mbGroupsUpToDate = sal_False;
618
619 if ( xPS.is() )
620 try
621 {
622 xPS->setPropertyValue( PROPERTY_RESOURCERESOLVER, makeAny( Reference< resource::XStringResourceResolver >() ) );
623 }
624 catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
625
626 // our "tab controller model" has potentially changed -> notify this
627 implNotifyTabModelChange( aName );
628 }
629
630 // ----------------------------------------------------------------------------
getGroupControl()631 sal_Bool SAL_CALL ControlModelContainerBase::getGroupControl( )
632 {
633 return sal_True;
634 }
635
636 // ----------------------------------------------------------------------------
setGroupControl(sal_Bool)637 void SAL_CALL ControlModelContainerBase::setGroupControl( sal_Bool )
638 {
639 DBG_ERROR( "UnoControlDialogModel::setGroupControl: explicit grouping not supported" );
640 }
641
642 // ----------------------------------------------------------------------------
setControlModels(const Sequence<Reference<XControlModel>> & _rControls)643 void SAL_CALL ControlModelContainerBase::setControlModels( const Sequence< Reference< XControlModel > >& _rControls )
644 {
645 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
646
647 // set the tab indexes according to the order of models in the sequence
648 const Reference< XControlModel >* pControls = _rControls.getConstArray( );
649 const Reference< XControlModel >* pControlsEnd = _rControls.getConstArray( ) + _rControls.getLength();
650
651 sal_Int16 nTabIndex = 1;
652
653 for ( ; pControls != pControlsEnd; ++pControls )
654 {
655 // look up the control in our own structure. This is to prevent invalid arguments
656 UnoControlModelHolderList::const_iterator aPos =
657 ::std::find_if(
658 maModels.begin(), maModels.end(),
659 CompareControlModel( *pControls )
660 );
661 if ( maModels.end() != aPos )
662 {
663 // okay, this is an existent model
664 // now set the TabIndex property (if applicable)
665 Reference< XPropertySet > xProps( aPos->first, UNO_QUERY );
666 Reference< XPropertySetInfo > xPSI;
667 if ( xProps.is() )
668 xPSI = xProps->getPropertySetInfo();
669 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
670 xProps->setPropertyValue( getTabIndexPropertyName(), makeAny( nTabIndex++ ) );
671 }
672 mbGroupsUpToDate = sal_False;
673 }
674 }
675
676
677 typedef ::std::multimap< sal_Int32, Reference< XControlModel >, ::std::less< sal_Int32 > > MapIndexToModel;
678
679 // ----------------------------------------------------------------------------
getControlModels()680 Sequence< Reference< XControlModel > > SAL_CALL ControlModelContainerBase::getControlModels( )
681 {
682 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
683
684 MapIndexToModel aSortedModels;
685 // will be the sorted container of all models which have a tab index property
686 ::std::vector< Reference< XControlModel > > aUnindexedModels;
687 // will be the container of all models which do not have a tab index property
688
689 UnoControlModelHolderList::const_iterator aLoop = maModels.begin();
690 for ( ; aLoop != maModels.end(); ++aLoop )
691 {
692 Reference< XControlModel > xModel( aLoop->first );
693
694 // see if the model has a TabIndex property
695 Reference< XPropertySet > xControlProps( xModel, UNO_QUERY );
696 Reference< XPropertySetInfo > xPSI;
697 if ( xControlProps.is() )
698 xPSI = xControlProps->getPropertySetInfo( );
699 DBG_ASSERT( xPSI.is(), "UnoControlDialogModel::getControlModels: invalid child model!" );
700
701 // has it?
702 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
703 { // yes
704 sal_Int32 nTabIndex = -1;
705 xControlProps->getPropertyValue( getTabIndexPropertyName() ) >>= nTabIndex;
706
707 aSortedModels.insert( MapIndexToModel::value_type( nTabIndex, xModel ) );
708 }
709 else if ( xModel.is() )
710 // no, it hasn't, but we have to include it, anyway
711 aUnindexedModels.push_back( xModel );
712 }
713
714 // okay, here we have a container of all our models, sorted by tab index,
715 // plus a container of "unindexed" models
716 // -> merge them
717 Sequence< Reference< XControlModel > > aReturn( aUnindexedModels.size() + aSortedModels.size() );
718 ::std::transform(
719 aSortedModels.begin(), aSortedModels.end(),
720 ::std::copy( aUnindexedModels.begin(), aUnindexedModels.end(), aReturn.getArray() ),
721 ::std::select2nd< MapIndexToModel::value_type >( )
722 );
723
724 return aReturn;
725 }
726
727 // ----------------------------------------------------------------------------
setGroup(const Sequence<Reference<XControlModel>> &,const::rtl::OUString &)728 void SAL_CALL ControlModelContainerBase::setGroup( const Sequence< Reference< XControlModel > >&, const ::rtl::OUString& )
729 {
730 // not supported. We have only implicit grouping:
731 // We only have a sequence of control models, and we _know_ (yes, that's a HACK relying on
732 // implementation details) that VCL does grouping according to the order of controls automatically
733 // At least VCL does this for all we're interested in: Radio buttons.
734 DBG_ERROR( "UnoControlDialogModel::setGroup: grouping not supported" );
735 }
736
737 ////----- XInitialization -------------------------------------------------------------------
initialize(const Sequence<Any> & rArguments)738 void SAL_CALL ControlModelContainerBase::initialize (const Sequence<Any>& rArguments)
739 {
740 sal_Int16 nPageId = -1;
741 if ( rArguments.getLength() == 1 )
742 {
743 if ( !( rArguments[ 0 ] >>= nPageId ))
744 throw lang::IllegalArgumentException();
745 m_nTabPageId = nPageId;
746 }
747 else
748 m_nTabPageId = -1;
749 }
getTabPageID()750 ::sal_Int16 SAL_CALL ControlModelContainerBase::getTabPageID()
751 {
752 return m_nTabPageId;
753 }
getEnabled()754 ::sal_Bool SAL_CALL ControlModelContainerBase::getEnabled()
755 {
756 return m_bEnabled;
757 }
setEnabled(::sal_Bool _enabled)758 void SAL_CALL ControlModelContainerBase::setEnabled( ::sal_Bool _enabled )
759 {
760 m_bEnabled = _enabled;
761 }
getTitle()762 ::rtl::OUString SAL_CALL ControlModelContainerBase::getTitle()
763 {
764 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
765 Reference<XPropertySet> xThis(*this,UNO_QUERY);
766 ::rtl::OUString sTitle;
767 xThis->getPropertyValue(GetPropertyName(BASEPROPERTY_TITLE)) >>= sTitle;
768 return sTitle;
769 }
setTitle(const::rtl::OUString & _title)770 void SAL_CALL ControlModelContainerBase::setTitle( const ::rtl::OUString& _title )
771 {
772 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
773 Reference<XPropertySet> xThis(*this,UNO_QUERY);
774 xThis->setPropertyValue(GetPropertyName(BASEPROPERTY_TITLE),makeAny(_title));
775 }
getImageURL()776 ::rtl::OUString SAL_CALL ControlModelContainerBase::getImageURL()
777 {
778 return m_sImageURL;
779 }
setImageURL(const::rtl::OUString & _imageurl)780 void SAL_CALL ControlModelContainerBase::setImageURL( const ::rtl::OUString& _imageurl )
781 {
782 m_sImageURL = _imageurl;
783 }
getToolTip()784 ::rtl::OUString SAL_CALL ControlModelContainerBase::getToolTip()
785 {
786 return m_sTooltip;
787 }
setToolTip(const::rtl::OUString & _tooltip)788 void SAL_CALL ControlModelContainerBase::setToolTip( const ::rtl::OUString& _tooltip )
789 {
790 m_sTooltip = _tooltip;
791 }
792
793 // ----------------------------------------------------------------------------
794 namespace
795 {
796 enum GroupingMachineState
797 {
798 eLookingForGroup,
799 eExpandingGroup
800 };
801
802 // ........................................................................
lcl_getDialogStep(const Reference<XControlModel> & _rxModel)803 static sal_Int32 lcl_getDialogStep( const Reference< XControlModel >& _rxModel )
804 {
805 sal_Int32 nStep = 0;
806 try
807 {
808 Reference< XPropertySet > xModelProps( _rxModel, UNO_QUERY );
809 xModelProps->getPropertyValue( getStepPropertyName() ) >>= nStep;
810 }
811 catch( const Exception& )
812 {
813 DBG_ERROR( "lcl_getDialogStep: caught an exception while determining the dialog page!" );
814 }
815 return nStep;
816 }
817 }
818
819 // ----------------------------------------------------------------------------
getGroupCount()820 sal_Int32 SAL_CALL ControlModelContainerBase::getGroupCount( )
821 {
822 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
823
824 implUpdateGroupStructure();
825
826 return maGroups.size();
827 }
828
829 // ----------------------------------------------------------------------------
getGroup(sal_Int32 _nGroup,Sequence<Reference<XControlModel>> & _rGroup,::rtl::OUString & _rName)830 void SAL_CALL ControlModelContainerBase::getGroup( sal_Int32 _nGroup, Sequence< Reference< XControlModel > >& _rGroup, ::rtl::OUString& _rName )
831 {
832 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
833
834 implUpdateGroupStructure();
835
836 if ( ( _nGroup < 0 ) || ( _nGroup >= (sal_Int32)maGroups.size() ) )
837 {
838 DBG_ERROR( "UnoControlDialogModel::getGroup: invalid argument and I am not allowed to throw an exception!" );
839 _rGroup.realloc( 0 );
840 _rName = ::rtl::OUString();
841 }
842 else
843 {
844 AllGroups::const_iterator aGroupPos = maGroups.begin() + _nGroup;
845 _rGroup.realloc( aGroupPos->size() );
846 // copy the models
847 ::std::copy( aGroupPos->begin(), aGroupPos->end(), _rGroup.getArray() );
848 // give the group a name
849 _rName = ::rtl::OUString::valueOf( _nGroup );
850 }
851 }
852
853 // ----------------------------------------------------------------------------
getGroupByName(const::rtl::OUString & _rName,Sequence<Reference<XControlModel>> & _rGroup)854 void SAL_CALL ControlModelContainerBase::getGroupByName( const ::rtl::OUString& _rName, Sequence< Reference< XControlModel > >& _rGroup )
855 {
856 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
857
858 ::rtl::OUString sDummyName;
859 getGroup( _rName.toInt32( ), _rGroup, sDummyName );
860 }
861
862 // ----------------------------------------------------------------------------
addChangesListener(const Reference<XChangesListener> & _rxListener)863 void SAL_CALL ControlModelContainerBase::addChangesListener( const Reference< XChangesListener >& _rxListener )
864 {
865 maChangeListeners.addInterface( _rxListener );
866 }
867
868 // ----------------------------------------------------------------------------
removeChangesListener(const Reference<XChangesListener> & _rxListener)869 void SAL_CALL ControlModelContainerBase::removeChangesListener( const Reference< XChangesListener >& _rxListener )
870 {
871 maChangeListeners.removeInterface( _rxListener );
872 }
873
874 // ----------------------------------------------------------------------------
implNotifyTabModelChange(const::rtl::OUString & _rAccessor)875 void ControlModelContainerBase::implNotifyTabModelChange( const ::rtl::OUString& _rAccessor )
876 {
877 // multiplex to our change listeners:
878 // the changes event
879 ChangesEvent aEvent;
880 aEvent.Source = *this;
881 aEvent.Base <<= aEvent.Source; // the "base of the changes root" is also ourself
882 aEvent.Changes.realloc( 1 ); // exactly one change
883 aEvent.Changes[ 0 ].Accessor <<= _rAccessor;
884
885
886 Sequence< Reference< XInterface > > aChangeListeners( maChangeListeners.getElements() );
887 const Reference< XInterface >* pListener = aChangeListeners.getConstArray();
888 const Reference< XInterface >* pListenerEnd = aChangeListeners.getConstArray() + aChangeListeners.getLength();
889 for ( ; pListener != pListenerEnd; ++pListener )
890 {
891 if ( pListener->is() )
892 static_cast< XChangesListener* >( pListener->get() )->changesOccurred( aEvent );
893 }
894 }
895
896
897 // ----------------------------------------------------------------------------
implUpdateGroupStructure()898 void ControlModelContainerBase::implUpdateGroupStructure()
899 {
900 if ( mbGroupsUpToDate )
901 // nothing to do
902 return;
903
904 // conditions for a group:
905 // * all elements of the group are radio buttons
906 // * all elements of the group are on the same dialog page
907 // * in the overall control order (determined by the tab index), all elements are subsequent
908
909 maGroups.clear();
910
911 Sequence< Reference< XControlModel > > aControlModels = getControlModels();
912 const Reference< XControlModel >* pControlModels = aControlModels.getConstArray();
913 const Reference< XControlModel >* pControlModelsEnd = pControlModels + aControlModels.getLength();
914
915 // in extreme we have as much groups as controls
916 maGroups.reserve( aControlModels.getLength() );
917
918 GroupingMachineState eState = eLookingForGroup; // the current state of our machine
919 Reference< XServiceInfo > xModelSI; // for checking for a radion button
920 AllGroups::iterator aCurrentGroup = maGroups.end(); // the group which we're currently building
921 sal_Int32 nCurrentGroupStep = -1; // the step which all controls of the current group belong to
922 sal_Bool bIsRadioButton; // is it a radio button?
923
924 #if OSL_DEBUG_LEVEL > 1
925 ::std::vector< ::rtl::OUString > aCurrentGroupLabels;
926 #endif
927
928 for ( ; pControlModels != pControlModelsEnd; ++pControlModels )
929 {
930 // we'll need this in every state
931 xModelSI = xModelSI.query( *pControlModels );
932 bIsRadioButton = xModelSI.is() && xModelSI->supportsService( ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRadioButtonModel ) );
933
934 switch ( eState )
935 {
936 case eLookingForGroup:
937 {
938 if ( !bIsRadioButton )
939 // this is no radio button -> still looking for the beginning of a group
940 continue;
941 // the current model is a radio button
942 // -> we found the beginning of a new group
943 // create the place for this group
944 size_t nGroups = maGroups.size();
945 maGroups.resize( nGroups + 1 );
946 aCurrentGroup = maGroups.begin() + nGroups;
947 // and add the (only, til now) member
948 aCurrentGroup->push_back( *pControlModels );
949
950 // get the step which all controls of this group now have to belong to
951 nCurrentGroupStep = lcl_getDialogStep( *pControlModels );
952 // new state: looking for further members
953 eState = eExpandingGroup;
954
955 #if OSL_DEBUG_LEVEL > 1
956 Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY );
957 ::rtl::OUString sLabel;
958 if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) )
959 xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel;
960 aCurrentGroupLabels.push_back( sLabel );
961 #endif
962 }
963 break;
964
965 case eExpandingGroup:
966 {
967 if ( !bIsRadioButton )
968 { // no radio button -> the group is done
969 aCurrentGroup = maGroups.end();
970 eState = eLookingForGroup;
971 #if OSL_DEBUG_LEVEL > 1
972 aCurrentGroupLabels.clear();
973 #endif
974 continue;
975 }
976
977 // it is a radio button - is it on the proper page?
978 const sal_Int32 nThisModelStep = lcl_getDialogStep( *pControlModels );
979 if ( ( nThisModelStep == nCurrentGroupStep ) // the current button is on the same dialog page
980 || ( 0 == nThisModelStep ) // the current button appears on all pages
981 )
982 {
983 // -> it belongs to the same group
984 aCurrentGroup->push_back( *pControlModels );
985 // state still is eExpandingGroup - we're looking for further elements
986 eState = eExpandingGroup;
987
988 #if OSL_DEBUG_LEVEL > 1
989 Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY );
990 ::rtl::OUString sLabel;
991 if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) )
992 xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel;
993 aCurrentGroupLabels.push_back( sLabel );
994 #endif
995 continue;
996 }
997
998 // it's a radio button, but on a different page
999 // -> we open a new group for it
1000
1001 // close the old group
1002 aCurrentGroup = maGroups.end();
1003 #if OSL_DEBUG_LEVEL > 1
1004 aCurrentGroupLabels.clear();
1005 #endif
1006
1007 // open a new group
1008 size_t nGroups = maGroups.size();
1009 maGroups.resize( nGroups + 1 );
1010 aCurrentGroup = maGroups.begin() + nGroups;
1011 // and add the (only, til now) member
1012 aCurrentGroup->push_back( *pControlModels );
1013
1014 nCurrentGroupStep = nThisModelStep;
1015
1016 // state is the same: we still are looking for further elements of the current group
1017 eState = eExpandingGroup;
1018 #if OSL_DEBUG_LEVEL > 1
1019 Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY );
1020 ::rtl::OUString sLabel;
1021 if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) )
1022 xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel;
1023 aCurrentGroupLabels.push_back( sLabel );
1024 #endif
1025 }
1026 break;
1027 }
1028 }
1029
1030 mbGroupsUpToDate = sal_True;
1031 }
1032
1033 // ----------------------------------------------------------------------------
propertyChange(const PropertyChangeEvent & _rEvent)1034 void SAL_CALL ControlModelContainerBase::propertyChange( const PropertyChangeEvent& _rEvent )
1035 {
1036 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1037
1038 DBG_ASSERT( 0 == _rEvent.PropertyName.compareToAscii( "TabIndex" ),
1039 "UnoControlDialogModel::propertyChange: not listening for this property!" );
1040
1041 // the accessor for the changed element
1042 ::rtl::OUString sAccessor;
1043 UnoControlModelHolderList::const_iterator aPos =
1044 ::std::find_if(
1045 maModels.begin(), maModels.end(),
1046 CompareControlModel( Reference< XControlModel >( _rEvent.Source, UNO_QUERY ) )
1047 );
1048 OSL_ENSURE( maModels.end() != aPos, "UnoControlDialogModel::propertyChange: don't know this model!" );
1049 if ( maModels.end() != aPos )
1050 sAccessor = aPos->second;
1051
1052 // our groups are not up-to-date
1053 mbGroupsUpToDate = sal_False;
1054
1055 // notify
1056 implNotifyTabModelChange( sAccessor );
1057 }
1058
1059 // ----------------------------------------------------------------------------
disposing(const EventObject &)1060 void SAL_CALL ControlModelContainerBase::disposing( const EventObject& /*rEvent*/ )
1061 {
1062 }
1063
1064 // ----------------------------------------------------------------------------
startControlListening(const Reference<XControlModel> & _rxChildModel)1065 void ControlModelContainerBase::startControlListening( const Reference< XControlModel >& _rxChildModel )
1066 {
1067 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1068
1069 Reference< XPropertySet > xModelProps( _rxChildModel, UNO_QUERY );
1070 Reference< XPropertySetInfo > xPSI;
1071 if ( xModelProps.is() )
1072 xPSI = xModelProps->getPropertySetInfo();
1073
1074 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
1075 xModelProps->addPropertyChangeListener( getTabIndexPropertyName(), this );
1076 }
1077
1078 // ----------------------------------------------------------------------------
stopControlListening(const Reference<XControlModel> & _rxChildModel)1079 void ControlModelContainerBase::stopControlListening( const Reference< XControlModel >& _rxChildModel )
1080 {
1081 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1082
1083 Reference< XPropertySet > xModelProps( _rxChildModel, UNO_QUERY );
1084 Reference< XPropertySetInfo > xPSI;
1085 if ( xModelProps.is() )
1086 xPSI = xModelProps->getPropertySetInfo();
1087
1088 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
1089 xModelProps->removePropertyChangeListener( getTabIndexPropertyName(), this );
1090 }
1091
1092 // ============================================================================
1093 // = class ResourceListener
1094 // ============================================================================
1095
ResourceListener(const Reference<util::XModifyListener> & rListener)1096 ResourceListener::ResourceListener(
1097 const Reference< util::XModifyListener >& rListener ) :
1098 OWeakObject(),
1099 m_xListener( rListener ),
1100 m_bListening( false )
1101 {
1102 }
1103
~ResourceListener()1104 ResourceListener::~ResourceListener()
1105 {
1106 }
1107
1108 // XInterface
queryInterface(const Type & rType)1109 Any SAL_CALL ResourceListener::queryInterface( const Type& rType )
1110 {
1111 Any a = ::cppu::queryInterface(
1112 rType ,
1113 static_cast< XModifyListener* >( this ),
1114 static_cast< XEventListener* >( this ));
1115
1116 if ( a.hasValue() )
1117 return a;
1118
1119 return OWeakObject::queryInterface( rType );
1120 }
1121
acquire()1122 void SAL_CALL ResourceListener::acquire() throw ()
1123 {
1124 OWeakObject::acquire();
1125 }
1126
release()1127 void SAL_CALL ResourceListener::release() throw ()
1128 {
1129 OWeakObject::release();
1130 }
1131
startListening(const Reference<resource::XStringResourceResolver> & rResource)1132 void ResourceListener::startListening(
1133 const Reference< resource::XStringResourceResolver >& rResource )
1134 {
1135 Reference< util::XModifyBroadcaster > xModifyBroadcaster( rResource, UNO_QUERY );
1136
1137 {
1138 // --- SAFE ---
1139 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1140 bool bListening( m_bListening );
1141 bool bResourceSet( m_xResource.is() );
1142 aGuard.clear();
1143 // --- SAFE ---
1144
1145 if ( bListening && bResourceSet )
1146 stopListening();
1147
1148 // --- SAFE ---
1149 aGuard.reset();
1150 m_xResource = rResource;
1151 aGuard.clear();
1152 // --- SAFE ---
1153 }
1154
1155 Reference< util::XModifyListener > xThis( static_cast<OWeakObject*>( this ), UNO_QUERY );
1156 if ( xModifyBroadcaster.is() )
1157 {
1158 try
1159 {
1160 xModifyBroadcaster->addModifyListener( xThis );
1161
1162 // --- SAFE ---
1163 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1164 m_bListening = true;
1165 // --- SAFE ---
1166 }
1167 catch ( RuntimeException& )
1168 {
1169 throw;
1170 }
1171 catch ( Exception& )
1172 {
1173 }
1174 }
1175 }
1176
stopListening()1177 void ResourceListener::stopListening()
1178 {
1179 Reference< util::XModifyBroadcaster > xModifyBroadcaster;
1180
1181 // --- SAFE ---
1182 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1183 if ( m_bListening && m_xResource.is() )
1184 xModifyBroadcaster = Reference< util::XModifyBroadcaster >( m_xResource, UNO_QUERY );
1185 aGuard.clear();
1186 // --- SAFE ---
1187
1188 Reference< util::XModifyListener > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
1189 if ( xModifyBroadcaster.is() )
1190 {
1191 try
1192 {
1193 // --- SAFE ---
1194 aGuard.reset();
1195 m_bListening = false;
1196 m_xResource.clear();
1197 aGuard.clear();
1198 // --- SAFE ---
1199
1200 xModifyBroadcaster->removeModifyListener( xThis );
1201 }
1202 catch ( RuntimeException& )
1203 {
1204 throw;
1205 }
1206 catch ( Exception& )
1207 {
1208 }
1209 }
1210 }
1211
1212 // XModifyListener
modified(const lang::EventObject & aEvent)1213 void SAL_CALL ResourceListener::modified(
1214 const lang::EventObject& aEvent )
1215 {
1216 Reference< util::XModifyListener > xListener;
1217
1218 // --- SAFE ---
1219 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1220 xListener = m_xListener;
1221 aGuard.clear();
1222 // --- SAFE ---
1223
1224 if ( xListener.is() )
1225 {
1226 try
1227 {
1228 xListener->modified( aEvent );
1229 }
1230 catch ( RuntimeException& )
1231 {
1232 throw;
1233 }
1234 catch ( Exception& )
1235 {
1236 }
1237 }
1238 }
1239
1240 // XEventListener
disposing(const EventObject & Source)1241 void SAL_CALL ResourceListener::disposing(
1242 const EventObject& Source )
1243 {
1244 Reference< lang::XEventListener > xListener;
1245 Reference< resource::XStringResourceResolver > xResource;
1246
1247 // --- SAFE ---
1248 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1249 Reference< XInterface > xIfacRes( m_xResource, UNO_QUERY );
1250 Reference< XInterface > xIfacList( m_xListener, UNO_QUERY );
1251 aGuard.clear();
1252 // --- SAFE ---
1253
1254 if ( Source.Source == xIfacRes )
1255 {
1256 // --- SAFE ---
1257 aGuard.reset();
1258 m_bListening = false;
1259 xResource = m_xResource;
1260 xListener = Reference< lang::XEventListener >( m_xListener, UNO_QUERY );
1261 m_xResource.clear();
1262 aGuard.clear();
1263 // --- SAFE ---
1264
1265 if ( xListener.is() )
1266 {
1267 try
1268 {
1269 xListener->disposing( Source );
1270 }
1271 catch ( RuntimeException& )
1272 {
1273 throw;
1274 }
1275 catch ( Exception& )
1276 {
1277 }
1278 }
1279 }
1280 else if ( Source.Source == xIfacList )
1281 {
1282 // --- SAFE ---
1283 aGuard.reset();
1284 m_bListening = false;
1285 xListener = Reference< lang::XEventListener >( m_xListener, UNO_QUERY );
1286 xResource = m_xResource;
1287 m_xResource.clear();
1288 m_xListener.clear();
1289 aGuard.clear();
1290 // --- SAFE ---
1291
1292 // Remove ourself as listener from resource resolver
1293 Reference< util::XModifyBroadcaster > xModifyBroadcaster( xResource, UNO_QUERY );
1294 Reference< util::XModifyListener > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
1295 if ( xModifyBroadcaster.is() )
1296 {
1297 try
1298 {
1299 xModifyBroadcaster->removeModifyListener( xThis );
1300 }
1301 catch ( RuntimeException& )
1302 {
1303 throw;
1304 }
1305 catch ( Exception& )
1306 {
1307 }
1308 }
1309 }
1310 }
1311
1312 //===============================================================
1313 // ----------------------------------------------------
1314 // class DialogContainerControl
1315 // ----------------------------------------------------
ControlContainerBase(const Reference<XMultiServiceFactory> & i_factory)1316 ControlContainerBase::ControlContainerBase( const Reference< XMultiServiceFactory >& i_factory )
1317 :ContainerControl_IBase( i_factory )
1318 ,mbSizeModified(false)
1319 ,mbPosModified(false)
1320 {
1321 maComponentInfos.nWidth = 280;
1322 maComponentInfos.nHeight = 400;
1323 mxListener = new ResourceListener( Reference< util::XModifyListener >(
1324 static_cast< OWeakObject* >( this ), UNO_QUERY ));
1325 }
1326
~ControlContainerBase()1327 ControlContainerBase::~ControlContainerBase()
1328 {
1329 }
1330
createPeer(const Reference<XToolkit> & rxToolkit,const Reference<XWindowPeer> & rParentPeer)1331 void ControlContainerBase::createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer > & rParentPeer )
1332 {
1333 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1334 UnoControlContainer::createPeer( rxToolkit, rParentPeer );
1335 }
1336
ImplInsertControl(Reference<XControlModel> & rxModel,const::rtl::OUString & rName)1337 void ControlContainerBase::ImplInsertControl( Reference< XControlModel >& rxModel, const ::rtl::OUString& rName )
1338 {
1339 Reference< XPropertySet > xP( rxModel, UNO_QUERY );
1340
1341 ::rtl::OUString aDefCtrl;
1342 xP->getPropertyValue( GetPropertyName( BASEPROPERTY_DEFAULTCONTROL ) ) >>= aDefCtrl;
1343 Reference < XControl > xCtrl;
1344 maContext.createComponent( aDefCtrl, xCtrl );
1345
1346 DBG_ASSERT( xCtrl.is(), "ControlContainerBase::ImplInsertControl: could not create the control!" );
1347 if ( xCtrl.is() )
1348 {
1349 xCtrl->setModel( rxModel );
1350 addControl( rName, xCtrl );
1351 // will implicitly call addingControl, where we can add the PropertiesChangeListener to the model
1352 // (which we formerly did herein)
1353 // 08.01.2001 - 96008 - fs@openoffice.org
1354
1355 ImplSetPosSize( xCtrl );
1356 }
1357 }
1358
ImplRemoveControl(Reference<XControlModel> & rxModel)1359 void ControlContainerBase::ImplRemoveControl( Reference< XControlModel >& rxModel )
1360 {
1361 Sequence< Reference< XControl > > aControls = getControls();
1362 Reference< XControl > xCtrl = StdTabController::FindControl( aControls, rxModel );
1363 if ( xCtrl.is() )
1364 {
1365 removeControl( xCtrl );
1366 try
1367 {
1368 Reference< XComponent > const xControlComp( xCtrl, UNO_QUERY_THROW );
1369 xControlComp->dispose();
1370 }
1371 catch( Exception const & )
1372 {
1373 DBG_UNHANDLED_EXCEPTION();
1374 }
1375 }
1376 }
1377
ImplSetPosSize(Reference<XControl> & rxCtrl)1378 void ControlContainerBase::ImplSetPosSize( Reference< XControl >& rxCtrl )
1379 {
1380 Reference< XPropertySet > xP( rxCtrl->getModel(), UNO_QUERY );
1381
1382 sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
1383 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) ) ) >>= nX;
1384 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) ) ) >>= nY;
1385 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ) ) >>= nWidth;
1386 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ) ) >>= nHeight;
1387 MapMode aMode( MAP_APPFONT );
1388 OutputDevice*pOutDev = Application::GetDefaultDevice();
1389 if ( pOutDev )
1390 {
1391 ::Size aTmp( nX, nY );
1392 aTmp = pOutDev->LogicToPixel( aTmp, aMode );
1393 nX = aTmp.Width();
1394 nY = aTmp.Height();
1395 aTmp = ::Size( nWidth, nHeight );
1396 aTmp = pOutDev->LogicToPixel( aTmp, aMode );
1397 nWidth = aTmp.Width();
1398 nHeight = aTmp.Height();
1399 }
1400 else
1401 {
1402 Reference< XWindowPeer > xPeer = ImplGetCompatiblePeer( sal_True );
1403 Reference< XDevice > xD( xPeer, UNO_QUERY );
1404
1405 SimpleFontMetric aFM;
1406 FontDescriptor aFD;
1407 Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_FONTDESCRIPTOR ) );
1408 aVal >>= aFD;
1409 if ( aFD.StyleName.getLength() )
1410 {
1411 Reference< XFont > xFont = xD->getFont( aFD );
1412 aFM = xFont->getFontMetric();
1413 }
1414 else
1415 {
1416 Reference< XGraphics > xG = xD->createGraphics();
1417 aFM = xG->getFontMetric();
1418 }
1419
1420 sal_Int16 nH = aFM.Ascent + aFM.Descent;
1421 sal_Int16 nW = nH/2; // calculate average width?!
1422
1423 nX *= nW;
1424 nX /= 4;
1425 nWidth *= nW;
1426 nWidth /= 4;
1427 nY *= nH;
1428 nY /= 8;
1429 nHeight *= nH;
1430 nHeight /= 8;
1431 }
1432 Reference < XWindow > xW( rxCtrl, UNO_QUERY );
1433 xW->setPosSize( nX, nY, nWidth, nHeight, PosSize::POSSIZE );
1434 }
1435
dispose()1436 void ControlContainerBase::dispose()
1437 {
1438 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1439
1440 EventObject aEvt;
1441 aEvt.Source = static_cast< ::cppu::OWeakObject* >( this );
1442 // Notify our listener helper about dispose
1443 // --- SAFE ---
1444 ::osl::ResettableGuard< ::osl::Mutex > aGuard( GetMutex() );
1445 Reference< XEventListener > xListener( mxListener, UNO_QUERY );
1446 mxListener.clear();
1447 aGuard.clear();
1448 // --- SAFE ---
1449
1450 if ( xListener.is() )
1451 xListener->disposing( aEvt );
1452 UnoControlContainer::dispose();
1453 }
1454
disposing(const EventObject & Source)1455 void SAL_CALL ControlContainerBase::disposing(
1456 const EventObject& Source )
1457 {
1458 UnoControlContainer::disposing( Source );
1459 }
1460
setModel(const Reference<XControlModel> & rxModel)1461 sal_Bool ControlContainerBase::setModel( const Reference< XControlModel >& rxModel )
1462 {
1463 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1464
1465 // destroy the old tab controller, if existent
1466 if ( mxTabController.is() )
1467 {
1468 mxTabController->setModel( NULL ); // just to be sure, should not be necessary
1469 removeTabController( mxTabController );
1470 ::comphelper::disposeComponent( mxTabController ); // just to be sure, should not be necessary
1471 mxTabController.clear();
1472 }
1473
1474 if ( getModel().is() )
1475 {
1476 Sequence< Reference< XControl > > aControls = getControls();
1477 const Reference< XControl >* pCtrls = aControls.getConstArray();
1478 const Reference< XControl >* pCtrlsEnd = pCtrls + aControls.getLength();
1479
1480 for ( ; pCtrls < pCtrlsEnd; ++pCtrls )
1481 removeControl( *pCtrls );
1482 // will implicitly call removingControl, which will remove the PropertyChangeListener
1483 // (which we formerly did herein)
1484 // 08.01.2001 - 96008 - fs@openoffice.org
1485
1486 Reference< XContainer > xC( getModel(), UNO_QUERY );
1487 if ( xC.is() )
1488 xC->removeContainerListener( this );
1489
1490 Reference< XChangesNotifier > xChangeNotifier( getModel(), UNO_QUERY );
1491 if ( xChangeNotifier.is() )
1492 xChangeNotifier->removeChangesListener( this );
1493 }
1494
1495 sal_Bool bRet = UnoControl::setModel( rxModel );
1496
1497 if ( getModel().is() )
1498 {
1499 Reference< XNameAccess > xNA( getModel(), UNO_QUERY );
1500 if ( xNA.is() )
1501 {
1502 Sequence< ::rtl::OUString > aNames = xNA->getElementNames();
1503 const ::rtl::OUString* pNames = aNames.getConstArray();
1504 sal_uInt32 nCtrls = aNames.getLength();
1505
1506 Reference< XControlModel > xCtrlModel;
1507 for( sal_uInt32 n = 0; n < nCtrls; ++n, ++pNames )
1508 {
1509 xNA->getByName( *pNames ) >>= xCtrlModel;
1510 ImplInsertControl( xCtrlModel, *pNames );
1511 }
1512 }
1513
1514 Reference< XContainer > xC( getModel(), UNO_QUERY );
1515 if ( xC.is() )
1516 xC->addContainerListener( this );
1517
1518 Reference< XChangesNotifier > xChangeNotifier( getModel(), UNO_QUERY );
1519 if ( xChangeNotifier.is() )
1520 xChangeNotifier->addChangesListener( this );
1521 }
1522
1523 Reference< XTabControllerModel > xTabbing( getModel(), UNO_QUERY );
1524 if ( xTabbing.is() )
1525 {
1526 mxTabController = new StdTabController;
1527 mxTabController->setModel( xTabbing );
1528 addTabController( mxTabController );
1529 }
1530 ImplStartListingForResourceEvents();
1531
1532 return bRet;
1533 }
setDesignMode(sal_Bool bOn)1534 void ControlContainerBase::setDesignMode( sal_Bool bOn )
1535 {
1536 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1537 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1538
1539 UnoControl::setDesignMode( bOn );
1540
1541 Sequence< Reference< XControl > > xCtrls = getControls();
1542 sal_Int32 nControls = xCtrls.getLength();
1543 Reference< XControl >* pControls = xCtrls.getArray();
1544 for ( sal_Int32 n = 0; n < nControls; n++ )
1545 pControls[n]->setDesignMode( bOn );
1546
1547 // #109067# in design mode the tab controller is not notified about
1548 // tab index changes, therefore the tab order must be activated
1549 // when switching from design mode to live mode
1550 if ( mxTabController.is() && !bOn )
1551 mxTabController->activateTabOrder();
1552 }
1553
elementInserted(const ContainerEvent & Event)1554 void ControlContainerBase::elementInserted( const ContainerEvent& Event )
1555 {
1556 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1557
1558 Reference< XControlModel > xModel;
1559 ::rtl::OUString aName;
1560
1561 Event.Accessor >>= aName;
1562 Event.Element >>= xModel;
1563 ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementInserted: illegal element!" );
1564 try
1565 {
1566 ImplInsertControl( xModel, aName );
1567 }
1568 catch ( const RuntimeException& e ) { throw; }
1569 catch( const Exception& )
1570 {
1571 DBG_UNHANDLED_EXCEPTION();
1572 }
1573 }
1574
elementRemoved(const ContainerEvent & Event)1575 void ControlContainerBase::elementRemoved( const ContainerEvent& Event )
1576 {
1577 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1578
1579 Reference< XControlModel > xModel;
1580 Event.Element >>= xModel;
1581 ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementRemoved: illegal element!" );
1582 try
1583 {
1584 ImplRemoveControl( xModel );
1585 }
1586 catch ( const RuntimeException& e ) { throw; }
1587 catch( const Exception& )
1588 {
1589 DBG_UNHANDLED_EXCEPTION();
1590 }
1591 }
1592
elementReplaced(const ContainerEvent & Event)1593 void ControlContainerBase::elementReplaced( const ContainerEvent& Event )
1594 {
1595 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1596
1597 Reference< XControlModel > xModel;
1598 Event.ReplacedElement >>= xModel;
1599 try
1600 {
1601 OSL_ENSURE( xModel.is(), "ControlContainerBase::elementReplaced: invalid ReplacedElement!" );
1602 if ( xModel.is() )
1603 ImplRemoveControl( xModel );
1604 }
1605 catch ( const RuntimeException& e ) { throw; }
1606 catch( const Exception& )
1607 {
1608 DBG_UNHANDLED_EXCEPTION();
1609 }
1610
1611 ::rtl::OUString aName;
1612 Event.Accessor >>= aName;
1613 Event.Element >>= xModel;
1614 ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementReplaced: invalid new element!" );
1615 try
1616 {
1617 ImplInsertControl( xModel, aName );
1618 }
1619 catch ( const RuntimeException& e ) { throw; }
1620 catch( const Exception& )
1621 {
1622 DBG_UNHANDLED_EXCEPTION();
1623 }
1624 }
1625
1626 // XPropertiesChangeListener
ImplModelPropertiesChanged(const Sequence<PropertyChangeEvent> & rEvents)1627 void ControlContainerBase::ImplModelPropertiesChanged( const Sequence< PropertyChangeEvent >& rEvents )
1628 {
1629 if( !isDesignMode() && !mbCreatingCompatiblePeer )
1630 {
1631 ::rtl::OUString s1( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) );
1632 ::rtl::OUString s2( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) );
1633 ::rtl::OUString s3( RTL_CONSTASCII_USTRINGPARAM( "Width" ) );
1634 ::rtl::OUString s4( RTL_CONSTASCII_USTRINGPARAM( "Height" ) );
1635
1636 sal_Int32 nLen = rEvents.getLength();
1637 for( sal_Int32 i = 0; i < nLen; i++ )
1638 {
1639 const PropertyChangeEvent& rEvt = rEvents.getConstArray()[i];
1640 Reference< XControlModel > xModel( rEvt.Source, UNO_QUERY );
1641 sal_Bool bOwnModel = (XControlModel*)xModel.get() == (XControlModel*)getModel().get();
1642 if ( ( rEvt.PropertyName == s1 ) ||
1643 ( rEvt.PropertyName == s2 ) ||
1644 ( rEvt.PropertyName == s3 ) ||
1645 ( rEvt.PropertyName == s4 ) )
1646 {
1647 if ( bOwnModel )
1648 {
1649 if ( !mbPosModified && !mbSizeModified )
1650 {
1651 // Don't set new pos/size if we get new values from window listener
1652 Reference< XControl > xThis( (XAggregation*)(::cppu::OWeakAggObject*)this, UNO_QUERY );
1653 ImplSetPosSize( xThis );
1654 }
1655 }
1656 else
1657 {
1658 Sequence<Reference<XControl> > aControlSequence(getControls());
1659 Reference<XControl> aControlRef( StdTabController::FindControl( aControlSequence, xModel ) );
1660 ImplSetPosSize( aControlRef );
1661 }
1662 break;
1663 }
1664 }
1665 }
1666
1667 UnoControlContainer::ImplModelPropertiesChanged( rEvents );
1668 }
1669
addingControl(const Reference<XControl> & _rxControl)1670 void ControlContainerBase::addingControl( const Reference< XControl >& _rxControl )
1671 {
1672 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1673 UnoControlContainer::addingControl( _rxControl );
1674
1675 if ( _rxControl.is() )
1676 {
1677 Reference< XMultiPropertySet > xProps( _rxControl->getModel(), UNO_QUERY );
1678 if ( xProps.is() )
1679 {
1680 Sequence< ::rtl::OUString > aNames( 4 );
1681 ::rtl::OUString* pNames = aNames.getArray();
1682 *pNames++ = ::rtl::OUString::createFromAscii( "PositionX" );
1683 *pNames++ = ::rtl::OUString::createFromAscii( "PositionY" );
1684 *pNames++ = ::rtl::OUString::createFromAscii( "Width" );
1685 *pNames++ = ::rtl::OUString::createFromAscii( "Height" );
1686
1687 xProps->addPropertiesChangeListener( aNames, this );
1688 }
1689 }
1690 }
1691
removingControl(const Reference<XControl> & _rxControl)1692 void ControlContainerBase::removingControl( const Reference< XControl >& _rxControl )
1693 {
1694 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1695 UnoControlContainer::removingControl( _rxControl );
1696
1697 if ( _rxControl.is() )
1698 {
1699 Reference< XMultiPropertySet > xProps( _rxControl->getModel(), UNO_QUERY );
1700 if ( xProps.is() )
1701 xProps->removePropertiesChangeListener( this );
1702 }
1703
1704 }
1705
changesOccurred(const ChangesEvent &)1706 void SAL_CALL ControlContainerBase::changesOccurred( const ChangesEvent& )
1707 {
1708 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1709 // a tab controller model may have changed
1710
1711 // #109067# in design mode don't notify the tab controller
1712 // about tab index changes
1713 if ( mxTabController.is() && !mbDesignMode )
1714 mxTabController->activateTabOrder();
1715 }
lcl_ApplyResolverToNestedContainees(const Reference<resource::XStringResourceResolver> & xStringResourceResolver,const Reference<XControlContainer> & xContainer)1716 void lcl_ApplyResolverToNestedContainees( const Reference< resource::XStringResourceResolver >& xStringResourceResolver, const Reference< XControlContainer >& xContainer )
1717 {
1718 rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER );
1719
1720 Any xNewStringResourceResolver; xNewStringResourceResolver <<= xStringResourceResolver;
1721
1722 Sequence< rtl::OUString > aPropNames(1);
1723 aPropNames[0] = aPropName;
1724
1725 const Sequence< Reference< awt::XControl > > aSeq = xContainer->getControls();
1726 for ( sal_Int32 i = 0; i < aSeq.getLength(); i++ )
1727 {
1728 Reference< XControl > xControl( aSeq[i] );
1729 Reference< XPropertySet > xPropertySet;
1730
1731 if ( xControl.is() )
1732 xPropertySet = Reference< XPropertySet >( xControl->getModel(), UNO_QUERY );
1733
1734 if ( !xPropertySet.is() )
1735 continue;
1736
1737 try
1738 {
1739 Reference< resource::XStringResourceResolver > xCurrStringResourceResolver;
1740 Any aOldValue = xPropertySet->getPropertyValue( aPropName );
1741 if ( ( aOldValue >>= xCurrStringResourceResolver )
1742 && ( xStringResourceResolver == xCurrStringResourceResolver )
1743 )
1744 {
1745 Reference< XMultiPropertySet > xMultiPropSet( xPropertySet, UNO_QUERY );
1746 Reference< XPropertiesChangeListener > xListener( xPropertySet, UNO_QUERY );
1747 xMultiPropSet->firePropertiesChangeEvent( aPropNames, xListener );
1748 }
1749 else
1750 xPropertySet->setPropertyValue( aPropName, xNewStringResourceResolver );
1751 }
1752 /*catch ( NoSuchElementException& )*/ // that's nonsense, this is never thrown above ...
1753 catch ( const Exception& )
1754 {
1755 }
1756
1757 uno::Reference< XControlContainer > xNestedContainer( xControl, uno::UNO_QUERY );
1758 if ( xNestedContainer.is() )
1759 lcl_ApplyResolverToNestedContainees( xStringResourceResolver, xNestedContainer );
1760
1761 }
1762
1763 }
ImplStartListingForResourceEvents()1764 void ControlContainerBase::ImplStartListingForResourceEvents()
1765 {
1766 Reference< resource::XStringResourceResolver > xStringResourceResolver;
1767
1768 ImplGetPropertyValue( PROPERTY_RESOURCERESOLVER ) >>= xStringResourceResolver;
1769
1770 // Add our helper as listener to retrieve notifications about changes
1771 Reference< util::XModifyListener > rListener( mxListener );
1772 ResourceListener* pResourceListener = static_cast< ResourceListener* >( rListener.get() );
1773
1774 // resource listener will stop listening if resolver reference is empty
1775 if ( pResourceListener )
1776 pResourceListener->startListening( xStringResourceResolver );
1777 ImplUpdateResourceResolver();
1778 }
1779
ImplUpdateResourceResolver()1780 void ControlContainerBase::ImplUpdateResourceResolver()
1781 {
1782 rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER );
1783 Reference< resource::XStringResourceResolver > xStringResourceResolver;
1784
1785 ImplGetPropertyValue( aPropName ) >>= xStringResourceResolver;
1786 if ( !xStringResourceResolver.is() )
1787 return;
1788
1789 lcl_ApplyResolverToNestedContainees( xStringResourceResolver, this );
1790
1791 // propagate resource resolver changes to language dependent props of the dialog
1792 Reference< XPropertySet > xPropertySet( getModel(), UNO_QUERY );
1793 if ( xPropertySet.is() )
1794 {
1795 Reference< XMultiPropertySet > xMultiPropSet( xPropertySet, UNO_QUERY );
1796 Reference< XPropertiesChangeListener > xListener( xPropertySet, UNO_QUERY );
1797 xMultiPropSet->firePropertiesChangeEvent( lcl_getLanguageDependentProperties(), xListener );
1798 }
1799 }
1800
1801
Impl_getGraphicFromURL_nothrow(const::rtl::OUString & _rURL)1802 uno::Reference< graphic::XGraphic > ControlContainerBase::Impl_getGraphicFromURL_nothrow( const ::rtl::OUString& _rURL )
1803 {
1804 uno::Reference< graphic::XGraphic > xGraphic;
1805 if ( !_rURL.getLength() )
1806 return xGraphic;
1807
1808 try
1809 {
1810 uno::Reference< graphic::XGraphicProvider > xProvider;
1811 if ( maContext.createComponent( "com.sun.star.graphic.GraphicProvider", xProvider ) )
1812 {
1813 uno::Sequence< beans::PropertyValue > aMediaProperties(1);
1814 aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
1815 aMediaProperties[0].Value <<= _rURL;
1816 xGraphic = xProvider->queryGraphic( aMediaProperties );
1817 }
1818 }
1819 catch( const Exception& )
1820 {
1821 DBG_UNHANDLED_EXCEPTION();
1822 }
1823
1824 return xGraphic;
1825 }
1826 //// ----------------------------------------------------
1827 //// Helper Method to convert relative url to physical location
1828 //// ----------------------------------------------------
1829
getPhysicalLocation(const::com::sun::star::uno::Any & rbase,const::com::sun::star::uno::Any & rUrl)1830 ::rtl::OUString getPhysicalLocation( const ::com::sun::star::uno::Any& rbase, const ::com::sun::star::uno::Any& rUrl )
1831 {
1832
1833 ::rtl::OUString baseLocation;
1834 ::rtl::OUString url;
1835
1836 rbase >>= baseLocation;
1837 rUrl >>= url;
1838
1839 ::rtl::OUString absoluteURL( url );
1840 if ( url.getLength() > 0 )
1841 {
1842 INetURLObject urlObj(baseLocation);
1843 urlObj.removeSegment();
1844 baseLocation = urlObj.GetMainURL( INetURLObject::NO_DECODE );
1845
1846 const INetURLObject protocolCheck( url );
1847 const INetProtocol protocol = protocolCheck.GetProtocol();
1848 if ( protocol == INET_PROT_NOT_VALID )
1849 {
1850 ::rtl::OUString testAbsoluteURL;
1851 if ( ::osl::FileBase::E_None == ::osl::FileBase::getAbsoluteFileURL( baseLocation, url, testAbsoluteURL ) )
1852 absoluteURL = testAbsoluteURL;
1853 }
1854 }
1855
1856 return absoluteURL;
1857 }
1858