sync master with lastest vba changes
[ooovba.git] / toolkit / source / controls / dialogcontrol.cxx
blobf976562629f4860bb5fd980e6e2927bf05de1084
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dialogcontrol.cxx,v $
10 * $Revision: 1.27 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_toolkit.hxx"
34 #include <vcl/svapp.hxx>
35 #include <vcl/window.hxx>
36 #include <vcl/wall.hxx>
37 #include <vos/mutex.hxx>
38 #include <toolkit/controls/dialogcontrol.hxx>
39 #include <toolkit/helper/property.hxx>
40 #include <toolkit/helper/unopropertyarrayhelper.hxx>
41 #include <toolkit/controls/geometrycontrolmodel.hxx>
42 #include <toolkit/controls/unocontrols.hxx>
43 #include "toolkit/controls/formattedcontrol.hxx"
44 #include "toolkit/controls/roadmapcontrol.hxx"
45 #ifndef TOOLKIT_INC_TOOLKIT_CONTROLS_TKSCROLLBAR_HXX
46 #include "toolkit/controls/tkscrollbar.hxx"
47 #endif
48 #include <toolkit/controls/stdtabcontroller.hxx>
49 #include <com/sun/star/awt/PosSize.hpp>
50 #include <com/sun/star/awt/WindowAttribute.hpp>
51 #include <com/sun/star/resource/XStringResourceResolver.hpp>
52 #include <com/sun/star/graphic/XGraphicProvider.hpp>
53 #include <tools/list.hxx>
54 #include <cppuhelper/typeprovider.hxx>
55 #include <tools/debug.hxx>
56 #include <tools/diagnose_ex.h>
57 #include <comphelper/processfactory.hxx>
58 #include <vcl/svapp.hxx>
59 #include <vcl/outdev.hxx>
60 #include <comphelper/types.hxx>
62 #include <comphelper/componentcontext.hxx>
63 #include <toolkit/helper/vclunohelper.hxx>
64 #include <unotools/ucbstreamhelper.hxx>
65 #include <vcl/graph.hxx>
66 #include <vcl/image.hxx>
68 #include "tree/treecontrol.hxx"
70 #include <map>
71 #include <algorithm>
72 #include <functional>
73 #include "tools/urlobj.hxx"
74 #include "osl/file.hxx"
76 using namespace ::com::sun::star;
77 using namespace ::com::sun::star::uno;
78 using namespace ::com::sun::star::awt;
79 using namespace ::com::sun::star::lang;
80 using namespace ::com::sun::star::container;
81 using namespace ::com::sun::star::beans;
82 using namespace ::com::sun::star::util;
83 using namespace ::com::sun::star::script;
84 using namespace toolkit;
86 #define PROPERTY_RESOURCERESOLVER ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ))
87 #define PROPERTY_DIALOGSOURCEURL ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogSourceURL" ))
88 #define PROPERTY_IMAGEURL ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ImageURL" ))
89 #define PROPERTY_GRAPHIC ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Graphic" ))
91 //HELPER
92 ::rtl::OUString getPhysicalLocation( const ::com::sun::star::uno::Any& rbase, const ::com::sun::star::uno::Any& rUrl );
94 uno::Reference< graphic::XGraphic > getGraphicFromURL_nothrow( uno::Reference< graphic::XGraphicObject >& rxGrfObj, const ::rtl::OUString& _rURL );
96 struct LanguageDependentProp
98 const char* pPropName;
99 sal_Int32 nPropNameLength;
102 // ----------------------------------------------------------------------------
103 namespace
105 static const Sequence< ::rtl::OUString >& lcl_getLanguageDependentProperties()
107 static Sequence< ::rtl::OUString > s_aLanguageDependentProperties;
108 if ( s_aLanguageDependentProperties.getLength() == 0 )
110 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
111 if ( s_aLanguageDependentProperties.getLength() == 0 )
113 s_aLanguageDependentProperties.realloc( 2 );
114 s_aLanguageDependentProperties[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HelpText" ) );
115 s_aLanguageDependentProperties[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
116 // note: properties must be sorted
119 return s_aLanguageDependentProperties;
122 static uno::Reference< graphic::XGraphic > lcl_getGraphicFromURL_nothrow( const ::rtl::OUString& _rURL )
124 uno::Reference< graphic::XGraphic > xGraphic;
125 if ( !_rURL.getLength() )
126 return xGraphic;
130 ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
131 uno::Reference< graphic::XGraphicProvider > xProvider;
132 if ( aContext.createComponent( "com.sun.star.graphic.GraphicProvider", xProvider ) )
134 uno::Sequence< beans::PropertyValue > aMediaProperties(1);
135 aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
136 aMediaProperties[0].Value <<= _rURL;
137 xGraphic = xProvider->queryGraphic( aMediaProperties );
140 catch( const Exception& )
142 DBG_UNHANDLED_EXCEPTION();
145 return xGraphic;
148 static ::rtl::OUString lcl_GetStringProperty( const ::rtl::OUString& sProperty, const Reference< XPropertySet >& xSet )
150 ::rtl::OUString sValue;
151 Reference< XPropertySetInfo > xPSI;
152 if (xSet.is() && (xPSI = xSet->getPropertySetInfo()).is() &&
153 xPSI->hasPropertyByName( sProperty ) )
155 xSet->getPropertyValue( sProperty ) >>= sValue;
157 return sValue;
162 // ----------------------------------------------------------------------------
163 // functor for disposing a control model
164 struct DisposeControlModel : public ::std::unary_function< Reference< XControlModel >, void >
166 void operator()( Reference< XControlModel >& _rxModel )
170 ::comphelper::disposeComponent( _rxModel );
172 catch( const Exception& )
174 DBG_ERROR( "DisposeControlModel::(): caught an exception while disposing a component!" );
179 // ----------------------------------------------------------------------------
180 // functor for searching control model by name
181 struct FindControlModel : public ::std::unary_function< UnoControlDialogModel::UnoControlModelHolder, bool >
183 private:
184 const ::rtl::OUString& m_rName;
186 public:
187 FindControlModel( const ::rtl::OUString& _rName ) : m_rName( _rName ) { }
189 bool operator()( const UnoControlDialogModel::UnoControlModelHolder& _rCompare )
191 return ( _rCompare.second == m_rName ) ? true : false;
195 // ----------------------------------------------------------------------------
196 // functor for cloning a control model, and insertion into a target list
197 struct CloneControlModel : public ::std::unary_function< UnoControlDialogModel::UnoControlModelHolder, void >
199 private:
200 UnoControlDialogModel::UnoControlModelHolderList& m_rTargetList;
202 public:
203 CloneControlModel( UnoControlDialogModel::UnoControlModelHolderList& _rTargetList )
204 :m_rTargetList( _rTargetList )
208 void operator()( const UnoControlDialogModel::UnoControlModelHolder& _rSource )
210 // clone the source object
211 Reference< XCloneable > xCloneSource( _rSource.first, UNO_QUERY );
212 Reference< XControlModel > xClone( xCloneSource->createClone(), UNO_QUERY );
213 // add to target list
214 m_rTargetList.push_back( UnoControlDialogModel::UnoControlModelHolder( xClone, _rSource.second ) );
218 // ----------------------------------------------------------------------------
219 // functor for comparing a XControlModel with a given reference
220 struct CompareControlModel : public ::std::unary_function< UnoControlDialogModel::UnoControlModelHolder, bool >
222 private:
223 Reference< XControlModel > m_xReference;
224 public:
225 CompareControlModel( const Reference< XControlModel >& _rxReference ) : m_xReference( _rxReference ) { }
227 bool operator()( const UnoControlDialogModel::UnoControlModelHolder& _rCompare )
229 return ( _rCompare.first.get() == m_xReference.get() ) ? true : false;
233 // ----------------------------------------------------------------------------
234 static void lcl_throwIllegalArgumentException( )
235 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
236 throw IllegalArgumentException();
239 // ----------------------------------------------------------------------------
240 static void lcl_throwNoSuchElementException( )
241 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
242 throw NoSuchElementException();
245 // ----------------------------------------------------------------------------
246 static void lcl_throwElementExistException( )
247 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
248 throw ElementExistException();
251 // ----------------------------------------------------------------------------
252 static const ::rtl::OUString& getTabIndexPropertyName( )
254 static const ::rtl::OUString s_sTabIndexProperty( RTL_CONSTASCII_USTRINGPARAM( "TabIndex" ) );
255 return s_sTabIndexProperty;
258 // ----------------------------------------------------------------------------
259 static const ::rtl::OUString& getStepPropertyName( )
261 static const ::rtl::OUString s_sStepProperty( RTL_CONSTASCII_USTRINGPARAM( "Step" ) );
262 return s_sStepProperty;
265 // ----------------------------------------------------
266 // class UnoControlDialogModel
267 // ----------------------------------------------------
268 UnoControlDialogModel::UnoControlDialogModel()
269 :maContainerListeners( *this )
270 ,maChangeListeners ( GetMutex() )
271 ,mbGroupsUpToDate( sal_False ), mbAdjustingGraphic( false )
273 ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR );
274 // ImplRegisterProperty( BASEPROPERTY_BORDER );
275 ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL );
276 ImplRegisterProperty( BASEPROPERTY_ENABLED );
277 ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR );
278 // ImplRegisterProperty( BASEPROPERTY_PRINTABLE );
279 ImplRegisterProperty( BASEPROPERTY_HELPTEXT );
280 ImplRegisterProperty( BASEPROPERTY_HELPURL );
281 ImplRegisterProperty( BASEPROPERTY_TITLE );
282 ImplRegisterProperty( BASEPROPERTY_SIZEABLE );
283 ImplRegisterProperty( BASEPROPERTY_DESKTOP_AS_PARENT );
284 ImplRegisterProperty( BASEPROPERTY_DECORATION );
285 ImplRegisterProperty( BASEPROPERTY_DIALOGSOURCEURL );
286 ImplRegisterProperty( BASEPROPERTY_GRAPHIC );
287 ImplRegisterProperty( BASEPROPERTY_IMAGEURL );
289 Any aBool;
290 aBool <<= (sal_Bool) sal_True;
291 ImplRegisterProperty( BASEPROPERTY_MOVEABLE, aBool );
292 ImplRegisterProperty( BASEPROPERTY_CLOSEABLE, aBool );
293 aBool <<= (sal_Bool) sal_False;
294 ImplRegisterProperty( BASEPROPERTY_VBAFORM, aBool );
297 UnoControlDialogModel::UnoControlDialogModel( const UnoControlDialogModel& rModel )
298 : UnoControlDialogModel_IBase( rModel )
299 , UnoControlDialogModel_Base( rModel )
300 , maContainerListeners( *this )
301 , maChangeListeners ( GetMutex() )
302 , mbGroupsUpToDate( sal_False ), mbAdjustingGraphic( false )
306 UnoControlDialogModel::~UnoControlDialogModel()
308 maModels.clear();
309 mbGroupsUpToDate = sal_False;
312 Any UnoControlDialogModel::queryAggregation( const Type & rType ) throw(RuntimeException)
314 Any aRet( UnoControlDialogModel_IBase::queryInterface( rType ) );
315 return (aRet.hasValue() ? aRet : UnoControlDialogModel_Base::queryAggregation( rType ));
318 // XTypeProvider
319 IMPL_IMPLEMENTATION_ID( UnoControlDialogModel )
320 Sequence< Type > UnoControlDialogModel::getTypes() throw(RuntimeException)
322 return ::comphelper::concatSequences(
323 UnoControlDialogModel_IBase::getTypes(),
324 UnoControlDialogModel_Base::getTypes()
328 ::rtl::OUString UnoControlDialogModel::getServiceName( ) throw(RuntimeException)
330 return ::rtl::OUString::createFromAscii( szServiceName_UnoControlDialogModel );
333 void SAL_CALL UnoControlDialogModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) throw (::com::sun::star::uno::Exception)
335 UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue );
338 switch ( nHandle )
340 case BASEPROPERTY_IMAGEURL:
341 if ( !mbAdjustingGraphic && ImplHasProperty( BASEPROPERTY_GRAPHIC ) )
343 mbAdjustingGraphic = true;
344 ::rtl::OUString sImageURL;
345 OSL_VERIFY( rValue >>= sImageURL );
346 setPropertyValue( GetPropertyName( BASEPROPERTY_GRAPHIC ), uno::makeAny( getGraphicFromURL_nothrow( mxGrfObj, sImageURL ) ) );
347 mbAdjustingGraphic = false;
349 break;
351 case BASEPROPERTY_GRAPHIC:
352 if ( !mbAdjustingGraphic && ImplHasProperty( BASEPROPERTY_IMAGEURL ) )
354 mbAdjustingGraphic = true;
355 setPropertyValue( GetPropertyName( BASEPROPERTY_IMAGEURL ), uno::makeAny( ::rtl::OUString() ) );
356 mbAdjustingGraphic = false;
358 break;
361 catch( const ::com::sun::star::uno::Exception& )
363 OSL_ENSURE( sal_False, "UnoControlDialogModel::setFastPropertyValue_NoBroadcast: caught an exception while setting Graphic/ImageURL properties!" );
367 Any UnoControlDialogModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
369 Any aAny;
371 switch ( nPropId )
373 case BASEPROPERTY_DEFAULTCONTROL:
374 aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlDialog );
375 break;
376 default:
377 aAny = UnoControlModel::ImplGetDefaultValue( nPropId );
380 return aAny;
383 ::cppu::IPropertyArrayHelper& UnoControlDialogModel::getInfoHelper()
385 static UnoPropertyArrayHelper* pHelper = NULL;
386 if ( !pHelper )
388 Sequence<sal_Int32> aIDs = ImplGetPropertyIds();
389 pHelper = new UnoPropertyArrayHelper( aIDs );
391 return *pHelper;
394 void SAL_CALL UnoControlDialogModel::dispose( ) throw(RuntimeException)
396 // ====================================================================
397 // tell our listeners
399 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
401 EventObject aDisposeEvent;
402 aDisposeEvent.Source = static_cast< XAggregation* >( static_cast< ::cppu::OWeakAggObject* >( this ) );
404 maContainerListeners.disposeAndClear( aDisposeEvent );
405 maChangeListeners.disposeAndClear( aDisposeEvent );
408 // ====================================================================
409 // call the base class
410 UnoControlModel::dispose();
412 // ====================================================================
413 // dispose our child models
414 // for this, collect the models (we collect them from maModels, and this is modified when disposing children)
415 ::std::vector< Reference< XControlModel > > aChildModels( maModels.size() );
417 ::std::transform(
418 maModels.begin(), maModels.end(), // source range
419 aChildModels.begin(), // target location
420 ::std::select1st< UnoControlModelHolder >( ) // operation to apply -> select the XControlModel part
423 // now dispose
424 ::std::for_each( aChildModels.begin(), aChildModels.end(), DisposeControlModel() );
425 aChildModels.clear();
427 mbGroupsUpToDate = sal_False;
430 // XMultiPropertySet
431 Reference< XPropertySetInfo > UnoControlDialogModel::getPropertySetInfo( ) throw(RuntimeException)
433 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
434 return xInfo;
437 UnoControlModel* UnoControlDialogModel::Clone() const
439 // clone the container itself
440 UnoControlDialogModel* pClone = new UnoControlDialogModel( *this );
442 // clone all children
443 ::std::for_each(
444 maModels.begin(), maModels.end(),
445 CloneControlModel( pClone->maModels )
448 return pClone;
451 UnoControlDialogModel::UnoControlModelHolderList::iterator UnoControlDialogModel::ImplFindElement( const ::rtl::OUString& rName )
453 return ::std::find_if( maModels.begin(), maModels.end(), FindControlModel( rName ) );
456 // ::XMultiServiceFactory
457 Reference< XInterface > UnoControlDialogModel::createInstance( const ::rtl::OUString& aServiceSpecifier ) throw(Exception, RuntimeException)
459 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
461 OGeometryControlModel_Base* pNewModel = NULL;
463 if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlEditModel ) == 0 )
464 pNewModel = new OGeometryControlModel< UnoControlEditModel >;
465 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFormattedFieldModel ) == 0 )
466 pNewModel = new OGeometryControlModel< UnoControlFormattedFieldModel >;
467 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFileControlModel ) == 0 )
468 pNewModel = new OGeometryControlModel< UnoControlFileControlModel >;
469 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlButtonModel ) == 0 )
470 pNewModel = new OGeometryControlModel< UnoControlButtonModel >;
471 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlImageControlModel ) == 0 )
472 pNewModel = new OGeometryControlModel< UnoControlImageControlModel >;
473 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRadioButtonModel ) == 0 )
474 pNewModel = new OGeometryControlModel< UnoControlRadioButtonModel >;
475 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCheckBoxModel ) == 0 )
476 pNewModel = new OGeometryControlModel< UnoControlCheckBoxModel >;
477 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedHyperlinkModel ) == 0 )
478 pNewModel = new OGeometryControlModel< UnoControlFixedHyperlinkModel >;
479 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedTextModel ) == 0 )
480 pNewModel = new OGeometryControlModel< UnoControlFixedTextModel >;
481 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlGroupBoxModel ) == 0 )
482 pNewModel = new OGeometryControlModel< UnoControlGroupBoxModel >;
483 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlListBoxModel ) == 0 )
484 pNewModel = new OGeometryControlModel< UnoControlListBoxModel >;
485 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlComboBoxModel ) == 0 )
486 pNewModel = new OGeometryControlModel< UnoControlComboBoxModel >;
487 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlDateFieldModel ) == 0 )
488 pNewModel = new OGeometryControlModel< UnoControlDateFieldModel >;
489 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlTimeFieldModel ) == 0 )
490 pNewModel = new OGeometryControlModel< UnoControlTimeFieldModel >;
491 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlNumericFieldModel ) == 0 )
492 pNewModel = new OGeometryControlModel< UnoControlNumericFieldModel >;
493 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCurrencyFieldModel ) == 0 )
494 pNewModel = new OGeometryControlModel< UnoControlCurrencyFieldModel >;
495 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlPatternFieldModel ) == 0 )
496 pNewModel = new OGeometryControlModel< UnoControlPatternFieldModel >;
497 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlProgressBarModel ) == 0 )
498 pNewModel = new OGeometryControlModel< UnoControlProgressBarModel >;
499 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlScrollBarModel ) == 0 )
500 pNewModel = new OGeometryControlModel< UnoControlScrollBarModel >;
501 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFixedLineModel ) == 0 )
502 pNewModel = new OGeometryControlModel< UnoControlFixedLineModel >;
503 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRoadmapModel ) == 0 )
504 pNewModel = new OGeometryControlModel< UnoControlRoadmapModel >;
505 else if ( aServiceSpecifier.compareToAscii( szServiceName_TreeControlModel ) == 0 )
506 pNewModel = new OGeometryControlModel< UnoTreeModel >;
508 if ( !pNewModel )
510 Reference< XMultiServiceFactory > xORB( ::comphelper::getProcessServiceFactory() );
511 if ( xORB.is() )
513 Reference< XInterface > xObject = xORB->createInstance( aServiceSpecifier );
514 Reference< XServiceInfo > xSI( xObject, UNO_QUERY );
515 Reference< XCloneable > xCloneAccess( xSI, UNO_QUERY );
516 Reference< XAggregation > xAgg( xCloneAccess, UNO_QUERY );
517 if ( xAgg.is() )
519 if ( xSI->supportsService( ::rtl::OUString::createFromAscii( "com.sun.star.awt.UnoControlModel" ) ) )
521 // release 3 of the 4 references we have to the object
522 xAgg.clear();
523 xSI.clear();
524 xObject.clear();
526 pNewModel = new OCommonGeometryControlModel( xCloneAccess, aServiceSpecifier );
532 Reference< XInterface > xNewModel = (::cppu::OWeakObject*)pNewModel;
533 return xNewModel;
536 Reference< XInterface > UnoControlDialogModel::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& /* Arguments */ ) throw(Exception, RuntimeException)
538 return createInstance( ServiceSpecifier );
541 Sequence< ::rtl::OUString > UnoControlDialogModel::getAvailableServiceNames() throw(RuntimeException)
543 static Sequence< ::rtl::OUString >* pNamesSeq = NULL;
544 if ( !pNamesSeq )
546 pNamesSeq = new Sequence< ::rtl::OUString >( 21 );
547 ::rtl::OUString* pNames = pNamesSeq->getArray();
548 pNames[0] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlEditModel );
549 pNames[1] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFormattedFieldModel );
550 pNames[2] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFileControlModel );
551 pNames[3] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlButtonModel );
552 pNames[4] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlImageControlModel );
553 pNames[5] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRadioButtonModel );
554 pNames[6] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlCheckBoxModel );
555 pNames[7] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFixedTextModel );
556 pNames[8] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlGroupBoxModel );
557 pNames[9] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlListBoxModel );
558 pNames[10] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlComboBoxModel );
559 pNames[11] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlDateFieldModel );
560 pNames[12] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlTimeFieldModel );
561 pNames[13] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlNumericFieldModel );
562 pNames[14] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlCurrencyFieldModel );
563 pNames[15] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlPatternFieldModel );
564 pNames[16] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlProgressBarModel );
565 pNames[17] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlScrollBarModel );
566 pNames[18] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFixedLineModel );
567 pNames[19] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRoadmapModel );
568 pNames[20] = ::rtl::OUString::createFromAscii( szServiceName_TreeControlModel );
571 return *pNamesSeq;
574 // XContainer
575 void UnoControlDialogModel::addContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException)
577 maContainerListeners.addInterface( l );
580 void UnoControlDialogModel::removeContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException)
582 maContainerListeners.removeInterface( l );
585 // XElementAcces
586 Type UnoControlDialogModel::getElementType() throw(RuntimeException)
588 Type aType = getCppuType( ( Reference< XControlModel>* ) NULL );
589 return aType;
592 sal_Bool UnoControlDialogModel::hasElements() throw(RuntimeException)
594 return !maModels.empty();
597 // XNameContainer, XNameReplace, XNameAccess
598 void UnoControlDialogModel::replaceByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
600 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
602 Reference< XControlModel > xNewModel;
603 aElement >>= xNewModel;
604 if ( !xNewModel.is() )
605 lcl_throwIllegalArgumentException();
607 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
608 if ( maModels.end() == aElementPos )
609 lcl_throwNoSuchElementException();
611 // stop listening at the old model
612 stopControlListening( aElementPos->first );
613 Reference< XControlModel > xReplaced( aElementPos->first );
614 // remember the new model, and start listening
615 aElementPos->first = xNewModel;
616 startControlListening( xNewModel );
618 ContainerEvent aEvent;
619 aEvent.Source = *this;
620 aEvent.Element = aElement;
621 aEvent.ReplacedElement <<= xReplaced;
622 aEvent.Accessor <<= aName;
624 // notify the container listener
625 maContainerListeners.elementReplaced( aEvent );
627 // our "tab controller model" has potentially changed -> notify this
628 implNotifyTabModelChange( aName );
631 Any UnoControlDialogModel::getByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
633 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
634 if ( maModels.end() == aElementPos )
635 lcl_throwNoSuchElementException();
637 return makeAny( aElementPos->first );
640 Sequence< ::rtl::OUString > UnoControlDialogModel::getElementNames() throw(RuntimeException)
642 Sequence< ::rtl::OUString > aNames( maModels.size() );
644 ::std::transform(
645 maModels.begin(), maModels.end(), // source range
646 aNames.getArray(), // target range
647 ::std::select2nd< UnoControlModelHolder >() // operator to apply: select the second element (the name)
650 return aNames;
653 sal_Bool UnoControlDialogModel::hasByName( const ::rtl::OUString& aName ) throw(RuntimeException)
655 return maModels.end() != ImplFindElement( aName );
658 void UnoControlDialogModel::insertByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
660 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
662 Reference< XControlModel > xM;
663 aElement >>= xM;
665 if ( xM.is() )
667 Reference< beans::XPropertySet > xProps( xM, UNO_QUERY );
668 if ( xProps.is() )
671 Reference< beans::XPropertySetInfo > xPropInfo = xProps.get()->getPropertySetInfo();
673 ::rtl::OUString sImageSourceProperty = GetPropertyName( BASEPROPERTY_IMAGEURL );
674 if ( xPropInfo.get()->hasPropertyByName( sImageSourceProperty ))
676 Any aUrl = xProps.get()->getPropertyValue( sImageSourceProperty );
678 ::rtl::OUString absoluteUrl =
679 getPhysicalLocation( getPropertyValue( GetPropertyName( BASEPROPERTY_DIALOGSOURCEURL ) ), aUrl );
681 aUrl <<= absoluteUrl;
683 xProps.get()->setPropertyValue( sImageSourceProperty , aUrl );
690 if ( !aName.getLength() || !xM.is() )
691 lcl_throwIllegalArgumentException();
693 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
694 if ( maModels.end() != aElementPos )
695 lcl_throwElementExistException();
697 maModels.push_back( UnoControlModelHolder( xM, aName ) );
698 mbGroupsUpToDate = sal_False;
699 startControlListening( xM );
701 ContainerEvent aEvent;
702 aEvent.Source = *this;
703 aEvent.Element <<= aElement;
704 aEvent.Accessor <<= aName;
705 maContainerListeners.elementInserted( aEvent );
707 // our "tab controller model" has potentially changed -> notify this
708 implNotifyTabModelChange( aName );
711 void UnoControlDialogModel::removeByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
713 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
715 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
716 if ( maModels.end() == aElementPos )
717 lcl_throwNoSuchElementException();
719 ContainerEvent aEvent;
720 aEvent.Source = *this;
721 aEvent.Element <<= aElementPos->first;
722 aEvent.Accessor <<= aName;
723 maContainerListeners.elementRemoved( aEvent );
725 stopControlListening( aElementPos->first );
726 Reference< XPropertySet > xPS( aElementPos->first, UNO_QUERY );
727 maModels.erase( aElementPos );
728 mbGroupsUpToDate = sal_False;
730 if ( xPS.is() )
733 xPS->setPropertyValue( PROPERTY_RESOURCERESOLVER, makeAny( Reference< resource::XStringResourceResolver >() ) );
735 catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
737 // our "tab controller model" has potentially changed -> notify this
738 implNotifyTabModelChange( aName );
741 // ----------------------------------------------------------------------------
742 sal_Bool SAL_CALL UnoControlDialogModel::getGroupControl( ) throw (RuntimeException)
744 return sal_True;
747 // ----------------------------------------------------------------------------
748 void SAL_CALL UnoControlDialogModel::setGroupControl( sal_Bool ) throw (RuntimeException)
750 DBG_ERROR( "UnoControlDialogModel::setGroupControl: explicit grouping not supported" );
753 // ----------------------------------------------------------------------------
754 void SAL_CALL UnoControlDialogModel::setControlModels( const Sequence< Reference< XControlModel > >& _rControls ) throw (RuntimeException)
756 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
758 // set the tab indexes according to the order of models in the sequence
759 const Reference< XControlModel >* pControls = _rControls.getConstArray( );
760 const Reference< XControlModel >* pControlsEnd = _rControls.getConstArray( ) + _rControls.getLength();
762 sal_Int16 nTabIndex = 1;
764 for ( ; pControls != pControlsEnd; ++pControls )
766 // look up the control in our own structure. This is to prevent invalid arguments
767 UnoControlModelHolderList::const_iterator aPos =
768 ::std::find_if(
769 maModels.begin(), maModels.end(),
770 CompareControlModel( *pControls )
772 if ( maModels.end() != aPos )
774 // okay, this is an existent model
775 // now set the TabIndex property (if applicable)
776 Reference< XPropertySet > xProps( aPos->first, UNO_QUERY );
777 Reference< XPropertySetInfo > xPSI;
778 if ( xProps.is() )
779 xPSI = xProps->getPropertySetInfo();
780 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
781 xProps->setPropertyValue( getTabIndexPropertyName(), makeAny( nTabIndex++ ) );
783 mbGroupsUpToDate = sal_False;
788 typedef ::std::multimap< sal_Int32, Reference< XControlModel >, ::std::less< sal_Int32 > > MapIndexToModel;
790 // ----------------------------------------------------------------------------
791 Sequence< Reference< XControlModel > > SAL_CALL UnoControlDialogModel::getControlModels( ) throw (RuntimeException)
793 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
795 MapIndexToModel aSortedModels;
796 // will be the sorted container of all models which have a tab index property
797 ::std::vector< Reference< XControlModel > > aUnindexedModels;
798 // will be the container of all models which do not have a tab index property
800 UnoControlModelHolderList::const_iterator aLoop = maModels.begin();
801 for ( ; aLoop != maModels.end(); ++aLoop )
803 Reference< XControlModel > xModel( aLoop->first );
805 // see if the model has a TabIndex property
806 Reference< XPropertySet > xControlProps( xModel, UNO_QUERY );
807 Reference< XPropertySetInfo > xPSI;
808 if ( xControlProps.is() )
809 xPSI = xControlProps->getPropertySetInfo( );
810 DBG_ASSERT( xPSI.is(), "UnoControlDialogModel::getControlModels: invalid child model!" );
812 // has it?
813 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
814 { // yes
815 sal_Int32 nTabIndex = -1;
816 xControlProps->getPropertyValue( getTabIndexPropertyName() ) >>= nTabIndex;
818 aSortedModels.insert( MapIndexToModel::value_type( nTabIndex, xModel ) );
820 else if ( xModel.is() )
821 // no, it hasn't, but we have to include it, anyway
822 aUnindexedModels.push_back( xModel );
825 // okay, here we have a container of all our models, sorted by tab index,
826 // plus a container of "unindexed" models
827 // -> merge them
828 Sequence< Reference< XControlModel > > aReturn( aUnindexedModels.size() + aSortedModels.size() );
829 ::std::transform(
830 aSortedModels.begin(), aSortedModels.end(),
831 ::std::copy( aUnindexedModels.begin(), aUnindexedModels.end(), aReturn.getArray() ),
832 ::std::select2nd< MapIndexToModel::value_type >( )
835 return aReturn;
838 // ----------------------------------------------------------------------------
839 void SAL_CALL UnoControlDialogModel::setGroup( const Sequence< Reference< XControlModel > >&, const ::rtl::OUString& ) throw (RuntimeException)
841 // not supported. We have only implicit grouping:
842 // We only have a sequence of control models, and we _know_ (yes, that's a HACK relying on
843 // implementation details) that VCL does grouping according to the order of controls automatically
844 // At least VCL does this for all we're interested in: Radio buttons.
845 DBG_ERROR( "UnoControlDialogModel::setGroup: grouping not supported" );
848 // ----------------------------------------------------------------------------
849 namespace
851 enum GroupingMachineState
853 eLookingForGroup,
854 eExpandingGroup
857 // ........................................................................
858 static sal_Int32 lcl_getDialogStep( const Reference< XControlModel >& _rxModel )
860 sal_Int32 nStep = 0;
863 Reference< XPropertySet > xModelProps( _rxModel, UNO_QUERY );
864 xModelProps->getPropertyValue( getStepPropertyName() ) >>= nStep;
866 catch( const Exception& )
868 DBG_ERROR( "lcl_getDialogStep: caught an exception while determining the dialog page!" );
870 return nStep;
874 // ----------------------------------------------------------------------------
875 sal_Int32 SAL_CALL UnoControlDialogModel::getGroupCount( ) throw (RuntimeException)
877 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
879 implUpdateGroupStructure();
881 return maGroups.size();
884 // ----------------------------------------------------------------------------
885 void SAL_CALL UnoControlDialogModel::getGroup( sal_Int32 _nGroup, Sequence< Reference< XControlModel > >& _rGroup, ::rtl::OUString& _rName ) throw (RuntimeException)
887 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
889 implUpdateGroupStructure();
891 if ( ( _nGroup < 0 ) || ( _nGroup >= (sal_Int32)maGroups.size() ) )
893 DBG_ERROR( "UnoControlDialogModel::getGroup: invalid argument and I am not allowed to throw an exception!" );
894 _rGroup.realloc( 0 );
895 _rName = ::rtl::OUString();
897 else
899 AllGroups::const_iterator aGroupPos = maGroups.begin() + _nGroup;
900 _rGroup.realloc( aGroupPos->size() );
901 // copy the models
902 ::std::copy( aGroupPos->begin(), aGroupPos->end(), _rGroup.getArray() );
903 // give the group a name
904 _rName = ::rtl::OUString::valueOf( _nGroup );
908 // ----------------------------------------------------------------------------
909 void SAL_CALL UnoControlDialogModel::getGroupByName( const ::rtl::OUString& _rName, Sequence< Reference< XControlModel > >& _rGroup ) throw (RuntimeException)
911 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
913 ::rtl::OUString sDummyName;
914 getGroup( _rName.toInt32( ), _rGroup, sDummyName );
917 // ----------------------------------------------------------------------------
918 void SAL_CALL UnoControlDialogModel::addChangesListener( const Reference< XChangesListener >& _rxListener ) throw (RuntimeException)
920 maChangeListeners.addInterface( _rxListener );
923 // ----------------------------------------------------------------------------
924 void SAL_CALL UnoControlDialogModel::removeChangesListener( const Reference< XChangesListener >& _rxListener ) throw (RuntimeException)
926 maChangeListeners.removeInterface( _rxListener );
929 // ----------------------------------------------------------------------------
930 void UnoControlDialogModel::implNotifyTabModelChange( const ::rtl::OUString& _rAccessor )
932 // multiplex to our change listeners:
933 // the changes event
934 ChangesEvent aEvent;
935 aEvent.Source = *this;
936 aEvent.Base <<= aEvent.Source; // the "base of the changes root" is also ourself
937 aEvent.Changes.realloc( 1 ); // exactly one change
938 aEvent.Changes[ 0 ].Accessor <<= _rAccessor;
941 Sequence< Reference< XInterface > > aChangeListeners( maChangeListeners.getElements() );
942 const Reference< XInterface >* pListener = aChangeListeners.getConstArray();
943 const Reference< XInterface >* pListenerEnd = aChangeListeners.getConstArray() + aChangeListeners.getLength();
944 for ( ; pListener != pListenerEnd; ++pListener )
946 if ( pListener->is() )
947 static_cast< XChangesListener* >( pListener->get() )->changesOccurred( aEvent );
951 // ----------------------------------------------------------------------------
952 void UnoControlDialogModel::AddRadioButtonGroup (
953 ::std::map< ::rtl::OUString, ModelGroup >& rNamedGroups )
955 if ( rNamedGroups.size() == 0 )
956 return;
958 size_t nGroups = maGroups.size();
959 maGroups.reserve( nGroups + rNamedGroups.size() );
960 ::std::map< ::rtl::OUString, ModelGroup >::const_iterator i = rNamedGroups.begin(), e = rNamedGroups.end();
961 for( ; i != e; ++i)
963 maGroups.push_back( i->second );
966 rNamedGroups.clear();
969 void UnoControlDialogModel::AddRadioButtonToGroup (
970 const Reference< XControlModel >& rControlModel,
971 const ::rtl::OUString& rPropertyName,
972 ::std::map< ::rtl::OUString, ModelGroup >& rNamedGroups,
973 ModelGroup*& rpCurrentGroup )
975 Reference< XPropertySet > xCurProps( rControlModel, UNO_QUERY );
976 ::rtl::OUString sGroup = lcl_GetStringProperty( rPropertyName, xCurProps );
977 const sal_Int32 nControlModelStep = lcl_getDialogStep( rControlModel );
979 if ( sGroup.getLength() == 0 )
981 // Create a new group if:
982 if ( maGroups.size() == 0 || // no groups
983 rpCurrentGroup == NULL || // previous group was closed
984 (nControlModelStep != 0 && // control step matches current group
985 maGroups.back().size() > 0 && // (group 0 == display everywhere)
986 nControlModelStep != lcl_getDialogStep( maGroups.back().back() ) ) )
988 size_t nGroups = maGroups.size();
989 maGroups.resize( nGroups + 1 );
991 rpCurrentGroup = &maGroups.back();
993 else
995 // Different steps get different sets of named groups
996 if ( rNamedGroups.size() > 0 &&
997 rNamedGroups.begin()->second.size() > 0 )
999 const sal_Int32 nPrevStep = lcl_getDialogStep( rNamedGroups.begin()->second.front() );
1000 if ( nControlModelStep != nPrevStep )
1001 AddRadioButtonGroup( rNamedGroups );
1004 rpCurrentGroup = &rNamedGroups[ sGroup ];
1006 rpCurrentGroup->push_back( rControlModel );
1009 // ----------------------------------------------------------------------------
1010 void UnoControlDialogModel::implUpdateGroupStructure()
1012 if ( mbGroupsUpToDate )
1013 // nothing to do
1014 return;
1016 // conditions for a group:
1017 // * all elements of the group are radio buttons
1018 // * all elements of the group are on the same dialog page
1019 // * in the overall control order (determined by the tab index), all elements are subsequent
1021 maGroups.clear();
1023 Sequence< Reference< XControlModel > > aControlModels = getControlModels();
1024 const Reference< XControlModel >* pControlModels = aControlModels.getConstArray();
1025 const Reference< XControlModel >* pControlModelsEnd = pControlModels + aControlModels.getLength();
1027 // in extreme we have as much groups as controls
1028 maGroups.reserve( aControlModels.getLength() );
1030 GroupingMachineState eState = eLookingForGroup; // the current state of our machine
1031 Reference< XServiceInfo > xModelSI; // for checking for a radion button
1032 ModelGroup* aCurrentGroup = NULL; // the group which we're currently building
1033 sal_Bool bIsRadioButton; // is it a radio button?
1035 const ::rtl::OUString GROUP_NAME( RTL_CONSTASCII_USTRINGPARAM( "GroupName" ) );
1037 ::std::map< ::rtl::OUString, ModelGroup > aNamedGroups;
1039 #if OSL_DEBUG_LEVEL > 1
1040 ::std::vector< ::rtl::OUString > aCurrentGroupLabels;
1041 #endif
1043 for ( ; pControlModels != pControlModelsEnd; ++pControlModels )
1045 // we'll need this in every state
1046 xModelSI = xModelSI.query( *pControlModels );
1047 bIsRadioButton = xModelSI.is() && xModelSI->supportsService( ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRadioButtonModel ) );
1049 switch ( eState )
1051 case eLookingForGroup:
1053 if ( !bIsRadioButton )
1054 // this is no radio button -> still looking for the beginning of a group
1055 continue;
1056 // the current model is a radio button
1057 // -> we found the beginning of a new group
1058 // create the place for this group
1059 AddRadioButtonToGroup( *pControlModels, GROUP_NAME, aNamedGroups, aCurrentGroup );
1061 // new state: looking for further members
1062 eState = eExpandingGroup;
1064 #if OSL_DEBUG_LEVEL > 1
1065 Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY );
1066 ::rtl::OUString sLabel;
1067 if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) )
1068 xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel;
1069 aCurrentGroupLabels.push_back( sLabel );
1070 #endif
1072 break;
1074 case eExpandingGroup:
1076 if ( !bIsRadioButton )
1077 { // no radio button -> the group is done
1078 aCurrentGroup = NULL;
1079 eState = eLookingForGroup;
1080 #if OSL_DEBUG_LEVEL > 1
1081 aCurrentGroupLabels.clear();
1082 #endif
1083 continue;
1086 AddRadioButtonToGroup( *pControlModels, GROUP_NAME, aNamedGroups, aCurrentGroup );
1088 #if OSL_DEBUG_LEVEL > 1
1089 Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY );
1090 ::rtl::OUString sLabel;
1091 if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) )
1092 xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel;
1093 aCurrentGroupLabels.push_back( sLabel );
1094 #endif
1096 break;
1100 AddRadioButtonGroup( aNamedGroups );
1101 mbGroupsUpToDate = sal_True;
1104 // ----------------------------------------------------------------------------
1105 void SAL_CALL UnoControlDialogModel::propertyChange( const PropertyChangeEvent& _rEvent ) throw (RuntimeException)
1107 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1109 DBG_ASSERT( 0 == _rEvent.PropertyName.compareToAscii( "TabIndex" ),
1110 "UnoControlDialogModel::propertyChange: not listening for this property!" );
1112 // the accessor for the changed element
1113 ::rtl::OUString sAccessor;
1114 UnoControlModelHolderList::const_iterator aPos =
1115 ::std::find_if(
1116 maModels.begin(), maModels.end(),
1117 CompareControlModel( Reference< XControlModel >( _rEvent.Source, UNO_QUERY ) )
1119 OSL_ENSURE( maModels.end() != aPos, "UnoControlDialogModel::propertyChange: don't know this model!" );
1120 if ( maModels.end() != aPos )
1121 sAccessor = aPos->second;
1123 // our groups are not up-to-date
1124 mbGroupsUpToDate = sal_False;
1126 // notify
1127 implNotifyTabModelChange( sAccessor );
1130 // ----------------------------------------------------------------------------
1131 void SAL_CALL UnoControlDialogModel::disposing( const EventObject& /*rEvent*/ ) throw (RuntimeException)
1135 // ----------------------------------------------------------------------------
1136 void UnoControlDialogModel::startControlListening( const Reference< XControlModel >& _rxChildModel )
1138 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1140 Reference< XPropertySet > xModelProps( _rxChildModel, UNO_QUERY );
1141 Reference< XPropertySetInfo > xPSI;
1142 if ( xModelProps.is() )
1143 xPSI = xModelProps->getPropertySetInfo();
1145 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
1146 xModelProps->addPropertyChangeListener( getTabIndexPropertyName(), this );
1149 // ----------------------------------------------------------------------------
1150 void UnoControlDialogModel::stopControlListening( const Reference< XControlModel >& _rxChildModel )
1152 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1154 Reference< XPropertySet > xModelProps( _rxChildModel, UNO_QUERY );
1155 Reference< XPropertySetInfo > xPSI;
1156 if ( xModelProps.is() )
1157 xPSI = xModelProps->getPropertySetInfo();
1159 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
1160 xModelProps->removePropertyChangeListener( getTabIndexPropertyName(), this );
1163 // ============================================================================
1164 // = class ResourceListener
1165 // ============================================================================
1167 ResourceListener::ResourceListener(
1168 const Reference< util::XModifyListener >& rListener ) :
1169 OWeakObject(),
1170 m_xListener( rListener ),
1171 m_bListening( false )
1175 ResourceListener::~ResourceListener()
1179 // XInterface
1180 Any SAL_CALL ResourceListener::queryInterface( const Type& rType )
1181 throw ( RuntimeException )
1183 Any a = ::cppu::queryInterface(
1184 rType ,
1185 static_cast< XModifyListener* >( this ),
1186 static_cast< XEventListener* >( this ));
1188 if ( a.hasValue() )
1189 return a;
1191 return OWeakObject::queryInterface( rType );
1194 void SAL_CALL ResourceListener::acquire() throw ()
1196 OWeakObject::acquire();
1199 void SAL_CALL ResourceListener::release() throw ()
1201 OWeakObject::release();
1204 void ResourceListener::startListening(
1205 const Reference< resource::XStringResourceResolver >& rResource )
1207 Reference< util::XModifyBroadcaster > xModifyBroadcaster( rResource, UNO_QUERY );
1210 // --- SAFE ---
1211 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1212 bool bListening( m_bListening );
1213 bool bResourceSet( m_xResource.is() );
1214 aGuard.clear();
1215 // --- SAFE ---
1217 if ( bListening && bResourceSet )
1218 stopListening();
1220 // --- SAFE ---
1221 aGuard.reset();
1222 m_xResource = rResource;
1223 aGuard.clear();
1224 // --- SAFE ---
1227 Reference< util::XModifyListener > xThis( static_cast<OWeakObject*>( this ), UNO_QUERY );
1228 if ( xModifyBroadcaster.is() )
1232 xModifyBroadcaster->addModifyListener( xThis );
1234 // --- SAFE ---
1235 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1236 m_bListening = true;
1237 // --- SAFE ---
1239 catch ( RuntimeException& )
1241 throw;
1243 catch ( Exception& )
1249 void ResourceListener::stopListening()
1251 Reference< util::XModifyBroadcaster > xModifyBroadcaster;
1253 // --- SAFE ---
1254 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1255 if ( m_bListening && m_xResource.is() )
1256 xModifyBroadcaster = Reference< util::XModifyBroadcaster >( m_xResource, UNO_QUERY );
1257 aGuard.clear();
1258 // --- SAFE ---
1260 Reference< util::XModifyListener > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
1261 if ( xModifyBroadcaster.is() )
1265 // --- SAFE ---
1266 aGuard.reset();
1267 m_bListening = false;
1268 m_xResource.clear();
1269 aGuard.clear();
1270 // --- SAFE ---
1272 xModifyBroadcaster->removeModifyListener( xThis );
1274 catch ( RuntimeException& )
1276 throw;
1278 catch ( Exception& )
1284 // XModifyListener
1285 void SAL_CALL ResourceListener::modified(
1286 const lang::EventObject& aEvent )
1287 throw ( RuntimeException )
1289 Reference< util::XModifyListener > xListener;
1291 // --- SAFE ---
1292 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1293 xListener = m_xListener;
1294 aGuard.clear();
1295 // --- SAFE ---
1297 if ( xListener.is() )
1301 xListener->modified( aEvent );
1303 catch ( RuntimeException& )
1305 throw;
1307 catch ( Exception& )
1313 // XEventListener
1314 void SAL_CALL ResourceListener::disposing(
1315 const EventObject& Source )
1316 throw ( RuntimeException )
1318 Reference< lang::XEventListener > xListener;
1319 Reference< resource::XStringResourceResolver > xResource;
1321 // --- SAFE ---
1322 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1323 Reference< XInterface > xIfacRes( m_xResource, UNO_QUERY );
1324 Reference< XInterface > xIfacList( m_xListener, UNO_QUERY );
1325 aGuard.clear();
1326 // --- SAFE ---
1328 if ( Source.Source == xIfacRes )
1330 // --- SAFE ---
1331 aGuard.reset();
1332 m_bListening = false;
1333 xResource = m_xResource;
1334 xListener = Reference< lang::XEventListener >( m_xListener, UNO_QUERY );
1335 m_xResource.clear();
1336 aGuard.clear();
1337 // --- SAFE ---
1339 if ( xListener.is() )
1343 xListener->disposing( Source );
1345 catch ( RuntimeException& )
1347 throw;
1349 catch ( Exception& )
1354 else if ( Source.Source == xIfacList )
1356 // --- SAFE ---
1357 aGuard.reset();
1358 m_bListening = false;
1359 xListener = Reference< lang::XEventListener >( m_xListener, UNO_QUERY );
1360 xResource = m_xResource;
1361 m_xResource.clear();
1362 m_xListener.clear();
1363 aGuard.clear();
1364 // --- SAFE ---
1366 // Remove ourself as listener from resource resolver
1367 Reference< util::XModifyBroadcaster > xModifyBroadcaster( xResource, UNO_QUERY );
1368 Reference< util::XModifyListener > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
1369 if ( xModifyBroadcaster.is() )
1373 xModifyBroadcaster->removeModifyListener( xThis );
1375 catch ( RuntimeException& )
1377 throw;
1379 catch ( Exception& )
1386 // ============================================================================
1387 // = class UnoDialogControl
1388 // ============================================================================
1390 UnoDialogControl::UnoDialogControl() :
1391 maTopWindowListeners( *this ),
1392 mbWindowListener(false),
1393 mbSizeModified(false),
1394 mbPosModified(false)
1396 maComponentInfos.nWidth = 300;
1397 maComponentInfos.nHeight = 450;
1398 mxListener = new ResourceListener( Reference< util::XModifyListener >(
1399 static_cast< OWeakObject* >( this ), UNO_QUERY ));
1402 ::rtl::OUString UnoDialogControl::GetComponentServiceName()
1405 sal_Bool bDecoration( sal_True );
1406 ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_DECORATION )) >>= bDecoration;
1407 if ( bDecoration )
1408 return ::rtl::OUString::createFromAscii( "Dialog" );
1409 else
1410 return ::rtl::OUString::createFromAscii( "TabPage" );
1413 // XInterface
1414 Any UnoDialogControl::queryAggregation( const Type & rType ) throw(RuntimeException)
1416 Any aRet( UnoDialogControl_IBase::queryInterface( rType ) );
1417 return (aRet.hasValue() ? aRet : UnoControlContainer::queryAggregation( rType ));
1420 // XTypeProvider
1421 IMPL_IMPLEMENTATION_ID( UnoDialogControl )
1422 Sequence< Type > UnoDialogControl::getTypes() throw(RuntimeException)
1424 return ::comphelper::concatSequences(
1425 UnoDialogControl_IBase::getTypes(),
1426 UnoControlContainer::getTypes()
1430 void UnoDialogControl::ImplInsertControl( Reference< XControlModel >& rxModel, const ::rtl::OUString& rName )
1432 Reference< XPropertySet > xP( rxModel, UNO_QUERY );
1434 ::rtl::OUString aDefCtrl;
1435 xP->getPropertyValue( GetPropertyName( BASEPROPERTY_DEFAULTCONTROL ) ) >>= aDefCtrl;
1437 // Add our own resource resolver to a newly created control
1438 Reference< resource::XStringResourceResolver > xStringResourceResolver;
1439 rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER );
1441 Any aAny;
1442 ImplGetPropertyValue( aPropName ) >>= xStringResourceResolver;
1444 aAny <<= xStringResourceResolver;
1445 xP->setPropertyValue( aPropName, aAny );
1447 Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
1448 Reference < XControl > xCtrl( xMSF->createInstance( aDefCtrl ), UNO_QUERY );
1450 DBG_ASSERT( xCtrl.is(), "UnoDialogControl::ImplInsertControl: could not create the control!" );
1451 if ( xCtrl.is() )
1453 xCtrl->setModel( rxModel );
1454 addControl( rName, xCtrl );
1455 // will implicitly call addingControl, where we can add the PropertiesChangeListener to the model
1456 // (which we formerly did herein)
1457 // 08.01.2001 - 96008 - fs@openoffice.org
1459 ImplSetPosSize( xCtrl );
1463 void UnoDialogControl::ImplRemoveControl( Reference< XControlModel >& rxModel )
1465 Sequence< Reference< XControl > > aControls = getControls();
1466 Reference< XControl > xCtrl = StdTabController::FindControl( aControls, rxModel );
1467 if ( xCtrl.is() )
1468 removeControl( xCtrl );
1471 void UnoDialogControl::ImplSetPosSize( Reference< XControl >& rxCtrl )
1473 Reference< XPropertySet > xP( rxCtrl->getModel(), UNO_QUERY );
1475 sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
1476 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) ) ) >>= nX;
1477 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) ) ) >>= nY;
1478 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ) ) >>= nWidth;
1479 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ) ) >>= nHeight;
1481 // Currentley we are simply using MAP_APPFONT ( for normal Dialogs )
1482 // and MAP_100TH_MM for imported Userforms
1483 MapMode aMode( MAP_APPFONT );
1484 sal_Bool bVBAForm = sal_False;
1485 Reference< XPropertySet > xDlgModelProps( getModel(), UNO_QUERY );
1486 if ( xDlgModelProps.is() )
1490 xDlgModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAForm" ) ) ) >>= bVBAForm;
1492 catch( Exception& )
1496 if ( bVBAForm )
1497 aMode = MapMode( MAP_100TH_MM );
1498 OutputDevice*pOutDev = Application::GetDefaultDevice();
1499 if ( pOutDev )
1501 ::Size aTmp( nX, nY );
1502 aTmp = pOutDev->LogicToPixel( aTmp, aMode );
1503 nX = aTmp.Width();
1504 nY = aTmp.Height();
1505 aTmp = ::Size( nWidth, nHeight );
1506 aTmp = pOutDev->LogicToPixel( aTmp, aMode );
1507 nWidth = aTmp.Width();
1508 nHeight = aTmp.Height();
1510 else
1512 Reference< XWindowPeer > xPeer = ImplGetCompatiblePeer( sal_True );
1513 Reference< XDevice > xD( xPeer, UNO_QUERY );
1515 SimpleFontMetric aFM;
1516 FontDescriptor aFD;
1517 Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_FONTDESCRIPTOR ) );
1518 aVal >>= aFD;
1519 if ( aFD.StyleName.getLength() )
1521 Reference< XFont > xFont = xD->getFont( aFD );
1522 aFM = xFont->getFontMetric();
1524 else
1526 Reference< XGraphics > xG = xD->createGraphics();
1527 aFM = xG->getFontMetric();
1530 sal_Int16 nH = aFM.Ascent + aFM.Descent;
1531 sal_Int16 nW = nH/2; // calculate avarage width?!
1533 nX *= nW;
1534 nX /= 4;
1535 nWidth *= nW;
1536 nWidth /= 4;
1537 nY *= nH;
1538 nY /= 8;
1539 nHeight *= nH;
1540 nHeight /= 8;
1542 Reference < XWindow > xW( rxCtrl, UNO_QUERY );
1543 xW->setPosSize( nX, nY, nWidth, nHeight, PosSize::POSSIZE );
1546 void UnoDialogControl::dispose() throw(RuntimeException)
1548 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1550 EventObject aEvt;
1551 aEvt.Source = static_cast< ::cppu::OWeakObject* >( this );
1552 maTopWindowListeners.disposeAndClear( aEvt );
1554 // Notify our listener helper about dispose
1555 // --- SAFE ---
1556 ::osl::ResettableGuard< ::osl::Mutex > aGuard( GetMutex() );
1557 Reference< XEventListener > xListener( mxListener, UNO_QUERY );
1558 mxListener.clear();
1559 aGuard.clear();
1560 // --- SAFE ---
1562 if ( xListener.is() )
1563 xListener->disposing( aEvt );
1565 UnoControlContainer::dispose();
1568 void SAL_CALL UnoDialogControl::disposing(
1569 const EventObject& Source )
1570 throw(RuntimeException)
1572 rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER );
1573 Reference< resource::XStringResourceResolver > xStringResourceResolver;
1575 ImplGetPropertyValue( aPropName ) >>= xStringResourceResolver;
1576 Reference< XInterface > xIfac( xStringResourceResolver, UNO_QUERY );
1578 if ( Source.Source == xIfac )
1580 Any aAny;
1582 // Reset resource resolver reference
1583 ImplSetPropertyValue( aPropName, aAny, sal_True );
1584 ImplUpdateResourceResolver();
1586 else
1588 UnoControlContainer::disposing( Source );
1592 sal_Bool UnoDialogControl::setModel( const Reference< XControlModel >& rxModel ) throw(RuntimeException)
1594 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1596 // destroy the old tab controller, if existent
1597 if ( mxTabController.is() )
1599 mxTabController->setModel( NULL ); // just to be sure, should not be necessary
1600 removeTabController( mxTabController );
1601 ::comphelper::disposeComponent( mxTabController ); // just to be sure, should not be necessary
1602 mxTabController.clear();
1605 if ( getModel().is() )
1607 Sequence< Reference< XControl > > aControls = getControls();
1608 const Reference< XControl >* pCtrls = aControls.getConstArray();
1609 const Reference< XControl >* pCtrlsEnd = pCtrls + aControls.getLength();
1611 for ( ; pCtrls < pCtrlsEnd; ++pCtrls )
1612 removeControl( *pCtrls );
1613 // will implicitly call removingControl, which will remove the PropertyChangeListener
1614 // (which we formerly did herein)
1615 // 08.01.2001 - 96008 - fs@openoffice.org
1617 Reference< XContainer > xC( getModel(), UNO_QUERY );
1618 if ( xC.is() )
1619 xC->removeContainerListener( this );
1621 Reference< XChangesNotifier > xChangeNotifier( getModel(), UNO_QUERY );
1622 if ( xChangeNotifier.is() )
1623 xChangeNotifier->removeChangesListener( this );
1626 sal_Bool bRet = UnoControl::setModel( rxModel );
1628 if ( getModel().is() )
1630 Reference< XNameAccess > xNA( getModel(), UNO_QUERY );
1631 if ( xNA.is() )
1633 Sequence< ::rtl::OUString > aNames = xNA->getElementNames();
1634 const ::rtl::OUString* pNames = aNames.getConstArray();
1635 sal_uInt32 nCtrls = aNames.getLength();
1637 Reference< XControlModel > xCtrlModel;
1638 for( sal_uInt32 n = 0; n < nCtrls; ++n, ++pNames )
1640 xNA->getByName( *pNames ) >>= xCtrlModel;
1641 ImplInsertControl( xCtrlModel, *pNames );
1645 Reference< XContainer > xC( getModel(), UNO_QUERY );
1646 if ( xC.is() )
1647 xC->addContainerListener( this );
1649 Reference< XChangesNotifier > xChangeNotifier( getModel(), UNO_QUERY );
1650 if ( xChangeNotifier.is() )
1651 xChangeNotifier->addChangesListener( this );
1654 Reference< XTabControllerModel > xTabbing( getModel(), UNO_QUERY );
1655 if ( xTabbing.is() )
1657 mxTabController = new StdTabController;
1658 mxTabController->setModel( xTabbing );
1659 addTabController( mxTabController );
1661 ImplStartListingForResourceEvents();
1663 return bRet;
1666 void UnoDialogControl::setDesignMode( sal_Bool bOn ) throw(RuntimeException)
1668 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1669 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1671 UnoControl::setDesignMode( bOn );
1673 Sequence< Reference< XControl > > xCtrls = getControls();
1674 sal_Int32 nControls = xCtrls.getLength();
1675 Reference< XControl >* pControls = xCtrls.getArray();
1676 for ( sal_Int32 n = 0; n < nControls; n++ )
1677 pControls[n]->setDesignMode( bOn );
1679 // #109067# in design mode the tab controller is not notified about
1680 // tab index changes, therefore the tab order must be activated
1681 // when switching from design mode to live mode
1682 if ( mxTabController.is() && !bOn )
1683 mxTabController->activateTabOrder();
1686 void UnoDialogControl::createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer > & rParentPeer ) throw(RuntimeException)
1688 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1690 UnoControlContainer::createPeer( rxToolkit, rParentPeer );
1692 Reference < XTopWindow > xTW( getPeer(), UNO_QUERY );
1693 if ( xTW.is() )
1695 xTW->setMenuBar( mxMenuBar );
1697 if ( !mbWindowListener )
1699 Reference< XWindowListener > xWL( static_cast< cppu::OWeakObject*>( this ), UNO_QUERY );
1700 addWindowListener( xWL );
1701 mbWindowListener = true;
1704 if ( maTopWindowListeners.getLength() )
1705 xTW->addTopWindowListener( &maTopWindowListeners );
1709 void UnoDialogControl::PrepareWindowDescriptor( ::com::sun::star::awt::WindowDescriptor& rDesc )
1711 sal_Bool bDecoration( sal_True );
1712 ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_DECORATION )) >>= bDecoration;
1713 if ( !bDecoration )
1715 // Now we have to manipulate the WindowDescriptor
1716 rDesc.WindowAttributes = rDesc.WindowAttributes | ::com::sun::star::awt::WindowAttribute::NODECORATION;
1719 // We have to set the graphic property before the peer
1720 // will be created. Otherwise the properties will be copied
1721 // into the peer via propertiesChangeEvents. As the order of
1722 // can lead to overwrites we have to set the graphic property
1723 // before the propertiesChangeEvents are sent!
1724 ::rtl::OUString aImageURL;
1725 if (( ImplGetPropertyValue( PROPERTY_IMAGEURL ) >>= aImageURL ) &&
1726 ( aImageURL.getLength() > 0 ))
1728 aImageURL =
1729 getPhysicalLocation( ImplGetPropertyValue( PROPERTY_DIALOGSOURCEURL ),
1730 ImplGetPropertyValue( PROPERTY_IMAGEURL ));
1733 if ( aImageURL.compareToAscii( UNO_NAME_GRAPHOBJ_URLPREFIX, RTL_CONSTASCII_LENGTH( UNO_NAME_GRAPHOBJ_URLPREFIX ) ) != 0 )
1734 ImplSetPropertyValue( PROPERTY_IMAGEURL, uno::makeAny( aImageURL ), sal_True );
1737 void UnoDialogControl::elementInserted( const ContainerEvent& Event ) throw(RuntimeException)
1739 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1741 Reference< XControlModel > xModel;
1742 ::rtl::OUString aName;
1744 Event.Accessor >>= aName;
1745 Event.Element >>= xModel;
1746 ImplInsertControl( xModel, aName );
1749 void UnoDialogControl::elementRemoved( const ContainerEvent& Event ) throw(RuntimeException)
1751 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1753 Reference< XControlModel > xModel;
1754 Event.Element >>= xModel;
1755 if ( xModel.is() )
1756 ImplRemoveControl( xModel );
1759 void UnoDialogControl::elementReplaced( const ContainerEvent& Event ) throw(RuntimeException)
1761 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1763 Reference< XControlModel > xModel;
1764 Event.ReplacedElement >>= xModel;
1765 if ( xModel.is() )
1766 ImplRemoveControl( xModel );
1768 ::rtl::OUString aName;
1769 Event.Accessor >>= aName;
1770 Event.Element >>= xModel;
1771 ImplInsertControl( xModel, aName );
1774 void UnoDialogControl::addTopWindowListener( const Reference< XTopWindowListener >& rxListener ) throw (RuntimeException)
1776 maTopWindowListeners.addInterface( rxListener );
1777 if( getPeer().is() && maTopWindowListeners.getLength() == 1 )
1779 Reference < XTopWindow > xTW( getPeer(), UNO_QUERY );
1780 xTW->addTopWindowListener( &maTopWindowListeners );
1784 void UnoDialogControl::removeTopWindowListener( const Reference< XTopWindowListener >& rxListener ) throw (RuntimeException)
1786 if( getPeer().is() && maTopWindowListeners.getLength() == 1 )
1788 Reference < XTopWindow > xTW( getPeer(), UNO_QUERY );
1789 xTW->removeTopWindowListener( &maTopWindowListeners );
1791 maTopWindowListeners.removeInterface( rxListener );
1794 void UnoDialogControl::toFront( ) throw (RuntimeException)
1796 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1797 if ( getPeer().is() )
1799 Reference< XTopWindow > xTW( getPeer(), UNO_QUERY );
1800 if( xTW.is() )
1801 xTW->toFront();
1805 void UnoDialogControl::toBack( ) throw (RuntimeException)
1807 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1808 if ( getPeer().is() )
1810 Reference< XTopWindow > xTW( getPeer(), UNO_QUERY );
1811 if( xTW.is() )
1812 xTW->toBack();
1816 void UnoDialogControl::setMenuBar( const Reference< XMenuBar >& rxMenuBar ) throw (RuntimeException)
1818 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1819 mxMenuBar = rxMenuBar;
1820 if ( getPeer().is() )
1822 Reference< XTopWindow > xTW( getPeer(), UNO_QUERY );
1823 if( xTW.is() )
1824 xTW->setMenuBar( mxMenuBar );
1828 static ::Size ImplMapPixelToAppFont( OutputDevice* pOutDev, const ::Size& aSize )
1830 ::Size aTmp = pOutDev->PixelToLogic( aSize, MAP_APPFONT );
1831 return aTmp;
1834 // ::com::sun::star::awt::XWindowListener
1835 void SAL_CALL UnoDialogControl::windowResized( const ::com::sun::star::awt::WindowEvent& e )
1836 throw (::com::sun::star::uno::RuntimeException)
1838 OutputDevice*pOutDev = Application::GetDefaultDevice();
1839 DBG_ASSERT( pOutDev, "Missing Default Device!" );
1840 if ( pOutDev && !mbSizeModified )
1842 // Currentley we are simply using MAP_APPFONT
1843 ::Size aAppFontSize( e.Width, e.Height );
1845 Reference< XControl > xDialogControl( *this, UNO_QUERY_THROW );
1846 Reference< XDevice > xDialogDevice( xDialogControl->getPeer(), UNO_QUERY );
1847 OSL_ENSURE( xDialogDevice.is(), "UnoDialogControl::windowResized: no peer, but a windowResized event?" );
1848 if ( xDialogDevice.is() )
1850 DeviceInfo aDeviceInfo( xDialogDevice->getInfo() );
1851 aAppFontSize.Width() -= aDeviceInfo.LeftInset + aDeviceInfo.RightInset;
1852 aAppFontSize.Height() -= aDeviceInfo.TopInset + aDeviceInfo.BottomInset;
1855 aAppFontSize = ImplMapPixelToAppFont( pOutDev, aAppFontSize );
1857 // Remember that changes have been done by listener. No need to
1858 // update the position because of property change event.
1859 mbSizeModified = true;
1860 Sequence< rtl::OUString > aProps( 2 );
1861 Sequence< Any > aValues( 2 );
1862 // Properties in a sequence must be sorted!
1863 aProps[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Height" ));
1864 aProps[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" ));
1865 aValues[0] <<= aAppFontSize.Height();
1866 aValues[1] <<= aAppFontSize.Width();
1868 ImplSetPropertyValues( aProps, aValues, true );
1869 mbSizeModified = false;
1873 void SAL_CALL UnoDialogControl::windowMoved( const ::com::sun::star::awt::WindowEvent& e )
1874 throw (::com::sun::star::uno::RuntimeException)
1876 OutputDevice*pOutDev = Application::GetDefaultDevice();
1877 DBG_ASSERT( pOutDev, "Missing Default Device!" );
1878 if ( pOutDev && !mbPosModified )
1880 // Currentley we are simply using MAP_APPFONT
1881 Any aAny;
1882 ::Size aTmp( e.X, e.Y );
1883 aTmp = ImplMapPixelToAppFont( pOutDev, aTmp );
1885 // Remember that changes have been done by listener. No need to
1886 // update the position because of property change event.
1887 mbPosModified = true;
1888 Sequence< rtl::OUString > aProps( 2 );
1889 Sequence< Any > aValues( 2 );
1890 aProps[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ));
1891 aProps[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ));
1892 aValues[0] <<= aTmp.Width();
1893 aValues[1] <<= aTmp.Height();
1895 ImplSetPropertyValues( aProps, aValues, true );
1896 mbPosModified = false;
1900 void SAL_CALL UnoDialogControl::windowShown( const ::com::sun::star::lang::EventObject& e )
1901 throw (::com::sun::star::uno::RuntimeException)
1903 (void)e;
1906 void SAL_CALL UnoDialogControl::windowHidden( const ::com::sun::star::lang::EventObject& e )
1907 throw (::com::sun::star::uno::RuntimeException)
1909 (void)e;
1912 // XPropertiesChangeListener
1913 void UnoDialogControl::ImplModelPropertiesChanged( const Sequence< PropertyChangeEvent >& rEvents ) throw(RuntimeException)
1915 if( !isDesignMode() && !mbCreatingCompatiblePeer )
1917 ::rtl::OUString s1( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) );
1918 ::rtl::OUString s2( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) );
1919 ::rtl::OUString s3( RTL_CONSTASCII_USTRINGPARAM( "Width" ) );
1920 ::rtl::OUString s4( RTL_CONSTASCII_USTRINGPARAM( "Height" ) );
1922 sal_Int32 nLen = rEvents.getLength();
1923 for( sal_Int32 i = 0; i < nLen; i++ )
1925 const PropertyChangeEvent& rEvt = rEvents.getConstArray()[i];
1926 Reference< XControlModel > xModel( rEvt.Source, UNO_QUERY );
1927 sal_Bool bOwnModel = (XControlModel*)xModel.get() == (XControlModel*)getModel().get();
1928 if ( ( rEvt.PropertyName == s1 ) ||
1929 ( rEvt.PropertyName == s2 ) ||
1930 ( rEvt.PropertyName == s3 ) ||
1931 ( rEvt.PropertyName == s4 ) )
1933 if ( bOwnModel )
1935 if ( !mbPosModified && !mbSizeModified )
1937 // Don't set new pos/size if we get new values from window listener
1938 Reference< XControl > xThis( (XAggregation*)(::cppu::OWeakAggObject*)this, UNO_QUERY );
1939 ImplSetPosSize( xThis );
1942 else
1944 Sequence<Reference<XControl> > aControlSequence(getControls());
1945 Reference<XControl> aControlRef( StdTabController::FindControl( aControlSequence, xModel ) );
1946 ImplSetPosSize( aControlRef );
1948 break;
1950 else if ( bOwnModel && rEvt.PropertyName.equalsAsciiL( "ResourceResolver", 16 ))
1952 ImplStartListingForResourceEvents();
1957 sal_Int32 nLen = rEvents.getLength();
1958 for( sal_Int32 i = 0; i < nLen; i++ )
1960 const PropertyChangeEvent& rEvt = rEvents.getConstArray()[i];
1961 Reference< XControlModel > xModel( rEvt.Source, UNO_QUERY );
1962 sal_Bool bOwnModel = (XControlModel*)xModel.get() == (XControlModel*)getModel().get();
1963 if ( bOwnModel && rEvt.PropertyName.equalsAsciiL( "ImageURL", 8 ))
1965 ::rtl::OUString aImageURL;
1966 if (( ImplGetPropertyValue( PROPERTY_IMAGEURL ) >>= aImageURL ) &&
1967 ( aImageURL.getLength() > 0 ))
1969 aImageURL =
1970 getPhysicalLocation( ImplGetPropertyValue( PROPERTY_DIALOGSOURCEURL ),
1971 ImplGetPropertyValue( PROPERTY_IMAGEURL ));
1975 ImplSetPropertyValue( PROPERTY_IMAGEURL, uno::makeAny( aImageURL ), sal_True );
1976 break;
1980 UnoControlContainer::ImplModelPropertiesChanged( rEvents );
1983 void UnoDialogControl::ImplStartListingForResourceEvents()
1985 Reference< resource::XStringResourceResolver > xStringResourceResolver;
1987 ImplGetPropertyValue( PROPERTY_RESOURCERESOLVER ) >>= xStringResourceResolver;
1989 // Add our helper as listener to retrieve notifications about changes
1990 Reference< util::XModifyListener > rListener( mxListener );
1991 ResourceListener* pResourceListener = static_cast< ResourceListener* >( rListener.get() );
1993 // resource listener will stop listening if resolver reference is empty
1994 if ( pResourceListener )
1995 pResourceListener->startListening( xStringResourceResolver );
1996 ImplUpdateResourceResolver();
1999 void UnoDialogControl::ImplUpdateResourceResolver()
2001 rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER );
2002 Reference< resource::XStringResourceResolver > xStringResourceResolver;
2004 ImplGetPropertyValue( aPropName ) >>= xStringResourceResolver;
2005 if ( !xStringResourceResolver.is() )
2006 return;
2008 Any xNewStringResourceResolver; xNewStringResourceResolver <<= xStringResourceResolver;
2010 Sequence< rtl::OUString > aPropNames(1);
2011 aPropNames[0] = aPropName;
2013 const Sequence< Reference< awt::XControl > > aSeq = getControls();
2014 for ( sal_Int32 i = 0; i < aSeq.getLength(); i++ )
2016 Reference< XControl > xControl( aSeq[i] );
2017 Reference< XPropertySet > xPropertySet;
2019 if ( xControl.is() )
2020 xPropertySet = Reference< XPropertySet >( xControl->getModel(), UNO_QUERY );
2022 if ( !xPropertySet.is() )
2023 continue;
2027 Reference< resource::XStringResourceResolver > xCurrStringResourceResolver;
2028 Any aOldValue = xPropertySet->getPropertyValue( aPropName );
2029 if ( ( aOldValue >>= xCurrStringResourceResolver )
2030 && ( xStringResourceResolver == xCurrStringResourceResolver )
2033 Reference< XMultiPropertySet > xMultiPropSet( xPropertySet, UNO_QUERY );
2034 Reference< XPropertiesChangeListener > xListener( xPropertySet, UNO_QUERY );
2035 xMultiPropSet->firePropertiesChangeEvent( aPropNames, xListener );
2037 else
2038 xPropertySet->setPropertyValue( aPropName, xNewStringResourceResolver );
2040 /*catch ( NoSuchElementException& )*/ // that's nonsense, this is never thrown above ...
2041 catch ( const Exception& )
2046 // propagate resource resolver changes to language dependent props of the dialog
2047 Reference< XPropertySet > xPropertySet( getModel(), UNO_QUERY );
2048 if ( xPropertySet.is() )
2050 Reference< XMultiPropertySet > xMultiPropSet( xPropertySet, UNO_QUERY );
2051 Reference< XPropertiesChangeListener > xListener( xPropertySet, UNO_QUERY );
2052 xMultiPropSet->firePropertiesChangeEvent( lcl_getLanguageDependentProperties(), xListener );
2056 void UnoDialogControl::setTitle( const ::rtl::OUString& Title ) throw(RuntimeException)
2058 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2059 Any aAny;
2060 aAny <<= Title;
2061 ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_TITLE ), aAny, sal_True );
2064 ::rtl::OUString UnoDialogControl::getTitle() throw(RuntimeException)
2066 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2067 return ImplGetPropertyValue_UString( BASEPROPERTY_TITLE );
2070 sal_Int16 UnoDialogControl::execute() throw(RuntimeException)
2072 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2073 sal_Int16 nDone = -1;
2074 if ( getPeer().is() )
2076 Reference< XDialog > xDlg( getPeer(), UNO_QUERY );
2077 if( xDlg.is() )
2079 GetComponentInfos().bVisible = sal_True;
2080 nDone = xDlg->execute();
2081 GetComponentInfos().bVisible = sal_False;
2084 return nDone;
2087 void UnoDialogControl::endExecute() throw(RuntimeException)
2089 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2090 if ( getPeer().is() )
2092 Reference< XDialog > xDlg( getPeer(), UNO_QUERY );
2093 if( xDlg.is() )
2095 xDlg->endExecute();
2096 GetComponentInfos().bVisible = sal_False;
2101 void UnoDialogControl::addingControl( const Reference< XControl >& _rxControl )
2103 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2104 UnoControlContainer::addingControl( _rxControl );
2106 if ( _rxControl.is() )
2108 Reference< XMultiPropertySet > xProps( _rxControl->getModel(), UNO_QUERY );
2109 if ( xProps.is() )
2111 Sequence< ::rtl::OUString > aNames( 4 );
2112 ::rtl::OUString* pNames = aNames.getArray();
2113 *pNames++ = ::rtl::OUString::createFromAscii( "PositionX" );
2114 *pNames++ = ::rtl::OUString::createFromAscii( "PositionY" );
2115 *pNames++ = ::rtl::OUString::createFromAscii( "Width" );
2116 *pNames++ = ::rtl::OUString::createFromAscii( "Height" );
2118 xProps->addPropertiesChangeListener( aNames, this );
2123 void UnoDialogControl::removingControl( const Reference< XControl >& _rxControl )
2125 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2126 UnoControlContainer::removingControl( _rxControl );
2128 if ( _rxControl.is() )
2130 Reference< XMultiPropertySet > xProps( _rxControl->getModel(), UNO_QUERY );
2131 if ( xProps.is() )
2132 xProps->removePropertiesChangeListener( this );
2137 void SAL_CALL UnoDialogControl::changesOccurred( const ChangesEvent& ) throw (RuntimeException)
2139 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2140 // a tab controller model may have changed
2142 // #109067# in design mode don't notify the tab controller
2143 // about tab index changes
2144 if ( mxTabController.is() && !mbDesignMode )
2145 mxTabController->activateTabOrder();
2148 // XModifyListener
2149 void SAL_CALL UnoDialogControl::modified(
2150 const lang::EventObject& /*rEvent*/ )
2151 throw (RuntimeException)
2153 ImplUpdateResourceResolver();
2156 // ----------------------------------------------------
2157 // Helper Method to convert relative url to physical location
2158 // ----------------------------------------------------
2160 ::rtl::OUString getPhysicalLocation( const ::com::sun::star::uno::Any& rbase, const ::com::sun::star::uno::Any& rUrl )
2164 ::rtl::OUString ret;
2166 ::rtl::OUString baseLocation;
2167 ::rtl::OUString url;
2169 rbase >>= baseLocation;
2170 rUrl >>= url;
2172 if ( url.getLength() > 0 )
2174 // Don't adjust GraphicObject url(s)
2175 if ( url.compareToAscii( UNO_NAME_GRAPHOBJ_URLPREFIX, RTL_CONSTASCII_LENGTH( UNO_NAME_GRAPHOBJ_URLPREFIX ) ) != 0 )
2177 INetURLObject urlObj(baseLocation);
2178 urlObj.removeSegment();
2179 baseLocation = urlObj.GetMainURL( INetURLObject::NO_DECODE );
2180 ::osl::FileBase::getAbsoluteFileURL( baseLocation, url, ret );
2182 else
2183 ret = url;
2187 return ret;