Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
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.
15 : : *
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).
21 : : *
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.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "genericpropertyhandler.hxx"
30 : : #include "formmetadata.hxx"
31 : : #include "handlerhelper.hxx"
32 : :
33 : : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
34 : : #include <com/sun/star/reflection/XEnumTypeDescription.hpp>
35 : : #include <com/sun/star/beans/XIntrospection.hpp>
36 : : #include <com/sun/star/inspection/PropertyControlType.hpp>
37 : : #include <com/sun/star/inspection/XHyperlinkControl.hpp>
38 : : #include <com/sun/star/awt/XActionListener.hpp>
39 : : #include <com/sun/star/util/URLTransformer.hpp>
40 : : #include <com/sun/star/util/XURLTransformer.hpp>
41 : : #include <com/sun/star/frame/XDispatchProvider.hpp>
42 : : #include <tools/debug.hxx>
43 : : #include <comphelper/extract.hxx>
44 : :
45 : : #include <algorithm>
46 : : #include <o3tl/compat_functional.hxx>
47 : :
48 : : //------------------------------------------------------------------------
49 : 0 : extern "C" void SAL_CALL createRegistryInfo_GenericPropertyHandler()
50 : : {
51 : 0 : ::pcr::OAutoRegistration< ::pcr::GenericPropertyHandler > aAutoRegistration;
52 : 0 : }
53 : :
54 : : //........................................................................
55 : : namespace pcr
56 : : {
57 : : //........................................................................
58 : :
59 : : using namespace ::com::sun::star::uno;
60 : : using namespace ::com::sun::star::beans;
61 : : using namespace ::com::sun::star::script;
62 : : using namespace ::com::sun::star::frame;
63 : : using namespace ::com::sun::star::lang;
64 : : using namespace ::com::sun::star::util;
65 : : using namespace ::com::sun::star::container;
66 : : using namespace ::com::sun::star::reflection;
67 : : using namespace ::com::sun::star::inspection;
68 : : using ::com::sun::star::awt::XActionListener;
69 : : using ::com::sun::star::awt::ActionEvent;
70 : :
71 : : //====================================================================
72 : : //= EnumRepresentation
73 : : //====================================================================
74 : 0 : class EnumRepresentation : public IPropertyEnumRepresentation
75 : : {
76 : : private:
77 : : oslInterlockedCount m_refCount;
78 : : Reference< XEnumTypeDescription > m_xTypeDescription;
79 : : Type m_aEnumType;
80 : :
81 : : public:
82 : : EnumRepresentation( const Reference< XComponentContext >& _rxContext, const Type& _rEnumType );
83 : :
84 : : // IPropertyEnumRepresentation implementqation
85 : : virtual ::std::vector< ::rtl::OUString >
86 : : SAL_CALL getDescriptions() const;
87 : : virtual void SAL_CALL getValueFromDescription( const ::rtl::OUString& _rDescription, ::com::sun::star::uno::Any& _out_rValue ) const;
88 : : virtual ::rtl::OUString SAL_CALL getDescriptionForValue( const ::com::sun::star::uno::Any& _rEnumValue ) const;
89 : :
90 : : // IReference implementqation
91 : : virtual oslInterlockedCount SAL_CALL acquire();
92 : : virtual oslInterlockedCount SAL_CALL release();
93 : :
94 : : private:
95 : : void impl_getValues( Sequence< sal_Int32 >& _out_rValues ) const;
96 : :
97 : : private:
98 : : EnumRepresentation(); // never implemented
99 : : EnumRepresentation( const EnumRepresentation& ); // never implemented
100 : : EnumRepresentation& operator=( const EnumRepresentation& ); // never implemented
101 : : };
102 : :
103 : : //--------------------------------------------------------------------
104 : 0 : EnumRepresentation::EnumRepresentation( const Reference< XComponentContext >& _rxContext, const Type& _rEnumType )
105 : : :m_refCount( 0 )
106 : 0 : ,m_aEnumType( _rEnumType )
107 : : {
108 : : try
109 : : {
110 : 0 : if ( _rxContext.is() )
111 : : {
112 : : Reference< XHierarchicalNameAccess > xTypeDescProv(
113 : 0 : _rxContext->getValueByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.reflection.theTypeDescriptionManager" ) ) ),
114 : 0 : UNO_QUERY_THROW );
115 : :
116 : 0 : m_xTypeDescription = Reference< XEnumTypeDescription >( xTypeDescProv->getByHierarchicalName( m_aEnumType.getTypeName() ), UNO_QUERY_THROW );
117 : : }
118 : : }
119 : 0 : catch( const Exception& )
120 : : {
121 : : OSL_FAIL( "EnumRepresentation::EnumRepresentation: caught an exception!" );
122 : : }
123 : 0 : }
124 : :
125 : : //--------------------------------------------------------------------
126 : 0 : ::std::vector< ::rtl::OUString > EnumRepresentation::getDescriptions() const
127 : : {
128 : 0 : Sequence< ::rtl::OUString > aNames;
129 : : try
130 : : {
131 : 0 : if ( m_xTypeDescription.is() )
132 : 0 : aNames = m_xTypeDescription->getEnumNames();
133 : : }
134 : 0 : catch( const Exception& )
135 : : {
136 : : OSL_FAIL( "EnumRepresentation::getDescriptions: caught an exception!" );
137 : : }
138 : :
139 : 0 : return ::std::vector< ::rtl::OUString >( aNames.getConstArray(), aNames.getConstArray() + aNames.getLength() );
140 : : }
141 : :
142 : : //--------------------------------------------------------------------
143 : 0 : void EnumRepresentation::impl_getValues( Sequence< sal_Int32 >& _out_rValues ) const
144 : : {
145 : 0 : _out_rValues.realloc( 0 );
146 : : try
147 : : {
148 : 0 : if ( m_xTypeDescription.is() )
149 : 0 : _out_rValues = m_xTypeDescription->getEnumValues();
150 : : }
151 : 0 : catch( const Exception& )
152 : : {
153 : : OSL_FAIL( "EnumRepresentation::impl_getValues: caught an exception!" );
154 : : }
155 : 0 : }
156 : :
157 : : //--------------------------------------------------------------------
158 : 0 : void EnumRepresentation::getValueFromDescription( const ::rtl::OUString& _rDescription, Any& _out_rValue ) const
159 : : {
160 : 0 : ::std::vector< ::rtl::OUString > aDescriptions( getDescriptions() );
161 : :
162 : : sal_Int32 index = ::std::find( aDescriptions.begin(), aDescriptions.end(),
163 : 0 : _rDescription ) - aDescriptions.begin();
164 : :
165 : 0 : Sequence< sal_Int32 > aValues;
166 : 0 : impl_getValues( aValues );
167 : :
168 : 0 : if ( ( index >= 0 ) && ( index < aValues.getLength() ) )
169 : 0 : _out_rValue = ::cppu::int2enum( aValues[ index ], m_aEnumType );
170 : : else
171 : : {
172 : : OSL_FAIL( "EnumRepresentation::getValueFromDescription: cannot convert!" );
173 : 0 : _out_rValue.clear();
174 : 0 : }
175 : 0 : }
176 : :
177 : : //--------------------------------------------------------------------
178 : 0 : ::rtl::OUString EnumRepresentation::getDescriptionForValue( const Any& _rEnumValue ) const
179 : : {
180 : 0 : ::rtl::OUString sDescription;
181 : :
182 : 0 : sal_Int32 nAsInt = 0;
183 : 0 : OSL_VERIFY( ::cppu::enum2int( nAsInt, _rEnumValue ) );
184 : :
185 : 0 : Sequence< sal_Int32 > aValues;
186 : 0 : impl_getValues( aValues );
187 : :
188 : 0 : sal_Int32 index = ::std::find( aValues.getConstArray(), aValues.getConstArray() + aValues.getLength(),
189 : 0 : nAsInt ) - aValues.getConstArray();
190 : :
191 : 0 : ::std::vector< ::rtl::OUString > aDescriptions( getDescriptions() );
192 : 0 : if ( ( index >= 0 ) && ( index < (sal_Int32)aDescriptions.size() ) )
193 : 0 : sDescription = aDescriptions[ index ];
194 : : else
195 : : {
196 : : OSL_FAIL( "EnumRepresentation::getDescriptionForValue: cannot convert!" );
197 : : }
198 : 0 : return sDescription;
199 : : }
200 : :
201 : : //--------------------------------------------------------------------
202 : 0 : oslInterlockedCount SAL_CALL EnumRepresentation::acquire()
203 : : {
204 : 0 : return osl_incrementInterlockedCount( &m_refCount );
205 : : }
206 : :
207 : : //--------------------------------------------------------------------
208 : 0 : oslInterlockedCount SAL_CALL EnumRepresentation::release()
209 : : {
210 : 0 : if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
211 : : {
212 : 0 : delete this;
213 : 0 : return 0;
214 : : }
215 : 0 : return m_refCount;
216 : : }
217 : :
218 : : //====================================================================
219 : : //= UrlClickHandler
220 : : //====================================================================
221 : : typedef ::cppu::WeakImplHelper1 < XActionListener
222 : : > UrlClickHandler_Base;
223 : : class UrlClickHandler : public UrlClickHandler_Base
224 : : {
225 : : ComponentContext m_aContext;
226 : : public:
227 : : UrlClickHandler( const ComponentContext& _rContext, const Reference< XHyperlinkControl >& _rxControl );
228 : :
229 : : protected:
230 : : ~UrlClickHandler();
231 : :
232 : : // XActionListener
233 : : virtual void SAL_CALL actionPerformed( const ActionEvent& rEvent ) throw (RuntimeException);
234 : :
235 : : // XEventListener
236 : : virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
237 : :
238 : : protected:
239 : : void impl_dispatch_throw( const ::rtl::OUString& _rURL );
240 : : };
241 : :
242 : : //--------------------------------------------------------------------
243 : : DBG_NAME( UrlClickHandler )
244 : : //--------------------------------------------------------------------
245 : 0 : UrlClickHandler::UrlClickHandler( const ComponentContext& _rContext, const Reference< XHyperlinkControl >& _rxControl )
246 : 0 : :m_aContext( _rContext )
247 : : {
248 : 0 : if ( !_rxControl.is() )
249 : 0 : throw NullPointerException();
250 : :
251 : 0 : osl_incrementInterlockedCount( &m_refCount );
252 : : {
253 : 0 : _rxControl->addActionListener( this );
254 : : }
255 : 0 : osl_decrementInterlockedCount( &m_refCount );
256 : : OSL_ENSURE( m_refCount > 0, "UrlClickHandler::UrlClickHandler: leaking!" );
257 : :
258 : : DBG_CTOR( UrlClickHandler, NULL );
259 : 0 : }
260 : :
261 : : //--------------------------------------------------------------------
262 : 0 : UrlClickHandler::~UrlClickHandler()
263 : : {
264 : : DBG_DTOR( UrlClickHandler, NULL );
265 : 0 : }
266 : :
267 : : //--------------------------------------------------------------------
268 : 0 : void SAL_CALL UrlClickHandler::actionPerformed( const ActionEvent& rEvent ) throw (RuntimeException)
269 : : {
270 : 0 : Reference< XPropertyControl > xControl( rEvent.Source, UNO_QUERY_THROW );
271 : 0 : Any aControlValue( xControl->getValue() );
272 : :
273 : 0 : ::rtl::OUString sURL;
274 : 0 : if ( aControlValue.hasValue() && !( aControlValue >>= sURL ) )
275 : 0 : throw RuntimeException( ::rtl::OUString(), *this );
276 : :
277 : 0 : if ( sURL.isEmpty() )
278 : 0 : return;
279 : :
280 : 0 : impl_dispatch_throw( sURL );
281 : : }
282 : :
283 : : //--------------------------------------------------------------------
284 : 0 : void SAL_CALL UrlClickHandler::disposing( const EventObject& /*Source*/ ) throw (RuntimeException)
285 : : {
286 : : // not interested in
287 : 0 : }
288 : :
289 : : //--------------------------------------------------------------------
290 : 0 : void UrlClickHandler::impl_dispatch_throw( const ::rtl::OUString& _rURL )
291 : : {
292 : 0 : Reference< XURLTransformer > xTransformer( URLTransformer::create(m_aContext.getUNOContext()) );
293 : 0 : URL aURL; aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:OpenHyperlink" ) );
294 : 0 : xTransformer->parseStrict( aURL );
295 : :
296 : 0 : Reference< XDispatchProvider > xDispProv( m_aContext.createComponent( "com.sun.star.frame.Desktop" ), UNO_QUERY_THROW );
297 : 0 : Reference< XDispatch > xDispatch( xDispProv->queryDispatch( aURL, ::rtl::OUString(), 0 ), UNO_QUERY_THROW );
298 : :
299 : 0 : Sequence< PropertyValue > aDispatchArgs(1);
300 : 0 : aDispatchArgs[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL"));
301 : 0 : aDispatchArgs[0].Value <<= _rURL;
302 : :
303 : 0 : xDispatch->dispatch( aURL, aDispatchArgs );
304 : 0 : }
305 : :
306 : : //====================================================================
307 : : //= GenericPropertyHandler
308 : : //====================================================================
309 : : DBG_NAME( GenericPropertyHandler )
310 : : //--------------------------------------------------------------------
311 : 0 : GenericPropertyHandler::GenericPropertyHandler( const Reference< XComponentContext >& _rxContext )
312 : : :GenericPropertyHandler_Base( m_aMutex )
313 : : ,m_aContext( _rxContext )
314 : : ,m_aPropertyListeners( m_aMutex )
315 : 0 : ,m_bPropertyMapInitialized( false )
316 : : {
317 : : DBG_CTOR( GenericPropertyHandler, NULL );
318 : :
319 : : m_xTypeConverter = Reference< XTypeConverter >(
320 : : m_aContext.createComponent( "com.sun.star.script.Converter" ),
321 : : UNO_QUERY_THROW
322 : 0 : );
323 : 0 : }
324 : :
325 : : //--------------------------------------------------------------------
326 : 0 : GenericPropertyHandler::~GenericPropertyHandler()
327 : : {
328 : : DBG_DTOR( GenericPropertyHandler, NULL );
329 : 0 : }
330 : :
331 : : //--------------------------------------------------------------------
332 : 0 : ::rtl::OUString SAL_CALL GenericPropertyHandler::getImplementationName( ) throw (RuntimeException)
333 : : {
334 : 0 : return getImplementationName_static();
335 : : }
336 : :
337 : : //--------------------------------------------------------------------
338 : 0 : ::sal_Bool SAL_CALL GenericPropertyHandler::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException)
339 : : {
340 : 0 : StlSyntaxSequence< ::rtl::OUString > aAllServices( getSupportedServiceNames() );
341 : 0 : return ::std::find( aAllServices.begin(), aAllServices.end(), ServiceName ) != aAllServices.end();
342 : : }
343 : :
344 : : //--------------------------------------------------------------------
345 : 0 : Sequence< ::rtl::OUString > SAL_CALL GenericPropertyHandler::getSupportedServiceNames( ) throw (RuntimeException)
346 : : {
347 : 0 : return getSupportedServiceNames_static();
348 : : }
349 : :
350 : : //--------------------------------------------------------------------
351 : 0 : ::rtl::OUString SAL_CALL GenericPropertyHandler::getImplementationName_static( ) throw (RuntimeException)
352 : : {
353 : 0 : return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.GenericPropertyHandler" ) );
354 : : }
355 : :
356 : : //--------------------------------------------------------------------
357 : 0 : Sequence< ::rtl::OUString > SAL_CALL GenericPropertyHandler::getSupportedServiceNames_static( ) throw (RuntimeException)
358 : : {
359 : 0 : Sequence< ::rtl::OUString > aSupported( 1 );
360 : 0 : aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.inspection.GenericPropertyHandler" ) );
361 : 0 : return aSupported;
362 : : }
363 : :
364 : : //--------------------------------------------------------------------
365 : 0 : Reference< XInterface > SAL_CALL GenericPropertyHandler::Create( const Reference< XComponentContext >& _rxContext )
366 : : {
367 : 0 : return *( new GenericPropertyHandler( _rxContext ) );
368 : : }
369 : :
370 : : //--------------------------------------------------------------------
371 : 0 : void SAL_CALL GenericPropertyHandler::inspect( const Reference< XInterface >& _rxIntrospectee ) throw (RuntimeException, NullPointerException)
372 : : {
373 : 0 : ::osl::MutexGuard aGuard( m_aMutex );
374 : :
375 : 0 : if ( !_rxIntrospectee.is() )
376 : 0 : throw NullPointerException();
377 : :
378 : : // revoke old property change listeners
379 : 0 : ::cppu::OInterfaceIteratorHelper iterRemove( m_aPropertyListeners );
380 : 0 : ::cppu::OInterfaceIteratorHelper iterReAdd( m_aPropertyListeners ); // this holds a copy of the container ...
381 : 0 : while ( iterRemove.hasMoreElements() )
382 : 0 : m_xComponent->removePropertyChangeListener( ::rtl::OUString(), static_cast< XPropertyChangeListener* >( iterRemove.next() ) );
383 : :
384 : 0 : m_xComponentIntrospectionAccess.clear();
385 : 0 : m_xComponent.clear();
386 : 0 : m_xPropertyState.clear();
387 : :
388 : : // create an introspection adapter for the component
389 : 0 : Reference< XIntrospection > xIntrospection;
390 : 0 : if ( !m_aContext.createComponent( "com.sun.star.beans.Introspection", xIntrospection ) )
391 : 0 : throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not create an instance of the service com.sun.star.beans.Introspection." ) ), *this );
392 : :
393 : 0 : Reference< XIntrospectionAccess > xIntrospectionAccess( xIntrospection->inspect( makeAny( _rxIntrospectee ) ) );
394 : 0 : if ( !xIntrospectionAccess.is() )
395 : 0 : throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The introspection service could not handle the given component." ) ), *this );
396 : :
397 : 0 : m_xComponent = Reference< XPropertySet >( xIntrospectionAccess->queryAdapter( XPropertySet::static_type() ), UNO_QUERY_THROW );
398 : : // now that we survived so far, remember m_xComponentIntrospectionAccess
399 : 0 : m_xComponentIntrospectionAccess = xIntrospectionAccess;
400 : 0 : m_xPropertyState = m_xPropertyState.query( m_xComponent );
401 : :
402 : 0 : m_bPropertyMapInitialized = false;
403 : 0 : m_aProperties.clear();
404 : :
405 : : // re-add the property change listeners
406 : 0 : while ( iterReAdd.hasMoreElements() )
407 : 0 : m_xComponent->addPropertyChangeListener( ::rtl::OUString(), static_cast< XPropertyChangeListener* >( iterReAdd.next() ) );
408 : 0 : }
409 : :
410 : : //--------------------------------------------------------------------
411 : 0 : Any SAL_CALL GenericPropertyHandler::getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
412 : : {
413 : 0 : ::osl::MutexGuard aGuard( m_aMutex );
414 : 0 : if ( !m_xComponent.is() )
415 : 0 : throw UnknownPropertyException();
416 : :
417 : 0 : return m_xComponent->getPropertyValue( _rPropertyName );
418 : : }
419 : :
420 : : //--------------------------------------------------------------------
421 : 0 : void SAL_CALL GenericPropertyHandler::setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException)
422 : : {
423 : 0 : ::osl::MutexGuard aGuard( m_aMutex );
424 : 0 : if ( !m_xComponent.is() )
425 : 0 : throw UnknownPropertyException();
426 : :
427 : 0 : m_xComponent->setPropertyValue( _rPropertyName, _rValue );
428 : 0 : }
429 : :
430 : : //--------------------------------------------------------------------
431 : 0 : ::rtl::Reference< IPropertyEnumRepresentation > GenericPropertyHandler::impl_getEnumConverter( const Type& _rEnumType )
432 : : {
433 : 0 : ::rtl::Reference< IPropertyEnumRepresentation >& rConverter = m_aEnumConverters[ _rEnumType ];
434 : 0 : if ( !rConverter.is() )
435 : 0 : rConverter = new EnumRepresentation( m_aContext.getUNOContext(), _rEnumType );
436 : 0 : return rConverter;
437 : : }
438 : :
439 : : //--------------------------------------------------------------------
440 : 0 : Any SAL_CALL GenericPropertyHandler::convertToPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rControlValue ) throw (UnknownPropertyException, RuntimeException)
441 : : {
442 : 0 : ::osl::MutexGuard aGuard( m_aMutex );
443 : 0 : const_cast< GenericPropertyHandler* >( this )->impl_ensurePropertyMap();
444 : :
445 : 0 : PropertyMap::const_iterator pos = m_aProperties.find( _rPropertyName );
446 : 0 : if ( pos == m_aProperties.end() )
447 : 0 : throw UnknownPropertyException();
448 : :
449 : 0 : Any aPropertyValue;
450 : 0 : if ( !_rControlValue.hasValue() )
451 : : // NULL is converted to NULL
452 : : return aPropertyValue;
453 : :
454 : 0 : if ( pos->second.Type.getTypeClass() == TypeClass_ENUM )
455 : : {
456 : 0 : ::rtl::OUString sControlValue;
457 : 0 : OSL_VERIFY( _rControlValue >>= sControlValue );
458 : 0 : impl_getEnumConverter( pos->second.Type )->getValueFromDescription( sControlValue, aPropertyValue );
459 : : }
460 : : else
461 : 0 : aPropertyValue = PropertyHandlerHelper::convertToPropertyValue( m_aContext.getContext(),m_xTypeConverter, pos->second, _rControlValue );
462 : :
463 : 0 : return aPropertyValue;
464 : : }
465 : :
466 : : //--------------------------------------------------------------------
467 : 0 : Any SAL_CALL GenericPropertyHandler::convertToControlValue( const ::rtl::OUString& _rPropertyName, const Any& _rPropertyValue, const Type& _rControlValueType ) throw (UnknownPropertyException, RuntimeException)
468 : : {
469 : 0 : ::osl::MutexGuard aGuard( m_aMutex );
470 : 0 : const_cast< GenericPropertyHandler* >( this )->impl_ensurePropertyMap();
471 : :
472 : 0 : PropertyMap::const_iterator pos = m_aProperties.find( _rPropertyName );
473 : 0 : if ( pos == m_aProperties.end() )
474 : 0 : throw UnknownPropertyException();
475 : :
476 : 0 : Any aControlValue;
477 : 0 : if ( !_rPropertyValue.hasValue() )
478 : : // NULL is converted to NULL
479 : : return aControlValue;
480 : :
481 : 0 : if ( pos->second.Type.getTypeClass() == TypeClass_ENUM )
482 : : {
483 : 0 : aControlValue <<= impl_getEnumConverter( pos->second.Type )->getDescriptionForValue( _rPropertyValue );
484 : : }
485 : : else
486 : 0 : aControlValue = PropertyHandlerHelper::convertToControlValue( m_aContext.getContext(),m_xTypeConverter, _rPropertyValue, _rControlValueType );
487 : 0 : return aControlValue;
488 : : }
489 : :
490 : : //--------------------------------------------------------------------
491 : 0 : PropertyState SAL_CALL GenericPropertyHandler::getPropertyState( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
492 : : {
493 : 0 : ::osl::MutexGuard aGuard( m_aMutex );
494 : 0 : PropertyState eState = PropertyState_DIRECT_VALUE;
495 : 0 : if ( m_xPropertyState.is() )
496 : 0 : eState = m_xPropertyState->getPropertyState( _rPropertyName );
497 : 0 : return eState;
498 : : }
499 : :
500 : : //--------------------------------------------------------------------
501 : 0 : void SAL_CALL GenericPropertyHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
502 : : {
503 : 0 : if ( !_rxListener.is() )
504 : 0 : throw NullPointerException();
505 : :
506 : 0 : ::osl::MutexGuard aGuard( m_aMutex );
507 : 0 : m_aPropertyListeners.addInterface( _rxListener );
508 : 0 : if ( m_xComponent.is() )
509 : : {
510 : : try
511 : : {
512 : 0 : m_xComponent->addPropertyChangeListener( ::rtl::OUString(), _rxListener );
513 : : }
514 : 0 : catch( const UnknownPropertyException& )
515 : : {
516 : : OSL_FAIL( "GenericPropertyHandler::addPropertyChangeListener:\nThe inspected component does not allow registering for all properties at once! This violates the interface contract!" );
517 : : }
518 : 0 : }
519 : 0 : }
520 : :
521 : : //--------------------------------------------------------------------
522 : 0 : void SAL_CALL GenericPropertyHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
523 : : {
524 : 0 : ::osl::MutexGuard aGuard( m_aMutex );
525 : 0 : if ( m_xComponent.is() )
526 : : {
527 : : try
528 : : {
529 : 0 : m_xComponent->removePropertyChangeListener( ::rtl::OUString(), _rxListener );
530 : : }
531 : 0 : catch( const UnknownPropertyException& )
532 : : {
533 : : OSL_FAIL( "GenericPropertyHandler::removePropertyChangeListener:\nThe inspected component does not allow de-registering for all properties at once! This violates the interface contract!" );
534 : : }
535 : : }
536 : 0 : m_aPropertyListeners.removeInterface( _rxListener );
537 : 0 : }
538 : :
539 : : //--------------------------------------------------------------------
540 : 0 : void GenericPropertyHandler::impl_ensurePropertyMap()
541 : : {
542 : 0 : if ( !m_bPropertyMapInitialized )
543 : : {
544 : 0 : m_bPropertyMapInitialized = true;
545 : : try
546 : : {
547 : 0 : Reference< XPropertySetInfo > xPSI;
548 : 0 : if ( m_xComponent.is() )
549 : 0 : xPSI = m_xComponent->getPropertySetInfo();
550 : 0 : Sequence< Property > aProperties;
551 : 0 : if ( xPSI.is() )
552 : 0 : aProperties = xPSI->getProperties();
553 : : DBG_ASSERT( aProperties.getLength(), "GenericPropertyHandler::getSupportedProperties: no properties!" );
554 : :
555 : 0 : for ( const Property* pProperties = aProperties.getConstArray();
556 : 0 : pProperties != aProperties.getConstArray() + aProperties.getLength();
557 : : ++pProperties
558 : : )
559 : : {
560 : 0 : switch ( pProperties->Type.getTypeClass() )
561 : : {
562 : : case TypeClass_BOOLEAN:
563 : : case TypeClass_BYTE:
564 : : case TypeClass_SHORT:
565 : : case TypeClass_UNSIGNED_SHORT:
566 : : case TypeClass_LONG:
567 : : case TypeClass_UNSIGNED_LONG:
568 : : case TypeClass_HYPER:
569 : : case TypeClass_UNSIGNED_HYPER:
570 : : case TypeClass_FLOAT:
571 : : case TypeClass_DOUBLE:
572 : : case TypeClass_ENUM:
573 : : case TypeClass_STRING:
574 : : // allowed, we can handle this type
575 : 0 : break;
576 : :
577 : : case TypeClass_SEQUENCE:
578 : : {
579 : 0 : TypeClass eElementTypeClass = ::comphelper::getSequenceElementType( pProperties->Type ).getTypeClass();
580 : 0 : if ( ( eElementTypeClass != TypeClass_STRING )
581 : : && ( eElementTypeClass != TypeClass_BYTE )
582 : : && ( eElementTypeClass != TypeClass_SHORT )
583 : : && ( eElementTypeClass != TypeClass_UNSIGNED_SHORT )
584 : : && ( eElementTypeClass != TypeClass_LONG )
585 : : && ( eElementTypeClass != TypeClass_UNSIGNED_LONG )
586 : : )
587 : : // can only handle the above
588 : 0 : continue;
589 : : }
590 : 0 : break;
591 : :
592 : : default:
593 : : // next property, we don't support this type
594 : 0 : continue;
595 : : }
596 : :
597 : 0 : m_aProperties.insert( PropertyMap::value_type( pProperties->Name, *pProperties ) );
598 : 0 : }
599 : : }
600 : 0 : catch( const Exception& )
601 : : {
602 : : OSL_FAIL( "GenericPropertyHandler::impl_ensurePropertyMap: caught an exception!" );
603 : : }
604 : : }
605 : 0 : }
606 : :
607 : : //--------------------------------------------------------------------
608 : 0 : Sequence< Property > SAL_CALL GenericPropertyHandler::getSupportedProperties() throw (RuntimeException)
609 : : {
610 : 0 : ::osl::MutexGuard aGuard( m_aMutex );
611 : 0 : const_cast< GenericPropertyHandler* >( this )->impl_ensurePropertyMap();
612 : :
613 : 0 : Sequence< Property > aReturn( m_aProperties.size() );
614 : : ::std::transform( m_aProperties.begin(), m_aProperties.end(),
615 : 0 : aReturn.getArray(), ::o3tl::select2nd< PropertyMap::value_type >() );
616 : 0 : return aReturn;
617 : : }
618 : :
619 : : //--------------------------------------------------------------------
620 : 0 : Sequence< ::rtl::OUString > SAL_CALL GenericPropertyHandler::getSupersededProperties( ) throw (RuntimeException)
621 : : {
622 : : // no superseded properties at all. This handler offers the very basic PropertyHandler
623 : : // functionality, so it's much more likely that other handlers want to supersede
624 : : // *our* properties ....
625 : 0 : return Sequence< ::rtl::OUString >( );
626 : : }
627 : :
628 : : //--------------------------------------------------------------------
629 : 0 : Sequence< ::rtl::OUString > SAL_CALL GenericPropertyHandler::getActuatingProperties( ) throw (RuntimeException)
630 : : {
631 : : // This basic PropertyHandler implementation is too dumb^Wgeneric to know
632 : : // anything about property dependencies
633 : 0 : return Sequence< ::rtl::OUString >( );
634 : : }
635 : :
636 : : //--------------------------------------------------------------------
637 : 0 : LineDescriptor SAL_CALL GenericPropertyHandler::describePropertyLine( const ::rtl::OUString& _rPropertyName,
638 : : const Reference< XPropertyControlFactory >& _rxControlFactory )
639 : : throw (UnknownPropertyException, NullPointerException, RuntimeException)
640 : : {
641 : 0 : if ( !_rxControlFactory.is() )
642 : 0 : throw NullPointerException();
643 : :
644 : 0 : ::osl::MutexGuard aGuard( m_aMutex );
645 : 0 : const_cast< GenericPropertyHandler* >( this )->impl_ensurePropertyMap();
646 : :
647 : 0 : PropertyMap::const_iterator pos = m_aProperties.find( _rPropertyName );
648 : 0 : if ( pos == m_aProperties.end() )
649 : 0 : throw UnknownPropertyException();
650 : :
651 : 0 : LineDescriptor aDescriptor;
652 : 0 : aDescriptor.DisplayName = _rPropertyName;
653 : 0 : switch ( pos->second.Type.getTypeClass() )
654 : : {
655 : : case TypeClass_ENUM:
656 : : aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory,
657 : 0 : impl_getEnumConverter( pos->second.Type )->getDescriptions(),
658 : 0 : PropertyHandlerHelper::requiresReadOnlyControl( pos->second.Attributes ),
659 : 0 : sal_False );
660 : 0 : break;
661 : : case TypeClass_STRING:
662 : : {
663 : : // some special handling for URL properties
664 : 0 : bool bIsURLProperty = ( _rPropertyName.getLength() >= 3 ) && _rPropertyName.matchAsciiL( "URL", 3, _rPropertyName.getLength() - 3 );
665 : 0 : if ( bIsURLProperty )
666 : : {
667 : 0 : aDescriptor.Control = _rxControlFactory->createPropertyControl(
668 : 0 : PropertyControlType::HyperlinkField, PropertyHandlerHelper::requiresReadOnlyControl( pos->second.Attributes ) );
669 : :
670 : 0 : Reference< XHyperlinkControl > xControl( aDescriptor.Control, UNO_QUERY_THROW );
671 : 0 : Reference< XActionListener > xEnsureDelete( new UrlClickHandler( m_aContext, xControl ) );
672 : : }
673 : : }
674 : 0 : break;
675 : : default:
676 : 0 : break;
677 : : }
678 : : // fallback
679 : 0 : if ( !aDescriptor.Control.is() )
680 : 0 : PropertyHandlerHelper::describePropertyLine( pos->second, aDescriptor, _rxControlFactory );
681 : :
682 : 0 : aDescriptor.Category = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "General" ) );
683 : 0 : return aDescriptor;
684 : : }
685 : :
686 : : //--------------------------------------------------------------------
687 : 0 : ::sal_Bool SAL_CALL GenericPropertyHandler::isComposable( const ::rtl::OUString& /*_rPropertyName*/ ) throw (UnknownPropertyException, RuntimeException)
688 : : {
689 : 0 : return sal_False;
690 : : }
691 : :
692 : : //--------------------------------------------------------------------
693 : 0 : InteractiveSelectionResult SAL_CALL GenericPropertyHandler::onInteractivePropertySelection( const ::rtl::OUString& /*_rPropertyName*/, sal_Bool /*_bPrimary*/, Any& /*_rData*/, const Reference< XObjectInspectorUI >& /*_rxInspectorUI*/ ) throw (UnknownPropertyException, NullPointerException, RuntimeException)
694 : : {
695 : : OSL_FAIL( "GenericPropertyHandler::onInteractivePropertySelection: I'm too dumb to know anything about property browse buttons!" );
696 : 0 : return InteractiveSelectionResult_Cancelled;
697 : : }
698 : :
699 : : //--------------------------------------------------------------------
700 : 0 : void SAL_CALL GenericPropertyHandler::actuatingPropertyChanged( const ::rtl::OUString& /*_rActuatingPropertyName*/, const Any& /*_rNewValue*/, const Any& /*_rOldValue*/, const Reference< XObjectInspectorUI >& /*_rxInspectorUI*/, sal_Bool /*_bFirstTimeInit*/ ) throw (NullPointerException, RuntimeException)
701 : : {
702 : : OSL_FAIL( "GenericPropertyHandler::actuatingPropertyChanged: no no no, I did not register for any actuating properties!" );
703 : 0 : }
704 : :
705 : : //--------------------------------------------------------------------
706 : 0 : sal_Bool SAL_CALL GenericPropertyHandler::suspend( sal_Bool /*_bSuspend*/ ) throw (RuntimeException)
707 : : {
708 : 0 : return sal_True;
709 : : }
710 : :
711 : : //--------------------------------------------------------------------
712 : 0 : void SAL_CALL GenericPropertyHandler::disposing()
713 : : {
714 : 0 : m_aPropertyListeners.clear();
715 : : // not disposeAndClear: the listeners are (virtually) listeners at our introspectee, not
716 : : // at this handler instance
717 : 0 : }
718 : :
719 : : //--------------------------------------------------------------------
720 : 0 : IMPLEMENT_FORWARD_XCOMPONENT( GenericPropertyHandler, GenericPropertyHandler_Base );
721 : :
722 : : //........................................................................
723 : : } // namespace pcr
724 : : //........................................................................
725 : :
726 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|