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