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