1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef EXTENSIONS_SOURCE_PROPCTRLR_PROPERTYHANDLER_HXX
29 #define EXTENSIONS_SOURCE_PROPCTRLR_PROPERTYHANDLER_HXX
30 
31 #include "pcrcomponentcontext.hxx"
32 #include "pcrcommon.hxx"
33 #ifndef _EXTENSIONS_PROPCTRLR_MODULEPCR_HXX_
34 #include "modulepcr.hxx"
35 #endif
36 
37 /** === begin UNO includes === **/
38 #include <com/sun/star/uno/XComponentContext.hpp>
39 #include <com/sun/star/beans/PropertyState.hpp>
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include <com/sun/star/beans/Property.hpp>
42 #include <com/sun/star/script/XTypeConverter.hpp>
43 #include <com/sun/star/frame/XModel.hpp>
44 #include <com/sun/star/uno/Sequence.hxx>
45 #include <com/sun/star/uno/Any.hxx>
46 #include <com/sun/star/util/Date.hpp>
47 #include <com/sun/star/util/Time.hpp>
48 #include <com/sun/star/util/DateTime.hpp>
49 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
50 #include <com/sun/star/inspection/XPropertyHandler.hpp>
51 #include <com/sun/star/lang/XServiceInfo.hpp>
52 /** === end UNO includes === **/
53 #include <osl/interlck.h>
54 #include <cppuhelper/compbase1.hxx>
55 #include <cppuhelper/implbase1.hxx>
56 #include <comphelper/uno3.hxx>
57 
58 #include <memory>
59 #include <vector>
60 
61 namespace com { namespace sun { namespace star {
62     namespace inspection {
63         struct LineDescriptor;
64         class XPropertyControlFactory;
65     }
66 } } }
67 
68 class Window;
69 //........................................................................
70 namespace pcr
71 {
72 //........................................................................
73 
74     typedef sal_Int32   PropertyId;
75 
76 	//====================================================================
77 	//= PropertyHandler
78 	//====================================================================
79     class OPropertyInfoService;
80     typedef ::cppu::WeakComponentImplHelper1    <   ::com::sun::star::inspection::XPropertyHandler
81                                                 >   PropertyHandler_Base;
82     /** the base class for property handlers
83     */
84     class PropertyHandler : public PropertyHandler_Base
85     {
86     private:
87         /// cache for getSupportedProperties
88         mutable StlSyntaxSequence< ::com::sun::star::beans::Property >
89                                     m_aSupportedProperties;
90         mutable bool                m_bSupportedPropertiesAreKnown;
91 
92         /// helper which ensures that we can access resources as long as the instance lives
93         PcrClient       m_aEnsureResAccess;
94 
95     private:
96         /// the property listener which has been registered
97         PropertyChangeListeners                                                         m_aPropertyListeners;
98 
99     protected:
100 		mutable ::osl::Mutex                                                            m_aMutex;
101         /// the context in which the instance was created
102         ComponentContext                                                                m_aContext;
103         /// the component we're inspecting
104         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >       m_xComponent;
105         /// info about our component's properties
106         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >   m_xComponentPropertyInfo;
107         /// type converter, needed on various occasions
108         ::com::sun::star::uno::Reference< ::com::sun::star::script::XTypeConverter >    m_xTypeConverter;
109         /// access to property meta data
110         ::std::auto_ptr< OPropertyInfoService >                                         m_pInfoService;
111 
112     protected:
113         PropertyHandler(
114             const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext
115         );
116         ~PropertyHandler();
117 
118         // default implementations for XPropertyHandler
119         virtual void SAL_CALL inspect( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxIntrospectee ) throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::NullPointerException);
120         virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL getSupportedProperties() throw (::com::sun::star::uno::RuntimeException);
121         virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupersededProperties( ) throw (::com::sun::star::uno::RuntimeException);
122         virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getActuatingProperties( ) throw (::com::sun::star::uno::RuntimeException);
123         virtual ::com::sun::star::uno::Any SAL_CALL convertToPropertyValue( const ::rtl::OUString& _rPropertyName, const ::com::sun::star::uno::Any& _rControlValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
124         virtual ::com::sun::star::uno::Any SAL_CALL convertToControlValue( const ::rtl::OUString& _rPropertyName, const ::com::sun::star::uno::Any& _rPropertyValue, const ::com::sun::star::uno::Type& _rControlValueType ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
125         virtual ::com::sun::star::beans::PropertyState  SAL_CALL getPropertyState( const ::rtl::OUString& _rPropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
126         virtual ::com::sun::star::inspection::LineDescriptor SAL_CALL describePropertyLine( const ::rtl::OUString& _rPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyControlFactory >& _rxControlFactory ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException);
127         virtual ::sal_Bool SAL_CALL isComposable( const ::rtl::OUString& _rPropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
128         virtual ::com::sun::star::inspection::InteractiveSelectionResult SAL_CALL onInteractivePropertySelection( const ::rtl::OUString& _rPropertyName, sal_Bool _bPrimary, ::com::sun::star::uno::Any& _rData, const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XObjectInspectorUI >& _rxInspectorUI ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException);
129         virtual void SAL_CALL actuatingPropertyChanged( const ::rtl::OUString& _rActuatingPropertyName, const ::com::sun::star::uno::Any& _rNewValue, const ::com::sun::star::uno::Any& _rOldValue, const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XObjectInspectorUI >& _rxInspectorUI, sal_Bool _bFirstTimeInit ) throw (::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException);
130         virtual void SAL_CALL addPropertyChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& _rxListener ) throw (::com::sun::star::uno::RuntimeException);
131         virtual void SAL_CALL removePropertyChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& _rxListener ) throw (::com::sun::star::uno::RuntimeException);
132         virtual sal_Bool SAL_CALL suspend( sal_Bool _bSuspend ) throw (::com::sun::star::uno::RuntimeException);
133 
134         // XComponent
135         DECLARE_XCOMPONENT()
136         virtual void SAL_CALL disposing();
137 
138         // own overridables
139         virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >
140                     SAL_CALL doDescribeSupportedProperties() const = 0;
141 
142         /// called when XPropertyHandler::inspect has been called, and we thus have a new component to inspect
143         virtual void onNewComponent();
144 
145     protected:
146         /** fires the change in a property value to our listener (if any)
147             @see addPropertyChangeListener
148         */
149         void    firePropertyChange( const ::rtl::OUString& _rPropName, PropertyId _nPropId,
150                     const ::com::sun::star::uno::Any& _rOldValue, const ::com::sun::star::uno::Any& _rNewValue ) SAL_THROW(());
151 
152         /** retrieves a window which can be used as parent for dialogs
153         */
154         Window* impl_getDefaultDialogParent_nothrow() const;
155 
156         /** retrieves the property id for a given property name
157             @throw com::sun::star::beans::UnknownPropertyException
158                 if the property name is not known to our ->m_pInfoService
159         */
160         PropertyId impl_getPropertyId_throw( const ::rtl::OUString& _rPropertyName ) const;
161 
162         //-------------------------------------------------------------------------------
163         // helper for implementing doDescribeSupportedProperties
164         /** adds a description for the given string property to the given property vector
165             Most probably to be called from within getSupportedProperties
166         */
167         inline void addStringPropertyDescription(
168                     ::std::vector< ::com::sun::star::beans::Property >& _rProperties,
169                     const ::rtl::OUString& _rPropertyName,
170                     sal_Int16 _nAttribs = 0
171                 ) const;
172 
173         /** adds a description for the given int32 property to the given property vector
174         */
175         inline void addInt32PropertyDescription(
176                     ::std::vector< ::com::sun::star::beans::Property >& _rProperties,
177                     const ::rtl::OUString& _rPropertyName,
178                     sal_Int16 _nAttribs = 0
179                 ) const;
180 
181         /** adds a description for the given int16 property to the given property vector
182         */
183         inline void addInt16PropertyDescription(
184                     ::std::vector< ::com::sun::star::beans::Property >& _rProperties,
185                     const ::rtl::OUString& _rPropertyName,
186                     sal_Int16 _nAttribs = 0
187                 ) const;
188 
189         /** adds a description for the given double property to the given property vector
190         */
191         inline void addDoublePropertyDescription(
192                     ::std::vector< ::com::sun::star::beans::Property >& _rProperties,
193                     const ::rtl::OUString& _rPropertyName,
194                     sal_Int16 _nAttribs = 0
195                 ) const;
196 
197         /** adds a description for the given date property to the given property vector
198         */
199         inline void addDatePropertyDescription(
200                     ::std::vector< ::com::sun::star::beans::Property >& _rProperties,
201                     const ::rtl::OUString& _rPropertyName,
202                     sal_Int16 _nAttribs = 0
203                 ) const;
204 
205         /** adds a description for the given time property to the given property vector
206         */
207         inline void addTimePropertyDescription(
208                     ::std::vector< ::com::sun::star::beans::Property >& _rProperties,
209                     const ::rtl::OUString& _rPropertyName,
210                     sal_Int16 _nAttribs = 0
211                 ) const;
212 
213         /** adds a description for the given DateTime property to the given property vector
214         */
215         inline void addDateTimePropertyDescription(
216                     ::std::vector< ::com::sun::star::beans::Property >& _rProperties,
217                     const ::rtl::OUString& _rPropertyName,
218                     sal_Int16 _nAttribs = 0
219                 ) const;
220 
221         /// adds a Property, given by name only, to a given vector of Properties
222         void implAddPropertyDescription(
223                     ::std::vector< ::com::sun::star::beans::Property >& _rProperties,
224                     const ::rtl::OUString& _rPropertyName,
225                     const ::com::sun::star::uno::Type& _rType,
226                     sal_Int16 _nAttribs = 0
227                 ) const;
228 
229         //-------------------------------------------------------------------------------
230         // helper for accessing and maintaining meta data about our supported properties
231 
232         /** retrieves a property given by handle
233 
234             @return
235                 a pointer to the descriptor for the given properties, if it is one of our
236                 supported properties, <NULL/> else.
237 
238             @see doDescribeSupportedProperties
239             @see impl_getPropertyFromId_throw
240         */
241         const ::com::sun::star::beans::Property*
242                     impl_getPropertyFromId_nothrow( PropertyId _nPropId ) const;
243 
244         /** retrieves a property given by handle
245 
246             @throws UnknownPropertyException
247                 if the handler does not support a property with the given handle
248 
249             @seealso doDescribeSupportedProperties
250             @see impl_getPropertyFromId_nothrow
251         */
252         const ::com::sun::star::beans::Property&
253                     impl_getPropertyFromId_throw( PropertyId _nPropId ) const;
254 
255         /** determines whether a given property id is part of our supported properties
256             @see getSupportedProperties
257             @see doDescribeSupportedProperties
258         */
259         inline bool impl_isSupportedProperty_nothrow( PropertyId _nPropId ) const
260         {
261             return impl_getPropertyFromId_nothrow( _nPropId ) != NULL;
262         }
263 
264         /** retrieves a property given by name
265 
266             @throws UnknownPropertyException
267                 if the handler does not support a property with the given name
268 
269             @seealso doDescribeSupportedProperties
270         */
271         const ::com::sun::star::beans::Property&
272                     impl_getPropertyFromName_throw( const ::rtl::OUString& _rPropertyName ) const;
273 
274         /** get the name of a property given by handle
275         */
276         inline ::rtl::OUString
277                     impl_getPropertyNameFromId_nothrow( PropertyId _nPropId ) const;
278 
279         /** returns the value of the ContextDocument property in the ComponentContext which was used to create
280             this handler.
281         */
282         inline ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >
283                     impl_getContextDocument_nothrow() const
284         {
285             return ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >(
286                 m_aContext.getContextValueByAsciiName( "ContextDocument" ), ::com::sun::star::uno::UNO_QUERY );
287         }
288 
289         /** marks the context document as modified
290 
291             @see impl_getContextDocument_nothrow
292         */
293         void impl_setContextDocumentModified_nothrow() const;
294 
295         /// determines whether our component has a given property
296         bool impl_componentHasProperty_throw( const ::rtl::OUString& _rPropName ) const;
297 
298         /** determines the default measure unit for the document in which our component lives
299         */
300         sal_Int16 impl_getDocumentMeasurementUnit_throw() const;
301 
302     private:
303         PropertyHandler();                                    // never implemented
304         PropertyHandler( const PropertyHandler& );            // never implemented
305         PropertyHandler& operator=( const PropertyHandler& ); // never implemented
306     };
307 
308     //--------------------------------------------------------------------
309     inline void PropertyHandler::addStringPropertyDescription( ::std::vector< ::com::sun::star::beans::Property >& _rProperties, const ::rtl::OUString& _rPropertyName, sal_Int16 _nAttribs ) const
310     {
311         implAddPropertyDescription( _rProperties, _rPropertyName, ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) ), _nAttribs );
312     }
313 
314     inline void PropertyHandler::addInt32PropertyDescription( ::std::vector< ::com::sun::star::beans::Property >& _rProperties, const ::rtl::OUString& _rPropertyName, sal_Int16 _nAttribs ) const
315     {
316         implAddPropertyDescription( _rProperties, _rPropertyName, ::getCppuType( static_cast< sal_Int32* >( NULL ) ), _nAttribs );
317     }
318 
319     inline void PropertyHandler::addInt16PropertyDescription( ::std::vector< ::com::sun::star::beans::Property >& _rProperties, const ::rtl::OUString& _rPropertyName, sal_Int16 _nAttribs ) const
320     {
321         implAddPropertyDescription( _rProperties, _rPropertyName, ::getCppuType( static_cast< sal_Int16* >( NULL ) ), _nAttribs );
322     }
323 
324     inline void PropertyHandler::addDoublePropertyDescription( ::std::vector< ::com::sun::star::beans::Property >& _rProperties, const ::rtl::OUString& _rPropertyName, sal_Int16 _nAttribs ) const
325     {
326         implAddPropertyDescription( _rProperties, _rPropertyName, ::getCppuType( static_cast< double* >( NULL ) ), _nAttribs );
327     }
328 
329     inline void PropertyHandler::addDatePropertyDescription( ::std::vector< ::com::sun::star::beans::Property >& _rProperties, const ::rtl::OUString& _rPropertyName, sal_Int16 _nAttribs ) const
330     {
331         implAddPropertyDescription( _rProperties, _rPropertyName, ::getCppuType( static_cast< com::sun::star::util::Date* >( NULL ) ), _nAttribs );
332     }
333 
334     inline void PropertyHandler::addTimePropertyDescription( ::std::vector< ::com::sun::star::beans::Property >& _rProperties, const ::rtl::OUString& _rPropertyName, sal_Int16 _nAttribs ) const
335     {
336         implAddPropertyDescription( _rProperties, _rPropertyName, ::getCppuType( static_cast< com::sun::star::util::Time* >( NULL ) ), _nAttribs );
337     }
338 
339     inline void PropertyHandler::addDateTimePropertyDescription( ::std::vector< ::com::sun::star::beans::Property >& _rProperties, const ::rtl::OUString& _rPropertyName, sal_Int16 _nAttribs ) const
340     {
341         implAddPropertyDescription( _rProperties, _rPropertyName, ::getCppuType( static_cast< com::sun::star::util::DateTime* >( NULL ) ), _nAttribs );
342     }
343 
344     inline ::rtl::OUString PropertyHandler::impl_getPropertyNameFromId_nothrow( PropertyId _nPropId ) const
345     {
346         const ::com::sun::star::beans::Property* pProp = impl_getPropertyFromId_nothrow( _nPropId );
347         return pProp ? pProp->Name : ::rtl::OUString();
348     }
349 
350     //====================================================================
351 	//= PropertyHandlerComponent
352 	//====================================================================
353     typedef ::cppu::ImplHelper1 <   ::com::sun::star::lang::XServiceInfo
354                                 >   PropertyHandlerComponent_Base;
355     /** PropertyHandler implementation which additionally supports XServiceInfo
356     */
357     class PropertyHandlerComponent  :public PropertyHandler
358                                     ,public PropertyHandlerComponent_Base
359     {
360     protected:
361         PropertyHandlerComponent(
362             const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext
363         );
364 
365         DECLARE_XINTERFACE()
366         DECLARE_XTYPEPROVIDER()
367 
368         // XServiceInfo
369         virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
370         virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
371         virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
372     };
373 
374     //====================================================================
375 	//= HandlerComponentBase
376 	//====================================================================
377     /** a PropertyHandlerComponent implementation which routes XServiceInfo::getImplementationName and
378         XServiceInfo::getSupportedServiceNames to static versions of those methods, which are part of
379         the derived class.
380 
381         Additionally, a method <member>Create</member> is provided which takes a component context, and returns a new
382         instance of the derived class. This <member>Create</member> is used to register the implementation
383         of the derived class at the <type>PcrModule</type>.
384 
385         Well, every time we're talking about derived class, we in fact mean the template argument of
386         <type>HandlerComponentBase</type>. But usually this equals your derived class:
387         <pre>
388         class MyHandler;
389         typedef HandlerComponentBase< MyHandler > MyHandler_Base;
390         class MyHandler : MyHandler_Base
391         {
392             ...
393         public:
394             static ::rtl::OUString SAL_CALL getImplementationName_static(  ) throw (::com::sun::star::uno::RuntimeException);
395             static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(  ) throw (::com::sun::star::uno::RuntimeException);
396         };
397         </pre>
398     */
399     template < class HANDLER >
400     class HandlerComponentBase : public PropertyHandlerComponent
401     {
402     protected:
403         HandlerComponentBase( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext )
404             :PropertyHandlerComponent( _rxContext )
405         {
406         }
407 
408     protected:
409         // XServiceInfo
410         virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw (::com::sun::star::uno::RuntimeException);
411         virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw (::com::sun::star::uno::RuntimeException);
412         static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL Create( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext );
413 
414     public:
415         /** registers the implementation of HANDLER at the <type>PcrModule</type>
416         */
417         static void registerImplementation();
418     };
419 
420 	//--------------------------------------------------------------------
421     template < class HANDLER >
422     ::rtl::OUString SAL_CALL HandlerComponentBase< HANDLER >::getImplementationName(  ) throw (::com::sun::star::uno::RuntimeException)
423     {
424         return HANDLER::getImplementationName_static();
425     }
426 
427 	//--------------------------------------------------------------------
428     template < class HANDLER >
429     ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL HandlerComponentBase< HANDLER >::getSupportedServiceNames(  ) throw (::com::sun::star::uno::RuntimeException)
430     {
431         return HANDLER::getSupportedServiceNames_static();
432     }
433 
434 	//--------------------------------------------------------------------
435     template < class HANDLER >
436     void HandlerComponentBase< HANDLER >::registerImplementation()
437     {
438         PcrModule::getInstance().registerImplementation(
439             HANDLER::getImplementationName_static(),
440             HANDLER::getSupportedServiceNames_static(),
441             HANDLER::Create
442         );
443     }
444 
445 	//--------------------------------------------------------------------
446     template < class HANDLER >
447     ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL HandlerComponentBase< HANDLER >::Create( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext )
448     {
449         return *( new HANDLER( _rxContext ) );
450     }
451 
452 //........................................................................
453 } // namespace pcr
454 //........................................................................
455 
456 #endif // EXTENSIONS_SOURCE_PROPCTRLR_PROPERTYHANDLER_HXX
457 
458