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