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