Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "formoperations.hxx"
31 : : #include "frm_strings.hxx"
32 : : #include "frm_resource.hxx"
33 : : #include "frm_resource.hrc"
34 : : #include "frm_module.hxx"
35 : :
36 : : #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
37 : : #include <com/sun/star/util/XModifyBroadcaster.hpp>
38 : : #include <com/sun/star/form/runtime/FormFeature.hpp>
39 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
40 : : #include <com/sun/star/lang/DisposedException.hpp>
41 : : #include <com/sun/star/awt/XControl.hpp>
42 : : #include <com/sun/star/form/XGrid.hpp>
43 : : #include <com/sun/star/form/XBoundControl.hpp>
44 : : #include <com/sun/star/form/XBoundComponent.hpp>
45 : : #include <com/sun/star/sdbcx/XRowLocate.hpp>
46 : : #include <com/sun/star/form/XConfirmDeleteListener.hpp>
47 : : #include <com/sun/star/sdb/RowChangeEvent.hpp>
48 : : #include <com/sun/star/sdb/RowChangeAction.hpp>
49 : : #include <com/sun/star/sdb/SQLFilterOperator.hpp>
50 : : #include <com/sun/star/sdbc/DataType.hpp>
51 : : #include <com/sun/star/form/XReset.hpp>
52 : : #include <com/sun/star/beans/XMultiPropertySet.hpp>
53 : : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
54 : : #include <com/sun/star/util/XRefreshable.hpp>
55 : :
56 : : #include <connectivity/dbtools.hxx>
57 : : #include <connectivity/dbexception.hxx>
58 : : #include <vcl/svapp.hxx>
59 : : #include <vcl/stdtext.hxx>
60 : : #include <vcl/msgbox.hxx>
61 : : #include <vcl/waitobj.hxx>
62 : : #include <tools/diagnose_ex.h>
63 : : #include <comphelper/container.hxx>
64 : : #include <comphelper/property.hxx>
65 : : #include <comphelper/namedvaluecollection.hxx>
66 : : #include <cppuhelper/exc_hlp.hxx>
67 : : #include <osl/mutex.hxx>
68 : : #include <sal/macros.h>
69 : :
70 : : //--------------------------------------------------------------------------
71 : 30 : extern "C" void SAL_CALL createRegistryInfo_FormOperations()
72 : : {
73 [ + - ][ + - ]: 30 : static ::frm::OMultiInstanceAutoRegistration< ::frm::FormOperations > aAutoRegistration;
[ + - ][ # # ]
74 : 30 : }
75 : :
76 : : //........................................................................
77 : : namespace frm
78 : : {
79 : : //........................................................................
80 : :
81 : : using ::dbtools::SQLExceptionInfo;
82 : : /** === begin UNO using === **/
83 : : using ::com::sun::star::uno::Reference;
84 : : using ::com::sun::star::uno::XComponentContext;
85 : : using ::com::sun::star::uno::RuntimeException;
86 : : using ::com::sun::star::uno::Sequence;
87 : : using ::com::sun::star::uno::Exception;
88 : : using ::com::sun::star::uno::Any;
89 : : using ::com::sun::star::uno::XInterface;
90 : : using ::com::sun::star::sdbc::XRowSet;
91 : : using ::com::sun::star::sdbc::XResultSetUpdate;
92 : : using ::com::sun::star::form::runtime::XFormController;
93 : : using ::com::sun::star::form::runtime::XFeatureInvalidation;
94 : : using ::com::sun::star::form::runtime::FeatureState;
95 : : using ::com::sun::star::lang::IllegalArgumentException;
96 : : using ::com::sun::star::sdbc::SQLException;
97 : : using namespace ::com::sun::star::sdbc;
98 : : using ::com::sun::star::form::XForm;
99 : : using ::com::sun::star::ucb::AlreadyInitializedException;
100 : : using ::com::sun::star::util::XModifyBroadcaster;
101 : : using ::com::sun::star::uno::UNO_QUERY;
102 : : using ::com::sun::star::lang::EventObject;
103 : : using ::com::sun::star::beans::PropertyChangeEvent;
104 : : using ::com::sun::star::lang::XMultiServiceFactory;
105 : : using ::com::sun::star::lang::DisposedException;
106 : : using ::com::sun::star::beans::XPropertySet;
107 : : using ::com::sun::star::awt::XControl;
108 : : using ::com::sun::star::form::XGrid;
109 : : using ::com::sun::star::container::XIndexAccess;
110 : : using ::com::sun::star::uno::UNO_QUERY_THROW;
111 : : using ::com::sun::star::form::XBoundControl;
112 : : using ::com::sun::star::form::XBoundComponent;
113 : : using ::com::sun::star::sdbcx::XRowLocate;
114 : : using ::com::sun::star::form::XConfirmDeleteListener;
115 : : using ::com::sun::star::sdb::RowChangeEvent;
116 : : using namespace ::com::sun::star::sdb;
117 : : using ::com::sun::star::form::XReset;
118 : : using ::com::sun::star::beans::XMultiPropertySet;
119 : : using ::com::sun::star::uno::makeAny;
120 : : using ::com::sun::star::lang::WrappedTargetException;
121 : : using ::com::sun::star::beans::PropertyValue;
122 : : using ::com::sun::star::ui::dialogs::XExecutableDialog;
123 : : using ::com::sun::star::beans::NamedValue;
124 : :
125 : : using ::com::sun::star::util::XRefreshable;
126 : : using ::com::sun::star::awt::XControlModel;
127 : : /** === end UNO using === **/
128 : : namespace FormFeature = ::com::sun::star::form::runtime::FormFeature;
129 : : namespace RowChangeAction = ::com::sun::star::sdb::RowChangeAction;
130 : :
131 : : //====================================================================
132 : : //= FormOperations
133 : : //====================================================================
134 : : //--------------------------------------------------------------------
135 : 22 : FormOperations::FormOperations( const Reference< XMultiServiceFactory >& _rxContext )
136 : : :FormOperations_Base( m_aMutex )
137 : : ,m_aContext( _rxContext )
138 : : ,m_bInitializedParser( false )
139 : : ,m_bActiveControlModified( false )
140 [ + - ]: 22 : ,m_bConstructed( false )
141 : : #ifdef DBG_UTIL
142 : : ,m_nMethodNestingLevel( false )
143 : : #endif
144 : : {
145 : 22 : }
146 : :
147 : : //--------------------------------------------------------------------
148 [ + - ][ + - ]: 19 : FormOperations::~FormOperations()
149 : : {
150 [ - + ]: 38 : }
151 : :
152 : : //--------------------------------------------------------------------
153 : 60 : ::rtl::OUString FormOperations::getImplementationName_Static( ) throw(RuntimeException)
154 : : {
155 : 60 : return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.forms.FormOperations" ) );
156 : : }
157 : :
158 : : //--------------------------------------------------------------------
159 : 30 : Sequence< ::rtl::OUString > FormOperations::getSupportedServiceNames_Static( ) throw(RuntimeException)
160 : : {
161 : 30 : Sequence< ::rtl::OUString > aNames(1);
162 [ + - ][ + - ]: 30 : aNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.runtime.FormOperations" ) );
163 : 30 : return aNames;
164 : : }
165 : :
166 : : //--------------------------------------------------------------------
167 : 22 : Reference< XInterface > SAL_CALL FormOperations::Create(const Reference< XMultiServiceFactory >& _rxFactory )
168 : : {
169 [ + - ]: 22 : return *new FormOperations( _rxFactory );
170 : : }
171 : :
172 : : //--------------------------------------------------------------------
173 : 22 : void SAL_CALL FormOperations::initialize( const Sequence< Any >& _arguments ) throw (Exception, RuntimeException)
174 : : {
175 [ - + ]: 22 : if ( m_bConstructed )
176 [ # # ]: 0 : throw AlreadyInitializedException();
177 : :
178 [ + - ]: 22 : if ( _arguments.getLength() == 1 )
179 : : {
180 : 22 : Reference< XFormController > xController;
181 : 22 : Reference< XForm > xForm;
182 [ + - ][ + - ]: 22 : if ( _arguments[0] >>= xController )
183 [ + - ]: 22 : createWithFormController( xController );
184 [ # # ][ # # ]: 0 : else if ( _arguments[0] >>= xForm )
185 [ # # ]: 0 : createWithForm( xForm );
186 : : else
187 [ # # ][ # # ]: 0 : throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
188 : 22 : return;
189 : : }
190 : :
191 [ # # ][ # # ]: 0 : throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
192 : : }
193 : :
194 : : //--------------------------------------------------------------------
195 : 0 : ::rtl::OUString SAL_CALL FormOperations::getImplementationName( ) throw (RuntimeException)
196 : : {
197 : 0 : return getImplementationName_Static();
198 : : }
199 : :
200 : : //--------------------------------------------------------------------
201 : 0 : ::sal_Bool SAL_CALL FormOperations::supportsService( const ::rtl::OUString& _ServiceName ) throw (RuntimeException)
202 : : {
203 [ # # ]: 0 : Sequence< ::rtl::OUString > aSupportedServiceNames( getSupportedServiceNames() );
204 : 0 : const ::rtl::OUString* pBegin = aSupportedServiceNames.getConstArray();
205 : 0 : const ::rtl::OUString* pEnd = aSupportedServiceNames.getConstArray() + aSupportedServiceNames.getLength();
206 [ # # ][ # # ]: 0 : return ::std::find( pBegin, pEnd, _ServiceName ) != pEnd;
207 : : }
208 : :
209 : : //--------------------------------------------------------------------
210 : 0 : Sequence< ::rtl::OUString > SAL_CALL FormOperations::getSupportedServiceNames( ) throw (RuntimeException)
211 : : {
212 : 0 : return getSupportedServiceNames_Static();
213 : : }
214 : :
215 : : //--------------------------------------------------------------------
216 : 0 : Reference< XRowSet > SAL_CALL FormOperations::getCursor() throw (RuntimeException)
217 : : {
218 [ # # ]: 0 : MethodGuard aGuard( *this );
219 [ # # ]: 0 : return m_xCursor;
220 : : }
221 : :
222 : : //--------------------------------------------------------------------
223 : 0 : Reference< XResultSetUpdate > SAL_CALL FormOperations::getUpdateCursor() throw (RuntimeException)
224 : : {
225 [ # # ]: 0 : MethodGuard aGuard( *this );
226 [ # # ]: 0 : return m_xUpdateCursor;
227 : : }
228 : :
229 : : //--------------------------------------------------------------------
230 : 0 : Reference< XFormController > SAL_CALL FormOperations::getController() throw (RuntimeException)
231 : : {
232 [ # # ]: 0 : MethodGuard aGuard( *this );
233 [ # # ]: 0 : return m_xController;
234 : : }
235 : :
236 : : //--------------------------------------------------------------------
237 : 0 : Reference< XFeatureInvalidation > SAL_CALL FormOperations::getFeatureInvalidation() throw (RuntimeException)
238 : : {
239 [ # # ]: 0 : MethodGuard aGuard( *this );
240 [ # # ]: 0 : return m_xFeatureInvalidation;
241 : : }
242 : :
243 : : //--------------------------------------------------------------------
244 : 22 : void SAL_CALL FormOperations::setFeatureInvalidation( const Reference< XFeatureInvalidation > & _rxFeatureInvalidation ) throw (RuntimeException)
245 : : {
246 [ + - ]: 22 : MethodGuard aGuard( *this );
247 [ + - ][ + - ]: 22 : m_xFeatureInvalidation = _rxFeatureInvalidation;
248 : 22 : }
249 : :
250 : : //--------------------------------------------------------------------
251 : 0 : FeatureState SAL_CALL FormOperations::getState( ::sal_Int16 _nFeature ) throw (RuntimeException)
252 : : {
253 [ # # ]: 0 : MethodGuard aGuard( *this );
254 : :
255 : 0 : FeatureState aState;
256 : 0 : aState.Enabled = sal_False;
257 : :
258 : : try
259 : : {
260 : : // some checks for basic pre-requisites
261 [ # # # # ]: 0 : if ( !m_xLoadableForm.is()
[ # # ][ # # ]
262 [ # # ][ # # ]: 0 : || !m_xLoadableForm->isLoaded()
263 : 0 : || !m_xCursorProperties.is()
264 : : )
265 : : {
266 : : return aState;
267 : : }
268 : :
269 [ # # # # : 0 : switch ( _nFeature )
# # # # #
# # # # #
# ]
270 : : {
271 : : case FormFeature::MoveToFirst:
272 : : case FormFeature::MoveToPrevious:
273 [ # # ]: 0 : aState.Enabled = impl_canMoveLeft_throw( );
274 : 0 : break;
275 : :
276 : : case FormFeature::MoveToNext:
277 [ # # ]: 0 : aState.Enabled = impl_canMoveRight_throw();
278 : 0 : break;
279 : :
280 : : case FormFeature::MoveToLast:
281 [ # # ][ # # ]: 0 : aState.Enabled = impl_getRowCount_throw() && ( !m_xCursor->isLast() || impl_isInsertionRow_throw() );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
282 : 0 : break;
283 : :
284 : : case FormFeature::DeleteRecord:
285 : : // already deleted ?
286 [ # # ][ # # ]: 0 : if ( m_xCursor->rowDeleted() )
[ # # ]
287 : 0 : aState.Enabled = sal_False;
288 : : else
289 : : {
290 : : // allowed to delete the row ?
291 [ # # ][ # # ]: 0 : aState.Enabled = !impl_isInsertionRow_throw() && ::dbtools::canDelete( m_xCursorProperties );
[ # # ][ # # ]
292 : : }
293 : 0 : break;
294 : :
295 : : case FormFeature::MoveToInsertRow:
296 : : // if we are inserting we can move to the next row if the current record or control is modified
297 [ # # ]: 0 : aState.Enabled = impl_isInsertionRow_throw()
298 [ # # ]: 0 : ? impl_isModifiedRow_throw() || m_bActiveControlModified
299 [ # # ][ # # ]: 0 : : ::dbtools::canInsert( m_xCursorProperties );
[ # # ][ # # ]
300 : 0 : break;
301 : :
302 : : case FormFeature::ReloadForm:
303 : : {
304 : : // there must be an active connection
305 [ # # ]: 0 : Reference< XRowSet > xCursorRowSet( m_xCursor, UNO_QUERY );
306 [ # # ]: 0 : aState.Enabled = ::dbtools::getConnection( xCursorRowSet ).is();
307 : :
308 : : // and an active command
309 : 0 : ::rtl::OUString sActiveCommand;
310 [ # # ][ # # ]: 0 : m_xCursorProperties->getPropertyValue( PROPERTY_ACTIVECOMMAND ) >>= sActiveCommand;
[ # # ]
311 : 0 : aState.Enabled &= !sActiveCommand.isEmpty();
312 : : }
313 : 0 : break;
314 : :
315 : : case FormFeature::RefreshCurrentControl:
316 : : {
317 [ # # ][ # # ]: 0 : Reference< XRefreshable > xControlModelRefresh( impl_getCurrentControlModel_throw(), UNO_QUERY );
318 : 0 : aState.Enabled = xControlModelRefresh.is();
319 : : }
320 : 0 : break;
321 : :
322 : : case FormFeature::SaveRecordChanges:
323 : : case FormFeature::UndoRecordChanges:
324 [ # # ][ # # ]: 0 : aState.Enabled = impl_isModifiedRow_throw() || m_bActiveControlModified;
[ # # ]
325 : 0 : break;
326 : :
327 : : case FormFeature::RemoveFilterAndSort:
328 [ # # ][ # # ]: 0 : if ( impl_isParseable_throw() && impl_hasFilterOrOrder_throw() )
[ # # ][ # # ]
[ # # ]
329 [ # # ]: 0 : aState.Enabled = !impl_isInsertOnlyForm_throw();
330 : 0 : break;
331 : :
332 : : case FormFeature::SortAscending:
333 : : case FormFeature::SortDescending:
334 : : case FormFeature::AutoFilter:
335 [ # # ][ # # ]: 0 : if ( m_xController.is() && impl_isParseable_throw() )
[ # # ][ # # ]
336 : : {
337 [ # # ][ # # ]: 0 : sal_Bool bIsDeleted = m_xCursor->rowDeleted();
338 : :
339 [ # # ][ # # ]: 0 : if ( !bIsDeleted && !impl_isInsertOnlyForm_throw() )
[ # # ][ # # ]
340 : : {
341 [ # # ]: 0 : Reference< XPropertySet > xBoundField = impl_getCurrentBoundField_nothrow( );
342 [ # # ]: 0 : if ( xBoundField.is() )
343 [ # # ][ # # ]: 0 : xBoundField->getPropertyValue( PROPERTY_SEARCHABLE ) >>= aState.Enabled;
[ # # ]
344 : : }
345 : : }
346 : 0 : break;
347 : :
348 : : case FormFeature::InteractiveSort:
349 : : case FormFeature::InteractiveFilter:
350 [ # # ][ # # ]: 0 : if ( impl_isParseable_throw() )
351 [ # # ]: 0 : aState.Enabled = !impl_isInsertOnlyForm_throw();
352 : 0 : break;
353 : :
354 : : case FormFeature::ToggleApplyFilter:
355 : : {
356 : 0 : ::rtl::OUString sFilter;
357 [ # # ][ # # ]: 0 : m_xCursorProperties->getPropertyValue( PROPERTY_FILTER ) >>= sFilter;
[ # # ]
358 [ # # ]: 0 : if ( !sFilter.isEmpty() )
359 : : {
360 [ # # ][ # # ]: 0 : aState.State = m_xCursorProperties->getPropertyValue( PROPERTY_APPLYFILTER );
[ # # ]
361 [ # # ]: 0 : aState.Enabled = !impl_isInsertOnlyForm_throw();
362 : : }
363 : : else
364 [ # # ]: 0 : aState.State <<= (sal_Bool)sal_False;
365 : : }
366 : 0 : break;
367 : :
368 : : case FormFeature::MoveAbsolute:
369 : : {
370 [ # # ][ # # ]: 0 : sal_Int32 nPosition = m_xCursor->getRow();
371 [ # # ]: 0 : sal_Bool bIsNew = impl_isInsertionRow_throw();
372 [ # # ]: 0 : sal_Int32 nCount = impl_getRowCount_throw();
373 [ # # ]: 0 : sal_Bool bFinalCount = impl_isRowCountFinal_throw();
374 : :
375 [ # # ][ # # ]: 0 : if ( ( nPosition >= 0 ) || bIsNew )
376 : : {
377 [ # # ]: 0 : if ( bFinalCount )
378 : : {
379 : : // special case: there are no records at all, and we
380 : : // can't insert records -> disabled
381 [ # # ][ # # ]: 0 : if ( !nCount && !::dbtools::canInsert( m_xCursorProperties ) )
[ # # ][ # # ]
382 : : {
383 : 0 : aState.Enabled = sal_False;
384 : : }
385 : : else
386 : : {
387 [ # # ]: 0 : if ( bIsNew )
388 : 0 : nPosition = ++nCount;
389 [ # # ]: 0 : aState.State <<= (sal_Int32)nPosition;
390 : 0 : aState.Enabled = sal_True;
391 : : }
392 : : }
393 : : else
394 : : {
395 [ # # ]: 0 : aState.State <<= (sal_Int32)nPosition;
396 : 0 : aState.Enabled = sal_True;
397 : : }
398 : : }
399 : : }
400 : 0 : break;
401 : :
402 : : case FormFeature::TotalRecords:
403 : : {
404 [ # # ]: 0 : sal_Bool bIsNew = impl_isInsertionRow_throw();
405 [ # # ]: 0 : sal_Int32 nCount = impl_getRowCount_throw();
406 [ # # ]: 0 : sal_Bool bFinalCount = impl_isRowCountFinal_throw();
407 : :
408 [ # # ]: 0 : if ( bIsNew )
409 : 0 : ++nCount;
410 : :
411 : 0 : ::rtl::OUString sValue = ::rtl::OUString::valueOf( sal_Int32( nCount ) );
412 [ # # ]: 0 : if ( !bFinalCount )
413 [ # # ]: 0 : sValue += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" *") );
414 : :
415 [ # # ]: 0 : aState.State <<= sValue;
416 [ # # ]: 0 : aState.Enabled = sal_True;
417 : : }
418 : 0 : break;
419 : :
420 : : default:
421 : : OSL_FAIL( "FormOperations::getState: unknown feature id!" );
422 : 0 : break;
423 : : }
424 : : }
425 [ # # ]: 0 : catch( const Exception& )
426 : : {
427 : : OSL_FAIL( "FormOperations::getState: caught an exception!" );
428 : : }
429 : :
430 [ # # ]: 0 : return aState;
431 : : }
432 : :
433 : : //--------------------------------------------------------------------
434 : 0 : ::sal_Bool SAL_CALL FormOperations::isEnabled( ::sal_Int16 _nFeature ) throw (RuntimeException)
435 : : {
436 [ # # ]: 0 : MethodGuard aGuard( *this );
437 : :
438 [ # # ]: 0 : FeatureState aState( getState( _nFeature ) );
439 [ # # ]: 0 : return aState.Enabled;
440 : : }
441 : :
442 : : //--------------------------------------------------------------------
443 : : namespace
444 : : {
445 : 0 : static bool lcl_needConfirmCommit( sal_Int32 _nFeature )
446 : : {
447 : : return ( ( _nFeature == FormFeature::ReloadForm )
448 : : || ( _nFeature == FormFeature::RemoveFilterAndSort )
449 : : || ( _nFeature == FormFeature::ToggleApplyFilter )
450 : : || ( _nFeature == FormFeature::SortAscending )
451 : : || ( _nFeature == FormFeature::SortDescending )
452 : : || ( _nFeature == FormFeature::AutoFilter )
453 : : || ( _nFeature == FormFeature::InteractiveSort )
454 : : || ( _nFeature == FormFeature::InteractiveFilter )
455 [ # # ][ # # ]: 0 : );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
456 : : }
457 : 0 : static bool lcl_requiresArguments( sal_Int32 _nFeature )
458 : : {
459 : 0 : return ( _nFeature == FormFeature::MoveAbsolute );
460 : : }
461 : 0 : static bool lcl_isExecutableFeature( sal_Int32 _nFeature )
462 : : {
463 : 0 : return ( _nFeature != FormFeature::TotalRecords );
464 : : }
465 : : }
466 : :
467 : : //--------------------------------------------------------------------
468 : 0 : void SAL_CALL FormOperations::execute( ::sal_Int16 _nFeature ) throw (RuntimeException, IllegalArgumentException, SQLException, WrappedTargetException)
469 : : {
470 [ # # ]: 0 : SolarMutexGuard aSolarGuard;
471 [ # # ]: 0 : MethodGuard aGuard( *this );
472 : :
473 [ # # ][ # # ]: 0 : if ( ( _nFeature != FormFeature::DeleteRecord ) && ( _nFeature != FormFeature::UndoRecordChanges ) )
474 : : {
475 : : // if we have a controller, commit the current control
476 [ # # ]: 0 : if ( m_xController.is() )
477 [ # # ][ # # ]: 0 : if ( !impl_commitCurrentControl_throw() )
478 : : return;
479 : :
480 : : // commit the current record
481 : 0 : bool bCommitCurrentRecord = true;
482 : : // (but before, let the user confirm if necessary)
483 [ # # ][ # # ]: 0 : if ( impl_isModifiedRow_throw() )
484 : : {
485 [ # # ]: 0 : if ( lcl_needConfirmCommit( _nFeature ) )
486 : : {
487 : : // TODO: shouldn't this be done with an interaction handler?
488 [ # # ][ # # ]: 0 : QueryBox aQuery( NULL, WB_YES_NO_CANCEL | WB_DEF_YES, FRM_RES_STRING( RID_STR_QUERY_SAVE_MODIFIED_ROW ) );
[ # # ][ # # ]
489 [ # # # ]: 0 : switch ( aQuery.Execute() )
[ # # ]
490 : : {
491 : 0 : case RET_NO: bCommitCurrentRecord = false; break;
492 : : case RET_CANCEL: return;
493 [ # # ][ # # ]: 0 : }
494 : : }
495 : : }
496 : :
497 [ # # ][ # # ]: 0 : if ( bCommitCurrentRecord && !impl_commitCurrentRecord_throw() )
[ # # ][ # # ]
498 : : return;
499 : : }
500 : :
501 : : try
502 : : {
503 [ # # # # : 0 : switch ( _nFeature )
# # # # #
# # # # #
# # # ]
504 : : {
505 : : case FormFeature::MoveToFirst:
506 [ # # ][ # # ]: 0 : m_xCursor->first();
507 : 0 : break;
508 : :
509 : : case FormFeature::MoveToNext:
510 [ # # ]: 0 : impl_moveRight_throw( );
511 : 0 : break;
512 : :
513 : : case FormFeature::MoveToPrevious:
514 [ # # ]: 0 : impl_moveLeft_throw( );
515 : 0 : break;
516 : :
517 : : case FormFeature::MoveToLast:
518 : : {
519 : : /*
520 : : // TODO: re-implement this .....
521 : : // run in an own thread if ...
522 : : // ... the data source is thread safe ...
523 : : sal_Bool bAllowOwnThread = sal_False;
524 : : if ( ::comphelper::hasProperty( PROPERTY_THREADSAFE, m_xCursorProperties ) )
525 : : m_xCursorProperties->getPropertyValue( PROPERTY_THREADSAFE ) >>= bAllowOwnThread;
526 : :
527 : : // ... the record count is unknown
528 : : sal_Bool bNeedOwnThread sal_False;
529 : : if ( ::comphelper::hasProperty( PROPERTY_ROWCOUNTFINAL, m_xCursorProperties ) )
530 : : m_xCursorProperties->getPropertyValue( PROPERTY_ROWCOUNTFINAL ) >>= bNeedOwnThread;
531 : :
532 : : if ( bNeedOwnThread && bAllowOwnThread )
533 : : ;
534 : : else
535 : : */
536 [ # # ][ # # ]: 0 : m_xCursor->last();
537 : : }
538 : 0 : break;
539 : :
540 : : case FormFeature::ReloadForm:
541 [ # # ]: 0 : if ( m_xLoadableForm.is() )
542 : : {
543 [ # # ]: 0 : WaitObject aWO( NULL );
544 [ # # ][ # # ]: 0 : m_xLoadableForm->reload();
545 : :
546 : : // refresh all controls in the form (and sub forms) which can be refreshed
547 : : // #i90914#
548 [ # # ]: 0 : ::comphelper::IndexAccessIterator aIter( m_xLoadableForm );
549 [ # # ]: 0 : Reference< XInterface > xElement( aIter.Next() );
550 [ # # ]: 0 : while ( xElement.is() )
551 : : {
552 [ # # ]: 0 : Reference< XRefreshable > xRefresh( xElement, UNO_QUERY );
553 [ # # ]: 0 : if ( xRefresh.is() )
554 [ # # ][ # # ]: 0 : xRefresh->refresh();
555 [ # # ][ # # ]: 0 : xElement = aIter.Next();
556 [ # # ][ # # ]: 0 : }
557 : : }
558 : 0 : break;
559 : :
560 : : case FormFeature::RefreshCurrentControl:
561 : : {
562 [ # # ][ # # ]: 0 : Reference< XRefreshable > xControlModelRefresh( impl_getCurrentControlModel_throw(), UNO_QUERY );
563 : : OSL_ENSURE( xControlModelRefresh.is(), "FormOperations::execute: how did you reach this?" );
564 [ # # ]: 0 : if ( xControlModelRefresh.is() )
565 [ # # ][ # # ]: 0 : xControlModelRefresh->refresh();
566 : : }
567 : 0 : break;
568 : :
569 : : case FormFeature::DeleteRecord:
570 : : {
571 [ # # ]: 0 : sal_uInt32 nCount = impl_getRowCount_throw();
572 : :
573 : : // next position
574 [ # # ][ # # ]: 0 : sal_Bool bLeft = m_xCursor->isLast() && ( nCount > 1 );
[ # # ][ # # ]
575 [ # # ][ # # ]: 0 : sal_Bool bRight= !m_xCursor->isLast();
576 : 0 : sal_Bool bSuccess = sal_False;
577 : : try
578 : : {
579 : : // ask for confirmation
580 [ # # ]: 0 : Reference< XConfirmDeleteListener > xConfirmDelete( m_xController, UNO_QUERY );
581 : :
582 [ # # ]: 0 : if ( xConfirmDelete.is() )
583 : : {
584 [ # # ]: 0 : RowChangeEvent aEvent;
585 [ # # ][ # # ]: 0 : aEvent.Source = Reference< XInterface >( m_xCursor, UNO_QUERY );
586 : 0 : aEvent.Action = RowChangeAction::DELETE;
587 : 0 : aEvent.Rows = 1;
588 [ # # ][ # # ]: 0 : bSuccess = xConfirmDelete->confirmDelete( aEvent );
[ # # ]
589 : : }
590 : :
591 : : // delete it
592 [ # # ]: 0 : if ( bSuccess )
593 [ # # ][ # # ]: 0 : m_xUpdateCursor->deleteRow();
[ # # ]
594 : : }
595 [ # # ]: 0 : catch( const Exception& )
596 : : {
597 : 0 : bSuccess = sal_False;
598 : : }
599 : :
600 [ # # ]: 0 : if ( bSuccess )
601 : : {
602 [ # # ][ # # ]: 0 : if ( bLeft || bRight )
603 [ # # ][ # # ]: 0 : m_xCursor->relative( bRight ? 1 : -1 );
[ # # ]
604 : : else
605 : : {
606 [ # # ]: 0 : sal_Bool bCanInsert = ::dbtools::canInsert( m_xCursorProperties );
607 : : // is it possible to insert another record?
608 [ # # ]: 0 : if ( bCanInsert )
609 [ # # ][ # # ]: 0 : m_xUpdateCursor->moveToInsertRow();
610 : : else
611 : : // move record to update stati
612 [ # # ][ # # ]: 0 : m_xCursor->first();
613 : : }
614 : : }
615 : : }
616 : 0 : break;
617 : :
618 : : case FormFeature::SaveRecordChanges:
619 : : case FormFeature::UndoRecordChanges:
620 : : {
621 [ # # ]: 0 : sal_Bool bInserting = impl_isInsertionRow_throw();
622 : :
623 [ # # ]: 0 : if ( FormFeature::UndoRecordChanges == _nFeature )
624 : : {
625 [ # # ]: 0 : if ( !bInserting )
626 [ # # ][ # # ]: 0 : m_xUpdateCursor->cancelRowUpdates();
627 : :
628 : : // reset all controls for this form
629 [ # # ]: 0 : impl_resetAllControls_nothrow( );
630 : :
631 [ # # ]: 0 : if ( bInserting ) // back to insertion mode for this form
632 [ # # ][ # # ]: 0 : m_xUpdateCursor->moveToInsertRow();
633 : : }
634 : : else
635 : : {
636 [ # # ]: 0 : if ( bInserting )
637 : : {
638 [ # # ][ # # ]: 0 : m_xUpdateCursor->insertRow();
639 [ # # ][ # # ]: 0 : m_xCursor->last();
640 : : }
641 : : else
642 [ # # ][ # # ]: 0 : m_xUpdateCursor->updateRow();
643 : : }
644 : : }
645 : 0 : break;
646 : :
647 : : case FormFeature::MoveToInsertRow:
648 : : // move to the last row before moving to the insert row
649 [ # # ][ # # ]: 0 : m_xCursor->last();
650 [ # # ][ # # ]: 0 : m_xUpdateCursor->moveToInsertRow();
651 : 0 : break;
652 : :
653 : : case FormFeature::RemoveFilterAndSort:
654 : : {
655 : : // simultaneously reset Filter and Order property
656 [ # # ]: 0 : Reference< XMultiPropertySet > xProperties( m_xCursorProperties, UNO_QUERY );
657 : : OSL_ENSURE( xProperties.is(), "FormOperations::execute: no multi property access!" );
658 [ # # ]: 0 : if ( xProperties.is() )
659 : : {
660 [ # # ]: 0 : Sequence< ::rtl::OUString > aNames( 2 );
661 [ # # ][ # # ]: 0 : aNames[0] = PROPERTY_FILTER;
662 [ # # ][ # # ]: 0 : aNames[1] = PROPERTY_SORT;
663 : :
664 [ # # ]: 0 : Sequence< Any> aValues( 2 );
665 [ # # ][ # # ]: 0 : aValues[0] <<= ::rtl::OUString();
666 [ # # ][ # # ]: 0 : aValues[1] <<= ::rtl::OUString();
667 : :
668 [ # # ]: 0 : WaitObject aWO( NULL );
669 [ # # ][ # # ]: 0 : xProperties->setPropertyValues( aNames, aValues );
670 : :
671 [ # # ]: 0 : if ( m_xLoadableForm.is() )
672 [ # # ][ # # ]: 0 : m_xLoadableForm->reload();
[ # # ][ # # ]
[ # # ]
673 : 0 : }
674 : : }
675 : 0 : break;
676 : :
677 : : case FormFeature::ToggleApplyFilter:
678 [ # # ][ # # ]: 0 : if ( impl_commitCurrentControl_throw() && impl_commitCurrentRecord_throw() )
[ # # ][ # # ]
[ # # ]
679 : : {
680 : : // simply toggle the value
681 : 0 : sal_Bool bApplied = sal_False;
682 [ # # ][ # # ]: 0 : m_xCursorProperties->getPropertyValue( PROPERTY_APPLYFILTER ) >>= bApplied;
[ # # ]
683 [ # # ][ # # ]: 0 : m_xCursorProperties->setPropertyValue( PROPERTY_APPLYFILTER, makeAny( (sal_Bool)!bApplied ) );
[ # # ][ # # ]
684 : :
685 : : // and reload
686 [ # # ]: 0 : WaitObject aWO( NULL );
687 [ # # ][ # # ]: 0 : m_xLoadableForm->reload();
[ # # ]
688 : : }
689 : 0 : break;
690 : :
691 : : case FormFeature::SortAscending:
692 [ # # ]: 0 : impl_executeAutoSort_throw( true );
693 : 0 : break;
694 : :
695 : : case FormFeature::SortDescending:
696 [ # # ]: 0 : impl_executeAutoSort_throw( false );
697 : 0 : break;
698 : :
699 : : case FormFeature::AutoFilter:
700 [ # # ]: 0 : impl_executeAutoFilter_throw();
701 : 0 : break;
702 : :
703 : : case FormFeature::InteractiveSort:
704 [ # # ]: 0 : impl_executeFilterOrSort_throw( false );
705 : 0 : break;
706 : :
707 : : case FormFeature::InteractiveFilter:
708 [ # # ]: 0 : impl_executeFilterOrSort_throw( true );
709 : 0 : break;
710 : :
711 : : default:
712 : : {
713 : 0 : sal_uInt16 nErrorResourceId = RID_STR_FEATURE_UNKNOWN;
714 [ # # ]: 0 : if ( lcl_requiresArguments( _nFeature ) )
715 : 0 : nErrorResourceId = RID_STR_FEATURE_REQUIRES_PARAMETERS;
716 [ # # ]: 0 : else if ( !lcl_isExecutableFeature( _nFeature ) )
717 : 0 : nErrorResourceId = RID_STR_FEATURE_NOT_EXECUTABLE;
718 [ # # ][ # # ]: 0 : throw IllegalArgumentException( FRM_RES_STRING( nErrorResourceId ), *this, 1 );
[ # # ]
719 : : }
720 : : } // switch
721 : : }
722 : 0 : catch( const RuntimeException& ) { throw; }
723 : 0 : catch( const SQLException& ) { throw; }
724 : 0 : catch( const IllegalArgumentException& ) { throw; }
725 [ # # # # : 0 : catch( const Exception& )
# ]
726 : : {
727 [ # # # # : 0 : throw WrappedTargetException( ::rtl::OUString(), *const_cast< FormOperations* >( this ), ::cppu::getCaughtException() );
# # ]
728 : : }
729 : :
730 [ # # ][ # # ]: 0 : impl_invalidateAllSupportedFeatures_nothrow( aGuard );
[ # # ][ # # ]
[ # # ]
731 : : }
732 : :
733 : : //--------------------------------------------------------------------
734 : 0 : void SAL_CALL FormOperations::executeWithArguments( ::sal_Int16 _nFeature, const Sequence< NamedValue >& _rArguments ) throw (RuntimeException, IllegalArgumentException, SQLException, WrappedTargetException)
735 : : {
736 [ # # ]: 0 : if ( !lcl_requiresArguments( _nFeature ) )
737 : : {
738 [ # # ]: 0 : execute( _nFeature );
739 : : return;
740 : : }
741 : :
742 [ # # ]: 0 : SolarMutexGuard aSolarGuard;
743 [ # # ]: 0 : MethodGuard aGuard( *this );
744 : :
745 : : // at the moment we have only one feature which supports execution parameters
746 [ # # ]: 0 : if ( !lcl_isExecutableFeature( _nFeature ) )
747 [ # # ][ # # ]: 0 : throw IllegalArgumentException( FRM_RES_STRING( RID_STR_FEATURE_NOT_EXECUTABLE ), *this, 1 );
[ # # ]
748 : :
749 [ # # ]: 0 : switch ( _nFeature )
750 : : {
751 : : case FormFeature::MoveAbsolute:
752 : : {
753 : 0 : sal_Int32 nPosition = -1;
754 : :
755 [ # # ]: 0 : ::comphelper::NamedValueCollection aArguments( _rArguments );
756 [ # # ]: 0 : aArguments.get_ensureType( "Position", nPosition );
757 : :
758 [ # # ]: 0 : if ( nPosition < 1 )
759 : 0 : nPosition = 1;
760 : :
761 : : try
762 : : {
763 : : // commit before doing anything else
764 [ # # ][ # # ]: 0 : if ( m_xController.is() && !impl_commitCurrentControl_throw() )
[ # # ][ # # ]
765 : : return;
766 [ # # ][ # # ]: 0 : if ( !impl_commitCurrentRecord_throw() )
767 : : return;
768 : :
769 [ # # ]: 0 : sal_Int32 nCount = impl_getRowCount_throw();
770 [ # # ]: 0 : sal_Bool bFinalCount = impl_isRowCountFinal_throw();
771 : :
772 [ # # ][ # # ]: 0 : if ( bFinalCount && ( (sal_Int32)nPosition > nCount ) )
773 : 0 : nPosition = nCount;
774 : :
775 [ # # ][ # # ]: 0 : m_xCursor->absolute( nPosition );
[ # # ]
776 : : }
777 : 0 : catch( const RuntimeException& ) { throw; }
778 : 0 : catch( const SQLException& ) { throw; }
779 [ # # # # ]: 0 : catch( const Exception& )
780 : : {
781 [ # # # # : 0 : throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
# # ]
782 [ # # ]: 0 : }
783 : : }
784 : 0 : break;
785 : : default:
786 [ # # ][ # # ]: 0 : throw IllegalArgumentException( FRM_RES_STRING( RID_STR_FEATURE_UNKNOWN ), *this, 1 );
[ # # ]
787 [ # # ][ # # ]: 0 : } // switch
[ # # ][ # # ]
788 : : }
789 : :
790 : : //--------------------------------------------------------------------
791 : 0 : ::sal_Bool SAL_CALL FormOperations::commitCurrentRecord( ::sal_Bool& _out_rRecordInserted ) throw (RuntimeException, SQLException)
792 : : {
793 [ # # ]: 0 : MethodGuard aGuard( *this );
794 : 0 : _out_rRecordInserted = sal_False;
795 : :
796 [ # # ][ # # ]: 0 : return impl_commitCurrentRecord_throw( &_out_rRecordInserted );
797 : : }
798 : :
799 : : //--------------------------------------------------------------------
800 : 0 : bool FormOperations::impl_commitCurrentRecord_throw( ::sal_Bool* _pRecordInserted ) const
801 : : {
802 : : DBG_ASSERT( m_nMethodNestingLevel, "FormOperations::impl_commitCurrentRecord_throw: to be called within a MethodGuard'ed section only!" );
803 : :
804 [ # # ]: 0 : if ( !impl_hasCursor_nothrow() )
805 : 0 : return false;
806 : :
807 : : // nothing to do if the record is not modified
808 : 0 : sal_Bool bResult = !impl_isModifiedRow_throw();
809 [ # # ]: 0 : if ( !bResult )
810 : : {
811 : : // insert respectively update the row
812 [ # # ]: 0 : if ( impl_isInsertionRow_throw() )
813 : : {
814 : 0 : m_xUpdateCursor->insertRow();
815 [ # # ]: 0 : if ( _pRecordInserted )
816 : 0 : *_pRecordInserted = sal_True;
817 : : }
818 : : else
819 : 0 : m_xUpdateCursor->updateRow();
820 : 0 : bResult = true;
821 : : }
822 : 0 : return bResult;
823 : : }
824 : :
825 : : //--------------------------------------------------------------------
826 : 6 : ::sal_Bool SAL_CALL FormOperations::commitCurrentControl() throw (RuntimeException, SQLException)
827 : : {
828 [ + - ]: 6 : MethodGuard aGuard( *this );
829 [ + - ][ + - ]: 6 : return impl_commitCurrentControl_throw();
830 : : }
831 : :
832 : : //--------------------------------------------------------------------
833 : 6 : bool FormOperations::impl_commitCurrentControl_throw() const
834 : : {
835 : : DBG_ASSERT( m_nMethodNestingLevel, "FormOperations::impl_commitCurrentRecord_throw: to be called within a MethodGuard'ed section only!" );
836 : : OSL_PRECOND( m_xController.is(), "FormOperations::commitCurrentControl: no controller!" );
837 [ - + ]: 6 : if ( !m_xController.is() )
838 : 0 : return false;
839 : :
840 : 6 : bool bSuccess = false;
841 : : try
842 : : {
843 [ + - ][ + - ]: 6 : Reference< XControl > xCurrentControl( m_xController->getCurrentControl() );
844 : :
845 : : // check whether the control is locked
846 [ + - ]: 6 : Reference< XBoundControl > xCheckLock( xCurrentControl, UNO_QUERY );
847 [ - + ][ # # ]: 6 : sal_Bool bControlIsLocked = xCheckLock.is() && xCheckLock->getLock();
[ # # ][ # # ]
848 : :
849 : : // commit if necessary
850 : 6 : bSuccess = true;
851 [ + - ][ + - ]: 6 : if ( xCurrentControl.is() && !bControlIsLocked )
[ + - ]
852 : : {
853 : : // both the control and it's model can be committable, so try both
854 [ + - ]: 6 : Reference< XBoundComponent > xBound( xCurrentControl, UNO_QUERY );
855 [ + - ]: 6 : if ( !xBound.is() )
856 [ + - ][ + - ]: 6 : xBound = xBound.query( xCurrentControl->getModel() );
[ + - ][ + - ]
857 : : // and now really commit
858 [ - + ]: 6 : if ( xBound.is() )
859 [ # # ][ # # ]: 6 : bSuccess = xBound->commit();
860 : 6 : }
861 : :
862 : : }
863 : 0 : catch( const RuntimeException& ) { throw; }
864 [ # # # # ]: 0 : catch( const SQLException& ) { throw; }
865 : 0 : catch( const Exception& )
866 : : {
867 : : DBG_UNHANDLED_EXCEPTION();
868 : 0 : bSuccess = false;
869 : : }
870 : :
871 : 6 : return bSuccess;
872 : : }
873 : :
874 : : //--------------------------------------------------------------------
875 : 0 : ::sal_Bool SAL_CALL FormOperations::isInsertionRow() throw (RuntimeException, WrappedTargetException)
876 : : {
877 : 0 : sal_Bool bIs = sal_False;
878 : : try
879 : : {
880 [ # # ]: 0 : bIs = impl_isInsertionRow_throw();
881 : : }
882 : 0 : catch( const RuntimeException& ) { throw; }
883 [ # # # ]: 0 : catch( const Exception& )
884 : : {
885 [ # # # # : 0 : throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
# # ]
886 : : }
887 : 0 : return bIs;
888 : : }
889 : :
890 : : //--------------------------------------------------------------------
891 : 6 : ::sal_Bool SAL_CALL FormOperations::isModifiedRow() throw (RuntimeException, WrappedTargetException)
892 : : {
893 : 6 : sal_Bool bIs = sal_False;
894 : : try
895 : : {
896 [ + - ]: 6 : bIs = impl_isModifiedRow_throw();
897 : : }
898 : 0 : catch( const RuntimeException& ) { throw; }
899 [ # # # ]: 0 : catch( const Exception& )
900 : : {
901 [ # # # # : 0 : throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
# # ]
902 : : }
903 : 6 : return bIs;
904 : : }
905 : :
906 : : //--------------------------------------------------------------------
907 : 0 : void SAL_CALL FormOperations::cursorMoved( const EventObject& /*_Event*/ ) throw (RuntimeException)
908 : : {
909 [ # # ]: 0 : MethodGuard aGuard( *this );
910 : 0 : m_bActiveControlModified = sal_False;
911 : :
912 [ # # ][ # # ]: 0 : impl_invalidateAllSupportedFeatures_nothrow( aGuard );
913 : 0 : }
914 : :
915 : : //--------------------------------------------------------------------
916 : 0 : void SAL_CALL FormOperations::rowChanged( const EventObject& /*_Event*/ ) throw (RuntimeException)
917 : : {
918 : : // not interested in
919 : 0 : }
920 : :
921 : : //--------------------------------------------------------------------
922 : 0 : void SAL_CALL FormOperations::rowSetChanged( const EventObject& /*_Event*/ ) throw (RuntimeException)
923 : : {
924 : : // not interested in
925 : 0 : }
926 : :
927 : : //--------------------------------------------------------------------
928 : 0 : void SAL_CALL FormOperations::modified( const EventObject& /*_Source*/ ) throw( RuntimeException )
929 : : {
930 [ # # ]: 0 : MethodGuard aGuard( *this );
931 : :
932 : : OSL_ENSURE( m_xCursor.is(), "FormOperations::modified: already disposed!" );
933 [ # # ]: 0 : if ( !m_bActiveControlModified )
934 : : {
935 : 0 : m_bActiveControlModified = sal_True;
936 [ # # ]: 0 : impl_invalidateModifyDependentFeatures_nothrow( aGuard );
937 [ # # ]: 0 : }
938 : 0 : }
939 : :
940 : : //--------------------------------------------------------------------
941 : 0 : void SAL_CALL FormOperations::propertyChange( const PropertyChangeEvent& _rEvent ) throw (RuntimeException)
942 : : {
943 [ # # ]: 0 : MethodGuard aGuard( *this );
944 : :
945 [ # # ][ # # ]: 0 : if ( m_xCursor.is() && ( m_xCursor == _rEvent.Source ) )
[ # # ][ # # ]
946 : : {
947 : 0 : sal_Bool bIs = sal_False;
948 [ # # ]: 0 : if ( ( _rEvent.PropertyName == PROPERTY_ISMODIFIED )
[ # # # # ]
[ # # ]
[ # # # # ]
949 [ # # ][ # # ]: 0 : || ( _rEvent.PropertyName == PROPERTY_ISNEW )
[ # # ]
950 : : )
951 : : {
952 [ # # ][ # # ]: 0 : if ( ( _rEvent.NewValue >>= bIs ) && !bIs )
[ # # ]
953 : 0 : m_bActiveControlModified = sal_False;
954 : : }
955 [ # # ]: 0 : impl_invalidateAllSupportedFeatures_nothrow( aGuard );
956 : : }
957 : :
958 [ # # ][ # # ]: 0 : if ( m_xParser.is() && ( m_xCursor == _rEvent.Source ) )
[ # # ][ # # ]
959 : : {
960 : : try
961 : : {
962 : 0 : ::rtl::OUString sNewValue;
963 : 0 : _rEvent.NewValue >>= sNewValue;
964 [ # # ][ # # ]: 0 : if ( _rEvent.PropertyName == PROPERTY_ACTIVECOMMAND )
965 : : {
966 [ # # ][ # # ]: 0 : m_xParser->setElementaryQuery( sNewValue );
967 : : }
968 [ # # ][ # # ]: 0 : else if ( _rEvent.PropertyName == PROPERTY_FILTER )
969 : : {
970 [ # # ][ # # ]: 0 : if ( m_xParser->getFilter() != sNewValue )
[ # # ]
971 [ # # ][ # # ]: 0 : m_xParser->setFilter( sNewValue );
972 : : }
973 [ # # ][ # # ]: 0 : else if ( _rEvent.PropertyName == PROPERTY_SORT )
974 : : {
975 : 0 : _rEvent.NewValue >>= sNewValue;
976 [ # # ][ # # ]: 0 : if ( m_xParser->getOrder() != sNewValue )
[ # # ]
977 [ # # ][ # # ]: 0 : m_xParser->setOrder( sNewValue );
978 [ # # ]: 0 : }
979 : : }
980 [ # # ]: 0 : catch( const Exception& )
981 : : {
982 : : OSL_FAIL( "FormOperations::propertyChange: caught an exception while updating the parser!" );
983 : : }
984 [ # # ]: 0 : impl_invalidateAllSupportedFeatures_nothrow( aGuard );
985 [ # # ]: 0 : }
986 : 0 : }
987 : :
988 : : //--------------------------------------------------------------------
989 : 17 : void SAL_CALL FormOperations::disposing( const EventObject& /*_Source*/ ) throw (RuntimeException)
990 : : {
991 : : // TODO: should we react on this? Or is this the responsibility of our owner to dispose us?
992 : 17 : }
993 : :
994 : : //--------------------------------------------------------------------
995 : 19 : void SAL_CALL FormOperations::disposing()
996 : : {
997 [ + - ]: 19 : ::osl::MutexGuard aGuard( m_aMutex );
998 : :
999 [ + - ]: 19 : impl_disposeParser_nothrow();
1000 : :
1001 : : try
1002 : : {
1003 : : // revoke various listeners
1004 [ + - ]: 19 : if ( m_xCursor.is() )
1005 [ + - ][ + - ]: 19 : m_xCursor->removeRowSetListener( this );
[ + - ]
1006 : :
1007 [ + - ]: 19 : if ( m_xCursorProperties.is() )
1008 : : {
1009 [ + - ][ + - ]: 19 : m_xCursorProperties->removePropertyChangeListener( PROPERTY_ISMODIFIED,this );
[ + - ][ + - ]
1010 [ + - ][ + - ]: 19 : m_xCursorProperties->removePropertyChangeListener( PROPERTY_ISNEW, this );
[ + - ][ + - ]
1011 : : }
1012 : :
1013 [ + - ]: 19 : Reference< XModifyBroadcaster > xBroadcaster( m_xController, UNO_QUERY );
1014 [ + - ]: 19 : if ( xBroadcaster.is() )
1015 [ + - ][ + - ]: 19 : xBroadcaster->removeModifyListener( this );
[ + - ][ # # ]
1016 : : }
1017 [ # # ]: 0 : catch( const Exception& )
1018 : : {
1019 : : DBG_UNHANDLED_EXCEPTION();
1020 : : }
1021 : :
1022 : 19 : m_xController.clear();
1023 : 19 : m_xCursor.clear();
1024 : 19 : m_xUpdateCursor.clear();
1025 : 19 : m_xCursorProperties.clear();
1026 : 19 : m_xLoadableForm.clear();
1027 : 19 : m_xFeatureInvalidation.clear();
1028 : :
1029 [ + - ]: 19 : m_bActiveControlModified = true;
1030 : 19 : }
1031 : :
1032 : : //--------------------------------------------------------------------
1033 : 28 : void FormOperations::impl_checkDisposed_throw() const
1034 : : {
1035 [ - + ]: 28 : if ( impl_isDisposed_nothrow() )
1036 [ # # ][ # # ]: 0 : throw DisposedException( ::rtl::OUString(), *const_cast< FormOperations* >( this ) );
1037 : 28 : }
1038 : :
1039 : : //--------------------------------------------------------------------
1040 : 22 : void FormOperations::impl_initFromController_throw()
1041 : : {
1042 : : OSL_PRECOND( m_xController.is(), "FormOperations::impl_initFromController_throw: invalid controller!" );
1043 [ + - ][ + - ]: 22 : m_xCursor = m_xCursor.query( m_xController->getModel() );
[ + - ][ + - ]
1044 [ - + ]: 22 : if ( !m_xCursor.is() )
1045 [ # # ][ # # ]: 0 : throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
1046 : :
1047 [ + - ]: 22 : impl_initFromForm_throw();
1048 : :
1049 [ + - ]: 22 : Reference< XModifyBroadcaster > xBroadcaster( m_xController, UNO_QUERY );
1050 [ + - ]: 22 : if ( xBroadcaster.is() )
1051 [ + - ][ + - ]: 22 : xBroadcaster->addModifyListener( this );
[ + - ]
1052 : 22 : }
1053 : :
1054 : : //--------------------------------------------------------------------
1055 : 22 : void FormOperations::impl_initFromForm_throw()
1056 : : {
1057 : : OSL_PRECOND( m_xCursor.is(), "FormOperations::impl_initFromForm_throw: invalid form!" );
1058 [ + - ]: 22 : m_xCursorProperties = m_xCursorProperties.query ( m_xCursor );
1059 [ + - ]: 22 : m_xUpdateCursor = m_xUpdateCursor.query ( m_xCursor );
1060 [ + - ]: 22 : m_xLoadableForm = m_xLoadableForm.query ( m_xCursor );
1061 : :
1062 [ + - ][ - + ]: 22 : if ( !m_xCursor.is() || !m_xCursorProperties.is() || !m_xLoadableForm.is() )
[ - + ][ + - ]
1063 [ # # ][ # # ]: 0 : throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
1064 : :
1065 [ + - ]: 22 : m_xCursor->addRowSetListener( this );
1066 [ + - ][ + - ]: 22 : m_xCursorProperties->addPropertyChangeListener( PROPERTY_ISMODIFIED,this );
1067 [ + - ][ + - ]: 22 : m_xCursorProperties->addPropertyChangeListener( PROPERTY_ISNEW, this );
1068 : 22 : }
1069 : :
1070 : : //--------------------------------------------------------------------
1071 : 22 : void FormOperations::createWithFormController( const Reference< XFormController >& _rxController )
1072 : : {
1073 : 22 : m_xController = _rxController;
1074 [ - + ]: 22 : if ( !m_xController.is() )
1075 [ # # ][ # # ]: 0 : throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
1076 : :
1077 : 22 : impl_initFromController_throw();
1078 : :
1079 : 22 : m_bConstructed = true;
1080 : 22 : }
1081 : :
1082 : : //--------------------------------------------------------------------
1083 : 0 : void FormOperations::createWithForm( const Reference< XForm >& _rxForm )
1084 : : {
1085 [ # # ]: 0 : m_xCursor = m_xCursor.query( _rxForm );
1086 [ # # ]: 0 : if ( !m_xCursor.is() )
1087 [ # # ][ # # ]: 0 : throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
1088 : :
1089 : 0 : impl_initFromForm_throw();
1090 : :
1091 : 0 : m_bConstructed = true;
1092 : 0 : }
1093 : :
1094 : : //------------------------------------------------------------------------------
1095 : 0 : void FormOperations::impl_invalidateAllSupportedFeatures_nothrow( MethodGuard& _rClearForCallback ) const
1096 : : {
1097 [ # # ]: 0 : if ( !m_xFeatureInvalidation.is() )
1098 : : // nobody's interested in ...
1099 : 0 : return;
1100 : :
1101 : 0 : Reference< XFeatureInvalidation > xInvalidation = m_xFeatureInvalidation;
1102 [ # # ]: 0 : _rClearForCallback.clear();
1103 [ # # ][ # # ]: 0 : xInvalidation->invalidateAllFeatures();
1104 : : }
1105 : :
1106 : : //------------------------------------------------------------------------------
1107 : 0 : void FormOperations::impl_invalidateModifyDependentFeatures_nothrow( MethodGuard& _rClearForCallback ) const
1108 : : {
1109 [ # # ]: 0 : if ( !m_xFeatureInvalidation.is() )
1110 : : // nobody's interested in ...
1111 : 0 : return;
1112 : :
1113 [ # # ][ # # ]: 0 : static Sequence< sal_Int16 > s_aModifyDependentFeatures;
[ # # ][ # # ]
1114 [ # # ]: 0 : if ( s_aModifyDependentFeatures.getLength() == 0 )
1115 : : {
1116 : : sal_Int16 pModifyDependentFeatures[] =
1117 : : {
1118 : : FormFeature::MoveToNext,
1119 : : FormFeature::MoveToInsertRow,
1120 : : FormFeature::SaveRecordChanges,
1121 : : FormFeature::UndoRecordChanges
1122 : 0 : };
1123 : 0 : size_t nFeatureCount = SAL_N_ELEMENTS( pModifyDependentFeatures );
1124 [ # # ][ # # ]: 0 : s_aModifyDependentFeatures = Sequence< sal_Int16 >( pModifyDependentFeatures, nFeatureCount );
[ # # ]
1125 : : }
1126 : :
1127 : 0 : Reference< XFeatureInvalidation > xInvalidation = m_xFeatureInvalidation;
1128 [ # # ]: 0 : _rClearForCallback.clear();
1129 : :
1130 [ # # ][ # # ]: 0 : xInvalidation->invalidateFeatures( s_aModifyDependentFeatures );
1131 : : }
1132 : :
1133 : : //--------------------------------------------------------------------
1134 : 0 : void FormOperations::impl_ensureInitializedParser_nothrow()
1135 : : {
1136 : : OSL_PRECOND( m_xCursorProperties.is(), "FormOperations::impl_ensureInitializedParser_nothrow: we're disposed!" );
1137 [ # # ]: 0 : if ( m_bInitializedParser )
1138 : 0 : return;
1139 : :
1140 : : try
1141 : : {
1142 : 0 : sal_Bool bUseEscapeProcessing = sal_False;
1143 [ # # ][ # # ]: 0 : m_xCursorProperties->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bUseEscapeProcessing;
[ # # ]
1144 [ # # ]: 0 : if ( bUseEscapeProcessing )
1145 : : {
1146 [ # # ][ # # ]: 0 : Reference< XMultiServiceFactory > xFactory( ::dbtools::getConnection( m_xCursor ), UNO_QUERY );
1147 [ # # ]: 0 : if ( xFactory.is() )
1148 : : {
1149 [ # # ][ # # ]: 0 : m_xParser.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.SingleSelectQueryComposer" ) ) ), UNO_QUERY );
[ # # ][ # # ]
1150 : : OSL_ENSURE( m_xParser.is(), "FormOperations::impl_ensureInitializedParser_nothrow: factory did not create a parser for us!" );
1151 : 0 : }
1152 : : }
1153 : :
1154 [ # # ]: 0 : if ( m_xParser.is() )
1155 : : {
1156 [ # # ][ # # ]: 0 : if ( m_xLoadableForm.is() && m_xLoadableForm->isLoaded() )
[ # # ][ # # ]
[ # # ]
1157 : : {
1158 : 0 : ::rtl::OUString sStatement;
1159 : 0 : ::rtl::OUString sFilter;
1160 : 0 : ::rtl::OUString sSort;
1161 : :
1162 [ # # ][ # # ]: 0 : m_xCursorProperties->getPropertyValue( PROPERTY_ACTIVECOMMAND ) >>= sStatement;
[ # # ]
1163 [ # # ][ # # ]: 0 : m_xCursorProperties->getPropertyValue( PROPERTY_FILTER ) >>= sFilter;
[ # # ]
1164 [ # # ][ # # ]: 0 : m_xCursorProperties->getPropertyValue( PROPERTY_SORT ) >>= sSort;
[ # # ]
1165 : :
1166 [ # # ][ # # ]: 0 : m_xParser->setElementaryQuery( sStatement );
1167 [ # # ][ # # ]: 0 : m_xParser->setFilter ( sFilter );
1168 [ # # ][ # # ]: 0 : m_xParser->setOrder ( sSort );
1169 : : }
1170 : :
1171 : : // start listening at the order/sort properties at the form, so
1172 : : // we can keep our parser in sync
1173 [ # # ][ # # ]: 0 : m_xCursorProperties->addPropertyChangeListener( PROPERTY_ACTIVECOMMAND, this );
[ # # ][ # # ]
1174 [ # # ][ # # ]: 0 : m_xCursorProperties->addPropertyChangeListener( PROPERTY_FILTER, this );
[ # # ][ # # ]
1175 [ # # ][ # # ]: 0 : m_xCursorProperties->addPropertyChangeListener( PROPERTY_SORT, this );
[ # # ][ # # ]
[ # # ]
1176 : : }
1177 : : }
1178 : 0 : catch( const Exception& )
1179 : : {
1180 : : OSL_FAIL( "FormOperations::impl_ensureInitializedParser_nothrow: caught an exception!" );
1181 : : }
1182 : :
1183 : 0 : m_bInitializedParser = true;
1184 : : }
1185 : :
1186 : : //--------------------------------------------------------------------
1187 : 19 : void FormOperations::impl_disposeParser_nothrow()
1188 : : {
1189 : : try
1190 : : {
1191 : : // if we have a parser (and a cursor), then we're listening at the cursor's
1192 : : // properties to keep the parser in sync with the cursor
1193 [ - + ][ # # ]: 19 : if ( m_xParser.is() && m_xCursorProperties.is() )
[ - + ]
1194 : : {
1195 [ # # ][ # # ]: 0 : m_xCursorProperties->removePropertyChangeListener( PROPERTY_FILTER, this );
[ # # ][ # # ]
1196 [ # # ][ # # ]: 0 : m_xCursorProperties->removePropertyChangeListener( PROPERTY_ACTIVECOMMAND, this );
[ # # ][ # # ]
1197 [ # # ][ # # ]: 0 : m_xCursorProperties->removePropertyChangeListener( PROPERTY_SORT, this );
[ # # ][ # # ]
1198 : : }
1199 : :
1200 [ + - ]: 19 : Reference< XComponent > xParserComp( m_xParser, UNO_QUERY );
1201 [ - + ]: 19 : if ( xParserComp.is() )
1202 [ # # ][ # # ]: 0 : xParserComp->dispose();
1203 : 19 : m_xParser.clear();
1204 : :
1205 [ # # ]: 19 : m_bInitializedParser = false;
1206 : : }
1207 : 0 : catch( const Exception& )
1208 : : {
1209 : : OSL_FAIL( "FormOperations::impl_disposeParser_nothrow: caught an exception!" );
1210 : : }
1211 : 19 : }
1212 : :
1213 : : //--------------------------------------------------------------------
1214 : 0 : bool FormOperations::impl_canMoveLeft_throw( ) const
1215 : : {
1216 [ # # ]: 0 : if ( !impl_hasCursor_nothrow() )
1217 : 0 : return false;
1218 : :
1219 [ # # ][ # # ]: 0 : return impl_getRowCount_throw() && ( !m_xCursor->isFirst() || impl_isInsertionRow_throw() );
[ # # ]
1220 : : }
1221 : :
1222 : : //--------------------------------------------------------------------
1223 : 0 : bool FormOperations::impl_canMoveRight_throw( ) const
1224 : : {
1225 [ # # ]: 0 : if ( !impl_hasCursor_nothrow() )
1226 : 0 : return false;
1227 : :
1228 : 0 : bool bIsNew = impl_isInsertionRow_throw();
1229 : :
1230 [ # # ][ # # ]: 0 : if ( impl_getRowCount_throw() && !m_xCursor->isLast() && !bIsNew )
[ # # ][ # # ]
1231 : 0 : return true;
1232 : :
1233 [ # # ]: 0 : if ( ::dbtools::canInsert( m_xCursorProperties ) )
1234 [ # # ][ # # ]: 0 : if ( !bIsNew || impl_isModifiedRow_throw() )
[ # # ]
1235 : 0 : return true;
1236 : :
1237 [ # # ][ # # ]: 0 : if ( bIsNew && m_bActiveControlModified )
1238 : 0 : return true;
1239 : :
1240 : 0 : return false;
1241 : : }
1242 : :
1243 : : //--------------------------------------------------------------------
1244 : : namespace
1245 : : {
1246 : : template < typename TYPE >
1247 : 6 : TYPE lcl_safeGetPropertyValue_throw( const Reference< XPropertySet >& _rxProperties, const ::rtl::OUString& _rPropertyName, TYPE _Default )
1248 : : {
1249 : 6 : TYPE value( _Default );
1250 : : OSL_PRECOND( _rxProperties.is(), "FormOperations::<foo>: no cursor (already disposed?)!" );
1251 [ # # ][ + - ]: 6 : if ( _rxProperties.is() )
1252 [ # # ][ # # ]: 6 : OSL_VERIFY( _rxProperties->getPropertyValue( _rPropertyName ) >>= value );
[ + - ][ + - ]
1253 : 6 : return value;
1254 : : }
1255 : : }
1256 : :
1257 : : //--------------------------------------------------------------------
1258 : 0 : bool FormOperations::impl_isInsertionRow_throw() const
1259 : : {
1260 [ # # ]: 0 : return lcl_safeGetPropertyValue_throw( m_xCursorProperties, PROPERTY_ISNEW, false );
1261 : : }
1262 : :
1263 : : //--------------------------------------------------------------------
1264 : 0 : sal_Int32 FormOperations::impl_getRowCount_throw() const
1265 : : {
1266 [ # # ]: 0 : return lcl_safeGetPropertyValue_throw( m_xCursorProperties, PROPERTY_ROWCOUNT, (sal_Int32)0 );
1267 : : }
1268 : : //--------------------------------------------------------------------
1269 : 0 : bool FormOperations::impl_isRowCountFinal_throw() const
1270 : : {
1271 [ # # ]: 0 : return lcl_safeGetPropertyValue_throw( m_xCursorProperties, PROPERTY_ROWCOUNTFINAL, false );
1272 : : }
1273 : :
1274 : : //--------------------------------------------------------------------
1275 : 6 : bool FormOperations::impl_isModifiedRow_throw() const
1276 : : {
1277 [ + - ]: 6 : return lcl_safeGetPropertyValue_throw( m_xCursorProperties, PROPERTY_ISMODIFIED, false );
1278 : : }
1279 : :
1280 : : //--------------------------------------------------------------------
1281 : 0 : bool FormOperations::impl_isParseable_throw() const
1282 : : {
1283 : 0 : const_cast< FormOperations* >( this )->impl_ensureInitializedParser_nothrow();
1284 [ # # ][ # # ]: 0 : return m_xParser.is() && !m_xParser->getQuery().isEmpty();
[ # # ][ # # ]
[ # # ][ # # ]
1285 : : }
1286 : :
1287 : : //--------------------------------------------------------------------
1288 : 0 : bool FormOperations::impl_hasFilterOrOrder_throw() const
1289 : : {
1290 [ # # ][ # # ]: 0 : return impl_isParseable_throw() && ( !m_xParser->getFilter().isEmpty() || !m_xParser->getOrder().isEmpty() );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
1291 : : }
1292 : :
1293 : : //--------------------------------------------------------------------
1294 : 0 : bool FormOperations::impl_isInsertOnlyForm_throw() const
1295 : : {
1296 [ # # ]: 0 : return lcl_safeGetPropertyValue_throw( m_xCursorProperties, PROPERTY_INSERTONLY, true );
1297 : : }
1298 : :
1299 : : //------------------------------------------------------------------------------
1300 : 0 : Reference< XControlModel > FormOperations::impl_getCurrentControlModel_throw() const
1301 : : {
1302 [ # # ][ # # ]: 0 : Reference< XControl > xControl( m_xController->getCurrentControl() );
1303 : :
1304 : : // special handling for grid controls
1305 [ # # ]: 0 : Reference< XGrid > xGrid( xControl, UNO_QUERY );
1306 : 0 : Reference< XControlModel > xControlModel;
1307 : :
1308 [ # # ]: 0 : if ( xGrid.is() )
1309 : : {
1310 [ # # ][ # # ]: 0 : Reference< XIndexAccess > xColumns( xControl->getModel(), UNO_QUERY_THROW );
[ # # ]
1311 [ # # ][ # # ]: 0 : sal_Int16 nCurrentPos = xGrid->getCurrentColumnPosition();
1312 [ # # ]: 0 : nCurrentPos = impl_gridView2ModelPos_nothrow( xColumns, nCurrentPos );
1313 : :
1314 [ # # ]: 0 : if ( nCurrentPos != (sal_Int16)-1 )
1315 [ # # ][ # # ]: 0 : xColumns->getByIndex( nCurrentPos ) >>= xControlModel;
[ # # ]
1316 : : }
1317 [ # # ]: 0 : else if ( xControl.is() )
1318 : : {
1319 [ # # ][ # # ]: 0 : xControlModel = xControl->getModel();
[ # # ]
1320 : : }
1321 : 0 : return xControlModel;
1322 : : }
1323 : :
1324 : : //------------------------------------------------------------------------------
1325 : 0 : Reference< XPropertySet > FormOperations::impl_getCurrentBoundField_nothrow( ) const
1326 : : {
1327 : : OSL_PRECOND( m_xController.is(), "FormOperations::impl_getCurrentBoundField_nothrow: no controller -> no control!" );
1328 [ # # ]: 0 : if ( !m_xController.is() )
1329 [ # # ]: 0 : return NULL;
1330 : :
1331 : 0 : Reference< XPropertySet > xField;
1332 : : try
1333 : : {
1334 [ # # ][ # # ]: 0 : Reference< XPropertySet > xControlModel( impl_getCurrentControlModel_throw(), UNO_QUERY );
1335 : :
1336 [ # # ][ # # ]: 0 : if ( xControlModel.is() && ::comphelper::hasProperty( PROPERTY_BOUNDFIELD, xControlModel ) )
[ # # ][ # # ]
[ # # # # ]
[ # # ]
1337 [ # # ][ # # ]: 0 : xControlModel->getPropertyValue( PROPERTY_BOUNDFIELD ) >>= xField;
[ # # ][ # # ]
[ # # ]
1338 : :
1339 : : }
1340 [ # # ]: 0 : catch( const Exception& )
1341 : : {
1342 : : DBG_UNHANDLED_EXCEPTION();
1343 : : }
1344 : :
1345 : 0 : return xField;
1346 : : }
1347 : :
1348 : : //------------------------------------------------------------------------------
1349 : 0 : sal_Int16 FormOperations::impl_gridView2ModelPos_nothrow( const Reference< XIndexAccess >& _rxColumns, sal_Int16 _nViewPos ) const
1350 : : {
1351 : : OSL_PRECOND( _rxColumns.is(), "FormOperations::impl_gridView2ModelPos_nothrow: invalid columns container!" );
1352 : : try
1353 : : {
1354 : : // loop through all columns
1355 : 0 : sal_Int16 col = 0;
1356 : 0 : Reference< XPropertySet > xCol;
1357 : 0 : bool bHidden( false );
1358 [ # # ][ # # ]: 0 : for ( col = 0; col < _rxColumns->getCount(); ++col )
[ # # ]
1359 : : {
1360 [ # # ][ # # ]: 0 : _rxColumns->getByIndex( col ) >>= xCol;
[ # # ]
1361 [ # # ][ # # ]: 0 : OSL_VERIFY( xCol->getPropertyValue( PROPERTY_HIDDEN ) >>= bHidden );
[ # # ]
1362 [ # # ]: 0 : if ( bHidden )
1363 : 0 : continue;
1364 : :
1365 : : // for every visible col : if nViewPos is greater zero, decrement it, else we
1366 : : // have found the model position
1367 [ # # ]: 0 : if ( !_nViewPos )
1368 : 0 : break;
1369 : : else
1370 : 0 : --_nViewPos;
1371 : : }
1372 [ # # ][ # # ]: 0 : if ( col < _rxColumns->getCount() )
[ # # ]
1373 [ # # ][ # # ]: 0 : return col;
1374 : : }
1375 : 0 : catch( const Exception& )
1376 : : {
1377 : : DBG_UNHANDLED_EXCEPTION();
1378 : : }
1379 : 0 : return (sal_Int16)-1;
1380 : : }
1381 : :
1382 : : //------------------------------------------------------------------------------
1383 : 0 : bool FormOperations::impl_moveLeft_throw( ) const
1384 : : {
1385 : : OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_moveLeft_throw: no cursor!" );
1386 [ # # ]: 0 : if ( !impl_hasCursor_nothrow() )
1387 : 0 : return false;
1388 : :
1389 : 0 : sal_Bool bRecordInserted = sal_False;
1390 [ # # ]: 0 : sal_Bool bSuccess = impl_commitCurrentRecord_throw( &bRecordInserted );
1391 : :
1392 [ # # ]: 0 : if ( !bSuccess )
1393 : 0 : return false;
1394 : :
1395 [ # # ]: 0 : if ( bRecordInserted )
1396 : : {
1397 : : // retrieve the bookmark of the new record and move to the record preceding this bookmark
1398 [ # # ]: 0 : Reference< XRowLocate > xLocate( m_xCursor, UNO_QUERY );
1399 : : OSL_ENSURE( xLocate.is(), "FormOperations::impl_moveLeft_throw: no XRowLocate!" );
1400 [ # # ]: 0 : if ( xLocate.is() )
1401 [ # # ][ # # ]: 0 : xLocate->moveRelativeToBookmark( xLocate->getBookmark(), -1 );
[ # # ][ # # ]
1402 : : }
1403 : : else
1404 : : {
1405 [ # # ][ # # ]: 0 : if ( impl_isInsertionRow_throw() )
1406 : : {
1407 : : // we assume that the inserted record is now the last record in the
1408 : : // result set
1409 [ # # ][ # # ]: 0 : m_xCursor->last();
1410 : : }
1411 : : else
1412 [ # # ][ # # ]: 0 : m_xCursor->previous();
1413 : : }
1414 : :
1415 : 0 : return true;
1416 : : }
1417 : :
1418 : : //--------------------------------------------------------------------
1419 : 0 : bool FormOperations::impl_moveRight_throw( ) const
1420 : : {
1421 : : OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_moveRight_throw: no cursor!" );
1422 [ # # ]: 0 : if ( !impl_hasCursor_nothrow() )
1423 : 0 : return false;
1424 : :
1425 : 0 : sal_Bool bRecordInserted = sal_False;
1426 [ # # ]: 0 : sal_Bool bSuccess = impl_commitCurrentRecord_throw( &bRecordInserted );
1427 : :
1428 [ # # ]: 0 : if ( !bSuccess )
1429 : 0 : return false;
1430 : :
1431 [ # # ]: 0 : if ( bRecordInserted )
1432 : : {
1433 : : // go to insert row
1434 [ # # ][ # # ]: 0 : m_xUpdateCursor->moveToInsertRow();
1435 : : }
1436 : : else
1437 : : {
1438 [ # # ][ # # ]: 0 : if ( m_xCursor->isLast() )
[ # # ]
1439 [ # # ][ # # ]: 0 : m_xUpdateCursor->moveToInsertRow();
1440 : : else
1441 [ # # ][ # # ]: 0 : m_xCursor->next();
1442 : : }
1443 : :
1444 : 0 : return true;
1445 : : }
1446 : :
1447 : : //--------------------------------------------------------------------
1448 : 0 : void FormOperations::impl_resetAllControls_nothrow() const
1449 : : {
1450 [ # # ]: 0 : Reference< XIndexAccess > xContainer( m_xCursor, UNO_QUERY );
1451 [ # # ]: 0 : if ( !xContainer.is() )
1452 : 0 : return;
1453 : :
1454 : : try
1455 : : {
1456 : 0 : Reference< XReset > xReset;
1457 [ # # ][ # # ]: 0 : sal_Int32 nCount( xContainer->getCount() );
1458 [ # # ]: 0 : for ( sal_Int32 i = 0; i < nCount; ++i )
1459 : : {
1460 [ # # ][ # # ]: 0 : if ( xContainer->getByIndex( i ) >>= xReset )
[ # # ][ # # ]
1461 : : {
1462 : : // no resets on sub forms
1463 [ # # ]: 0 : Reference< XForm > xAsForm( xReset, UNO_QUERY );
1464 [ # # ]: 0 : if ( !xAsForm.is() )
1465 [ # # ][ # # ]: 0 : xReset->reset();
1466 : : }
1467 [ # # ]: 0 : }
1468 : : }
1469 [ # # ]: 0 : catch( const Exception& )
1470 : : {
1471 : : DBG_UNHANDLED_EXCEPTION();
1472 [ # # ]: 0 : }
1473 : : }
1474 : :
1475 : : //------------------------------------------------------------------------------
1476 : 0 : void FormOperations::impl_executeAutoSort_throw( bool _bUp ) const
1477 : : {
1478 : : OSL_PRECOND( m_xController.is(), "FormOperations::impl_executeAutoSort_throw: need a controller for this!" );
1479 : : OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeAutoSort_throw: need a cursor for this!" );
1480 : : OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeAutoSort_throw: need a parseable statement for this!" );
1481 [ # # ][ # # ]: 0 : if ( !m_xController.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
[ # # ][ # # ]
1482 : 0 : return;
1483 : :
1484 : : try
1485 : : {
1486 [ # # ][ # # ]: 0 : Reference< XControl > xControl = m_xController->getCurrentControl();
1487 [ # # ][ # # ]: 0 : if ( !xControl.is() || !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
[ # # ][ # # ]
[ # # ][ # # ]
1488 : : return;
1489 : :
1490 [ # # ]: 0 : Reference< XPropertySet > xBoundField( impl_getCurrentBoundField_nothrow() );
1491 [ # # ]: 0 : if ( !xBoundField.is() )
1492 : : return;
1493 : :
1494 : 0 : ::rtl::OUString sOriginalSort;
1495 [ # # ][ # # ]: 0 : m_xCursorProperties->getPropertyValue( PROPERTY_SORT ) >>= sOriginalSort;
[ # # ]
1496 : :
1497 : : // automatic sort by field is expected to always resets the previous sort order
1498 [ # # ][ # # ]: 0 : m_xParser->setOrder( ::rtl::OUString() );
1499 : :
1500 [ # # ]: 0 : param_appendOrderByColumn aParam;
1501 [ # # ]: 0 : aParam.xField = xBoundField;
1502 : 0 : aParam.bUp = _bUp;
1503 : : impl_doActionInSQLContext_throw(
1504 : : (Action)&FormOperations::impl_appendOrderByColumn_throw,
1505 : : static_cast< const void* >( &aParam ),
1506 : : (sal_uInt16)RID_STR_COULD_NOT_SET_ORDER
1507 [ # # ]: 0 : );
1508 : :
1509 [ # # ]: 0 : WaitObject aWO( NULL );
1510 : : try
1511 : : {
1512 [ # # ][ # # ]: 0 : m_xCursorProperties->setPropertyValue( PROPERTY_SORT, makeAny( m_xParser->getOrder() ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1513 [ # # ][ # # ]: 0 : m_xLoadableForm->reload();
1514 : : }
1515 [ # # ]: 0 : catch( const Exception& )
1516 : : {
1517 : : OSL_FAIL( "FormOperations::impl_executeAutoSort_throw: caught an exception while setting the parser properties!" );
1518 : : }
1519 : :
1520 : :
1521 [ # # ][ # # ]: 0 : if ( !m_xLoadableForm->isLoaded() )
[ # # ]
1522 : : { // something went wrong -> restore the original state
1523 : : try
1524 : : {
1525 [ # # ][ # # ]: 0 : m_xParser->setOrder( sOriginalSort );
1526 [ # # ][ # # ]: 0 : m_xCursorProperties->setPropertyValue( PROPERTY_SORT, makeAny( m_xParser->getOrder() ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1527 [ # # ][ # # ]: 0 : m_xLoadableForm->reload();
1528 : : }
1529 [ # # ]: 0 : catch( const Exception& )
1530 : : {
1531 : : OSL_FAIL( "FormOperations::impl_executeAutoSort_throw: could not reset the form to it's original state!" );
1532 : : }
1533 : :
1534 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
1535 : : }
1536 : 0 : catch( const RuntimeException& ) { throw; }
1537 : 0 : catch( const SQLException& ) { throw; }
1538 [ # # # # ]: 0 : catch( const Exception& )
1539 : : {
1540 [ # # # # : 0 : throw WrappedTargetException( ::rtl::OUString(), *const_cast< FormOperations* >( this ), ::cppu::getCaughtException() );
# # ]
1541 : : }
1542 : : }
1543 : :
1544 : : //------------------------------------------------------------------------------
1545 : 0 : void FormOperations::impl_executeAutoFilter_throw( ) const
1546 : : {
1547 : : OSL_PRECOND( m_xController.is(), "FormOperations::impl_executeAutoFilter_throw: need a controller for this!" );
1548 : : OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeAutoFilter_throw: need a cursor for this!" );
1549 : : OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeAutoFilter_throw: need a parseable statement for this!" );
1550 [ # # ][ # # ]: 0 : if ( !m_xController.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
[ # # ][ # # ]
1551 : 0 : return;
1552 : :
1553 : : try
1554 : : {
1555 [ # # ][ # # ]: 0 : Reference< XControl > xControl = m_xController->getCurrentControl();
1556 [ # # ][ # # ]: 0 : if ( !xControl.is() || !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
[ # # ][ # # ]
[ # # ][ # # ]
1557 : : return;
1558 : :
1559 [ # # ]: 0 : Reference< XPropertySet > xBoundField( impl_getCurrentBoundField_nothrow() );
1560 [ # # ]: 0 : if ( !xBoundField.is() )
1561 : : return;
1562 : :
1563 : 0 : ::rtl::OUString sOriginalFilter;
1564 [ # # ][ # # ]: 0 : m_xCursorProperties->getPropertyValue( PROPERTY_FILTER ) >>= sOriginalFilter;
[ # # ]
1565 : 0 : sal_Bool bApplied = sal_True;
1566 [ # # ][ # # ]: 0 : m_xCursorProperties->getPropertyValue( PROPERTY_APPLYFILTER ) >>= bApplied;
[ # # ]
1567 : :
1568 : : // if we have a filter, but it's not applied, then we have to overwrite it, else append one
1569 [ # # ]: 0 : if ( !bApplied )
1570 [ # # ][ # # ]: 0 : m_xParser->setFilter( ::rtl::OUString() );
1571 : :
1572 [ # # ]: 0 : param_appendFilterByColumn aParam;
1573 [ # # ]: 0 : aParam.xField = xBoundField;
1574 : : impl_doActionInSQLContext_throw(
1575 : : (Action)&FormOperations::impl_appendFilterByColumn_throw,
1576 : : static_cast< const void* >( &aParam ),
1577 : : (sal_uInt16)RID_STR_COULD_NOT_SET_FILTER
1578 [ # # ]: 0 : );
1579 : :
1580 [ # # ]: 0 : WaitObject aWO( NULL );
1581 : : try
1582 : : {
1583 [ # # ][ # # ]: 0 : m_xCursorProperties->setPropertyValue( PROPERTY_FILTER, makeAny( m_xParser->getFilter() ) );
[ # # ][ # # ]
[ # # ][ # # ]
1584 [ # # ][ # # ]: 0 : m_xCursorProperties->setPropertyValue( PROPERTY_APPLYFILTER, makeAny( (sal_Bool)sal_True ) );
[ # # ][ # # ]
[ # # ]
1585 : :
1586 [ # # ][ # # ]: 0 : m_xLoadableForm->reload();
1587 : : }
1588 [ # # ]: 0 : catch( const Exception& )
1589 : : {
1590 : : OSL_FAIL( "FormOperations::impl_executeAutoFilter_throw: caught an exception while setting the parser properties!" );
1591 : : }
1592 : :
1593 : :
1594 [ # # ][ # # ]: 0 : if ( !m_xLoadableForm->isLoaded() )
[ # # ]
1595 : : { // something went wrong -> restore the original state
1596 : : try
1597 : : {
1598 [ # # ][ # # ]: 0 : m_xParser->setOrder( sOriginalFilter );
1599 [ # # ][ # # ]: 0 : m_xCursorProperties->setPropertyValue( PROPERTY_APPLYFILTER, makeAny( (sal_Bool)bApplied ) );
[ # # ][ # # ]
1600 [ # # ][ # # ]: 0 : m_xCursorProperties->setPropertyValue( PROPERTY_FILTER, makeAny( m_xParser->getFilter() ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1601 [ # # ][ # # ]: 0 : m_xLoadableForm->reload();
1602 : : }
1603 [ # # ]: 0 : catch( const Exception& )
1604 : : {
1605 : : OSL_FAIL( "FormOperations::impl_executeAutoFilter_throw: could not reset the form to it's original state!" );
1606 : : }
1607 : :
1608 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
1609 : : }
1610 : 0 : catch( const RuntimeException& ) { throw; }
1611 : 0 : catch( const SQLException& ) { throw; }
1612 [ # # # # ]: 0 : catch( const Exception& )
1613 : : {
1614 [ # # # # : 0 : throw WrappedTargetException( ::rtl::OUString(), *const_cast< FormOperations* >( this ), ::cppu::getCaughtException() );
# # ]
1615 : : }
1616 : : }
1617 : :
1618 : : //--------------------------------------------------------------------
1619 : 0 : void FormOperations::impl_executeFilterOrSort_throw( bool _bFilter ) const
1620 : : {
1621 : : OSL_PRECOND( m_xController.is(), "FormOperations::impl_executeFilterOrSort_throw: need a controller for this!" );
1622 : : OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeFilterOrSort_throw: need a cursor for this!" );
1623 : : OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeFilterOrSort_throw: need a parseable statement for this!" );
1624 [ # # ][ # # ]: 0 : if ( !m_xController.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
[ # # ][ # # ]
1625 : 0 : return;
1626 : :
1627 [ # # ][ # # ]: 0 : if ( !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
[ # # ]
1628 : 0 : return;
1629 : : try
1630 : : {
1631 : 0 : PropertyValue aFirst;
1632 [ # # ]: 0 : aFirst.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "QueryComposer" ) );
1633 [ # # ]: 0 : aFirst.Value <<= m_xParser;
1634 : :
1635 : 0 : PropertyValue aSecond;
1636 [ # # ]: 0 : aSecond.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RowSet" ) );
1637 [ # # ]: 0 : aSecond.Value <<= m_xCursorProperties;
1638 : :
1639 [ # # ]: 0 : Sequence<Any> aInit(2);
1640 [ # # ][ # # ]: 0 : aInit[0] <<= aFirst;
1641 [ # # ][ # # ]: 0 : aInit[1] <<= aSecond;
1642 : :
1643 : 0 : ::rtl::OUString sDialogServiceName;
1644 [ # # ]: 0 : if ( _bFilter )
1645 [ # # ]: 0 : sDialogServiceName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.FilterDialog" ) );
1646 : : else
1647 [ # # ]: 0 : sDialogServiceName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.OrderDialog" ) );
1648 : :
1649 : 0 : Reference< XExecutableDialog> xDialog;
1650 [ # # ]: 0 : m_aContext.createComponentWithArguments( sDialogServiceName, aInit, xDialog );
1651 : :
1652 [ # # ]: 0 : if ( !xDialog.is() )
1653 : : {
1654 [ # # ][ # # ]: 0 : ShowServiceNotAvailableError( NULL, sDialogServiceName, sal_True );
[ # # ]
1655 : : return;
1656 : : }
1657 : :
1658 [ # # ][ # # ]: 0 : if ( RET_OK == xDialog->execute() )
[ # # ]
1659 : : {
1660 [ # # ]: 0 : WaitObject aWO( NULL );
1661 [ # # ]: 0 : if ( _bFilter )
1662 [ # # ][ # # ]: 0 : m_xCursorProperties->setPropertyValue( PROPERTY_FILTER, makeAny( m_xParser->getFilter() ) );
[ # # ][ # # ]
[ # # ][ # # ]
1663 : : else
1664 [ # # ][ # # ]: 0 : m_xCursorProperties->setPropertyValue( PROPERTY_SORT, makeAny( m_xParser->getOrder() ) );
[ # # ][ # # ]
[ # # ][ # # ]
1665 [ # # ][ # # ]: 0 : m_xLoadableForm->reload();
[ # # ]
1666 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
[ # # ][ # # ]
1667 : :
1668 : : }
1669 : 0 : catch( const RuntimeException& ) { throw; }
1670 : 0 : catch( const SQLException& ) { throw; }
1671 [ # # # # ]: 0 : catch( const Exception& )
1672 : : {
1673 [ # # # # : 0 : throw WrappedTargetException( ::rtl::OUString(), *const_cast< FormOperations* >( this ), ::cppu::getCaughtException() );
# # ]
1674 : : }
1675 : : }
1676 : :
1677 : : //------------------------------------------------------------------------------
1678 : 0 : void FormOperations::impl_appendOrderByColumn_throw( const void* _pActionParam ) const
1679 : : {
1680 : 0 : const param_appendOrderByColumn* pParam = static_cast< const param_appendOrderByColumn* >( _pActionParam );
1681 : 0 : m_xParser->appendOrderByColumn( pParam->xField, pParam->bUp );
1682 : 0 : }
1683 : :
1684 : : //------------------------------------------------------------------------------
1685 : 0 : void FormOperations::impl_appendFilterByColumn_throw( const void* _pActionParam ) const
1686 : : {
1687 : 0 : const param_appendFilterByColumn* pParam = static_cast< const param_appendFilterByColumn* >( _pActionParam );
1688 : 0 : sal_Int32 nOp = SQLFilterOperator::EQUAL;
1689 [ # # ]: 0 : if ( pParam->xField.is() )
1690 : : {
1691 : 0 : sal_Int32 nType = 0;
1692 [ # # ][ # # ]: 0 : pParam->xField->getPropertyValue(PROPERTY_FIELDTYPE) >>= nType;
[ # # ]
1693 [ # # ]: 0 : switch(nType)
1694 : : {
1695 : : case DataType::VARCHAR:
1696 : : case DataType::CHAR:
1697 : : case DataType::LONGVARCHAR:
1698 : 0 : nOp = SQLFilterOperator::LIKE;
1699 : 0 : break;
1700 : : default:
1701 : 0 : nOp = SQLFilterOperator::EQUAL;
1702 : : }
1703 : : }
1704 : 0 : m_xParser->appendFilterByColumn( pParam->xField, sal_True,nOp );
1705 : 0 : }
1706 : :
1707 : : //------------------------------------------------------------------------------
1708 : 0 : void FormOperations::impl_doActionInSQLContext_throw( Action _pAction, const void* _pParam, sal_uInt16 _nErrorResourceId ) const
1709 : : {
1710 : : try
1711 : : {
1712 [ # # ][ # # ]: 0 : (this->*_pAction)( _pParam );
1713 : : }
1714 : 0 : catch( const SQLException& e )
1715 : : {
1716 : : (void)e;
1717 [ # # ]: 0 : if ( !_nErrorResourceId )
1718 : : // no information to prepend
1719 : 0 : throw;
1720 : :
1721 [ # # # # ]: 0 : SQLExceptionInfo aInfo( ::cppu::getCaughtException() );
1722 [ # # ]: 0 : ::rtl::OUString sAdditionalError( FRM_RES_STRING( _nErrorResourceId ) );
1723 [ # # ]: 0 : aInfo.prepend( sAdditionalError );
1724 [ # # # # ]: 0 : aInfo.doThrow();
1725 : : }
1726 : 0 : catch( const RuntimeException& ) { throw; }
1727 [ # # # # ]: 0 : catch( const Exception& )
1728 : : {
1729 [ # # ]: 0 : ::rtl::OUString sAdditionalError( FRM_RES_STRING( _nErrorResourceId ) );
1730 [ # # # # : 0 : throw WrappedTargetException( sAdditionalError, *const_cast< FormOperations* >( this ), ::cppu::getCaughtException() );
# # ]
1731 : : }
1732 : 0 : }
1733 : :
1734 : : //........................................................................
1735 : : } // namespace frm
1736 : : //........................................................................
1737 : :
1738 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|