1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "propertyhandler.hxx"
30 #include "formmetadata.hxx"
31 #include "formbrowsertools.hxx"
32 #include "handlerhelper.hxx"
33 #include "formstrings.hxx"
35 /** === begin UNO includes === **/
36 #include <com/sun/star/beans/PropertyAttribute.hpp>
37 #include <com/sun/star/lang/NullPointerException.hpp>
38 #include <com/sun/star/util/XModifiable.hpp>
39 /** === end UNO includes === **/
41 #include <tools/debug.hxx>
42 #include <unotools/confignode.hxx>
43 #include <unotools/localedatawrapper.hxx>
44 #include <unotools/syslocale.hxx>
45 #include <toolkit/helper/vclunohelper.hxx>
49 //........................................................................
52 //........................................................................
54 using namespace ::com::sun::star::uno
;
55 using namespace ::com::sun::star::awt
;
56 using namespace ::com::sun::star::beans
;
57 using namespace ::com::sun::star::script
;
58 using namespace ::com::sun::star::lang
;
59 using namespace ::com::sun::star::util
;
60 using namespace ::com::sun::star::frame
;
61 using namespace ::com::sun::star::inspection
;
62 using namespace ::comphelper
;
64 //====================================================================
66 //====================================================================
67 DBG_NAME( PropertyHandler
)
68 //--------------------------------------------------------------------
69 PropertyHandler::PropertyHandler( const Reference
< XComponentContext
>& _rxContext
)
70 :PropertyHandler_Base( m_aMutex
)
71 ,m_bSupportedPropertiesAreKnown( false )
72 ,m_aPropertyListeners( m_aMutex
)
73 ,m_aContext( _rxContext
)
74 ,m_pInfoService ( new OPropertyInfoService
)
76 DBG_CTOR( PropertyHandler
, NULL
);
78 m_xTypeConverter
= Reference
< XTypeConverter
>(
79 m_aContext
.createComponent( "com.sun.star.script.Converter" ),
84 //--------------------------------------------------------------------
85 PropertyHandler::~PropertyHandler()
87 DBG_DTOR( PropertyHandler
, NULL
);
90 //--------------------------------------------------------------------
91 void SAL_CALL
PropertyHandler::inspect( const Reference
< XInterface
>& _rxIntrospectee
) throw (RuntimeException
, NullPointerException
)
93 if ( !_rxIntrospectee
.is() )
94 throw NullPointerException();
96 ::osl::MutexGuard
aGuard( m_aMutex
);
98 Reference
< XPropertySet
> xNewComponent( _rxIntrospectee
, UNO_QUERY
);
99 if ( xNewComponent
== m_xComponent
)
102 // remove all old property change listeners
103 SAL_WNODEPRECATED_DECLARATIONS_PUSH
104 ::std::auto_ptr
< ::cppu::OInterfaceIteratorHelper
> removeListener
= m_aPropertyListeners
.createIterator();
105 ::std::auto_ptr
< ::cppu::OInterfaceIteratorHelper
> readdListener
= m_aPropertyListeners
.createIterator(); // will copy the container as needed
106 SAL_WNODEPRECATED_DECLARATIONS_POP
107 while ( removeListener
->hasMoreElements() )
108 removePropertyChangeListener( static_cast< XPropertyChangeListener
* >( removeListener
->next() ) );
109 OSL_ENSURE( m_aPropertyListeners
.empty(), "PropertyHandler::inspect: derived classes are expected to forward the removePropertyChangeListener call to their base class (me)!" );
111 // remember the new component, and give derived classes the chance to react on it
112 m_xComponent
= xNewComponent
;
115 // add the listeners, again
116 while ( readdListener
->hasMoreElements() )
117 addPropertyChangeListener( static_cast< XPropertyChangeListener
* >( readdListener
->next() ) );
120 //--------------------------------------------------------------------
121 void PropertyHandler::onNewComponent()
123 if ( m_xComponent
.is() )
124 m_xComponentPropertyInfo
= m_xComponent
->getPropertySetInfo();
126 m_xComponentPropertyInfo
.clear();
128 m_bSupportedPropertiesAreKnown
= false;
129 m_aSupportedProperties
.realloc( 0 );
132 //--------------------------------------------------------------------
133 Sequence
< Property
> SAL_CALL
PropertyHandler::getSupportedProperties() throw (RuntimeException
)
135 ::osl::MutexGuard
aGuard( m_aMutex
);
136 if ( !m_bSupportedPropertiesAreKnown
)
138 m_aSupportedProperties
= doDescribeSupportedProperties();
139 m_bSupportedPropertiesAreKnown
= true;
141 return (Sequence
< Property
>)m_aSupportedProperties
;
144 //--------------------------------------------------------------------
145 Sequence
< ::rtl::OUString
> SAL_CALL
PropertyHandler::getSupersededProperties( ) throw (RuntimeException
)
147 return Sequence
< ::rtl::OUString
>();
150 //--------------------------------------------------------------------
151 Sequence
< ::rtl::OUString
> SAL_CALL
PropertyHandler::getActuatingProperties( ) throw (RuntimeException
)
153 return Sequence
< ::rtl::OUString
>();
156 //--------------------------------------------------------------------
157 Any SAL_CALL
PropertyHandler::convertToPropertyValue( const ::rtl::OUString
& _rPropertyName
, const Any
& _rControlValue
) throw (UnknownPropertyException
, RuntimeException
)
159 ::osl::MutexGuard
aGuard( m_aMutex
);
160 PropertyId nPropId
= m_pInfoService
->getPropertyId( _rPropertyName
);
161 Property
aProperty( impl_getPropertyFromName_throw( _rPropertyName
) );
164 if ( !_rControlValue
.hasValue() )
165 // NULL is converted to NULL
166 return aPropertyValue
;
168 if ( ( m_pInfoService
->getPropertyUIFlags( nPropId
) & PROP_FLAG_ENUM
) != 0 )
170 ::rtl::OUString sControlValue
;
171 OSL_VERIFY( _rControlValue
>>= sControlValue
);
172 ::rtl::Reference
< IPropertyEnumRepresentation
> aEnumConversion(
173 new DefaultEnumRepresentation( *m_pInfoService
, aProperty
.Type
, nPropId
) );
174 // TODO/UNOize: cache those converters?
175 aEnumConversion
->getValueFromDescription( sControlValue
, aPropertyValue
);
178 aPropertyValue
= PropertyHandlerHelper::convertToPropertyValue(
179 m_aContext
.getContext(),m_xTypeConverter
, aProperty
, _rControlValue
);
180 return aPropertyValue
;
183 //--------------------------------------------------------------------
184 Any SAL_CALL
PropertyHandler::convertToControlValue( const ::rtl::OUString
& _rPropertyName
, const Any
& _rPropertyValue
, const Type
& _rControlValueType
) throw (UnknownPropertyException
, RuntimeException
)
186 ::osl::MutexGuard
aGuard( m_aMutex
);
187 PropertyId nPropId
= m_pInfoService
->getPropertyId( _rPropertyName
);
189 if ( ( m_pInfoService
->getPropertyUIFlags( nPropId
) & PROP_FLAG_ENUM
) != 0 )
191 DBG_ASSERT( _rControlValueType
.getTypeClass() == TypeClass_STRING
, "PropertyHandler::convertToControlValue: ENUM, but not STRING?" );
193 ::rtl::Reference
< IPropertyEnumRepresentation
> aEnumConversion(
194 new DefaultEnumRepresentation( *m_pInfoService
, _rPropertyValue
.getValueType(), nPropId
) );
195 // TODO/UNOize: cache those converters?
196 return makeAny( aEnumConversion
->getDescriptionForValue( _rPropertyValue
) );
199 return PropertyHandlerHelper::convertToControlValue(
200 m_aContext
.getContext(),m_xTypeConverter
, _rPropertyValue
, _rControlValueType
);
203 //--------------------------------------------------------------------
204 PropertyState SAL_CALL
PropertyHandler::getPropertyState( const ::rtl::OUString
& /*_rPropertyName*/ ) throw (UnknownPropertyException
, RuntimeException
)
206 return PropertyState_DIRECT_VALUE
;
209 //--------------------------------------------------------------------
210 LineDescriptor SAL_CALL
PropertyHandler::describePropertyLine( const ::rtl::OUString
& _rPropertyName
,
211 const Reference
< XPropertyControlFactory
>& _rxControlFactory
)
212 throw (UnknownPropertyException
, NullPointerException
, RuntimeException
)
214 if ( !_rxControlFactory
.is() )
215 throw NullPointerException();
217 ::osl::MutexGuard
aGuard( m_aMutex
);
218 PropertyId
nPropId( impl_getPropertyId_throw( _rPropertyName
) );
219 const Property
& rProperty( impl_getPropertyFromId_throw( nPropId
) );
221 LineDescriptor aDescriptor
;
222 if ( ( m_pInfoService
->getPropertyUIFlags( nPropId
) & PROP_FLAG_ENUM
) != 0 )
224 aDescriptor
.Control
= PropertyHandlerHelper::createListBoxControl(
225 _rxControlFactory
, m_pInfoService
->getPropertyEnumRepresentations( nPropId
),
226 PropertyHandlerHelper::requiresReadOnlyControl( rProperty
.Attributes
), sal_False
);
229 PropertyHandlerHelper::describePropertyLine( rProperty
, aDescriptor
, _rxControlFactory
);
231 aDescriptor
.HelpURL
= HelpIdUrl::getHelpURL( m_pInfoService
->getPropertyHelpId( nPropId
) );
232 aDescriptor
.DisplayName
= m_pInfoService
->getPropertyTranslation( nPropId
);
234 if ( ( m_pInfoService
->getPropertyUIFlags( nPropId
) & PROP_FLAG_DATA_PROPERTY
) != 0 )
235 aDescriptor
.Category
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Data" ) );
237 aDescriptor
.Category
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "General" ) );
241 //--------------------------------------------------------------------
242 ::sal_Bool SAL_CALL
PropertyHandler::isComposable( const ::rtl::OUString
& _rPropertyName
) throw (UnknownPropertyException
, RuntimeException
)
244 ::osl::MutexGuard
aGuard( m_aMutex
);
245 return m_pInfoService
->isComposeable( _rPropertyName
);
248 //--------------------------------------------------------------------
249 InteractiveSelectionResult SAL_CALL
PropertyHandler::onInteractivePropertySelection( const ::rtl::OUString
& /*_rPropertyName*/, sal_Bool
/*_bPrimary*/, Any
& /*_rData*/, const Reference
< XObjectInspectorUI
>& /*_rxInspectorUI*/ ) throw (UnknownPropertyException
, NullPointerException
, RuntimeException
)
251 OSL_FAIL( "PropertyHandler::onInteractivePropertySelection: not implemented!" );
252 return InteractiveSelectionResult_Cancelled
;
255 //--------------------------------------------------------------------
256 void SAL_CALL
PropertyHandler::actuatingPropertyChanged( const ::rtl::OUString
& /*_rActuatingPropertyName*/, const Any
& /*_rNewValue*/, const Any
& /*_rOldValue*/, const Reference
< XObjectInspectorUI
>& /*_rxInspectorUI*/, sal_Bool
/*_bFirstTimeInit*/ ) throw (NullPointerException
, RuntimeException
)
258 OSL_FAIL( "PropertyHandler::actuatingPropertyChanged: not implemented!" );
261 //--------------------------------------------------------------------
262 void SAL_CALL
PropertyHandler::addPropertyChangeListener( const Reference
< XPropertyChangeListener
>& _rxListener
) throw (RuntimeException
)
264 ::osl::MutexGuard
aGuard( m_aMutex
);
265 if ( !_rxListener
.is() )
266 throw NullPointerException();
267 m_aPropertyListeners
.addListener( _rxListener
);
270 //--------------------------------------------------------------------
271 void SAL_CALL
PropertyHandler::removePropertyChangeListener( const Reference
< XPropertyChangeListener
>& _rxListener
) throw (RuntimeException
)
273 ::osl::MutexGuard
aGuard( m_aMutex
);
274 m_aPropertyListeners
.removeListener( _rxListener
);
277 //--------------------------------------------------------------------
278 sal_Bool SAL_CALL
PropertyHandler::suspend( sal_Bool
/*_bSuspend*/ ) throw (RuntimeException
)
283 //--------------------------------------------------------------------
284 IMPLEMENT_FORWARD_XCOMPONENT( PropertyHandler
, PropertyHandler_Base
)
285 //--------------------------------------------------------------------
286 void SAL_CALL
PropertyHandler::disposing()
288 m_xComponent
.clear();
289 m_aPropertyListeners
.clear();
290 m_xTypeConverter
.clear();
291 m_aSupportedProperties
.realloc( 0 );
294 //--------------------------------------------------------------------
295 void PropertyHandler::firePropertyChange( const ::rtl::OUString
& _rPropName
, PropertyId _nPropId
, const Any
& _rOldValue
, const Any
& _rNewValue
) SAL_THROW(())
297 PropertyChangeEvent aEvent
;
298 aEvent
.Source
= m_xComponent
;
299 aEvent
.PropertyHandle
= _nPropId
;
300 aEvent
.PropertyName
= _rPropName
;
301 aEvent
.OldValue
= _rOldValue
;
302 aEvent
.NewValue
= _rNewValue
;
303 m_aPropertyListeners
.notify( aEvent
, &XPropertyChangeListener::propertyChange
);
306 //--------------------------------------------------------------------
307 const Property
* PropertyHandler::impl_getPropertyFromId_nothrow( PropertyId _nPropId
) const
309 const_cast< PropertyHandler
* >( this )->getSupportedProperties();
310 const Property
* pFound
= ::std::find_if( m_aSupportedProperties
.begin(), m_aSupportedProperties
.end(),
311 FindPropertyByHandle( _nPropId
)
313 if ( pFound
!= m_aSupportedProperties
.end() )
318 //--------------------------------------------------------------------
319 const Property
& PropertyHandler::impl_getPropertyFromId_throw( PropertyId _nPropId
) const
321 const Property
* pProperty
= impl_getPropertyFromId_nothrow( _nPropId
);
323 throw UnknownPropertyException();
328 //--------------------------------------------------------------------
329 const Property
& PropertyHandler::impl_getPropertyFromName_throw( const ::rtl::OUString
& _rPropertyName
) const
331 const_cast< PropertyHandler
* >( this )->getSupportedProperties();
332 StlSyntaxSequence
< Property
>::const_iterator pFound
= ::std::find_if( m_aSupportedProperties
.begin(), m_aSupportedProperties
.end(),
333 FindPropertyByName( _rPropertyName
)
335 if ( pFound
== m_aSupportedProperties
.end() )
336 throw UnknownPropertyException();
341 //--------------------------------------------------------------------
342 void PropertyHandler::implAddPropertyDescription( ::std::vector
< Property
>& _rProperties
, const ::rtl::OUString
& _rPropertyName
, const Type
& _rType
, sal_Int16 _nAttribs
) const
344 _rProperties
.push_back( Property(
346 m_pInfoService
->getPropertyId( _rPropertyName
),
352 //------------------------------------------------------------------------
353 Window
* PropertyHandler::impl_getDefaultDialogParent_nothrow() const
355 return PropertyHandlerHelper::getDialogParentWindow( m_aContext
);
358 //------------------------------------------------------------------------
359 PropertyId
PropertyHandler::impl_getPropertyId_throw( const ::rtl::OUString
& _rPropertyName
) const
361 PropertyId nPropId
= m_pInfoService
->getPropertyId( _rPropertyName
);
363 throw UnknownPropertyException();
367 //------------------------------------------------------------------------
368 void PropertyHandler::impl_setContextDocumentModified_nothrow() const
370 Reference
< XModifiable
> xModifiable( impl_getContextDocument_nothrow(), UNO_QUERY
);
371 if ( xModifiable
.is() )
372 xModifiable
->setModified( sal_True
);
375 //------------------------------------------------------------------------
376 bool PropertyHandler::impl_componentHasProperty_throw( const ::rtl::OUString
& _rPropName
) const
378 return m_xComponentPropertyInfo
.is() && m_xComponentPropertyInfo
->hasPropertyByName( _rPropName
);
381 //--------------------------------------------------------------------
382 sal_Int16
PropertyHandler::impl_getDocumentMeasurementUnit_throw() const
384 FieldUnit eUnit
= FUNIT_NONE
;
386 Reference
< XServiceInfo
> xDocumentSI( impl_getContextDocument_nothrow(), UNO_QUERY
);
387 OSL_ENSURE( xDocumentSI
.is(), "PropertyHandlerHelper::impl_getDocumentMeasurementUnit_throw: No context document - where do I live?" );
388 if ( xDocumentSI
.is() )
390 // determine the application type we live in
391 ::rtl::OUString sConfigurationLocation
;
392 ::rtl::OUString sConfigurationProperty
;
393 if ( xDocumentSI
->supportsService( SERVICE_WEB_DOCUMENT
) )
395 sConfigurationLocation
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.WriterWeb/Layout/Other" ) );
396 sConfigurationProperty
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MeasureUnit" ) );
398 else if ( xDocumentSI
->supportsService( SERVICE_TEXT_DOCUMENT
) )
400 sConfigurationLocation
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Writer/Layout/Other" ) );
401 sConfigurationProperty
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MeasureUnit" ) );
403 else if ( xDocumentSI
->supportsService( SERVICE_SPREADSHEET_DOCUMENT
) )
405 sConfigurationLocation
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Calc/Layout/Other/MeasureUnit" ) );
406 sConfigurationProperty
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Metric" ) );
408 else if ( xDocumentSI
->supportsService( SERVICE_DRAWING_DOCUMENT
) )
410 sConfigurationLocation
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Draw/Layout/Other/MeasureUnit" ) );
411 sConfigurationProperty
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Metric" ) );
413 else if ( xDocumentSI
->supportsService( SERVICE_PRESENTATION_DOCUMENT
) )
415 sConfigurationLocation
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Impress/Layout/Other/MeasureUnit" ) );
416 sConfigurationProperty
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Metric" ) );
419 // read the measurement unit from the configuration
420 if ( !(sConfigurationLocation
.isEmpty() || sConfigurationProperty
.isEmpty()) )
422 ::utl::OConfigurationTreeRoot
aConfigTree( ::utl::OConfigurationTreeRoot::createWithServiceFactory(
423 m_aContext
.getLegacyServiceFactory(), sConfigurationLocation
, -1, ::utl::OConfigurationTreeRoot::CM_READONLY
) );
424 sal_Int32 nUnitAsInt
= (sal_Int32
)FUNIT_NONE
;
425 aConfigTree
.getNodeValue( sConfigurationProperty
) >>= nUnitAsInt
;
427 // if this denotes a valid (and accepted) unit, then use it
428 if ( ( nUnitAsInt
> FUNIT_NONE
) && ( nUnitAsInt
<= FUNIT_100TH_MM
) )
429 eUnit
= static_cast< FieldUnit
>( nUnitAsInt
);
433 if ( FUNIT_NONE
== eUnit
)
435 MeasurementSystem eSystem
= SvtSysLocale().GetLocaleData().getMeasurementSystemEnum();
436 eUnit
= MEASURE_METRIC
== eSystem
? FUNIT_CM
: FUNIT_INCH
;
439 return VCLUnoHelper::ConvertToMeasurementUnit( eUnit
, 1 );
442 //====================================================================
443 //= PropertyHandlerComponent
444 //====================================================================
445 //------------------------------------------------------------------------
446 PropertyHandlerComponent::PropertyHandlerComponent( const Reference
< XComponentContext
>& _rxContext
)
447 :PropertyHandler( _rxContext
)
451 //--------------------------------------------------------------------
452 IMPLEMENT_FORWARD_XINTERFACE2( PropertyHandlerComponent
, PropertyHandler
, PropertyHandlerComponent_Base
)
453 IMPLEMENT_FORWARD_XTYPEPROVIDER2( PropertyHandlerComponent
, PropertyHandler
, PropertyHandlerComponent_Base
)
455 //--------------------------------------------------------------------
456 ::sal_Bool SAL_CALL
PropertyHandlerComponent::supportsService( const ::rtl::OUString
& ServiceName
) throw (RuntimeException
)
458 StlSyntaxSequence
< ::rtl::OUString
> aAllServices( getSupportedServiceNames() );
459 return ::std::find( aAllServices
.begin(), aAllServices
.end(), ServiceName
) != aAllServices
.end();
462 //........................................................................
464 //........................................................................
466 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */