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