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