1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef FORMS_FORMOPERATIONS_HXX
25 #define FORMS_FORMOPERATIONS_HXX
26 
27 /** === begin UNO includes === **/
28 #include <com/sun/star/form/runtime/XFormOperations.hpp>
29 #include <com/sun/star/lang/XServiceInfo.hpp>
30 #include <com/sun/star/form/XForm.hpp>
31 #include <com/sun/star/beans/XPropertySet.hpp>
32 #include <com/sun/star/form/XLoadable.hpp>
33 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
34 #include <com/sun/star/util/XModifyListener.hpp>
35 #include <com/sun/star/container/XIndexAccess.hpp>
36 #include <com/sun/star/lang/XInitialization.hpp>
37 /** === end UNO includes === **/
38 
39 #include <comphelper/componentcontext.hxx>
40 
41 #include <cppuhelper/basemutex.hxx>
42 #include <cppuhelper/compbase6.hxx>
43 
44 //........................................................................
45 namespace frm
46 {
47 //........................................................................
48 
49 	//====================================================================
50 	//= FormOperations
51 	//====================================================================
52     typedef ::cppu::WeakComponentImplHelper6    <   ::com::sun::star::form::runtime::XFormOperations
53                                                 ,   ::com::sun::star::lang::XInitialization
54                                                 ,   ::com::sun::star::lang::XServiceInfo
55                                                 ,   ::com::sun::star::beans::XPropertyChangeListener
56                                                 ,   ::com::sun::star::util::XModifyListener
57                                                 ,   ::com::sun::star::sdbc::XRowSetListener
58                                                 >   FormOperations_Base;
59 
60     class FormOperations    :public ::cppu::BaseMutex
61                             ,public FormOperations_Base
62 	{
63     public:
64         class MethodGuard;
65 
66     private:
67         ::comphelper::ComponentContext                                                          m_aContext;
68         ::com::sun::star::uno::Reference< ::com::sun::star::form::runtime::XFormController >    m_xController;
69         ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet >                     m_xCursor;
70         ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetUpdate >            m_xUpdateCursor;
71         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >               m_xCursorProperties;
72         ::com::sun::star::uno::Reference< ::com::sun::star::form::XLoadable >                   m_xLoadableForm;
73         ::com::sun::star::uno::Reference< ::com::sun::star::form::runtime::XFeatureInvalidation >
74                                                                                                 m_xFeatureInvalidation;
75         mutable ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSingleSelectQueryComposer >
76                                                                                                 m_xParser;
77 
78         bool    m_bInitializedParser;
79         bool    m_bActiveControlModified;
80         bool    m_bConstructed;
81     #ifdef DBG_UTIL
82         mutable long
83                 m_nMethodNestingLevel;
84     #endif
85 
86     public:
87         FormOperations( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxContext );
88 
89         // XServiceInfo - static versions
90 		static ::rtl::OUString getImplementationName_Static(  ) throw(::com::sun::star::uno::RuntimeException);
91 		static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static(  ) throw(::com::sun::star::uno::RuntimeException);
92 		static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
93 						Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&);
94 
MethodAccessfrm::FormOperations::MethodAccess95         struct MethodAccess { friend class MethodGuard; private: MethodAccess() { } };
96 
enterMethod(MethodAccess) const97         inline void enterMethod( MethodAccess ) const
98         {
99             m_aMutex.acquire();
100             impl_checkDisposed_throw();
101         #ifdef DBG_UTIL
102             ++m_nMethodNestingLevel;
103         #endif
104         }
105 
leaveMethod(MethodAccess) const106         inline void leaveMethod( MethodAccess ) const
107         {
108             m_aMutex.release();
109         #ifdef DBG_UTIL
110             --m_nMethodNestingLevel;
111         #endif
112         }
113 
114     protected:
115         virtual ~FormOperations();
116 
117         // XInitialization
118         virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
119 
120         // XServiceInfo
121         virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw (::com::sun::star::uno::RuntimeException);
122         virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
123         virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw (::com::sun::star::uno::RuntimeException);
124 
125         // XFormOperations
126         virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet > SAL_CALL getCursor() throw (::com::sun::star::uno::RuntimeException);
127         virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetUpdate > SAL_CALL getUpdateCursor() throw (::com::sun::star::uno::RuntimeException);
128         virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::runtime::XFormController > SAL_CALL getController() throw (::com::sun::star::uno::RuntimeException);
129         virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::runtime::XFeatureInvalidation > SAL_CALL getFeatureInvalidation() throw (::com::sun::star::uno::RuntimeException);
130         virtual void SAL_CALL setFeatureInvalidation(const ::com::sun::star::uno::Reference< ::com::sun::star::form::runtime::XFeatureInvalidation > & the_value) throw (::com::sun::star::uno::RuntimeException);
131         virtual ::com::sun::star::form::runtime::FeatureState SAL_CALL getState(::sal_Int16 Feature) throw (::com::sun::star::uno::RuntimeException);
132         virtual ::sal_Bool SAL_CALL isEnabled(::sal_Int16 Feature) throw (::com::sun::star::uno::RuntimeException);
133         virtual void SAL_CALL execute(::sal_Int16 Feature) throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::sdbc::SQLException, ::com::sun::star::lang::WrappedTargetException);
134         virtual void SAL_CALL executeWithArguments(::sal_Int16 Feature, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& Arguments) throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::sdbc::SQLException, ::com::sun::star::lang::WrappedTargetException);
135         virtual ::sal_Bool SAL_CALL commitCurrentRecord(::sal_Bool & RecordInserted) throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::sdbc::SQLException);
136         virtual ::sal_Bool SAL_CALL commitCurrentControl() throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::sdbc::SQLException);
137         virtual ::sal_Bool SAL_CALL isInsertionRow() throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::WrappedTargetException);
138         virtual ::sal_Bool SAL_CALL isModifiedRow() throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::WrappedTargetException);
139 
140         // XRowSetListener
141         virtual void SAL_CALL cursorMoved( const ::com::sun::star::lang::EventObject& event ) throw (::com::sun::star::uno::RuntimeException);
142         virtual void SAL_CALL rowChanged( const ::com::sun::star::lang::EventObject& event ) throw (::com::sun::star::uno::RuntimeException);
143         virtual void SAL_CALL rowSetChanged( const ::com::sun::star::lang::EventObject& event ) throw (::com::sun::star::uno::RuntimeException);
144 
145         // XModifyListener
146         virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& _rSource ) throw( ::com::sun::star::uno::RuntimeException );
147 
148         // XPropertyChangeListener
149         virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw (::com::sun::star::uno::RuntimeException);
150 
151         // XEventListener
152         virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
153 
154         // XComponent/OComponentHelper
155         virtual void SAL_CALL disposing();
156 
157     private:
158         // service constructors
159         void    createWithFormController( const ::com::sun::star::uno::Reference< ::com::sun::star::form::runtime::XFormController >& _rxController );
160         void    createWithForm( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm >& _rxForm );
161 
162         /** determines whether or not we're already disposed
163         */
impl_isDisposed_nothrow() const164         inline bool impl_isDisposed_nothrow() const { return !m_xCursor.is(); }
165 
166         /** checks whether the instance is already disposed, and throws an exception if so
167         */
168         void        impl_checkDisposed_throw() const;
169 
170         /** initializes the instance after m_xController has been set
171             @precond
172                 m_xController is not <NULL/>
173         */
174         void        impl_initFromController_throw();
175 
176         /** initializes the instance after m_xCursor has been set
177             @precond
178                 m_xCursor is not <NULL/>
179         */
180         void        impl_initFromForm_throw();
181 
182         /// invalidate the full palette of features which we know
183         void        impl_invalidateAllSupportedFeatures_nothrow( MethodGuard& _rClearForCallback ) const;
184 
185         /** invalidate the features which depend on the "modified" state of the current control
186             of our controller
187         */
188         void        impl_invalidateModifyDependentFeatures_nothrow( MethodGuard& _rClearForCallback ) const;
189 
190         /** ensures that our parse is initialized, or at least that we attempted to do so
191             @precond
192                 we're not disposed
193         */
194         void        impl_ensureInitializedParser_nothrow();
195 
196         /// disposes our parser, if we have one
197         void        impl_disposeParser_nothrow();
198 
199         /** determines whether our cursor can be moved left
200             @precond hasCursor()
201         */
202         bool        impl_canMoveLeft_throw() const;
203 
204         /** determines whether our cursor can be moved right
205             @precond hasCursor()
206         */
207         bool        impl_canMoveRight_throw() const;
208 
209         /// determines whether we're positioned on the insertion row
210         bool        impl_isInsertionRow_throw() const;
211 
212         /// retrieves the RowCount property of the form
213         sal_Int32   impl_getRowCount_throw() const;
214 
215         /// retrieves the RowCountFinal property of the form
216         bool        impl_isRowCountFinal_throw() const;
217 
218         /// retrieves the IsModified property of the form
219         bool        impl_isModifiedRow_throw() const;
220 
221         /// determines whether we can parse the query of our form
222     	bool        impl_isParseable_throw() const;
223 
224         /// determines if we have an active filter or order condition
225 	    bool        impl_hasFilterOrOrder_throw() const;
226 
227         /// determines whether our form is in "insert-only" mode
228         bool        impl_isInsertOnlyForm_throw() const;
229 
230         /** retrieces the column to which the current control of our controller is bound
231             @precond
232                 m_xController.is()
233         */
234         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
235                     impl_getCurrentBoundField_nothrow( ) const;
236 
237         /** returns the control model of the current control
238 
239             If the current control is a grid control, then the returned model is the
240             model of the current <em>column</em> in the grid.
241 
242             @precond
243                 m_xController.is()
244         */
245         ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >
246                     impl_getCurrentControlModel_throw() const;
247 
248         /// determines if we have a valid cursor
impl_hasCursor_nothrow() const249         inline  bool    impl_hasCursor_nothrow() const { return m_xCursorProperties.is(); }
250 
251         /** determines the model position from a grid control column's view position
252 
253             A grid control can have columns which are currently hidden, so the index of a
254             column in the view is not necessarily the same as its index in the model.
255         */
256         sal_Int16   impl_gridView2ModelPos_nothrow( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >& _rxColumns, sal_Int16 _nViewPos ) const;
257 
258         /** moves our cursor one position to the left, caring for different possible
259             cursor states.
260 
261             Before the movement is done, the current row is saved, if necessary.
262 
263             @precond
264                 canMoveLeft()
265         */
266         bool        impl_moveLeft_throw() const;
267 
268         /** moves our cursor one position to the right, caring for different possible
269             cursor states.
270 
271             Before the movement is done, the current row is saved, if necessary.
272 
273             @precond
274                 canMoveRight()
275         */
276         bool        impl_moveRight_throw( ) const;
277 
278         /** impl-version of commitCurrentRecord, which can be called without caring for
279             an output parameter, and within const-contexts
280 
281             @precond
282                 our mutex is locked
283         */
284         bool        impl_commitCurrentRecord_throw( sal_Bool* _pRecordInserted = NULL ) const;
285 
286         /** impl-version of commitCurrentControl, which can be called in const-contexts
287 
288             @precond
289                 our mutex is locked
290         */
291         bool        impl_commitCurrentControl_throw() const;
292 
293         /// resets all control models in our own form
294         void        impl_resetAllControls_nothrow() const;
295 
296         /// executes the "auto sort ascending" and "auto sort descending" features
297         void        impl_executeAutoSort_throw( bool _bUp ) const;
298 
299         /// executes the "auto filter" feature
300         void        impl_executeAutoFilter_throw( ) const;
301 
302         /// executes the interactive sort resp. filter feature
303         void        impl_executeFilterOrSort_throw( bool _bFilter ) const;
304 
305     private:
306         /// typedef for member method of this class
307 		typedef void (FormOperations::*Action)( const void* ) const;
308 
309         /** calls a member function, catches SQLExceptions, extends them with additional context information,
310             and rethrows them
311 
312             @param _pAction
313                 the member function to call
314             @param _pParam
315                 the parameters to pass to the member function
316             @param _nErrorResourceId
317                 the id of the resources string to use as error message
318         */
319         void        impl_doActionInSQLContext_throw( Action _pAction, const void* _pParam, sal_uInt16 _nErrorResourceId ) const;
320 
321         // parameter structure for appendOrderByColumn
322         struct param_appendOrderByColumn
323         {
324             ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
325                         xField;
326             bool        bUp;
327         };
328         void        impl_appendOrderByColumn_throw( const void* _pActionParam ) const;
329 
330         // parameter structure for appendFilterByColumn
331         struct param_appendFilterByColumn
332         {
333             ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
334                         xField;
335         };
336         void        impl_appendFilterByColumn_throw( const void* _pActionParam ) const;
337 
338     private:
339         FormOperations();                                   // never implemented
340         FormOperations( const FormOperations& );            // never implemented
341         FormOperations& operator=( const FormOperations& ); // never implemented
342 
343     public:
344         class MethodGuard
345         {
346             FormOperations& m_rOwner;
347             bool            m_bCleared;
348 
349         public:
MethodGuard(FormOperations & _rOwner)350             inline MethodGuard( FormOperations& _rOwner )
351                 :m_rOwner( _rOwner )
352                 ,m_bCleared( false )
353             {
354                 m_rOwner.enterMethod( FormOperations::MethodAccess() );
355             }
356 
~MethodGuard()357             inline ~MethodGuard()
358             {
359                 clear();
360             }
361 
clear()362             inline void clear()
363             {
364                 if ( !m_bCleared )
365                     m_rOwner.leaveMethod( FormOperations::MethodAccess() );
366                 m_bCleared = true;
367             }
368         };
369 	};
370 
371 //........................................................................
372 } // namespace frm
373 //........................................................................
374 
375 #endif // FORMS_FORMOPERATIONS_HXX
376