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