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_EFORMSHELPER_HXX
29 #define EXTENSIONS_SOURCE_PROPCTRLR_EFORMSHELPER_HXX
30 
31 #include "pcrcommon.hxx"
32 
33 /** === begin UNO includes === **/
34 #include <com/sun/star/frame/XModel.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/xforms/XModel.hpp>
37 #include <com/sun/star/xforms/XFormsSupplier.hpp>
38 #include <com/sun/star/form/binding/XBindableValue.hpp>
39 #include <com/sun/star/form/binding/XListEntrySource.hpp>
40 /** === end UNO includes === **/
41 #include <osl/mutex.hxx>
42 #include <tools/string.hxx>
43 #include <comphelper/listenernotification.hxx>
44 
45 #include <vector>
46 #include <set>
47 #include <map>
48 
49 //........................................................................
50 namespace pcr
51 {
52 //........................................................................
53 
54     typedef ::std::map< ::rtl::OUString, ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >, ::std::less< ::rtl::OUString > >
55             MapStringToPropertySet;
56 
57 	//====================================================================
58 	//= EFormsHelper
59 	//====================================================================
60 	class EFormsHelper
61 	{
62     protected:
63         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
64                         m_xControlModel;
65         ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XBindableValue >
66                         m_xBindableControl;
67         ::com::sun::star::uno::Reference< ::com::sun::star::xforms::XFormsSupplier >
68                         m_xDocument;
69         PropertyChangeListeners
70                         m_aPropertyListeners;
71         MapStringToPropertySet
72                         m_aSubmissionUINames;   // only filled upon request
73         MapStringToPropertySet
74                         m_aBindingUINames;      // only filled upon request
75 
76     public:
77         EFormsHelper(
78             ::osl::Mutex& _rMutex,
79             const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxControlModel,
80             const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& _rxContextDocument
81         );
82 
83         /** determines whether the given document is an eForm
84 
85             If this method returns <FALSE/>, you cannot instantiate a EFormsHelper with
86             this document, since then no of it's functionality will be available.
87         */
88         static  bool
89                 isEForm(
90                     const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& _rxContextDocument
91                 ) SAL_THROW(());
92 
93         /** registers a listener to be notified when any aspect of the binding changes.
94 
95             The listener will be registered at the current binding of the control model. If the binding
96             changes (see <method>setBinding</method>), the listener will be revoked from the old binding,
97             registered at the new binding, and for all properties which differ between both bindings,
98             the listener will be notified.
99             @see revokeBindingListener
100         */
101         void    registerBindingListener(
102                     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& _rxBindingListener
103                 );
104 
105         /** revokes the binding listener which has previously been registered
106             @see registerBindingListener
107         */
108         void    revokeBindingListener(
109                     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& _rxBindingListener
110                 );
111 
112         /** checks whether it's possible to bind the control model to a given XSD data type
113 
114             @param _nDataType
115                 the data type which should be bound. If this is -1, <TRUE/> is returned if the control model
116                 can be bound to <em>any</em> data type.
117         */
118         bool    canBindToDataType( sal_Int32 _nDataType = -1 ) const SAL_THROW(());
119 
120         /** checks whether the control model cna be bound to any XSD data type
121         */
122         bool    canBindToAnyDataType() const SAL_THROW(()) { return canBindToDataType( -1 ); }
123 
124         /** checks whether the control model is a source for list entries, as supplied by XML data bindings
125         */
126         bool    isListEntrySink() const SAL_THROW(());
127 
128         /** retrieves the names of all XForms models in the document the control lives in
129         */
130         void    getFormModelNames( ::std::vector< ::rtl::OUString >& /* [out] */ _rModelNames ) const SAL_THROW(());
131 
132         /** retrieves the names of all bindings for a given model
133             @see getFormModelNames
134         */
135         void    getBindingNames( const ::rtl::OUString& _rModelName, ::std::vector< ::rtl::OUString >& /* [out] */ _rBindingNames ) const SAL_THROW(());
136 
137         /// retrieves the XForms model (within the control model's document) with the given name
138         ::com::sun::star::uno::Reference< ::com::sun::star::xforms::XModel >
139                 getFormModelByName( const ::rtl::OUString& _rModelName ) const SAL_THROW(());
140 
141         /** retrieves the model which the active binding of the control model belongs to
142         */
143         ::com::sun::star::uno::Reference< ::com::sun::star::xforms::XModel >
144                 getCurrentFormModel() const SAL_THROW(());
145 
146         /** retrieves the name of the model which the active binding of the control model belongs to
147         */
148         ::rtl::OUString
149                 getCurrentFormModelName() const SAL_THROW(());
150 
151         /** retrieves the binding instance which is currently attached to the control model
152         */
153         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
154                 getCurrentBinding() const SAL_THROW(());
155 
156         /** retrieves the name of the binding instance which is currently attached to the control model
157         */
158         ::rtl::OUString
159                 getCurrentBindingName() const SAL_THROW(());
160 
161         /** sets a new binding at the control model
162         */
163         void    setBinding( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxBinding ) SAL_THROW(());
164 
165         /** retrieves the binding instance which is currently used as list source for the control model
166             @see isListEntrySink
167         */
168         ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XListEntrySource >
169                 getCurrentListSourceBinding() const SAL_THROW(());
170 
171         /** sets a new list source at the control model
172             @see isListEntrySink
173         */
174         void    setListSourceBinding( const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XListEntrySource >& _rxListSource ) SAL_THROW(());
175 
176         /** retrieves a given binding for a given model, or creates a new one
177 
178             @param _rTargetModel
179                 the name of the model to create a binding for. Must not be empty
180             @param _rBindingName
181                 the name of the binding to retrieve. If the model denoted by <arg>_rTargetModel</arg> does not
182                 have a binding with this name, a new binding is created and returned.
183         */
184         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
185             getOrCreateBindingForModel( const ::rtl::OUString& _rTargetModel, const ::rtl::OUString& _rBindingName ) const SAL_THROW(());
186 
187         /** types of sub-elements of a model
188         */
189         enum ModelElementType
190         {
191             Submission,
192             Binding
193         };
194 
195         /** retrieves the name of a model's sub-element, as to be shown in the UI
196             @see getModelElementFromUIName
197             @see getAllElementUINames
198         */
199         ::rtl::OUString
200                 getModelElementUIName(
201                     const ModelElementType _eType,
202                     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxElement
203                 ) const SAL_THROW(());
204 
205         /** retrieves the submission object for an UI name
206 
207             Note that <member>getAllElementUINames</member> must have been called before, for the given element type
208 
209             @see getModelElementUIName
210             @see getAllElementUINames
211         */
212         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
213                 getModelElementFromUIName(
214                     const ModelElementType _eType,
215                     const ::rtl::OUString& _rUIName
216                 ) const SAL_THROW(());
217 
218         /** retrieves the UI names of all elements of all models in our document
219             @param _eType
220                 the type of elements for which the names should be retrieved
221             @param _rElementNames
222                 the array of element names
223             @see getModelElementUIName
224             @see getModelElementFromUIName
225         */
226         void    getAllElementUINames(
227                     const ModelElementType _eType,
228                     ::std::vector< ::rtl::OUString >& /* [out] */ _rElementNames,
229                     bool _bPrepentEmptyEntry
230                 );
231 
232     protected:
233         void    firePropertyChanges(
234                     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxOldProps,
235                     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxNewProps,
236                     ::std::set< ::rtl::OUString >& _rFilter
237                 ) const;
238 
239         /** fires a change in a single property, if the property value changed, and if we have a listener
240             interested in property changes
241         */
242         void    firePropertyChange(
243                     const ::rtl::OUString& _rName,
244                     const ::com::sun::star::uno::Any& _rOldValue,
245                     const ::com::sun::star::uno::Any& _rNewValue
246                 ) const;
247 
248     private:
249         void impl_switchBindingListening_throw( bool _bDoListening, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& _rxListener );
250 
251         /// implementation for both <member>getOrCreateBindingForModel</member>
252         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
253             implGetOrCreateBinding( const ::rtl::OUString& _rTargetModel, const ::rtl::OUString& _rBindingName ) const SAL_THROW(());
254 
255         void
256             impl_toggleBindingPropertyListening_throw( bool _bDoListen, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& _rxConcreteListenerOrNull );
257 
258     private:
259         EFormsHelper();                                 // never implemented
260         EFormsHelper( const EFormsHelper& );            // never implemented
261         EFormsHelper& operator=( const EFormsHelper& ); // never implemented
262 	};
263 
264 //........................................................................
265 } // namespace pcr
266 //........................................................................
267 
268 #endif // EXTENSIONS_SOURCE_PROPCTRLR_EFORMSHELPER_HXX
269 
270