Update ooo320-m1
[ooovba.git] / extensions / source / propctrlr / propertyhandler.cxx
blobd8ff719deed9d3517f178034c287a2ca881669fe
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: propertyhandler.cxx,v $
10 * $Revision: 1.13 $
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_extensions.hxx"
33 #include "propertyhandler.hxx"
34 #include "formmetadata.hxx"
35 #include "formbrowsertools.hxx"
36 #include "handlerhelper.hxx"
37 #include "formstrings.hxx"
39 /** === begin UNO includes === **/
40 #include <com/sun/star/beans/PropertyAttribute.hpp>
41 #include <com/sun/star/lang/NullPointerException.hpp>
42 #include <com/sun/star/util/XModifiable.hpp>
43 /** === end UNO includes === **/
45 #include <tools/debug.hxx>
46 #include <unotools/confignode.hxx>
47 #include <unotools/localedatawrapper.hxx>
48 #include <svtools/syslocale.hxx>
49 #include <toolkit/helper/vclunohelper.hxx>
51 #include <algorithm>
53 //........................................................................
54 namespace pcr
56 //........................................................................
58 using namespace ::com::sun::star::uno;
59 using namespace ::com::sun::star::awt;
60 using namespace ::com::sun::star::beans;
61 using namespace ::com::sun::star::script;
62 using namespace ::com::sun::star::lang;
63 using namespace ::com::sun::star::util;
64 using namespace ::com::sun::star::frame;
65 using namespace ::com::sun::star::inspection;
66 using namespace ::comphelper;
68 //====================================================================
69 //= PropertyHandler
70 //====================================================================
71 DBG_NAME( PropertyHandler )
72 //--------------------------------------------------------------------
73 PropertyHandler::PropertyHandler( const Reference< XComponentContext >& _rxContext )
74 :PropertyHandler_Base( m_aMutex )
75 ,m_bSupportedPropertiesAreKnown( false )
76 ,m_aPropertyListeners( m_aMutex )
77 ,m_aContext( _rxContext )
78 ,m_pInfoService ( new OPropertyInfoService )
80 DBG_CTOR( PropertyHandler, NULL );
82 m_xTypeConverter = Reference< XTypeConverter >(
83 m_aContext.createComponent( "com.sun.star.script.Converter" ),
84 UNO_QUERY_THROW
88 //--------------------------------------------------------------------
89 PropertyHandler::~PropertyHandler()
91 DBG_DTOR( PropertyHandler, NULL );
94 //--------------------------------------------------------------------
95 void SAL_CALL PropertyHandler::inspect( const Reference< XInterface >& _rxIntrospectee ) throw (RuntimeException, NullPointerException)
97 if ( !_rxIntrospectee.is() )
98 throw NullPointerException();
100 ::osl::MutexGuard aGuard( m_aMutex );
102 Reference< XPropertySet > xNewComponent( _rxIntrospectee, UNO_QUERY );
103 if ( xNewComponent == m_xComponent )
104 return;
106 // remove all old property change listeners
107 ::std::auto_ptr< ::cppu::OInterfaceIteratorHelper > removeListener = m_aPropertyListeners.createIterator();
108 ::std::auto_ptr< ::cppu::OInterfaceIteratorHelper > readdListener = m_aPropertyListeners.createIterator(); // will copy the container as needed
109 while ( removeListener->hasMoreElements() )
110 removePropertyChangeListener( static_cast< XPropertyChangeListener* >( removeListener->next() ) );
111 OSL_ENSURE( m_aPropertyListeners.empty(), "PropertyHandler::inspect: derived classes are expected to forward the removePropertyChangeListener call to their base class (me)!" );
113 // remember the new component, and give derived classes the chance to react on it
114 m_xComponent = xNewComponent;
115 onNewComponent();
117 // add the listeners, again
118 while ( readdListener->hasMoreElements() )
119 addPropertyChangeListener( static_cast< XPropertyChangeListener* >( readdListener->next() ) );
122 //--------------------------------------------------------------------
123 void PropertyHandler::onNewComponent()
125 if ( m_xComponent.is() )
126 m_xComponentPropertyInfo = m_xComponent->getPropertySetInfo();
127 else
128 m_xComponentPropertyInfo.clear();
130 m_bSupportedPropertiesAreKnown = false;
131 m_aSupportedProperties.realloc( 0 );
134 //--------------------------------------------------------------------
135 Sequence< Property > SAL_CALL PropertyHandler::getSupportedProperties() throw (RuntimeException)
137 ::osl::MutexGuard aGuard( m_aMutex );
138 if ( !m_bSupportedPropertiesAreKnown )
140 m_aSupportedProperties = doDescribeSupportedProperties();
141 m_bSupportedPropertiesAreKnown = true;
143 return (Sequence< Property >)m_aSupportedProperties;
146 //--------------------------------------------------------------------
147 Sequence< ::rtl::OUString > SAL_CALL PropertyHandler::getSupersededProperties( ) throw (RuntimeException)
149 return Sequence< ::rtl::OUString >();
152 //--------------------------------------------------------------------
153 Sequence< ::rtl::OUString > SAL_CALL PropertyHandler::getActuatingProperties( ) throw (RuntimeException)
155 return Sequence< ::rtl::OUString >();
158 //--------------------------------------------------------------------
159 Any SAL_CALL PropertyHandler::convertToPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rControlValue ) throw (UnknownPropertyException, RuntimeException)
161 ::osl::MutexGuard aGuard( m_aMutex );
162 PropertyId nPropId = m_pInfoService->getPropertyId( _rPropertyName );
163 Property aProperty( impl_getPropertyFromName_throw( _rPropertyName ) );
165 Any aPropertyValue;
166 if ( !_rControlValue.hasValue() )
167 // NULL is converted to NULL
168 return aPropertyValue;
170 if ( ( m_pInfoService->getPropertyUIFlags( nPropId ) & PROP_FLAG_ENUM ) != 0 )
172 ::rtl::OUString sControlValue;
173 OSL_VERIFY( _rControlValue >>= sControlValue );
174 ::rtl::Reference< IPropertyEnumRepresentation > aEnumConversion(
175 new DefaultEnumRepresentation( *m_pInfoService, aProperty.Type, nPropId ) );
176 // TODO/UNOize: cache those converters?
177 aEnumConversion->getValueFromDescription( sControlValue, aPropertyValue );
179 else
180 aPropertyValue = PropertyHandlerHelper::convertToPropertyValue(
181 m_aContext.getContext(),m_xTypeConverter, aProperty, _rControlValue );
182 return aPropertyValue;
185 //--------------------------------------------------------------------
186 Any SAL_CALL PropertyHandler::convertToControlValue( const ::rtl::OUString& _rPropertyName, const Any& _rPropertyValue, const Type& _rControlValueType ) throw (UnknownPropertyException, RuntimeException)
188 ::osl::MutexGuard aGuard( m_aMutex );
189 PropertyId nPropId = m_pInfoService->getPropertyId( _rPropertyName );
191 if ( ( m_pInfoService->getPropertyUIFlags( nPropId ) & PROP_FLAG_ENUM ) != 0 )
193 DBG_ASSERT( _rControlValueType.getTypeClass() == TypeClass_STRING, "PropertyHandler::convertToControlValue: ENUM, but not STRING?" );
195 ::rtl::Reference< IPropertyEnumRepresentation > aEnumConversion(
196 new DefaultEnumRepresentation( *m_pInfoService, _rPropertyValue.getValueType(), nPropId ) );
197 // TODO/UNOize: cache those converters?
198 return makeAny( aEnumConversion->getDescriptionForValue( _rPropertyValue ) );
201 return PropertyHandlerHelper::convertToControlValue(
202 m_aContext.getContext(),m_xTypeConverter, _rPropertyValue, _rControlValueType );
205 //--------------------------------------------------------------------
206 PropertyState SAL_CALL PropertyHandler::getPropertyState( const ::rtl::OUString& /*_rPropertyName*/ ) throw (UnknownPropertyException, RuntimeException)
208 return PropertyState_DIRECT_VALUE;
211 //--------------------------------------------------------------------
212 LineDescriptor SAL_CALL PropertyHandler::describePropertyLine( const ::rtl::OUString& _rPropertyName,
213 const Reference< XPropertyControlFactory >& _rxControlFactory )
214 throw (UnknownPropertyException, NullPointerException, RuntimeException)
216 if ( !_rxControlFactory.is() )
217 throw NullPointerException();
219 ::osl::MutexGuard aGuard( m_aMutex );
220 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
221 const Property& rProperty( impl_getPropertyFromId_throw( nPropId ) );
223 LineDescriptor aDescriptor;
224 if ( ( m_pInfoService->getPropertyUIFlags( nPropId ) & PROP_FLAG_ENUM ) != 0 )
226 aDescriptor.Control = PropertyHandlerHelper::createListBoxControl(
227 _rxControlFactory, m_pInfoService->getPropertyEnumRepresentations( nPropId ),
228 PropertyHandlerHelper::requiresReadOnlyControl( rProperty.Attributes ), sal_False );
230 else
231 PropertyHandlerHelper::describePropertyLine( rProperty, aDescriptor, _rxControlFactory );
233 aDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( nPropId ) );
234 aDescriptor.DisplayName = m_pInfoService->getPropertyTranslation( nPropId );
236 if ( ( m_pInfoService->getPropertyUIFlags( nPropId ) & PROP_FLAG_DATA_PROPERTY ) != 0 )
237 aDescriptor.Category = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Data" ) );
238 else
239 aDescriptor.Category = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "General" ) );
240 return aDescriptor;
243 //--------------------------------------------------------------------
244 ::sal_Bool SAL_CALL PropertyHandler::isComposable( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
246 ::osl::MutexGuard aGuard( m_aMutex );
247 return m_pInfoService->isComposeable( _rPropertyName );
250 //--------------------------------------------------------------------
251 InteractiveSelectionResult SAL_CALL PropertyHandler::onInteractivePropertySelection( const ::rtl::OUString& /*_rPropertyName*/, sal_Bool /*_bPrimary*/, Any& /*_rData*/, const Reference< XObjectInspectorUI >& /*_rxInspectorUI*/ ) throw (UnknownPropertyException, NullPointerException, RuntimeException)
253 DBG_ERROR( "PropertyHandler::onInteractivePropertySelection: not implemented!" );
254 return InteractiveSelectionResult_Cancelled;
257 //--------------------------------------------------------------------
258 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)
260 DBG_ERROR( "PropertyHandler::actuatingPropertyChanged: not implemented!" );
263 //--------------------------------------------------------------------
264 void SAL_CALL PropertyHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
266 ::osl::MutexGuard aGuard( m_aMutex );
267 if ( !_rxListener.is() )
268 throw NullPointerException();
269 m_aPropertyListeners.addListener( _rxListener );
272 //--------------------------------------------------------------------
273 void SAL_CALL PropertyHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
275 ::osl::MutexGuard aGuard( m_aMutex );
276 m_aPropertyListeners.removeListener( _rxListener );
279 //--------------------------------------------------------------------
280 sal_Bool SAL_CALL PropertyHandler::suspend( sal_Bool /*_bSuspend*/ ) throw (RuntimeException)
282 return sal_True;
285 //--------------------------------------------------------------------
286 IMPLEMENT_FORWARD_XCOMPONENT( PropertyHandler, PropertyHandler_Base )
287 //--------------------------------------------------------------------
288 void SAL_CALL PropertyHandler::disposing()
290 m_xComponent.clear();
291 m_aPropertyListeners.clear();
292 m_xTypeConverter.clear();
293 m_aSupportedProperties.realloc( 0 );
296 //--------------------------------------------------------------------
297 void PropertyHandler::firePropertyChange( const ::rtl::OUString& _rPropName, PropertyId _nPropId, const Any& _rOldValue, const Any& _rNewValue ) SAL_THROW(())
299 PropertyChangeEvent aEvent;
300 aEvent.Source = m_xComponent;
301 aEvent.PropertyHandle = _nPropId;
302 aEvent.PropertyName = _rPropName;
303 aEvent.OldValue = _rOldValue;
304 aEvent.NewValue = _rNewValue;
305 m_aPropertyListeners.notify( aEvent, &XPropertyChangeListener::propertyChange );
308 //--------------------------------------------------------------------
309 const Property* PropertyHandler::impl_getPropertyFromId_nothrow( PropertyId _nPropId ) const
311 const_cast< PropertyHandler* >( this )->getSupportedProperties();
312 const Property* pFound = ::std::find_if( m_aSupportedProperties.begin(), m_aSupportedProperties.end(),
313 FindPropertyByHandle( _nPropId )
315 if ( pFound != m_aSupportedProperties.end() )
316 return &(*pFound);
317 return NULL;
320 //--------------------------------------------------------------------
321 const Property& PropertyHandler::impl_getPropertyFromId_throw( PropertyId _nPropId ) const
323 const Property* pProperty = impl_getPropertyFromId_nothrow( _nPropId );
324 if ( !pProperty )
325 throw UnknownPropertyException();
327 return *pProperty;
330 //--------------------------------------------------------------------
331 const Property& PropertyHandler::impl_getPropertyFromName_throw( const ::rtl::OUString& _rPropertyName ) const
333 const_cast< PropertyHandler* >( this )->getSupportedProperties();
334 StlSyntaxSequence< Property >::const_iterator pFound = ::std::find_if( m_aSupportedProperties.begin(), m_aSupportedProperties.end(),
335 FindPropertyByName( _rPropertyName )
337 if ( pFound == m_aSupportedProperties.end() )
338 throw UnknownPropertyException();
340 return *pFound;
343 //--------------------------------------------------------------------
344 void PropertyHandler::implAddPropertyDescription( ::std::vector< Property >& _rProperties, const ::rtl::OUString& _rPropertyName, const Type& _rType, sal_Int16 _nAttribs ) const
346 _rProperties.push_back( Property(
347 _rPropertyName,
348 m_pInfoService->getPropertyId( _rPropertyName ),
349 _rType,
350 _nAttribs
351 ) );
354 //------------------------------------------------------------------------
355 Window* PropertyHandler::impl_getDefaultDialogParent_nothrow() const
357 return PropertyHandlerHelper::getDialogParentWindow( m_aContext );
360 //------------------------------------------------------------------------
361 PropertyId PropertyHandler::impl_getPropertyId_throw( const ::rtl::OUString& _rPropertyName ) const
363 PropertyId nPropId = m_pInfoService->getPropertyId( _rPropertyName );
364 if ( nPropId == -1 )
365 throw UnknownPropertyException();
366 return nPropId;
369 //------------------------------------------------------------------------
370 void PropertyHandler::impl_setContextDocumentModified_nothrow() const
372 Reference< XModifiable > xModifiable( impl_getContextDocument_nothrow(), UNO_QUERY );
373 if ( xModifiable.is() )
374 xModifiable->setModified( sal_True );
377 //------------------------------------------------------------------------
378 bool PropertyHandler::impl_componentHasProperty_throw( const ::rtl::OUString& _rPropName ) const
380 return m_xComponentPropertyInfo.is() && m_xComponentPropertyInfo->hasPropertyByName( _rPropName );
383 //--------------------------------------------------------------------
384 sal_Int16 PropertyHandler::impl_getDocumentMeasurementUnit_throw() const
386 FieldUnit eUnit = FUNIT_NONE;
388 Reference< XServiceInfo > xDocumentSI( impl_getContextDocument_nothrow(), UNO_QUERY );
389 OSL_ENSURE( xDocumentSI.is(), "PropertyHandlerHelper::impl_getDocumentMeasurementUnit_throw: No context document - where do I live?" );
390 if ( xDocumentSI.is() )
392 // determine the application type we live in
393 ::rtl::OUString sConfigurationLocation;
394 ::rtl::OUString sConfigurationProperty;
395 if ( xDocumentSI->supportsService( SERVICE_WEB_DOCUMENT ) )
396 { // writer
397 sConfigurationLocation = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.WriterWeb/Layout/Other" ) );
398 sConfigurationProperty = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MeasureUnit" ) );
400 else if ( xDocumentSI->supportsService( SERVICE_TEXT_DOCUMENT ) )
401 { // writer
402 sConfigurationLocation = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Writer/Layout/Other" ) );
403 sConfigurationProperty = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MeasureUnit" ) );
405 else if ( xDocumentSI->supportsService( SERVICE_SPREADSHEET_DOCUMENT ) )
406 { // calc
407 sConfigurationLocation = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Calc/Layout/Other/MeasureUnit" ) );
408 sConfigurationProperty = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Metric" ) );
410 else if ( xDocumentSI->supportsService( SERVICE_DRAWING_DOCUMENT ) )
412 sConfigurationLocation = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Draw/Layout/Other/MeasureUnit" ) );
413 sConfigurationProperty = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Metric" ) );
415 else if ( xDocumentSI->supportsService( SERVICE_PRESENTATION_DOCUMENT ) )
417 sConfigurationLocation = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Impress/Layout/Other/MeasureUnit" ) );
418 sConfigurationProperty = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Metric" ) );
421 // read the measurement unit from the configuration
422 if ( sConfigurationLocation.getLength() && sConfigurationProperty.getLength() )
424 ::utl::OConfigurationTreeRoot aConfigTree( ::utl::OConfigurationTreeRoot::createWithServiceFactory(
425 m_aContext.getLegacyServiceFactory(), sConfigurationLocation, -1, ::utl::OConfigurationTreeRoot::CM_READONLY ) );
426 sal_Int32 nUnitAsInt = (sal_Int32)FUNIT_NONE;
427 aConfigTree.getNodeValue( sConfigurationProperty ) >>= nUnitAsInt;
429 // if this denotes a valid (and accepted) unit, then use it
430 if ( ( nUnitAsInt > FUNIT_NONE ) && ( nUnitAsInt <= FUNIT_100TH_MM ) )
431 eUnit = static_cast< FieldUnit >( nUnitAsInt );
435 if ( FUNIT_NONE == eUnit )
437 MeasurementSystem eSystem = SvtSysLocale().GetLocaleData().getMeasurementSystemEnum();
438 eUnit = MEASURE_METRIC == eSystem ? FUNIT_CM : FUNIT_INCH;
441 return VCLUnoHelper::ConvertToMeasurementUnit( eUnit, 1 );
444 //====================================================================
445 //= PropertyHandlerComponent
446 //====================================================================
447 //------------------------------------------------------------------------
448 PropertyHandlerComponent::PropertyHandlerComponent( const Reference< XComponentContext >& _rxContext )
449 :PropertyHandler( _rxContext )
453 //--------------------------------------------------------------------
454 IMPLEMENT_FORWARD_XINTERFACE2( PropertyHandlerComponent, PropertyHandler, PropertyHandlerComponent_Base )
455 IMPLEMENT_FORWARD_XTYPEPROVIDER2( PropertyHandlerComponent, PropertyHandler, PropertyHandlerComponent_Base )
457 //--------------------------------------------------------------------
458 ::sal_Bool SAL_CALL PropertyHandlerComponent::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException)
460 StlSyntaxSequence< ::rtl::OUString > aAllServices( getSupportedServiceNames() );
461 return ::std::find( aAllServices.begin(), aAllServices.end(), ServiceName ) != aAllServices.end();
464 //........................................................................
465 } // namespace pcr
466 //........................................................................