merge the formfield patch from ooo-build
[ooovba.git] / toolkit / source / controls / dialogcontrol.cxx
blob4d7a1b8b64a3e715ff5a62f5289a3eb8fc9506d3
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"
69 #include "grid/gridcontrol.hxx"
71 #include <map>
72 #include <algorithm>
73 #include <functional>
74 #include "tools/urlobj.hxx"
75 #include "osl/file.hxx"
77 using namespace ::com::sun::star;
78 using namespace ::com::sun::star::uno;
79 using namespace ::com::sun::star::awt;
80 using namespace ::com::sun::star::lang;
81 using namespace ::com::sun::star::container;
82 using namespace ::com::sun::star::beans;
83 using namespace ::com::sun::star::util;
84 using namespace ::com::sun::star::script;
85 using namespace toolkit;
87 #define PROPERTY_RESOURCERESOLVER ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ))
88 #define PROPERTY_DIALOGSOURCEURL ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogSourceURL" ))
89 #define PROPERTY_IMAGEURL ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ImageURL" ))
90 #define PROPERTY_GRAPHIC ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Graphic" ))
92 //HELPER
93 ::rtl::OUString getPhysicalLocation( const ::com::sun::star::uno::Any& rbase, const ::com::sun::star::uno::Any& rUrl );
95 uno::Reference< graphic::XGraphic > getGraphicFromURL_nothrow( uno::Reference< graphic::XGraphicObject >& rxGrfObj, const ::rtl::OUString& _rURL );
97 struct LanguageDependentProp
99 const char* pPropName;
100 sal_Int32 nPropNameLength;
103 // ----------------------------------------------------------------------------
104 namespace
106 static const Sequence< ::rtl::OUString >& lcl_getLanguageDependentProperties()
108 static Sequence< ::rtl::OUString > s_aLanguageDependentProperties;
109 if ( s_aLanguageDependentProperties.getLength() == 0 )
111 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
112 if ( s_aLanguageDependentProperties.getLength() == 0 )
114 s_aLanguageDependentProperties.realloc( 2 );
115 s_aLanguageDependentProperties[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HelpText" ) );
116 s_aLanguageDependentProperties[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
117 // note: properties must be sorted
120 return s_aLanguageDependentProperties;
123 static uno::Reference< graphic::XGraphic > lcl_getGraphicFromURL_nothrow( const ::rtl::OUString& _rURL )
125 uno::Reference< graphic::XGraphic > xGraphic;
126 if ( !_rURL.getLength() )
127 return xGraphic;
131 ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
132 uno::Reference< graphic::XGraphicProvider > xProvider;
133 if ( aContext.createComponent( "com.sun.star.graphic.GraphicProvider", xProvider ) )
135 uno::Sequence< beans::PropertyValue > aMediaProperties(1);
136 aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
137 aMediaProperties[0].Value <<= _rURL;
138 xGraphic = xProvider->queryGraphic( aMediaProperties );
141 catch( const Exception& )
143 DBG_UNHANDLED_EXCEPTION();
146 return xGraphic;
149 static ::rtl::OUString lcl_GetStringProperty( const ::rtl::OUString& sProperty, const Reference< XPropertySet >& xSet )
151 ::rtl::OUString sValue;
152 Reference< XPropertySetInfo > xPSI;
153 if (xSet.is() && (xPSI = xSet->getPropertySetInfo()).is() &&
154 xPSI->hasPropertyByName( sProperty ) )
156 xSet->getPropertyValue( sProperty ) >>= sValue;
158 return sValue;
163 // ----------------------------------------------------------------------------
164 // functor for disposing a control model
165 struct DisposeControlModel : public ::std::unary_function< Reference< XControlModel >, void >
167 void operator()( Reference< XControlModel >& _rxModel )
171 ::comphelper::disposeComponent( _rxModel );
173 catch( const Exception& )
175 DBG_ERROR( "DisposeControlModel::(): caught an exception while disposing a component!" );
180 // ----------------------------------------------------------------------------
181 // functor for searching control model by name
182 struct FindControlModel : public ::std::unary_function< UnoControlDialogModel::UnoControlModelHolder, bool >
184 private:
185 const ::rtl::OUString& m_rName;
187 public:
188 FindControlModel( const ::rtl::OUString& _rName ) : m_rName( _rName ) { }
190 bool operator()( const UnoControlDialogModel::UnoControlModelHolder& _rCompare )
192 return ( _rCompare.second == m_rName ) ? true : false;
196 // ----------------------------------------------------------------------------
197 // functor for cloning a control model, and insertion into a target list
198 struct CloneControlModel : public ::std::unary_function< UnoControlDialogModel::UnoControlModelHolder, void >
200 private:
201 UnoControlDialogModel::UnoControlModelHolderList& m_rTargetList;
203 public:
204 CloneControlModel( UnoControlDialogModel::UnoControlModelHolderList& _rTargetList )
205 :m_rTargetList( _rTargetList )
209 void operator()( const UnoControlDialogModel::UnoControlModelHolder& _rSource )
211 // clone the source object
212 Reference< XCloneable > xCloneSource( _rSource.first, UNO_QUERY );
213 Reference< XControlModel > xClone( xCloneSource->createClone(), UNO_QUERY );
214 // add to target list
215 m_rTargetList.push_back( UnoControlDialogModel::UnoControlModelHolder( xClone, _rSource.second ) );
219 // ----------------------------------------------------------------------------
220 // functor for comparing a XControlModel with a given reference
221 struct CompareControlModel : public ::std::unary_function< UnoControlDialogModel::UnoControlModelHolder, bool >
223 private:
224 Reference< XControlModel > m_xReference;
225 public:
226 CompareControlModel( const Reference< XControlModel >& _rxReference ) : m_xReference( _rxReference ) { }
228 bool operator()( const UnoControlDialogModel::UnoControlModelHolder& _rCompare )
230 return ( _rCompare.first.get() == m_xReference.get() ) ? true : false;
234 // ----------------------------------------------------------------------------
235 static void lcl_throwIllegalArgumentException( )
236 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
237 throw IllegalArgumentException();
240 // ----------------------------------------------------------------------------
241 static void lcl_throwNoSuchElementException( )
242 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
243 throw NoSuchElementException();
246 // ----------------------------------------------------------------------------
247 static void lcl_throwElementExistException( )
248 { // throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
249 throw ElementExistException();
252 // ----------------------------------------------------------------------------
253 static const ::rtl::OUString& getTabIndexPropertyName( )
255 static const ::rtl::OUString s_sTabIndexProperty( RTL_CONSTASCII_USTRINGPARAM( "TabIndex" ) );
256 return s_sTabIndexProperty;
259 // ----------------------------------------------------------------------------
260 static const ::rtl::OUString& getStepPropertyName( )
262 static const ::rtl::OUString s_sStepProperty( RTL_CONSTASCII_USTRINGPARAM( "Step" ) );
263 return s_sStepProperty;
266 // ----------------------------------------------------
267 // class UnoControlDialogModel
268 // ----------------------------------------------------
269 UnoControlDialogModel::UnoControlDialogModel()
270 :maContainerListeners( *this )
271 ,maChangeListeners ( GetMutex() )
272 ,mbGroupsUpToDate( sal_False ), mbAdjustingGraphic( false )
274 ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR );
275 // ImplRegisterProperty( BASEPROPERTY_BORDER );
276 ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL );
277 ImplRegisterProperty( BASEPROPERTY_ENABLED );
278 ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR );
279 // ImplRegisterProperty( BASEPROPERTY_PRINTABLE );
280 ImplRegisterProperty( BASEPROPERTY_HELPTEXT );
281 ImplRegisterProperty( BASEPROPERTY_HELPURL );
282 ImplRegisterProperty( BASEPROPERTY_TITLE );
283 ImplRegisterProperty( BASEPROPERTY_SIZEABLE );
284 ImplRegisterProperty( BASEPROPERTY_DESKTOP_AS_PARENT );
285 ImplRegisterProperty( BASEPROPERTY_DECORATION );
286 ImplRegisterProperty( BASEPROPERTY_DIALOGSOURCEURL );
287 ImplRegisterProperty( BASEPROPERTY_GRAPHIC );
288 ImplRegisterProperty( BASEPROPERTY_IMAGEURL );
290 Any aBool;
291 aBool <<= (sal_Bool) sal_True;
292 ImplRegisterProperty( BASEPROPERTY_MOVEABLE, aBool );
293 ImplRegisterProperty( BASEPROPERTY_CLOSEABLE, aBool );
294 aBool <<= (sal_Bool) sal_False;
295 ImplRegisterProperty( BASEPROPERTY_VBAFORM, aBool );
298 UnoControlDialogModel::UnoControlDialogModel( const UnoControlDialogModel& rModel )
299 : UnoControlDialogModel_IBase( rModel )
300 , UnoControlDialogModel_Base( rModel )
301 , maContainerListeners( *this )
302 , maChangeListeners ( GetMutex() )
303 , mbGroupsUpToDate( sal_False ), mbAdjustingGraphic( false )
307 UnoControlDialogModel::~UnoControlDialogModel()
309 maModels.clear();
310 mbGroupsUpToDate = sal_False;
313 Any UnoControlDialogModel::queryAggregation( const Type & rType ) throw(RuntimeException)
315 Any aRet( UnoControlDialogModel_IBase::queryInterface( rType ) );
316 return (aRet.hasValue() ? aRet : UnoControlDialogModel_Base::queryAggregation( rType ));
319 // XTypeProvider
320 IMPL_IMPLEMENTATION_ID( UnoControlDialogModel )
321 Sequence< Type > UnoControlDialogModel::getTypes() throw(RuntimeException)
323 return ::comphelper::concatSequences(
324 UnoControlDialogModel_IBase::getTypes(),
325 UnoControlDialogModel_Base::getTypes()
329 ::rtl::OUString UnoControlDialogModel::getServiceName( ) throw(RuntimeException)
331 return ::rtl::OUString::createFromAscii( szServiceName_UnoControlDialogModel );
334 void SAL_CALL UnoControlDialogModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) throw (::com::sun::star::uno::Exception)
336 UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue );
339 switch ( nHandle )
341 case BASEPROPERTY_IMAGEURL:
342 if ( !mbAdjustingGraphic && ImplHasProperty( BASEPROPERTY_GRAPHIC ) )
344 mbAdjustingGraphic = true;
345 ::rtl::OUString sImageURL;
346 OSL_VERIFY( rValue >>= sImageURL );
347 setPropertyValue( GetPropertyName( BASEPROPERTY_GRAPHIC ), uno::makeAny( getGraphicFromURL_nothrow( mxGrfObj, sImageURL ) ) );
348 mbAdjustingGraphic = false;
350 break;
352 case BASEPROPERTY_GRAPHIC:
353 if ( !mbAdjustingGraphic && ImplHasProperty( BASEPROPERTY_IMAGEURL ) )
355 mbAdjustingGraphic = true;
356 setPropertyValue( GetPropertyName( BASEPROPERTY_IMAGEURL ), uno::makeAny( ::rtl::OUString() ) );
357 mbAdjustingGraphic = false;
359 break;
362 catch( const ::com::sun::star::uno::Exception& )
364 OSL_ENSURE( sal_False, "UnoControlDialogModel::setFastPropertyValue_NoBroadcast: caught an exception while setting Graphic/ImageURL properties!" );
368 Any UnoControlDialogModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
370 Any aAny;
372 switch ( nPropId )
374 case BASEPROPERTY_DEFAULTCONTROL:
375 aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlDialog );
376 break;
377 default:
378 aAny = UnoControlModel::ImplGetDefaultValue( nPropId );
381 return aAny;
384 ::cppu::IPropertyArrayHelper& UnoControlDialogModel::getInfoHelper()
386 static UnoPropertyArrayHelper* pHelper = NULL;
387 if ( !pHelper )
389 Sequence<sal_Int32> aIDs = ImplGetPropertyIds();
390 pHelper = new UnoPropertyArrayHelper( aIDs );
392 return *pHelper;
395 void SAL_CALL UnoControlDialogModel::dispose( ) throw(RuntimeException)
397 // ====================================================================
398 // tell our listeners
400 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
402 EventObject aDisposeEvent;
403 aDisposeEvent.Source = static_cast< XAggregation* >( static_cast< ::cppu::OWeakAggObject* >( this ) );
405 maContainerListeners.disposeAndClear( aDisposeEvent );
406 maChangeListeners.disposeAndClear( aDisposeEvent );
409 // ====================================================================
410 // call the base class
411 UnoControlModel::dispose();
413 // ====================================================================
414 // dispose our child models
415 // for this, collect the models (we collect them from maModels, and this is modified when disposing children)
416 ::std::vector< Reference< XControlModel > > aChildModels( maModels.size() );
418 ::std::transform(
419 maModels.begin(), maModels.end(), // source range
420 aChildModels.begin(), // target location
421 ::std::select1st< UnoControlModelHolder >( ) // operation to apply -> select the XControlModel part
424 // now dispose
425 ::std::for_each( aChildModels.begin(), aChildModels.end(), DisposeControlModel() );
426 aChildModels.clear();
428 mbGroupsUpToDate = sal_False;
431 // XMultiPropertySet
432 Reference< XPropertySetInfo > UnoControlDialogModel::getPropertySetInfo( ) throw(RuntimeException)
434 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
435 return xInfo;
438 UnoControlModel* UnoControlDialogModel::Clone() const
440 // clone the container itself
441 UnoControlDialogModel* pClone = new UnoControlDialogModel( *this );
443 // clone all children
444 ::std::for_each(
445 maModels.begin(), maModels.end(),
446 CloneControlModel( pClone->maModels )
449 return pClone;
452 UnoControlDialogModel::UnoControlModelHolderList::iterator UnoControlDialogModel::ImplFindElement( const ::rtl::OUString& rName )
454 return ::std::find_if( maModels.begin(), maModels.end(), FindControlModel( rName ) );
457 // ::XMultiServiceFactory
458 Reference< XInterface > UnoControlDialogModel::createInstance( const ::rtl::OUString& aServiceSpecifier ) throw(Exception, RuntimeException)
460 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
462 OGeometryControlModel_Base* pNewModel = NULL;
464 if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlEditModel ) == 0 )
465 pNewModel = new OGeometryControlModel< UnoControlEditModel >;
466 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFormattedFieldModel ) == 0 )
467 pNewModel = new OGeometryControlModel< UnoControlFormattedFieldModel >;
468 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFileControlModel ) == 0 )
469 pNewModel = new OGeometryControlModel< UnoControlFileControlModel >;
470 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlButtonModel ) == 0 )
471 pNewModel = new OGeometryControlModel< UnoControlButtonModel >;
472 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlImageControlModel ) == 0 )
473 pNewModel = new OGeometryControlModel< UnoControlImageControlModel >;
474 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRadioButtonModel ) == 0 )
475 pNewModel = new OGeometryControlModel< UnoControlRadioButtonModel >;
476 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCheckBoxModel ) == 0 )
477 pNewModel = new OGeometryControlModel< UnoControlCheckBoxModel >;
478 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedHyperlinkModel ) == 0 )
479 pNewModel = new OGeometryControlModel< UnoControlFixedHyperlinkModel >;
480 else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedTextModel ) == 0 )
481 pNewModel = new OGeometryControlModel< UnoControlFixedTextModel >;
482 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlGroupBoxModel ) == 0 )
483 pNewModel = new OGeometryControlModel< UnoControlGroupBoxModel >;
484 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlListBoxModel ) == 0 )
485 pNewModel = new OGeometryControlModel< UnoControlListBoxModel >;
486 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlComboBoxModel ) == 0 )
487 pNewModel = new OGeometryControlModel< UnoControlComboBoxModel >;
488 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlDateFieldModel ) == 0 )
489 pNewModel = new OGeometryControlModel< UnoControlDateFieldModel >;
490 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlTimeFieldModel ) == 0 )
491 pNewModel = new OGeometryControlModel< UnoControlTimeFieldModel >;
492 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlNumericFieldModel ) == 0 )
493 pNewModel = new OGeometryControlModel< UnoControlNumericFieldModel >;
494 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCurrencyFieldModel ) == 0 )
495 pNewModel = new OGeometryControlModel< UnoControlCurrencyFieldModel >;
496 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlPatternFieldModel ) == 0 )
497 pNewModel = new OGeometryControlModel< UnoControlPatternFieldModel >;
498 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlProgressBarModel ) == 0 )
499 pNewModel = new OGeometryControlModel< UnoControlProgressBarModel >;
500 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlScrollBarModel ) == 0 )
501 pNewModel = new OGeometryControlModel< UnoControlScrollBarModel >;
502 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFixedLineModel ) == 0 )
503 pNewModel = new OGeometryControlModel< UnoControlFixedLineModel >;
504 else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRoadmapModel ) == 0 )
505 pNewModel = new OGeometryControlModel< UnoControlRoadmapModel >;
506 else if ( aServiceSpecifier.compareToAscii( szServiceName_TreeControlModel ) == 0 )
507 pNewModel = new OGeometryControlModel< UnoTreeModel >;
508 else if ( aServiceSpecifier.compareToAscii( szServiceName_GridControlModel ) == 0 )
509 pNewModel = new OGeometryControlModel< UnoGridModel >;
511 if ( !pNewModel )
513 Reference< XMultiServiceFactory > xORB( ::comphelper::getProcessServiceFactory() );
514 if ( xORB.is() )
516 Reference< XInterface > xObject = xORB->createInstance( aServiceSpecifier );
517 Reference< XServiceInfo > xSI( xObject, UNO_QUERY );
518 Reference< XCloneable > xCloneAccess( xSI, UNO_QUERY );
519 Reference< XAggregation > xAgg( xCloneAccess, UNO_QUERY );
520 if ( xAgg.is() )
522 if ( xSI->supportsService( ::rtl::OUString::createFromAscii( "com.sun.star.awt.UnoControlModel" ) ) )
524 // release 3 of the 4 references we have to the object
525 xAgg.clear();
526 xSI.clear();
527 xObject.clear();
529 pNewModel = new OCommonGeometryControlModel( xCloneAccess, aServiceSpecifier );
535 Reference< XInterface > xNewModel = (::cppu::OWeakObject*)pNewModel;
536 return xNewModel;
539 Reference< XInterface > UnoControlDialogModel::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& /* Arguments */ ) throw(Exception, RuntimeException)
541 return createInstance( ServiceSpecifier );
544 Sequence< ::rtl::OUString > UnoControlDialogModel::getAvailableServiceNames() throw(RuntimeException)
546 static Sequence< ::rtl::OUString >* pNamesSeq = NULL;
547 if ( !pNamesSeq )
549 pNamesSeq = new Sequence< ::rtl::OUString >( 21 );
550 ::rtl::OUString* pNames = pNamesSeq->getArray();
551 pNames[0] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlEditModel );
552 pNames[1] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFormattedFieldModel );
553 pNames[2] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFileControlModel );
554 pNames[3] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlButtonModel );
555 pNames[4] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlImageControlModel );
556 pNames[5] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRadioButtonModel );
557 pNames[6] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlCheckBoxModel );
558 pNames[7] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFixedTextModel );
559 pNames[8] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlGroupBoxModel );
560 pNames[9] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlListBoxModel );
561 pNames[10] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlComboBoxModel );
562 pNames[11] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlDateFieldModel );
563 pNames[12] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlTimeFieldModel );
564 pNames[13] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlNumericFieldModel );
565 pNames[14] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlCurrencyFieldModel );
566 pNames[15] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlPatternFieldModel );
567 pNames[16] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlProgressBarModel );
568 pNames[17] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlScrollBarModel );
569 pNames[18] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFixedLineModel );
570 pNames[19] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRoadmapModel );
571 pNames[20] = ::rtl::OUString::createFromAscii( szServiceName_TreeControlModel );
572 pNames[20] = ::rtl::OUString::createFromAscii( szServiceName_GridControlModel );
575 return *pNamesSeq;
578 // XContainer
579 void UnoControlDialogModel::addContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException)
581 maContainerListeners.addInterface( l );
584 void UnoControlDialogModel::removeContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException)
586 maContainerListeners.removeInterface( l );
589 // XElementAcces
590 Type UnoControlDialogModel::getElementType() throw(RuntimeException)
592 Type aType = getCppuType( ( Reference< XControlModel>* ) NULL );
593 return aType;
596 sal_Bool UnoControlDialogModel::hasElements() throw(RuntimeException)
598 return !maModels.empty();
601 // XNameContainer, XNameReplace, XNameAccess
602 void UnoControlDialogModel::replaceByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
604 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
606 Reference< XControlModel > xNewModel;
607 aElement >>= xNewModel;
608 if ( !xNewModel.is() )
609 lcl_throwIllegalArgumentException();
611 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
612 if ( maModels.end() == aElementPos )
613 lcl_throwNoSuchElementException();
615 // stop listening at the old model
616 stopControlListening( aElementPos->first );
617 Reference< XControlModel > xReplaced( aElementPos->first );
618 // remember the new model, and start listening
619 aElementPos->first = xNewModel;
620 startControlListening( xNewModel );
622 ContainerEvent aEvent;
623 aEvent.Source = *this;
624 aEvent.Element = aElement;
625 aEvent.ReplacedElement <<= xReplaced;
626 aEvent.Accessor <<= aName;
628 // notify the container listener
629 maContainerListeners.elementReplaced( aEvent );
631 // our "tab controller model" has potentially changed -> notify this
632 implNotifyTabModelChange( aName );
635 Any UnoControlDialogModel::getByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
637 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
638 if ( maModels.end() == aElementPos )
639 lcl_throwNoSuchElementException();
641 return makeAny( aElementPos->first );
644 Sequence< ::rtl::OUString > UnoControlDialogModel::getElementNames() throw(RuntimeException)
646 Sequence< ::rtl::OUString > aNames( maModels.size() );
648 ::std::transform(
649 maModels.begin(), maModels.end(), // source range
650 aNames.getArray(), // target range
651 ::std::select2nd< UnoControlModelHolder >() // operator to apply: select the second element (the name)
654 return aNames;
657 sal_Bool UnoControlDialogModel::hasByName( const ::rtl::OUString& aName ) throw(RuntimeException)
659 return maModels.end() != ImplFindElement( aName );
662 void UnoControlDialogModel::insertByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
664 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
666 Reference< XControlModel > xM;
667 aElement >>= xM;
669 if ( xM.is() )
671 Reference< beans::XPropertySet > xProps( xM, UNO_QUERY );
672 if ( xProps.is() )
675 Reference< beans::XPropertySetInfo > xPropInfo = xProps.get()->getPropertySetInfo();
677 ::rtl::OUString sImageSourceProperty = GetPropertyName( BASEPROPERTY_IMAGEURL );
678 if ( xPropInfo.get()->hasPropertyByName( sImageSourceProperty ))
680 Any aUrl = xProps.get()->getPropertyValue( sImageSourceProperty );
682 ::rtl::OUString absoluteUrl =
683 getPhysicalLocation( getPropertyValue( GetPropertyName( BASEPROPERTY_DIALOGSOURCEURL ) ), aUrl );
685 aUrl <<= absoluteUrl;
687 xProps.get()->setPropertyValue( sImageSourceProperty , aUrl );
694 if ( !aName.getLength() || !xM.is() )
695 lcl_throwIllegalArgumentException();
697 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
698 if ( maModels.end() != aElementPos )
699 lcl_throwElementExistException();
701 maModels.push_back( UnoControlModelHolder( xM, aName ) );
702 mbGroupsUpToDate = sal_False;
703 startControlListening( xM );
705 ContainerEvent aEvent;
706 aEvent.Source = *this;
707 aEvent.Element <<= aElement;
708 aEvent.Accessor <<= aName;
709 maContainerListeners.elementInserted( aEvent );
711 // our "tab controller model" has potentially changed -> notify this
712 implNotifyTabModelChange( aName );
715 void UnoControlDialogModel::removeByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
717 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
719 UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
720 if ( maModels.end() == aElementPos )
721 lcl_throwNoSuchElementException();
723 ContainerEvent aEvent;
724 aEvent.Source = *this;
725 aEvent.Element <<= aElementPos->first;
726 aEvent.Accessor <<= aName;
727 maContainerListeners.elementRemoved( aEvent );
729 stopControlListening( aElementPos->first );
730 Reference< XPropertySet > xPS( aElementPos->first, UNO_QUERY );
731 maModels.erase( aElementPos );
732 mbGroupsUpToDate = sal_False;
734 if ( xPS.is() )
737 xPS->setPropertyValue( PROPERTY_RESOURCERESOLVER, makeAny( Reference< resource::XStringResourceResolver >() ) );
739 catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
741 // our "tab controller model" has potentially changed -> notify this
742 implNotifyTabModelChange( aName );
745 // ----------------------------------------------------------------------------
746 sal_Bool SAL_CALL UnoControlDialogModel::getGroupControl( ) throw (RuntimeException)
748 return sal_True;
751 // ----------------------------------------------------------------------------
752 void SAL_CALL UnoControlDialogModel::setGroupControl( sal_Bool ) throw (RuntimeException)
754 DBG_ERROR( "UnoControlDialogModel::setGroupControl: explicit grouping not supported" );
757 // ----------------------------------------------------------------------------
758 void SAL_CALL UnoControlDialogModel::setControlModels( const Sequence< Reference< XControlModel > >& _rControls ) throw (RuntimeException)
760 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
762 // set the tab indexes according to the order of models in the sequence
763 const Reference< XControlModel >* pControls = _rControls.getConstArray( );
764 const Reference< XControlModel >* pControlsEnd = _rControls.getConstArray( ) + _rControls.getLength();
766 sal_Int16 nTabIndex = 1;
768 for ( ; pControls != pControlsEnd; ++pControls )
770 // look up the control in our own structure. This is to prevent invalid arguments
771 UnoControlModelHolderList::const_iterator aPos =
772 ::std::find_if(
773 maModels.begin(), maModels.end(),
774 CompareControlModel( *pControls )
776 if ( maModels.end() != aPos )
778 // okay, this is an existent model
779 // now set the TabIndex property (if applicable)
780 Reference< XPropertySet > xProps( aPos->first, UNO_QUERY );
781 Reference< XPropertySetInfo > xPSI;
782 if ( xProps.is() )
783 xPSI = xProps->getPropertySetInfo();
784 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
785 xProps->setPropertyValue( getTabIndexPropertyName(), makeAny( nTabIndex++ ) );
787 mbGroupsUpToDate = sal_False;
792 typedef ::std::multimap< sal_Int32, Reference< XControlModel >, ::std::less< sal_Int32 > > MapIndexToModel;
794 // ----------------------------------------------------------------------------
795 Sequence< Reference< XControlModel > > SAL_CALL UnoControlDialogModel::getControlModels( ) throw (RuntimeException)
797 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
799 MapIndexToModel aSortedModels;
800 // will be the sorted container of all models which have a tab index property
801 ::std::vector< Reference< XControlModel > > aUnindexedModels;
802 // will be the container of all models which do not have a tab index property
804 UnoControlModelHolderList::const_iterator aLoop = maModels.begin();
805 for ( ; aLoop != maModels.end(); ++aLoop )
807 Reference< XControlModel > xModel( aLoop->first );
809 // see if the model has a TabIndex property
810 Reference< XPropertySet > xControlProps( xModel, UNO_QUERY );
811 Reference< XPropertySetInfo > xPSI;
812 if ( xControlProps.is() )
813 xPSI = xControlProps->getPropertySetInfo( );
814 DBG_ASSERT( xPSI.is(), "UnoControlDialogModel::getControlModels: invalid child model!" );
816 // has it?
817 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
818 { // yes
819 sal_Int32 nTabIndex = -1;
820 xControlProps->getPropertyValue( getTabIndexPropertyName() ) >>= nTabIndex;
822 aSortedModels.insert( MapIndexToModel::value_type( nTabIndex, xModel ) );
824 else if ( xModel.is() )
825 // no, it hasn't, but we have to include it, anyway
826 aUnindexedModels.push_back( xModel );
829 // okay, here we have a container of all our models, sorted by tab index,
830 // plus a container of "unindexed" models
831 // -> merge them
832 Sequence< Reference< XControlModel > > aReturn( aUnindexedModels.size() + aSortedModels.size() );
833 ::std::transform(
834 aSortedModels.begin(), aSortedModels.end(),
835 ::std::copy( aUnindexedModels.begin(), aUnindexedModels.end(), aReturn.getArray() ),
836 ::std::select2nd< MapIndexToModel::value_type >( )
839 return aReturn;
842 // ----------------------------------------------------------------------------
843 void SAL_CALL UnoControlDialogModel::setGroup( const Sequence< Reference< XControlModel > >&, const ::rtl::OUString& ) throw (RuntimeException)
845 // not supported. We have only implicit grouping:
846 // We only have a sequence of control models, and we _know_ (yes, that's a HACK relying on
847 // implementation details) that VCL does grouping according to the order of controls automatically
848 // At least VCL does this for all we're interested in: Radio buttons.
849 DBG_ERROR( "UnoControlDialogModel::setGroup: grouping not supported" );
852 // ----------------------------------------------------------------------------
853 namespace
855 enum GroupingMachineState
857 eLookingForGroup,
858 eExpandingGroup
861 // ........................................................................
862 static sal_Int32 lcl_getDialogStep( const Reference< XControlModel >& _rxModel )
864 sal_Int32 nStep = 0;
867 Reference< XPropertySet > xModelProps( _rxModel, UNO_QUERY );
868 xModelProps->getPropertyValue( getStepPropertyName() ) >>= nStep;
870 catch( const Exception& )
872 DBG_ERROR( "lcl_getDialogStep: caught an exception while determining the dialog page!" );
874 return nStep;
878 // ----------------------------------------------------------------------------
879 sal_Int32 SAL_CALL UnoControlDialogModel::getGroupCount( ) throw (RuntimeException)
881 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
883 implUpdateGroupStructure();
885 return maGroups.size();
888 // ----------------------------------------------------------------------------
889 void SAL_CALL UnoControlDialogModel::getGroup( sal_Int32 _nGroup, Sequence< Reference< XControlModel > >& _rGroup, ::rtl::OUString& _rName ) throw (RuntimeException)
891 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
893 implUpdateGroupStructure();
895 if ( ( _nGroup < 0 ) || ( _nGroup >= (sal_Int32)maGroups.size() ) )
897 DBG_ERROR( "UnoControlDialogModel::getGroup: invalid argument and I am not allowed to throw an exception!" );
898 _rGroup.realloc( 0 );
899 _rName = ::rtl::OUString();
901 else
903 AllGroups::const_iterator aGroupPos = maGroups.begin() + _nGroup;
904 _rGroup.realloc( aGroupPos->size() );
905 // copy the models
906 ::std::copy( aGroupPos->begin(), aGroupPos->end(), _rGroup.getArray() );
907 // give the group a name
908 _rName = ::rtl::OUString::valueOf( _nGroup );
912 // ----------------------------------------------------------------------------
913 void SAL_CALL UnoControlDialogModel::getGroupByName( const ::rtl::OUString& _rName, Sequence< Reference< XControlModel > >& _rGroup ) throw (RuntimeException)
915 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
917 ::rtl::OUString sDummyName;
918 getGroup( _rName.toInt32( ), _rGroup, sDummyName );
921 // ----------------------------------------------------------------------------
922 void SAL_CALL UnoControlDialogModel::addChangesListener( const Reference< XChangesListener >& _rxListener ) throw (RuntimeException)
924 maChangeListeners.addInterface( _rxListener );
927 // ----------------------------------------------------------------------------
928 void SAL_CALL UnoControlDialogModel::removeChangesListener( const Reference< XChangesListener >& _rxListener ) throw (RuntimeException)
930 maChangeListeners.removeInterface( _rxListener );
933 // ----------------------------------------------------------------------------
934 void UnoControlDialogModel::implNotifyTabModelChange( const ::rtl::OUString& _rAccessor )
936 // multiplex to our change listeners:
937 // the changes event
938 ChangesEvent aEvent;
939 aEvent.Source = *this;
940 aEvent.Base <<= aEvent.Source; // the "base of the changes root" is also ourself
941 aEvent.Changes.realloc( 1 ); // exactly one change
942 aEvent.Changes[ 0 ].Accessor <<= _rAccessor;
945 Sequence< Reference< XInterface > > aChangeListeners( maChangeListeners.getElements() );
946 const Reference< XInterface >* pListener = aChangeListeners.getConstArray();
947 const Reference< XInterface >* pListenerEnd = aChangeListeners.getConstArray() + aChangeListeners.getLength();
948 for ( ; pListener != pListenerEnd; ++pListener )
950 if ( pListener->is() )
951 static_cast< XChangesListener* >( pListener->get() )->changesOccurred( aEvent );
955 // ----------------------------------------------------------------------------
956 void UnoControlDialogModel::AddRadioButtonGroup (
957 ::std::map< ::rtl::OUString, ModelGroup >& rNamedGroups )
959 if ( rNamedGroups.size() == 0 )
960 return;
962 size_t nGroups = maGroups.size();
963 maGroups.reserve( nGroups + rNamedGroups.size() );
964 ::std::map< ::rtl::OUString, ModelGroup >::const_iterator i = rNamedGroups.begin(), e = rNamedGroups.end();
965 for( ; i != e; ++i)
967 maGroups.push_back( i->second );
970 rNamedGroups.clear();
973 void UnoControlDialogModel::AddRadioButtonToGroup (
974 const Reference< XControlModel >& rControlModel,
975 const ::rtl::OUString& rPropertyName,
976 ::std::map< ::rtl::OUString, ModelGroup >& rNamedGroups,
977 ModelGroup*& rpCurrentGroup )
979 Reference< XPropertySet > xCurProps( rControlModel, UNO_QUERY );
980 ::rtl::OUString sGroup = lcl_GetStringProperty( rPropertyName, xCurProps );
981 const sal_Int32 nControlModelStep = lcl_getDialogStep( rControlModel );
983 if ( sGroup.getLength() == 0 )
985 // Create a new group if:
986 if ( maGroups.size() == 0 || // no groups
987 rpCurrentGroup == NULL || // previous group was closed
988 (nControlModelStep != 0 && // control step matches current group
989 maGroups.back().size() > 0 && // (group 0 == display everywhere)
990 nControlModelStep != lcl_getDialogStep( maGroups.back().back() ) ) )
992 size_t nGroups = maGroups.size();
993 maGroups.resize( nGroups + 1 );
995 rpCurrentGroup = &maGroups.back();
997 else
999 // Different steps get different sets of named groups
1000 if ( rNamedGroups.size() > 0 &&
1001 rNamedGroups.begin()->second.size() > 0 )
1003 const sal_Int32 nPrevStep = lcl_getDialogStep( rNamedGroups.begin()->second.front() );
1004 if ( nControlModelStep != nPrevStep )
1005 AddRadioButtonGroup( rNamedGroups );
1008 rpCurrentGroup = &rNamedGroups[ sGroup ];
1010 rpCurrentGroup->push_back( rControlModel );
1013 // ----------------------------------------------------------------------------
1014 void UnoControlDialogModel::implUpdateGroupStructure()
1016 if ( mbGroupsUpToDate )
1017 // nothing to do
1018 return;
1020 // conditions for a group:
1021 // * all elements of the group are radio buttons
1022 // * all elements of the group are on the same dialog page
1023 // * in the overall control order (determined by the tab index), all elements are subsequent
1025 maGroups.clear();
1027 Sequence< Reference< XControlModel > > aControlModels = getControlModels();
1028 const Reference< XControlModel >* pControlModels = aControlModels.getConstArray();
1029 const Reference< XControlModel >* pControlModelsEnd = pControlModels + aControlModels.getLength();
1031 // in extreme we have as much groups as controls
1032 maGroups.reserve( aControlModels.getLength() );
1034 GroupingMachineState eState = eLookingForGroup; // the current state of our machine
1035 Reference< XServiceInfo > xModelSI; // for checking for a radion button
1036 ModelGroup* aCurrentGroup = NULL; // the group which we're currently building
1037 sal_Bool bIsRadioButton; // is it a radio button?
1039 const ::rtl::OUString GROUP_NAME( RTL_CONSTASCII_USTRINGPARAM( "GroupName" ) );
1041 ::std::map< ::rtl::OUString, ModelGroup > aNamedGroups;
1043 #if OSL_DEBUG_LEVEL > 1
1044 ::std::vector< ::rtl::OUString > aCurrentGroupLabels;
1045 #endif
1047 for ( ; pControlModels != pControlModelsEnd; ++pControlModels )
1049 // we'll need this in every state
1050 xModelSI = xModelSI.query( *pControlModels );
1051 bIsRadioButton = xModelSI.is() && xModelSI->supportsService( ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRadioButtonModel ) );
1053 switch ( eState )
1055 case eLookingForGroup:
1057 if ( !bIsRadioButton )
1058 // this is no radio button -> still looking for the beginning of a group
1059 continue;
1060 // the current model is a radio button
1061 // -> we found the beginning of a new group
1062 // create the place for this group
1063 AddRadioButtonToGroup( *pControlModels, GROUP_NAME, aNamedGroups, aCurrentGroup );
1065 // new state: looking for further members
1066 eState = eExpandingGroup;
1068 #if OSL_DEBUG_LEVEL > 1
1069 Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY );
1070 ::rtl::OUString sLabel;
1071 if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) )
1072 xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel;
1073 aCurrentGroupLabels.push_back( sLabel );
1074 #endif
1076 break;
1078 case eExpandingGroup:
1080 if ( !bIsRadioButton )
1081 { // no radio button -> the group is done
1082 aCurrentGroup = NULL;
1083 eState = eLookingForGroup;
1084 #if OSL_DEBUG_LEVEL > 1
1085 aCurrentGroupLabels.clear();
1086 #endif
1087 continue;
1090 AddRadioButtonToGroup( *pControlModels, GROUP_NAME, aNamedGroups, aCurrentGroup );
1092 #if OSL_DEBUG_LEVEL > 1
1093 Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY );
1094 ::rtl::OUString sLabel;
1095 if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) )
1096 xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel;
1097 aCurrentGroupLabels.push_back( sLabel );
1098 #endif
1100 break;
1104 AddRadioButtonGroup( aNamedGroups );
1105 mbGroupsUpToDate = sal_True;
1108 // ----------------------------------------------------------------------------
1109 void SAL_CALL UnoControlDialogModel::propertyChange( const PropertyChangeEvent& _rEvent ) throw (RuntimeException)
1111 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1113 DBG_ASSERT( 0 == _rEvent.PropertyName.compareToAscii( "TabIndex" ),
1114 "UnoControlDialogModel::propertyChange: not listening for this property!" );
1116 // the accessor for the changed element
1117 ::rtl::OUString sAccessor;
1118 UnoControlModelHolderList::const_iterator aPos =
1119 ::std::find_if(
1120 maModels.begin(), maModels.end(),
1121 CompareControlModel( Reference< XControlModel >( _rEvent.Source, UNO_QUERY ) )
1123 OSL_ENSURE( maModels.end() != aPos, "UnoControlDialogModel::propertyChange: don't know this model!" );
1124 if ( maModels.end() != aPos )
1125 sAccessor = aPos->second;
1127 // our groups are not up-to-date
1128 mbGroupsUpToDate = sal_False;
1130 // notify
1131 implNotifyTabModelChange( sAccessor );
1134 // ----------------------------------------------------------------------------
1135 void SAL_CALL UnoControlDialogModel::disposing( const EventObject& /*rEvent*/ ) throw (RuntimeException)
1139 // ----------------------------------------------------------------------------
1140 void UnoControlDialogModel::startControlListening( const Reference< XControlModel >& _rxChildModel )
1142 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1144 Reference< XPropertySet > xModelProps( _rxChildModel, UNO_QUERY );
1145 Reference< XPropertySetInfo > xPSI;
1146 if ( xModelProps.is() )
1147 xPSI = xModelProps->getPropertySetInfo();
1149 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
1150 xModelProps->addPropertyChangeListener( getTabIndexPropertyName(), this );
1153 // ----------------------------------------------------------------------------
1154 void UnoControlDialogModel::stopControlListening( const Reference< XControlModel >& _rxChildModel )
1156 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1158 Reference< XPropertySet > xModelProps( _rxChildModel, UNO_QUERY );
1159 Reference< XPropertySetInfo > xPSI;
1160 if ( xModelProps.is() )
1161 xPSI = xModelProps->getPropertySetInfo();
1163 if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
1164 xModelProps->removePropertyChangeListener( getTabIndexPropertyName(), this );
1167 // ============================================================================
1168 // = class ResourceListener
1169 // ============================================================================
1171 ResourceListener::ResourceListener(
1172 const Reference< util::XModifyListener >& rListener ) :
1173 OWeakObject(),
1174 m_xListener( rListener ),
1175 m_bListening( false )
1179 ResourceListener::~ResourceListener()
1183 // XInterface
1184 Any SAL_CALL ResourceListener::queryInterface( const Type& rType )
1185 throw ( RuntimeException )
1187 Any a = ::cppu::queryInterface(
1188 rType ,
1189 static_cast< XModifyListener* >( this ),
1190 static_cast< XEventListener* >( this ));
1192 if ( a.hasValue() )
1193 return a;
1195 return OWeakObject::queryInterface( rType );
1198 void SAL_CALL ResourceListener::acquire() throw ()
1200 OWeakObject::acquire();
1203 void SAL_CALL ResourceListener::release() throw ()
1205 OWeakObject::release();
1208 void ResourceListener::startListening(
1209 const Reference< resource::XStringResourceResolver >& rResource )
1211 Reference< util::XModifyBroadcaster > xModifyBroadcaster( rResource, UNO_QUERY );
1214 // --- SAFE ---
1215 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1216 bool bListening( m_bListening );
1217 bool bResourceSet( m_xResource.is() );
1218 aGuard.clear();
1219 // --- SAFE ---
1221 if ( bListening && bResourceSet )
1222 stopListening();
1224 // --- SAFE ---
1225 aGuard.reset();
1226 m_xResource = rResource;
1227 aGuard.clear();
1228 // --- SAFE ---
1231 Reference< util::XModifyListener > xThis( static_cast<OWeakObject*>( this ), UNO_QUERY );
1232 if ( xModifyBroadcaster.is() )
1236 xModifyBroadcaster->addModifyListener( xThis );
1238 // --- SAFE ---
1239 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1240 m_bListening = true;
1241 // --- SAFE ---
1243 catch ( RuntimeException& )
1245 throw;
1247 catch ( Exception& )
1253 void ResourceListener::stopListening()
1255 Reference< util::XModifyBroadcaster > xModifyBroadcaster;
1257 // --- SAFE ---
1258 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1259 if ( m_bListening && m_xResource.is() )
1260 xModifyBroadcaster = Reference< util::XModifyBroadcaster >( m_xResource, UNO_QUERY );
1261 aGuard.clear();
1262 // --- SAFE ---
1264 Reference< util::XModifyListener > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
1265 if ( xModifyBroadcaster.is() )
1269 // --- SAFE ---
1270 aGuard.reset();
1271 m_bListening = false;
1272 m_xResource.clear();
1273 aGuard.clear();
1274 // --- SAFE ---
1276 xModifyBroadcaster->removeModifyListener( xThis );
1278 catch ( RuntimeException& )
1280 throw;
1282 catch ( Exception& )
1288 // XModifyListener
1289 void SAL_CALL ResourceListener::modified(
1290 const lang::EventObject& aEvent )
1291 throw ( RuntimeException )
1293 Reference< util::XModifyListener > xListener;
1295 // --- SAFE ---
1296 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1297 xListener = m_xListener;
1298 aGuard.clear();
1299 // --- SAFE ---
1301 if ( xListener.is() )
1305 xListener->modified( aEvent );
1307 catch ( RuntimeException& )
1309 throw;
1311 catch ( Exception& )
1317 // XEventListener
1318 void SAL_CALL ResourceListener::disposing(
1319 const EventObject& Source )
1320 throw ( RuntimeException )
1322 Reference< lang::XEventListener > xListener;
1323 Reference< resource::XStringResourceResolver > xResource;
1325 // --- SAFE ---
1326 ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
1327 Reference< XInterface > xIfacRes( m_xResource, UNO_QUERY );
1328 Reference< XInterface > xIfacList( m_xListener, UNO_QUERY );
1329 aGuard.clear();
1330 // --- SAFE ---
1332 if ( Source.Source == xIfacRes )
1334 // --- SAFE ---
1335 aGuard.reset();
1336 m_bListening = false;
1337 xResource = m_xResource;
1338 xListener = Reference< lang::XEventListener >( m_xListener, UNO_QUERY );
1339 m_xResource.clear();
1340 aGuard.clear();
1341 // --- SAFE ---
1343 if ( xListener.is() )
1347 xListener->disposing( Source );
1349 catch ( RuntimeException& )
1351 throw;
1353 catch ( Exception& )
1358 else if ( Source.Source == xIfacList )
1360 // --- SAFE ---
1361 aGuard.reset();
1362 m_bListening = false;
1363 xListener = Reference< lang::XEventListener >( m_xListener, UNO_QUERY );
1364 xResource = m_xResource;
1365 m_xResource.clear();
1366 m_xListener.clear();
1367 aGuard.clear();
1368 // --- SAFE ---
1370 // Remove ourself as listener from resource resolver
1371 Reference< util::XModifyBroadcaster > xModifyBroadcaster( xResource, UNO_QUERY );
1372 Reference< util::XModifyListener > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
1373 if ( xModifyBroadcaster.is() )
1377 xModifyBroadcaster->removeModifyListener( xThis );
1379 catch ( RuntimeException& )
1381 throw;
1383 catch ( Exception& )
1390 // ============================================================================
1391 // = class UnoDialogControl
1392 // ============================================================================
1394 UnoDialogControl::UnoDialogControl() :
1395 maTopWindowListeners( *this ),
1396 mbWindowListener(false),
1397 mbSizeModified(false),
1398 mbPosModified(false)
1400 maComponentInfos.nWidth = 300;
1401 maComponentInfos.nHeight = 450;
1402 mxListener = new ResourceListener( Reference< util::XModifyListener >(
1403 static_cast< OWeakObject* >( this ), UNO_QUERY ));
1406 ::rtl::OUString UnoDialogControl::GetComponentServiceName()
1409 sal_Bool bDecoration( sal_True );
1410 ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_DECORATION )) >>= bDecoration;
1411 if ( bDecoration )
1412 return ::rtl::OUString::createFromAscii( "Dialog" );
1413 else
1414 return ::rtl::OUString::createFromAscii( "TabPage" );
1417 // XInterface
1418 Any UnoDialogControl::queryAggregation( const Type & rType ) throw(RuntimeException)
1420 Any aRet( UnoDialogControl_IBase::queryInterface( rType ) );
1421 return (aRet.hasValue() ? aRet : UnoControlContainer::queryAggregation( rType ));
1424 // XTypeProvider
1425 IMPL_IMPLEMENTATION_ID( UnoDialogControl )
1426 Sequence< Type > UnoDialogControl::getTypes() throw(RuntimeException)
1428 return ::comphelper::concatSequences(
1429 UnoDialogControl_IBase::getTypes(),
1430 UnoControlContainer::getTypes()
1434 void UnoDialogControl::ImplInsertControl( Reference< XControlModel >& rxModel, const ::rtl::OUString& rName )
1436 Reference< XPropertySet > xP( rxModel, UNO_QUERY );
1438 ::rtl::OUString aDefCtrl;
1439 xP->getPropertyValue( GetPropertyName( BASEPROPERTY_DEFAULTCONTROL ) ) >>= aDefCtrl;
1441 // Add our own resource resolver to a newly created control
1442 Reference< resource::XStringResourceResolver > xStringResourceResolver;
1443 rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER );
1445 Any aAny;
1446 ImplGetPropertyValue( aPropName ) >>= xStringResourceResolver;
1448 aAny <<= xStringResourceResolver;
1449 xP->setPropertyValue( aPropName, aAny );
1451 Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
1452 Reference < XControl > xCtrl( xMSF->createInstance( aDefCtrl ), UNO_QUERY );
1454 DBG_ASSERT( xCtrl.is(), "UnoDialogControl::ImplInsertControl: could not create the control!" );
1455 if ( xCtrl.is() )
1457 xCtrl->setModel( rxModel );
1458 addControl( rName, xCtrl );
1459 // will implicitly call addingControl, where we can add the PropertiesChangeListener to the model
1460 // (which we formerly did herein)
1461 // 08.01.2001 - 96008 - fs@openoffice.org
1463 ImplSetPosSize( xCtrl );
1467 void UnoDialogControl::ImplRemoveControl( Reference< XControlModel >& rxModel )
1469 Sequence< Reference< XControl > > aControls = getControls();
1470 Reference< XControl > xCtrl = StdTabController::FindControl( aControls, rxModel );
1471 if ( xCtrl.is() )
1472 removeControl( xCtrl );
1475 void UnoDialogControl::ImplSetPosSize( Reference< XControl >& rxCtrl )
1477 Reference< XPropertySet > xP( rxCtrl->getModel(), UNO_QUERY );
1479 sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
1480 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) ) ) >>= nX;
1481 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) ) ) >>= nY;
1482 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ) ) >>= nWidth;
1483 xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ) ) >>= nHeight;
1485 // Currentley we are simply using MAP_APPFONT ( for normal Dialogs )
1486 // and MAP_100TH_MM for imported Userforms
1487 MapMode aMode( MAP_APPFONT );
1488 sal_Bool bVBAForm = sal_False;
1489 Reference< XPropertySet > xDlgModelProps( getModel(), UNO_QUERY );
1490 if ( xDlgModelProps.is() )
1494 xDlgModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAForm" ) ) ) >>= bVBAForm;
1496 catch( Exception& )
1500 if ( bVBAForm )
1501 aMode = MapMode( MAP_100TH_MM );
1502 OutputDevice*pOutDev = Application::GetDefaultDevice();
1503 if ( pOutDev )
1505 ::Size aTmp( nX, nY );
1506 aTmp = pOutDev->LogicToPixel( aTmp, aMode );
1507 nX = aTmp.Width();
1508 nY = aTmp.Height();
1509 aTmp = ::Size( nWidth, nHeight );
1510 aTmp = pOutDev->LogicToPixel( aTmp, aMode );
1511 nWidth = aTmp.Width();
1512 nHeight = aTmp.Height();
1514 else
1516 Reference< XWindowPeer > xPeer = ImplGetCompatiblePeer( sal_True );
1517 Reference< XDevice > xD( xPeer, UNO_QUERY );
1519 SimpleFontMetric aFM;
1520 FontDescriptor aFD;
1521 Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_FONTDESCRIPTOR ) );
1522 aVal >>= aFD;
1523 if ( aFD.StyleName.getLength() )
1525 Reference< XFont > xFont = xD->getFont( aFD );
1526 aFM = xFont->getFontMetric();
1528 else
1530 Reference< XGraphics > xG = xD->createGraphics();
1531 aFM = xG->getFontMetric();
1534 sal_Int16 nH = aFM.Ascent + aFM.Descent;
1535 sal_Int16 nW = nH/2; // calculate avarage width?!
1537 nX *= nW;
1538 nX /= 4;
1539 nWidth *= nW;
1540 nWidth /= 4;
1541 nY *= nH;
1542 nY /= 8;
1543 nHeight *= nH;
1544 nHeight /= 8;
1546 Reference < XWindow > xW( rxCtrl, UNO_QUERY );
1547 xW->setPosSize( nX, nY, nWidth, nHeight, PosSize::POSSIZE );
1550 void UnoDialogControl::dispose() throw(RuntimeException)
1552 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1554 EventObject aEvt;
1555 aEvt.Source = static_cast< ::cppu::OWeakObject* >( this );
1556 maTopWindowListeners.disposeAndClear( aEvt );
1558 // Notify our listener helper about dispose
1559 // --- SAFE ---
1560 ::osl::ResettableGuard< ::osl::Mutex > aGuard( GetMutex() );
1561 Reference< XEventListener > xListener( mxListener, UNO_QUERY );
1562 mxListener.clear();
1563 aGuard.clear();
1564 // --- SAFE ---
1566 if ( xListener.is() )
1567 xListener->disposing( aEvt );
1569 UnoControlContainer::dispose();
1572 void SAL_CALL UnoDialogControl::disposing(
1573 const EventObject& Source )
1574 throw(RuntimeException)
1576 rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER );
1577 Reference< resource::XStringResourceResolver > xStringResourceResolver;
1579 ImplGetPropertyValue( aPropName ) >>= xStringResourceResolver;
1580 Reference< XInterface > xIfac( xStringResourceResolver, UNO_QUERY );
1582 if ( Source.Source == xIfac )
1584 Any aAny;
1586 // Reset resource resolver reference
1587 ImplSetPropertyValue( aPropName, aAny, sal_True );
1588 ImplUpdateResourceResolver();
1590 else
1592 UnoControlContainer::disposing( Source );
1596 sal_Bool UnoDialogControl::setModel( const Reference< XControlModel >& rxModel ) throw(RuntimeException)
1598 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1600 // destroy the old tab controller, if existent
1601 if ( mxTabController.is() )
1603 mxTabController->setModel( NULL ); // just to be sure, should not be necessary
1604 removeTabController( mxTabController );
1605 ::comphelper::disposeComponent( mxTabController ); // just to be sure, should not be necessary
1606 mxTabController.clear();
1609 if ( getModel().is() )
1611 Sequence< Reference< XControl > > aControls = getControls();
1612 const Reference< XControl >* pCtrls = aControls.getConstArray();
1613 const Reference< XControl >* pCtrlsEnd = pCtrls + aControls.getLength();
1615 for ( ; pCtrls < pCtrlsEnd; ++pCtrls )
1616 removeControl( *pCtrls );
1617 // will implicitly call removingControl, which will remove the PropertyChangeListener
1618 // (which we formerly did herein)
1619 // 08.01.2001 - 96008 - fs@openoffice.org
1621 Reference< XContainer > xC( getModel(), UNO_QUERY );
1622 if ( xC.is() )
1623 xC->removeContainerListener( this );
1625 Reference< XChangesNotifier > xChangeNotifier( getModel(), UNO_QUERY );
1626 if ( xChangeNotifier.is() )
1627 xChangeNotifier->removeChangesListener( this );
1630 sal_Bool bRet = UnoControl::setModel( rxModel );
1632 if ( getModel().is() )
1634 Reference< XNameAccess > xNA( getModel(), UNO_QUERY );
1635 if ( xNA.is() )
1637 Sequence< ::rtl::OUString > aNames = xNA->getElementNames();
1638 const ::rtl::OUString* pNames = aNames.getConstArray();
1639 sal_uInt32 nCtrls = aNames.getLength();
1641 Reference< XControlModel > xCtrlModel;
1642 for( sal_uInt32 n = 0; n < nCtrls; ++n, ++pNames )
1644 xNA->getByName( *pNames ) >>= xCtrlModel;
1645 ImplInsertControl( xCtrlModel, *pNames );
1649 Reference< XContainer > xC( getModel(), UNO_QUERY );
1650 if ( xC.is() )
1651 xC->addContainerListener( this );
1653 Reference< XChangesNotifier > xChangeNotifier( getModel(), UNO_QUERY );
1654 if ( xChangeNotifier.is() )
1655 xChangeNotifier->addChangesListener( this );
1658 Reference< XTabControllerModel > xTabbing( getModel(), UNO_QUERY );
1659 if ( xTabbing.is() )
1661 mxTabController = new StdTabController;
1662 mxTabController->setModel( xTabbing );
1663 addTabController( mxTabController );
1665 ImplStartListingForResourceEvents();
1667 return bRet;
1670 void UnoDialogControl::setDesignMode( sal_Bool bOn ) throw(RuntimeException)
1672 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1673 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1675 UnoControl::setDesignMode( bOn );
1677 Sequence< Reference< XControl > > xCtrls = getControls();
1678 sal_Int32 nControls = xCtrls.getLength();
1679 Reference< XControl >* pControls = xCtrls.getArray();
1680 for ( sal_Int32 n = 0; n < nControls; n++ )
1681 pControls[n]->setDesignMode( bOn );
1683 // #109067# in design mode the tab controller is not notified about
1684 // tab index changes, therefore the tab order must be activated
1685 // when switching from design mode to live mode
1686 if ( mxTabController.is() && !bOn )
1687 mxTabController->activateTabOrder();
1690 void UnoDialogControl::createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer > & rParentPeer ) throw(RuntimeException)
1692 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1694 UnoControlContainer::createPeer( rxToolkit, rParentPeer );
1696 Reference < XTopWindow > xTW( getPeer(), UNO_QUERY );
1697 if ( xTW.is() )
1699 xTW->setMenuBar( mxMenuBar );
1701 if ( !mbWindowListener )
1703 Reference< XWindowListener > xWL( static_cast< cppu::OWeakObject*>( this ), UNO_QUERY );
1704 addWindowListener( xWL );
1705 mbWindowListener = true;
1708 if ( maTopWindowListeners.getLength() )
1709 xTW->addTopWindowListener( &maTopWindowListeners );
1713 void UnoDialogControl::PrepareWindowDescriptor( ::com::sun::star::awt::WindowDescriptor& rDesc )
1715 sal_Bool bDecoration( sal_True );
1716 ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_DECORATION )) >>= bDecoration;
1717 if ( !bDecoration )
1719 // Now we have to manipulate the WindowDescriptor
1720 rDesc.WindowAttributes = rDesc.WindowAttributes | ::com::sun::star::awt::WindowAttribute::NODECORATION;
1723 // We have to set the graphic property before the peer
1724 // will be created. Otherwise the properties will be copied
1725 // into the peer via propertiesChangeEvents. As the order of
1726 // can lead to overwrites we have to set the graphic property
1727 // before the propertiesChangeEvents are sent!
1728 ::rtl::OUString aImageURL;
1729 if (( ImplGetPropertyValue( PROPERTY_IMAGEURL ) >>= aImageURL ) &&
1730 ( aImageURL.getLength() > 0 ))
1732 aImageURL =
1733 getPhysicalLocation( ImplGetPropertyValue( PROPERTY_DIALOGSOURCEURL ),
1734 ImplGetPropertyValue( PROPERTY_IMAGEURL ));
1737 if ( aImageURL.compareToAscii( UNO_NAME_GRAPHOBJ_URLPREFIX, RTL_CONSTASCII_LENGTH( UNO_NAME_GRAPHOBJ_URLPREFIX ) ) != 0 )
1738 ImplSetPropertyValue( PROPERTY_IMAGEURL, uno::makeAny( aImageURL ), sal_True );
1741 void UnoDialogControl::elementInserted( const ContainerEvent& Event ) throw(RuntimeException)
1743 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1745 Reference< XControlModel > xModel;
1746 ::rtl::OUString aName;
1748 Event.Accessor >>= aName;
1749 Event.Element >>= xModel;
1750 ImplInsertControl( xModel, aName );
1753 void UnoDialogControl::elementRemoved( const ContainerEvent& Event ) throw(RuntimeException)
1755 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1757 Reference< XControlModel > xModel;
1758 Event.Element >>= xModel;
1759 if ( xModel.is() )
1760 ImplRemoveControl( xModel );
1763 void UnoDialogControl::elementReplaced( const ContainerEvent& Event ) throw(RuntimeException)
1765 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1767 Reference< XControlModel > xModel;
1768 Event.ReplacedElement >>= xModel;
1769 if ( xModel.is() )
1770 ImplRemoveControl( xModel );
1772 ::rtl::OUString aName;
1773 Event.Accessor >>= aName;
1774 Event.Element >>= xModel;
1775 ImplInsertControl( xModel, aName );
1778 void UnoDialogControl::addTopWindowListener( const Reference< XTopWindowListener >& rxListener ) throw (RuntimeException)
1780 maTopWindowListeners.addInterface( rxListener );
1781 if( getPeer().is() && maTopWindowListeners.getLength() == 1 )
1783 Reference < XTopWindow > xTW( getPeer(), UNO_QUERY );
1784 xTW->addTopWindowListener( &maTopWindowListeners );
1788 void UnoDialogControl::removeTopWindowListener( const Reference< XTopWindowListener >& rxListener ) throw (RuntimeException)
1790 if( getPeer().is() && maTopWindowListeners.getLength() == 1 )
1792 Reference < XTopWindow > xTW( getPeer(), UNO_QUERY );
1793 xTW->removeTopWindowListener( &maTopWindowListeners );
1795 maTopWindowListeners.removeInterface( rxListener );
1798 void UnoDialogControl::toFront( ) throw (RuntimeException)
1800 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1801 if ( getPeer().is() )
1803 Reference< XTopWindow > xTW( getPeer(), UNO_QUERY );
1804 if( xTW.is() )
1805 xTW->toFront();
1809 void UnoDialogControl::toBack( ) throw (RuntimeException)
1811 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1812 if ( getPeer().is() )
1814 Reference< XTopWindow > xTW( getPeer(), UNO_QUERY );
1815 if( xTW.is() )
1816 xTW->toBack();
1820 void UnoDialogControl::setMenuBar( const Reference< XMenuBar >& rxMenuBar ) throw (RuntimeException)
1822 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1823 mxMenuBar = rxMenuBar;
1824 if ( getPeer().is() )
1826 Reference< XTopWindow > xTW( getPeer(), UNO_QUERY );
1827 if( xTW.is() )
1828 xTW->setMenuBar( mxMenuBar );
1832 static ::Size ImplMapPixelToAppFont( OutputDevice* pOutDev, const ::Size& aSize )
1834 ::Size aTmp = pOutDev->PixelToLogic( aSize, MAP_APPFONT );
1835 return aTmp;
1838 // ::com::sun::star::awt::XWindowListener
1839 void SAL_CALL UnoDialogControl::windowResized( const ::com::sun::star::awt::WindowEvent& e )
1840 throw (::com::sun::star::uno::RuntimeException)
1842 OutputDevice*pOutDev = Application::GetDefaultDevice();
1843 DBG_ASSERT( pOutDev, "Missing Default Device!" );
1844 if ( pOutDev && !mbSizeModified )
1846 // Currentley we are simply using MAP_APPFONT
1847 ::Size aAppFontSize( e.Width, e.Height );
1849 Reference< XControl > xDialogControl( *this, UNO_QUERY_THROW );
1850 Reference< XDevice > xDialogDevice( xDialogControl->getPeer(), UNO_QUERY );
1851 OSL_ENSURE( xDialogDevice.is(), "UnoDialogControl::windowResized: no peer, but a windowResized event?" );
1852 if ( xDialogDevice.is() )
1854 DeviceInfo aDeviceInfo( xDialogDevice->getInfo() );
1855 aAppFontSize.Width() -= aDeviceInfo.LeftInset + aDeviceInfo.RightInset;
1856 aAppFontSize.Height() -= aDeviceInfo.TopInset + aDeviceInfo.BottomInset;
1859 aAppFontSize = ImplMapPixelToAppFont( pOutDev, aAppFontSize );
1861 // Remember that changes have been done by listener. No need to
1862 // update the position because of property change event.
1863 mbSizeModified = true;
1864 Sequence< rtl::OUString > aProps( 2 );
1865 Sequence< Any > aValues( 2 );
1866 // Properties in a sequence must be sorted!
1867 aProps[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Height" ));
1868 aProps[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" ));
1869 aValues[0] <<= aAppFontSize.Height();
1870 aValues[1] <<= aAppFontSize.Width();
1872 ImplSetPropertyValues( aProps, aValues, true );
1873 mbSizeModified = false;
1877 void SAL_CALL UnoDialogControl::windowMoved( const ::com::sun::star::awt::WindowEvent& e )
1878 throw (::com::sun::star::uno::RuntimeException)
1880 OutputDevice*pOutDev = Application::GetDefaultDevice();
1881 DBG_ASSERT( pOutDev, "Missing Default Device!" );
1882 if ( pOutDev && !mbPosModified )
1884 // Currentley we are simply using MAP_APPFONT
1885 Any aAny;
1886 ::Size aTmp( e.X, e.Y );
1887 aTmp = ImplMapPixelToAppFont( pOutDev, aTmp );
1889 // Remember that changes have been done by listener. No need to
1890 // update the position because of property change event.
1891 mbPosModified = true;
1892 Sequence< rtl::OUString > aProps( 2 );
1893 Sequence< Any > aValues( 2 );
1894 aProps[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ));
1895 aProps[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ));
1896 aValues[0] <<= aTmp.Width();
1897 aValues[1] <<= aTmp.Height();
1899 ImplSetPropertyValues( aProps, aValues, true );
1900 mbPosModified = false;
1904 void SAL_CALL UnoDialogControl::windowShown( const ::com::sun::star::lang::EventObject& e )
1905 throw (::com::sun::star::uno::RuntimeException)
1907 (void)e;
1910 void SAL_CALL UnoDialogControl::windowHidden( const ::com::sun::star::lang::EventObject& e )
1911 throw (::com::sun::star::uno::RuntimeException)
1913 (void)e;
1916 // XPropertiesChangeListener
1917 void UnoDialogControl::ImplModelPropertiesChanged( const Sequence< PropertyChangeEvent >& rEvents ) throw(RuntimeException)
1919 if( !isDesignMode() && !mbCreatingCompatiblePeer )
1921 ::rtl::OUString s1( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) );
1922 ::rtl::OUString s2( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) );
1923 ::rtl::OUString s3( RTL_CONSTASCII_USTRINGPARAM( "Width" ) );
1924 ::rtl::OUString s4( RTL_CONSTASCII_USTRINGPARAM( "Height" ) );
1926 sal_Int32 nLen = rEvents.getLength();
1927 for( sal_Int32 i = 0; i < nLen; i++ )
1929 const PropertyChangeEvent& rEvt = rEvents.getConstArray()[i];
1930 Reference< XControlModel > xModel( rEvt.Source, UNO_QUERY );
1931 sal_Bool bOwnModel = (XControlModel*)xModel.get() == (XControlModel*)getModel().get();
1932 if ( ( rEvt.PropertyName == s1 ) ||
1933 ( rEvt.PropertyName == s2 ) ||
1934 ( rEvt.PropertyName == s3 ) ||
1935 ( rEvt.PropertyName == s4 ) )
1937 if ( bOwnModel )
1939 if ( !mbPosModified && !mbSizeModified )
1941 // Don't set new pos/size if we get new values from window listener
1942 Reference< XControl > xThis( (XAggregation*)(::cppu::OWeakAggObject*)this, UNO_QUERY );
1943 ImplSetPosSize( xThis );
1946 else
1948 Sequence<Reference<XControl> > aControlSequence(getControls());
1949 Reference<XControl> aControlRef( StdTabController::FindControl( aControlSequence, xModel ) );
1950 ImplSetPosSize( aControlRef );
1952 break;
1954 else if ( bOwnModel && rEvt.PropertyName.equalsAsciiL( "ResourceResolver", 16 ))
1956 ImplStartListingForResourceEvents();
1961 sal_Int32 nLen = rEvents.getLength();
1962 for( sal_Int32 i = 0; i < nLen; i++ )
1964 const PropertyChangeEvent& rEvt = rEvents.getConstArray()[i];
1965 Reference< XControlModel > xModel( rEvt.Source, UNO_QUERY );
1966 sal_Bool bOwnModel = (XControlModel*)xModel.get() == (XControlModel*)getModel().get();
1967 if ( bOwnModel && rEvt.PropertyName.equalsAsciiL( "ImageURL", 8 ))
1969 ::rtl::OUString aImageURL;
1970 if (( ImplGetPropertyValue( PROPERTY_IMAGEURL ) >>= aImageURL ) &&
1971 ( aImageURL.getLength() > 0 ))
1973 aImageURL =
1974 getPhysicalLocation( ImplGetPropertyValue( PROPERTY_DIALOGSOURCEURL ),
1975 ImplGetPropertyValue( PROPERTY_IMAGEURL ));
1979 ImplSetPropertyValue( PROPERTY_IMAGEURL, uno::makeAny( aImageURL ), sal_True );
1980 break;
1984 UnoControlContainer::ImplModelPropertiesChanged( rEvents );
1987 void UnoDialogControl::ImplStartListingForResourceEvents()
1989 Reference< resource::XStringResourceResolver > xStringResourceResolver;
1991 ImplGetPropertyValue( PROPERTY_RESOURCERESOLVER ) >>= xStringResourceResolver;
1993 // Add our helper as listener to retrieve notifications about changes
1994 Reference< util::XModifyListener > rListener( mxListener );
1995 ResourceListener* pResourceListener = static_cast< ResourceListener* >( rListener.get() );
1997 // resource listener will stop listening if resolver reference is empty
1998 if ( pResourceListener )
1999 pResourceListener->startListening( xStringResourceResolver );
2000 ImplUpdateResourceResolver();
2003 void UnoDialogControl::ImplUpdateResourceResolver()
2005 rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER );
2006 Reference< resource::XStringResourceResolver > xStringResourceResolver;
2008 ImplGetPropertyValue( aPropName ) >>= xStringResourceResolver;
2009 if ( !xStringResourceResolver.is() )
2010 return;
2012 Any xNewStringResourceResolver; xNewStringResourceResolver <<= xStringResourceResolver;
2014 Sequence< rtl::OUString > aPropNames(1);
2015 aPropNames[0] = aPropName;
2017 const Sequence< Reference< awt::XControl > > aSeq = getControls();
2018 for ( sal_Int32 i = 0; i < aSeq.getLength(); i++ )
2020 Reference< XControl > xControl( aSeq[i] );
2021 Reference< XPropertySet > xPropertySet;
2023 if ( xControl.is() )
2024 xPropertySet = Reference< XPropertySet >( xControl->getModel(), UNO_QUERY );
2026 if ( !xPropertySet.is() )
2027 continue;
2031 Reference< resource::XStringResourceResolver > xCurrStringResourceResolver;
2032 Any aOldValue = xPropertySet->getPropertyValue( aPropName );
2033 if ( ( aOldValue >>= xCurrStringResourceResolver )
2034 && ( xStringResourceResolver == xCurrStringResourceResolver )
2037 Reference< XMultiPropertySet > xMultiPropSet( xPropertySet, UNO_QUERY );
2038 Reference< XPropertiesChangeListener > xListener( xPropertySet, UNO_QUERY );
2039 xMultiPropSet->firePropertiesChangeEvent( aPropNames, xListener );
2041 else
2042 xPropertySet->setPropertyValue( aPropName, xNewStringResourceResolver );
2044 /*catch ( NoSuchElementException& )*/ // that's nonsense, this is never thrown above ...
2045 catch ( const Exception& )
2050 // propagate resource resolver changes to language dependent props of the dialog
2051 Reference< XPropertySet > xPropertySet( getModel(), UNO_QUERY );
2052 if ( xPropertySet.is() )
2054 Reference< XMultiPropertySet > xMultiPropSet( xPropertySet, UNO_QUERY );
2055 Reference< XPropertiesChangeListener > xListener( xPropertySet, UNO_QUERY );
2056 xMultiPropSet->firePropertiesChangeEvent( lcl_getLanguageDependentProperties(), xListener );
2060 void UnoDialogControl::setTitle( const ::rtl::OUString& Title ) throw(RuntimeException)
2062 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2063 Any aAny;
2064 aAny <<= Title;
2065 ImplSetPropertyValue( GetPropertyName( BASEPROPERTY_TITLE ), aAny, sal_True );
2068 ::rtl::OUString UnoDialogControl::getTitle() throw(RuntimeException)
2070 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2071 return ImplGetPropertyValue_UString( BASEPROPERTY_TITLE );
2074 sal_Int16 UnoDialogControl::execute() throw(RuntimeException)
2076 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2077 sal_Int16 nDone = -1;
2078 if ( getPeer().is() )
2080 Reference< XDialog > xDlg( getPeer(), UNO_QUERY );
2081 if( xDlg.is() )
2083 GetComponentInfos().bVisible = sal_True;
2084 nDone = xDlg->execute();
2085 GetComponentInfos().bVisible = sal_False;
2088 return nDone;
2091 void UnoDialogControl::endExecute() throw(RuntimeException)
2093 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2094 if ( getPeer().is() )
2096 Reference< XDialog > xDlg( getPeer(), UNO_QUERY );
2097 if( xDlg.is() )
2099 xDlg->endExecute();
2100 GetComponentInfos().bVisible = sal_False;
2105 void UnoDialogControl::addingControl( const Reference< XControl >& _rxControl )
2107 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2108 UnoControlContainer::addingControl( _rxControl );
2110 if ( _rxControl.is() )
2112 Reference< XMultiPropertySet > xProps( _rxControl->getModel(), UNO_QUERY );
2113 if ( xProps.is() )
2115 Sequence< ::rtl::OUString > aNames( 4 );
2116 ::rtl::OUString* pNames = aNames.getArray();
2117 *pNames++ = ::rtl::OUString::createFromAscii( "PositionX" );
2118 *pNames++ = ::rtl::OUString::createFromAscii( "PositionY" );
2119 *pNames++ = ::rtl::OUString::createFromAscii( "Width" );
2120 *pNames++ = ::rtl::OUString::createFromAscii( "Height" );
2122 xProps->addPropertiesChangeListener( aNames, this );
2127 void UnoDialogControl::removingControl( const Reference< XControl >& _rxControl )
2129 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2130 UnoControlContainer::removingControl( _rxControl );
2132 if ( _rxControl.is() )
2134 Reference< XMultiPropertySet > xProps( _rxControl->getModel(), UNO_QUERY );
2135 if ( xProps.is() )
2136 xProps->removePropertiesChangeListener( this );
2141 void SAL_CALL UnoDialogControl::changesOccurred( const ChangesEvent& ) throw (RuntimeException)
2143 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2144 // a tab controller model may have changed
2146 // #109067# in design mode don't notify the tab controller
2147 // about tab index changes
2148 if ( mxTabController.is() && !mbDesignMode )
2149 mxTabController->activateTabOrder();
2152 // XModifyListener
2153 void SAL_CALL UnoDialogControl::modified(
2154 const lang::EventObject& /*rEvent*/ )
2155 throw (RuntimeException)
2157 ImplUpdateResourceResolver();
2160 // ----------------------------------------------------
2161 // Helper Method to convert relative url to physical location
2162 // ----------------------------------------------------
2164 ::rtl::OUString getPhysicalLocation( const ::com::sun::star::uno::Any& rbase, const ::com::sun::star::uno::Any& rUrl )
2168 ::rtl::OUString ret;
2170 ::rtl::OUString baseLocation;
2171 ::rtl::OUString url;
2173 rbase >>= baseLocation;
2174 rUrl >>= url;
2176 if ( url.getLength() > 0 )
2178 // Don't adjust GraphicObject url(s)
2179 if ( url.compareToAscii( UNO_NAME_GRAPHOBJ_URLPREFIX, RTL_CONSTASCII_LENGTH( UNO_NAME_GRAPHOBJ_URLPREFIX ) ) != 0 )
2181 INetURLObject urlObj(baseLocation);
2182 urlObj.removeSegment();
2183 baseLocation = urlObj.GetMainURL( INetURLObject::NO_DECODE );
2184 ::osl::FileBase::getAbsoluteFileURL( baseLocation, url, ret );
2186 else
2187 ret = url;
2191 return ret;