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