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