1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
22 #include "formoperations.hxx"
23 #include "frm_strings.hxx"
24 #include "frm_resource.hxx"
25 #include "frm_resource.hrc"
26 #include "services.hxx"
28 #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
29 #include <com/sun/star/util/XModifyBroadcaster.hpp>
30 #include <com/sun/star/form/runtime/FormFeature.hpp>
31 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
32 #include <com/sun/star/lang/DisposedException.hpp>
33 #include <com/sun/star/awt/XControl.hpp>
34 #include <com/sun/star/form/XGrid.hpp>
35 #include <com/sun/star/form/XBoundControl.hpp>
36 #include <com/sun/star/form/XBoundComponent.hpp>
37 #include <com/sun/star/sdbcx/XRowLocate.hpp>
38 #include <com/sun/star/form/XConfirmDeleteListener.hpp>
39 #include <com/sun/star/sdb/RowChangeEvent.hpp>
40 #include <com/sun/star/sdb/RowChangeAction.hpp>
41 #include <com/sun/star/sdb/OrderDialog.hpp>
42 #include <com/sun/star/sdb/FilterDialog.hpp>
43 #include <com/sun/star/sdbc/DataType.hpp>
44 #include <com/sun/star/form/XReset.hpp>
45 #include <com/sun/star/beans/XMultiPropertySet.hpp>
46 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
47 #include <com/sun/star/util/XRefreshable.hpp>
49 #include <connectivity/dbtools.hxx>
50 #include <connectivity/dbexception.hxx>
51 #include <vcl/svapp.hxx>
52 #include <vcl/stdtext.hxx>
53 #include <vcl/msgbox.hxx>
54 #include <vcl/waitobj.hxx>
55 #include <tools/diagnose_ex.h>
56 #include <comphelper/container.hxx>
57 #include <comphelper/property.hxx>
58 #include <comphelper/namedvaluecollection.hxx>
59 #include <comphelper/processfactory.hxx>
60 #include <cppuhelper/exc_hlp.hxx>
61 #include <cppuhelper/supportsservice.hxx>
62 #include <osl/mutex.hxx>
63 #include <sal/macros.h>
70 using ::dbtools::SQLExceptionInfo
;
71 using ::com::sun::star::uno::Reference
;
72 using ::com::sun::star::uno::XComponentContext
;
73 using ::com::sun::star::uno::RuntimeException
;
74 using ::com::sun::star::uno::Sequence
;
75 using ::com::sun::star::uno::Exception
;
76 using ::com::sun::star::uno::Any
;
77 using ::com::sun::star::uno::XInterface
;
78 using ::com::sun::star::sdbc::XRowSet
;
79 using ::com::sun::star::sdbc::XResultSetUpdate
;
80 using ::com::sun::star::form::runtime::XFormController
;
81 using ::com::sun::star::form::runtime::XFormOperations
;
82 using ::com::sun::star::form::runtime::XFeatureInvalidation
;
83 using ::com::sun::star::form::runtime::FeatureState
;
84 using ::com::sun::star::lang::IllegalArgumentException
;
85 using ::com::sun::star::sdbc::SQLException
;
86 using namespace ::com::sun::star::sdbc
;
87 using ::com::sun::star::form::XForm
;
88 using ::com::sun::star::ucb::AlreadyInitializedException
;
89 using ::com::sun::star::util::XModifyBroadcaster
;
90 using ::com::sun::star::uno::UNO_QUERY
;
91 using ::com::sun::star::lang::EventObject
;
92 using ::com::sun::star::beans::PropertyChangeEvent
;
93 using ::com::sun::star::lang::XMultiServiceFactory
;
94 using ::com::sun::star::lang::DisposedException
;
95 using ::com::sun::star::beans::XPropertySet
;
96 using ::com::sun::star::awt::XControl
;
97 using ::com::sun::star::form::XGrid
;
98 using ::com::sun::star::container::XIndexAccess
;
99 using ::com::sun::star::uno::UNO_QUERY_THROW
;
100 using ::com::sun::star::form::XBoundControl
;
101 using ::com::sun::star::form::XBoundComponent
;
102 using ::com::sun::star::sdbcx::XRowLocate
;
103 using ::com::sun::star::form::XConfirmDeleteListener
;
104 using ::com::sun::star::sdb::RowChangeEvent
;
105 using namespace ::com::sun::star::sdb
;
106 using ::com::sun::star::form::XReset
;
107 using ::com::sun::star::beans::XMultiPropertySet
;
108 using ::com::sun::star::uno::makeAny
;
109 using ::com::sun::star::lang::WrappedTargetException
;
110 using ::com::sun::star::beans::PropertyValue
;
111 using ::com::sun::star::ui::dialogs::XExecutableDialog
;
112 using ::com::sun::star::beans::NamedValue
;
113 using ::com::sun::star::util::XRefreshable
;
114 using ::com::sun::star::awt::XControlModel
;
116 namespace FormFeature
= ::com::sun::star::form::runtime::FormFeature
;
117 namespace RowChangeAction
= ::com::sun::star::sdb::RowChangeAction
;
119 FormOperations::FormOperations( const Reference
< XComponentContext
>& _rxContext
)
120 :FormOperations_Base( m_aMutex
)
121 ,m_xContext( _rxContext
)
122 ,m_bInitializedParser( false )
123 ,m_bActiveControlModified( false )
124 ,m_bConstructed( false )
126 ,m_nMethodNestingLevel( 0 )
131 FormOperations::~FormOperations()
135 OUString
FormOperations::getImplementationName_Static( ) throw(RuntimeException
)
137 return OUString( "com.sun.star.comp.forms.FormOperations" );
140 Sequence
< OUString
> FormOperations::getSupportedServiceNames_Static( ) throw(RuntimeException
)
142 Sequence
< OUString
> aNames(1);
143 aNames
[0] = "com.sun.star.form.runtime.FormOperations";
147 void SAL_CALL
FormOperations::initialize( const Sequence
< Any
>& _arguments
) throw (Exception
, RuntimeException
, std::exception
)
149 if ( m_bConstructed
)
150 throw AlreadyInitializedException();
152 if ( _arguments
.getLength() == 1 )
154 Reference
< XFormController
> xController
;
155 Reference
< XForm
> xForm
;
156 if ( _arguments
[0] >>= xController
)
157 createWithFormController( xController
);
158 else if ( _arguments
[0] >>= xForm
)
159 createWithForm( xForm
);
161 throw IllegalArgumentException( OUString(), *this, 1 );
165 throw IllegalArgumentException( OUString(), *this, 0 );
168 OUString SAL_CALL
FormOperations::getImplementationName( ) throw (RuntimeException
, std::exception
)
170 return getImplementationName_Static();
173 sal_Bool SAL_CALL
FormOperations::supportsService( const OUString
& _ServiceName
) throw (RuntimeException
, std::exception
)
175 return cppu::supportsService(this, _ServiceName
);
178 Sequence
< OUString
> SAL_CALL
FormOperations::getSupportedServiceNames( ) throw (RuntimeException
, std::exception
)
180 return getSupportedServiceNames_Static();
183 Reference
< XRowSet
> SAL_CALL
FormOperations::getCursor() throw (RuntimeException
, std::exception
)
185 MethodGuard
aGuard( *this );
189 Reference
< XResultSetUpdate
> SAL_CALL
FormOperations::getUpdateCursor() throw (RuntimeException
, std::exception
)
191 MethodGuard
aGuard( *this );
192 return m_xUpdateCursor
;
196 Reference
< XFormController
> SAL_CALL
FormOperations::getController() throw (RuntimeException
, std::exception
)
198 MethodGuard
aGuard( *this );
199 return m_xController
;
203 Reference
< XFeatureInvalidation
> SAL_CALL
FormOperations::getFeatureInvalidation() throw (RuntimeException
, std::exception
)
205 MethodGuard
aGuard( *this );
206 return m_xFeatureInvalidation
;
210 void SAL_CALL
FormOperations::setFeatureInvalidation( const Reference
< XFeatureInvalidation
> & _rxFeatureInvalidation
) throw (RuntimeException
, std::exception
)
212 MethodGuard
aGuard( *this );
213 m_xFeatureInvalidation
= _rxFeatureInvalidation
;
217 FeatureState SAL_CALL
FormOperations::getState( ::sal_Int16 _nFeature
) throw (RuntimeException
, std::exception
)
219 MethodGuard
aGuard( *this );
222 aState
.Enabled
= sal_False
;
226 // some checks for basic pre-requisites
227 if ( !m_xLoadableForm
.is()
228 || !m_xLoadableForm
->isLoaded()
229 || !m_xCursorProperties
.is()
237 case FormFeature::MoveToFirst
:
238 case FormFeature::MoveToPrevious
:
239 aState
.Enabled
= impl_canMoveLeft_throw( );
242 case FormFeature::MoveToNext
:
243 aState
.Enabled
= impl_canMoveRight_throw();
246 case FormFeature::MoveToLast
:
247 aState
.Enabled
= impl_getRowCount_throw() && ( !m_xCursor
->isLast() || impl_isInsertionRow_throw() );
250 case FormFeature::DeleteRecord
:
252 if ( m_xCursor
->rowDeleted() )
253 aState
.Enabled
= sal_False
;
256 // allowed to delete the row ?
257 aState
.Enabled
= !impl_isInsertionRow_throw() && ::dbtools::canDelete( m_xCursorProperties
);
261 case FormFeature::MoveToInsertRow
:
262 // if we are inserting we can move to the next row if the current record or control is modified
263 aState
.Enabled
= impl_isInsertionRow_throw()
264 ? impl_isModifiedRow_throw() || m_bActiveControlModified
265 : ::dbtools::canInsert( m_xCursorProperties
);
268 case FormFeature::ReloadForm
:
270 // there must be an active connection
271 Reference
< XRowSet
> xCursorRowSet( m_xCursor
, UNO_QUERY
);
272 aState
.Enabled
= ::dbtools::getConnection( xCursorRowSet
).is();
274 // and an active command
275 OUString sActiveCommand
;
276 m_xCursorProperties
->getPropertyValue( PROPERTY_ACTIVECOMMAND
) >>= sActiveCommand
;
277 aState
.Enabled
= aState
.Enabled
&& !sActiveCommand
.isEmpty();
281 case FormFeature::RefreshCurrentControl
:
283 Reference
< XRefreshable
> xControlModelRefresh( impl_getCurrentControlModel_throw(), UNO_QUERY
);
284 aState
.Enabled
= xControlModelRefresh
.is();
288 case FormFeature::SaveRecordChanges
:
289 case FormFeature::UndoRecordChanges
:
290 aState
.Enabled
= impl_isModifiedRow_throw() || m_bActiveControlModified
;
293 case FormFeature::RemoveFilterAndSort
:
294 if ( impl_isParseable_throw() && impl_hasFilterOrOrder_throw() )
295 aState
.Enabled
= !impl_isInsertOnlyForm_throw();
298 case FormFeature::SortAscending
:
299 case FormFeature::SortDescending
:
300 case FormFeature::AutoFilter
:
301 if ( m_xController
.is() && impl_isParseable_throw() )
303 bool bIsDeleted
= m_xCursor
->rowDeleted();
305 if ( !bIsDeleted
&& !impl_isInsertOnlyForm_throw() )
307 Reference
< XPropertySet
> xBoundField
= impl_getCurrentBoundField_nothrow( );
308 if ( xBoundField
.is() )
309 xBoundField
->getPropertyValue( PROPERTY_SEARCHABLE
) >>= aState
.Enabled
;
314 case FormFeature::InteractiveSort
:
315 case FormFeature::InteractiveFilter
:
316 if ( impl_isParseable_throw() )
317 aState
.Enabled
= !impl_isInsertOnlyForm_throw();
320 case FormFeature::ToggleApplyFilter
:
323 m_xCursorProperties
->getPropertyValue( PROPERTY_FILTER
) >>= sFilter
;
324 if ( !sFilter
.isEmpty() )
326 aState
.State
= m_xCursorProperties
->getPropertyValue( PROPERTY_APPLYFILTER
);
327 aState
.Enabled
= !impl_isInsertOnlyForm_throw();
330 aState
.State
<<= false;
334 case FormFeature::MoveAbsolute
:
336 sal_Int32 nPosition
= m_xCursor
->getRow();
337 bool bIsNew
= impl_isInsertionRow_throw();
338 sal_Int32 nCount
= impl_getRowCount_throw();
339 bool bFinalCount
= impl_isRowCountFinal_throw();
341 if ( ( nPosition
>= 0 ) || bIsNew
)
345 // special case: there are no records at all, and we
346 // can't insert records -> disabled
347 if ( !nCount
&& !::dbtools::canInsert( m_xCursorProperties
) )
349 aState
.Enabled
= sal_False
;
354 nPosition
= ++nCount
;
355 aState
.State
<<= (sal_Int32
)nPosition
;
356 aState
.Enabled
= sal_True
;
361 aState
.State
<<= (sal_Int32
)nPosition
;
362 aState
.Enabled
= sal_True
;
368 case FormFeature::TotalRecords
:
370 bool bIsNew
= impl_isInsertionRow_throw();
371 sal_Int32 nCount
= impl_getRowCount_throw();
372 bool bFinalCount
= impl_isRowCountFinal_throw();
377 OUString sValue
= OUString::number( nCount
);
381 aState
.State
<<= sValue
;
382 aState
.Enabled
= sal_True
;
387 OSL_FAIL( "FormOperations::getState: unknown feature id!" );
391 catch( const Exception
& )
393 OSL_FAIL( "FormOperations::getState: caught an exception!" );
400 sal_Bool SAL_CALL
FormOperations::isEnabled( ::sal_Int16 _nFeature
) throw (RuntimeException
, std::exception
)
402 MethodGuard
aGuard( *this );
404 FeatureState
aState( getState( _nFeature
) );
405 return aState
.Enabled
;
411 static bool lcl_needConfirmCommit( sal_Int32 _nFeature
)
413 return ( ( _nFeature
== FormFeature::ReloadForm
)
414 || ( _nFeature
== FormFeature::RemoveFilterAndSort
)
415 || ( _nFeature
== FormFeature::ToggleApplyFilter
)
416 || ( _nFeature
== FormFeature::SortAscending
)
417 || ( _nFeature
== FormFeature::SortDescending
)
418 || ( _nFeature
== FormFeature::AutoFilter
)
419 || ( _nFeature
== FormFeature::InteractiveSort
)
420 || ( _nFeature
== FormFeature::InteractiveFilter
)
423 static bool lcl_requiresArguments( sal_Int32 _nFeature
)
425 return ( _nFeature
== FormFeature::MoveAbsolute
);
427 static bool lcl_isExecutableFeature( sal_Int32 _nFeature
)
429 return ( _nFeature
!= FormFeature::TotalRecords
);
432 template < typename TYPE
>
433 TYPE
lcl_safeGetPropertyValue_throw( const Reference
< XPropertySet
>& _rxProperties
, const OUString
& _rPropertyName
, TYPE _Default
)
435 TYPE
value( _Default
);
436 OSL_PRECOND( _rxProperties
.is(), "FormOperations::<foo>: no cursor (already disposed?)!" );
437 if ( _rxProperties
.is() )
438 OSL_VERIFY( _rxProperties
->getPropertyValue( _rPropertyName
) >>= value
);
442 // returns false if parent should *abort* (user pressed cancel)
443 bool checkConfirmation(bool &needConfirmation
, bool &shouldCommit
)
447 // TODO: shouldn't this be done with an interaction handler?
448 ScopedVclPtrInstance
< QueryBox
> aQuery( nullptr, WB_YES_NO_CANCEL
| WB_DEF_YES
, FRM_RES_STRING( RID_STR_QUERY_SAVE_MODIFIED_ROW
) );
449 switch ( aQuery
->Execute() )
452 shouldCommit
= false;
453 // no break on purpose: don't ask again!
455 needConfirmation
= false;
464 bool commit1Form(Reference
< XFormController
> xCntrl
, bool &needConfirmation
, bool &shouldCommit
)
466 Reference
< XFormOperations
> xFrmOps(xCntrl
->getFormOperations());
467 if (!xFrmOps
->commitCurrentControl())
470 if(xFrmOps
->isModifiedRow())
472 if(!checkConfirmation(needConfirmation
, shouldCommit
))
475 if (shouldCommit
&& !xFrmOps
->commitCurrentRecord(bTmp
))
481 bool commitFormAndSubforms(Reference
< XFormController
> xCntrl
, bool needConfirmation
)
483 bool shouldCommit(true);
485 Reference
< XIndexAccess
> xSubForms(xCntrl
, UNO_QUERY
);
486 assert(xSubForms
.is());
489 const sal_Int32 cnt
= xSubForms
->getCount();
490 for(int i
=0; i
< cnt
; ++i
)
492 Reference
< XFormController
> xSubForm(xSubForms
->getByIndex(i
), UNO_QUERY
);
493 assert(xSubForm
.is());
496 if (!commit1Form(xSubForm
, needConfirmation
, shouldCommit
))
502 if(!commit1Form(xCntrl
, needConfirmation
, shouldCommit
))
508 bool commit1Form(Reference
< XForm
> xFrm
, bool &needConfirmation
, bool &shouldCommit
)
510 Reference
< XPropertySet
> xProps(xFrm
, UNO_QUERY_THROW
);
511 // nothing to do if the record is not modified
512 if(!lcl_safeGetPropertyValue_throw( xProps
, PROPERTY_ISMODIFIED
, false ))
515 if(!checkConfirmation(needConfirmation
, shouldCommit
))
519 Reference
< XResultSetUpdate
> xUpd(xFrm
, UNO_QUERY_THROW
);
520 // insert respectively update the row
521 if ( lcl_safeGetPropertyValue_throw( xProps
, PROPERTY_ISNEW
, false ) )
529 bool commitFormAndSubforms(Reference
< XForm
> xFrm
, bool needConfirmation
)
531 // No control... do what we can with the models
532 bool shouldCommit(true);
533 Reference
< XIndexAccess
> xFormComps(xFrm
, UNO_QUERY_THROW
);
534 assert( xFormComps
.is() );
536 const sal_Int32 cnt
= xFormComps
->getCount();
537 for(int i
=0; i
< cnt
; ++i
)
539 Reference
< XForm
> xSubForm(xFormComps
->getByIndex(i
), UNO_QUERY
);
542 if(!commit1Form(xSubForm
, needConfirmation
, shouldCommit
))
547 if(!commit1Form(xFrm
, needConfirmation
, shouldCommit
))
554 void SAL_CALL
FormOperations::execute( ::sal_Int16 _nFeature
) throw (RuntimeException
, IllegalArgumentException
, SQLException
, WrappedTargetException
, std::exception
)
556 SolarMutexGuard aSolarGuard
;
557 MethodGuard
aGuard( *this );
559 if ( ( _nFeature
!= FormFeature::DeleteRecord
) && ( _nFeature
!= FormFeature::UndoRecordChanges
) )
563 if(m_xController
.is())
565 if(!commitFormAndSubforms(m_xController
, lcl_needConfirmCommit( _nFeature
)))
568 else if(m_xCursor
.is())
570 Reference
< XForm
> xForm(m_xCursor
, UNO_QUERY
);
572 if(!commitFormAndSubforms(xForm
, lcl_needConfirmCommit( _nFeature
)))
577 SAL_WARN( "forms.runtime", "No cursor, but trying to execute form operation " << _nFeature
);
585 case FormFeature::MoveToFirst
:
589 case FormFeature::MoveToNext
:
590 impl_moveRight_throw( );
593 case FormFeature::MoveToPrevious
:
594 impl_moveLeft_throw( );
597 case FormFeature::MoveToLast
:
600 // TODO: re-implement this .....
601 // run in an own thread if ...
602 // ... the data source is thread safe ...
603 sal_Bool bAllowOwnThread = sal_False;
604 if ( ::comphelper::hasProperty( PROPERTY_THREADSAFE, m_xCursorProperties ) )
605 m_xCursorProperties->getPropertyValue( PROPERTY_THREADSAFE ) >>= bAllowOwnThread;
607 // ... the record count is unknown
608 sal_Bool bNeedOwnThread sal_False;
609 if ( ::comphelper::hasProperty( PROPERTY_ROWCOUNTFINAL, m_xCursorProperties ) )
610 m_xCursorProperties->getPropertyValue( PROPERTY_ROWCOUNTFINAL ) >>= bNeedOwnThread;
612 if ( bNeedOwnThread && bAllowOwnThread )
620 case FormFeature::ReloadForm
:
621 if ( m_xLoadableForm
.is() )
623 WaitObject
aWO( NULL
);
624 m_xLoadableForm
->reload();
626 // refresh all controls in the form (and sub forms) which can be refreshed
628 ::comphelper::IndexAccessIterator
aIter( m_xLoadableForm
);
629 Reference
< XInterface
> xElement( aIter
.Next() );
630 while ( xElement
.is() )
632 Reference
< XRefreshable
> xRefresh( xElement
, UNO_QUERY
);
635 xElement
= aIter
.Next();
640 case FormFeature::RefreshCurrentControl
:
642 Reference
< XRefreshable
> xControlModelRefresh( impl_getCurrentControlModel_throw(), UNO_QUERY
);
643 OSL_ENSURE( xControlModelRefresh
.is(), "FormOperations::execute: how did you reach this?" );
644 if ( xControlModelRefresh
.is() )
645 xControlModelRefresh
->refresh();
649 case FormFeature::DeleteRecord
:
651 sal_uInt32 nCount
= impl_getRowCount_throw();
654 bool bLeft
= m_xCursor
->isLast() && ( nCount
> 1 );
655 bool bRight
= !m_xCursor
->isLast();
656 bool bSuccess
= false;
659 // ask for confirmation
660 Reference
< XConfirmDeleteListener
> xConfirmDelete( m_xController
, UNO_QUERY
);
662 if ( xConfirmDelete
.is() )
664 RowChangeEvent aEvent
;
665 aEvent
.Source
= Reference
< XInterface
>( m_xCursor
, UNO_QUERY
);
666 aEvent
.Action
= RowChangeAction::DELETE
;
668 bSuccess
= xConfirmDelete
->confirmDelete( aEvent
);
673 m_xUpdateCursor
->deleteRow();
675 catch( const Exception
& )
682 if ( bLeft
|| bRight
)
683 m_xCursor
->relative( bRight
? 1 : -1 );
686 bool bCanInsert
= ::dbtools::canInsert( m_xCursorProperties
);
687 // is it possible to insert another record?
689 m_xUpdateCursor
->moveToInsertRow();
691 // move record to update status
698 case FormFeature::SaveRecordChanges
:
699 case FormFeature::UndoRecordChanges
:
701 bool bInserting
= impl_isInsertionRow_throw();
703 if ( FormFeature::UndoRecordChanges
== _nFeature
)
706 m_xUpdateCursor
->cancelRowUpdates();
708 // reset all controls for this form
709 impl_resetAllControls_nothrow( );
711 if ( bInserting
) // back to insertion mode for this form
712 m_xUpdateCursor
->moveToInsertRow();
718 m_xUpdateCursor
->insertRow();
722 m_xUpdateCursor
->updateRow();
727 case FormFeature::MoveToInsertRow
:
728 // move to the last row before moving to the insert row
730 m_xUpdateCursor
->moveToInsertRow();
733 case FormFeature::RemoveFilterAndSort
:
735 // simultaneously reset Filter and Order property
736 Reference
< XMultiPropertySet
> xProperties( m_xCursorProperties
, UNO_QUERY
);
737 OSL_ENSURE( xProperties
.is(), "FormOperations::execute: no multi property access!" );
738 if ( xProperties
.is() )
740 Sequence
< OUString
> aNames( 2 );
741 aNames
[0] = PROPERTY_FILTER
;
742 aNames
[1] = PROPERTY_SORT
;
744 Sequence
< Any
> aValues( 2 );
745 aValues
[0] <<= OUString();
746 aValues
[1] <<= OUString();
748 WaitObject
aWO( NULL
);
749 xProperties
->setPropertyValues( aNames
, aValues
);
751 if ( m_xLoadableForm
.is() )
752 m_xLoadableForm
->reload();
757 case FormFeature::ToggleApplyFilter
:
758 if ( impl_commitCurrentControl_throw() && impl_commitCurrentRecord_throw() )
760 // simply toggle the value
761 bool bApplied
= false;
762 m_xCursorProperties
->getPropertyValue( PROPERTY_APPLYFILTER
) >>= bApplied
;
763 m_xCursorProperties
->setPropertyValue( PROPERTY_APPLYFILTER
, makeAny( !bApplied
) );
766 WaitObject
aWO( NULL
);
767 m_xLoadableForm
->reload();
771 case FormFeature::SortAscending
:
772 impl_executeAutoSort_throw( true );
775 case FormFeature::SortDescending
:
776 impl_executeAutoSort_throw( false );
779 case FormFeature::AutoFilter
:
780 impl_executeAutoFilter_throw();
783 case FormFeature::InteractiveSort
:
784 impl_executeFilterOrSort_throw( false );
787 case FormFeature::InteractiveFilter
:
788 impl_executeFilterOrSort_throw( true );
793 sal_uInt16 nErrorResourceId
= RID_STR_FEATURE_UNKNOWN
;
794 if ( lcl_requiresArguments( _nFeature
) )
795 nErrorResourceId
= RID_STR_FEATURE_REQUIRES_PARAMETERS
;
796 else if ( !lcl_isExecutableFeature( _nFeature
) )
797 nErrorResourceId
= RID_STR_FEATURE_NOT_EXECUTABLE
;
798 throw IllegalArgumentException( FRM_RES_STRING( nErrorResourceId
), *this, 1 );
802 catch( const RuntimeException
& ) { throw; }
803 catch( const SQLException
& ) { throw; }
804 catch( const Exception
& )
806 throw WrappedTargetException( OUString(), *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
809 impl_invalidateAllSupportedFeatures_nothrow( aGuard
);
813 void SAL_CALL
FormOperations::executeWithArguments( ::sal_Int16 _nFeature
, const Sequence
< NamedValue
>& _rArguments
) throw (RuntimeException
, IllegalArgumentException
, SQLException
, WrappedTargetException
, std::exception
)
815 if ( !lcl_requiresArguments( _nFeature
) )
817 execute( _nFeature
);
821 SolarMutexGuard aSolarGuard
;
822 MethodGuard
aGuard( *this );
824 // at the moment we have only one feature which supports execution parameters
825 if ( !lcl_isExecutableFeature( _nFeature
) )
826 throw IllegalArgumentException( FRM_RES_STRING( RID_STR_FEATURE_NOT_EXECUTABLE
), *this, 1 );
830 case FormFeature::MoveAbsolute
:
832 sal_Int32 nPosition
= -1;
834 ::comphelper::NamedValueCollection
aArguments( _rArguments
);
835 aArguments
.get_ensureType( "Position", nPosition
);
842 // commit before doing anything else
843 if ( m_xController
.is() && !impl_commitCurrentControl_throw() )
845 if ( !impl_commitCurrentRecord_throw() )
848 sal_Int32 nCount
= impl_getRowCount_throw();
849 bool bFinalCount
= impl_isRowCountFinal_throw();
851 if ( bFinalCount
&& ( (sal_Int32
)nPosition
> nCount
) )
854 m_xCursor
->absolute( nPosition
);
856 catch( const RuntimeException
& ) { throw; }
857 catch( const SQLException
& ) { throw; }
858 catch( const Exception
& )
860 throw WrappedTargetException( OUString(), *this, ::cppu::getCaughtException() );
865 throw IllegalArgumentException( FRM_RES_STRING( RID_STR_FEATURE_UNKNOWN
), *this, 1 );
870 sal_Bool SAL_CALL
FormOperations::commitCurrentRecord( sal_Bool
& _out_rRecordInserted
) throw (RuntimeException
, SQLException
, std::exception
)
872 MethodGuard
aGuard( *this );
873 _out_rRecordInserted
= sal_False
;
875 return impl_commitCurrentRecord_throw( &_out_rRecordInserted
);
879 bool FormOperations::impl_commitCurrentRecord_throw( sal_Bool
* _pRecordInserted
) const
881 DBG_ASSERT( m_nMethodNestingLevel
, "FormOperations::impl_commitCurrentRecord_throw: to be called within a MethodGuard'ed section only!" );
883 if ( !impl_hasCursor_nothrow() )
886 // nothing to do if the record is not modified
887 bool bResult
= !impl_isModifiedRow_throw();
890 // insert respectively update the row
891 if ( impl_isInsertionRow_throw() )
893 m_xUpdateCursor
->insertRow();
894 if ( _pRecordInserted
)
895 *_pRecordInserted
= sal_True
;
898 m_xUpdateCursor
->updateRow();
905 sal_Bool SAL_CALL
FormOperations::commitCurrentControl() throw (RuntimeException
, SQLException
, std::exception
)
907 MethodGuard
aGuard( *this );
908 return impl_commitCurrentControl_throw();
912 bool FormOperations::impl_commitCurrentControl_throw() const
914 DBG_ASSERT( m_nMethodNestingLevel
, "FormOperations::impl_commitCurrentControl_throw: to be called within a MethodGuard'ed section only!" );
915 OSL_PRECOND( m_xController
.is(), "FormOperations::commitCurrentControl: no controller!" );
916 if ( !m_xController
.is() )
919 bool bSuccess
= false;
922 Reference
< XControl
> xCurrentControl( m_xController
->getCurrentControl() );
924 // check whether the control is locked
925 Reference
< XBoundControl
> xCheckLock( xCurrentControl
, UNO_QUERY
);
926 bool bControlIsLocked
= xCheckLock
.is() && xCheckLock
->getLock();
928 // commit if necessary
930 if ( xCurrentControl
.is() && !bControlIsLocked
)
932 // both the control and its model can be committable, so try both
933 Reference
< XBoundComponent
> xBound( xCurrentControl
, UNO_QUERY
);
935 xBound
.set(xCurrentControl
->getModel(), css::uno::UNO_QUERY
);
936 // and now really commit
938 bSuccess
= xBound
->commit();
942 catch( const RuntimeException
& ) { throw; }
943 catch( const SQLException
& ) { throw; }
944 catch( const Exception
& )
946 DBG_UNHANDLED_EXCEPTION();
954 sal_Bool SAL_CALL
FormOperations::isInsertionRow() throw (RuntimeException
, WrappedTargetException
, std::exception
)
959 bIs
= impl_isInsertionRow_throw();
961 catch( const RuntimeException
& ) { throw; }
962 catch( const Exception
& )
964 throw WrappedTargetException( OUString(), *this, ::cppu::getCaughtException() );
970 sal_Bool SAL_CALL
FormOperations::isModifiedRow() throw (RuntimeException
, WrappedTargetException
, std::exception
)
975 bIs
= impl_isModifiedRow_throw();
977 catch( const RuntimeException
& ) { throw; }
978 catch( const Exception
& )
980 throw WrappedTargetException( OUString(), *this, ::cppu::getCaughtException() );
986 void SAL_CALL
FormOperations::cursorMoved( const EventObject
& /*_Event*/ ) throw (RuntimeException
, std::exception
)
988 MethodGuard
aGuard( *this );
989 m_bActiveControlModified
= false;
991 impl_invalidateAllSupportedFeatures_nothrow( aGuard
);
995 void SAL_CALL
FormOperations::rowChanged( const EventObject
& /*_Event*/ ) throw (RuntimeException
, std::exception
)
1001 void SAL_CALL
FormOperations::rowSetChanged( const EventObject
& /*_Event*/ ) throw (RuntimeException
, std::exception
)
1003 // not interested in
1007 void SAL_CALL
FormOperations::modified( const EventObject
& /*_Source*/ ) throw( RuntimeException
, std::exception
)
1009 MethodGuard
aGuard( *this );
1011 OSL_ENSURE( m_xCursor
.is(), "FormOperations::modified: already disposed!" );
1012 if ( !m_bActiveControlModified
)
1014 m_bActiveControlModified
= true;
1015 impl_invalidateModifyDependentFeatures_nothrow( aGuard
);
1020 void SAL_CALL
FormOperations::propertyChange( const PropertyChangeEvent
& _rEvent
) throw (RuntimeException
, std::exception
)
1022 MethodGuard
aGuard( *this );
1024 if ( m_xCursor
.is() && ( m_xCursor
== _rEvent
.Source
) )
1026 if ( ( _rEvent
.PropertyName
== PROPERTY_ISMODIFIED
)
1027 || ( _rEvent
.PropertyName
== PROPERTY_ISNEW
)
1031 if ( ( _rEvent
.NewValue
>>= bIs
) && !bIs
)
1032 m_bActiveControlModified
= false;
1034 impl_invalidateAllSupportedFeatures_nothrow( aGuard
);
1037 if ( m_xParser
.is() && ( m_xCursor
== _rEvent
.Source
) )
1042 _rEvent
.NewValue
>>= sNewValue
;
1043 if ( _rEvent
.PropertyName
== PROPERTY_ACTIVECOMMAND
)
1045 m_xParser
->setElementaryQuery( sNewValue
);
1047 else if ( _rEvent
.PropertyName
== PROPERTY_FILTER
)
1049 if ( m_xParser
->getFilter() != sNewValue
)
1050 m_xParser
->setFilter( sNewValue
);
1052 else if ( _rEvent
.PropertyName
== PROPERTY_SORT
)
1054 _rEvent
.NewValue
>>= sNewValue
;
1055 if ( m_xParser
->getOrder() != sNewValue
)
1056 m_xParser
->setOrder( sNewValue
);
1059 catch( const Exception
& )
1061 OSL_FAIL( "FormOperations::propertyChange: caught an exception while updating the parser!" );
1063 impl_invalidateAllSupportedFeatures_nothrow( aGuard
);
1068 void SAL_CALL
FormOperations::disposing( const EventObject
& /*_Source*/ ) throw (RuntimeException
, std::exception
)
1070 // TODO: should we react on this? Or is this the responsibility of our owner to dispose us?
1074 void SAL_CALL
FormOperations::disposing()
1076 ::osl::MutexGuard
aGuard( m_aMutex
);
1078 impl_disposeParser_nothrow();
1082 // revoke various listeners
1083 if ( m_xCursor
.is() )
1084 m_xCursor
->removeRowSetListener( this );
1086 if ( m_xCursorProperties
.is() )
1088 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_ISMODIFIED
,this );
1089 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_ISNEW
, this );
1092 Reference
< XModifyBroadcaster
> xBroadcaster( m_xController
, UNO_QUERY
);
1093 if ( xBroadcaster
.is() )
1094 xBroadcaster
->removeModifyListener( this );
1096 catch( const Exception
& )
1098 DBG_UNHANDLED_EXCEPTION();
1101 m_xController
.clear();
1103 m_xUpdateCursor
.clear();
1104 m_xCursorProperties
.clear();
1105 m_xLoadableForm
.clear();
1106 m_xFeatureInvalidation
.clear();
1108 m_bActiveControlModified
= true;
1112 void FormOperations::impl_checkDisposed_throw() const
1114 if ( impl_isDisposed_nothrow() )
1115 throw DisposedException( OUString(), *const_cast< FormOperations
* >( this ) );
1119 void FormOperations::impl_initFromController_throw()
1121 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_initFromController_throw: invalid controller!" );
1122 m_xCursor
.set(m_xController
->getModel(), css::uno::UNO_QUERY
);
1123 if ( !m_xCursor
.is() )
1124 throw IllegalArgumentException( OUString(), *this, 0 );
1126 impl_initFromForm_throw();
1128 Reference
< XModifyBroadcaster
> xBroadcaster( m_xController
, UNO_QUERY
);
1129 if ( xBroadcaster
.is() )
1130 xBroadcaster
->addModifyListener( this );
1134 void FormOperations::impl_initFromForm_throw()
1136 OSL_PRECOND( m_xCursor
.is(), "FormOperations::impl_initFromForm_throw: invalid form!" );
1137 m_xCursorProperties
.set(m_xCursor
, css::uno::UNO_QUERY
);
1138 m_xUpdateCursor
.set(m_xCursor
, css::uno::UNO_QUERY
);
1139 m_xLoadableForm
.set(m_xCursor
, css::uno::UNO_QUERY
);
1141 if ( !m_xCursor
.is() || !m_xCursorProperties
.is() || !m_xLoadableForm
.is() )
1142 throw IllegalArgumentException( OUString(), *this, 0 );
1144 m_xCursor
->addRowSetListener( this );
1145 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_ISMODIFIED
,this );
1146 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_ISNEW
, this );
1150 void FormOperations::createWithFormController( const Reference
< XFormController
>& _rxController
)
1152 m_xController
= _rxController
;
1153 if ( !m_xController
.is() )
1154 throw IllegalArgumentException( OUString(), *this, 0 );
1156 impl_initFromController_throw();
1158 m_bConstructed
= true;
1162 void FormOperations::createWithForm( const Reference
< XForm
>& _rxForm
)
1164 m_xCursor
.set(_rxForm
, css::uno::UNO_QUERY
);
1165 if ( !m_xCursor
.is() )
1166 throw IllegalArgumentException( OUString(), *this, 0 );
1168 impl_initFromForm_throw();
1170 m_bConstructed
= true;
1174 void FormOperations::impl_invalidateAllSupportedFeatures_nothrow( MethodGuard
& _rClearForCallback
) const
1176 if ( !m_xFeatureInvalidation
.is() )
1177 // nobody's interested in ...
1180 Reference
< XFeatureInvalidation
> xInvalidation
= m_xFeatureInvalidation
;
1181 _rClearForCallback
.clear();
1182 xInvalidation
->invalidateAllFeatures();
1186 void FormOperations::impl_invalidateModifyDependentFeatures_nothrow( MethodGuard
& _rClearForCallback
) const
1188 if ( !m_xFeatureInvalidation
.is() )
1189 // nobody's interested in ...
1192 static Sequence
< sal_Int16
> s_aModifyDependentFeatures
;
1193 if ( s_aModifyDependentFeatures
.getLength() == 0 )
1195 sal_Int16 pModifyDependentFeatures
[] =
1197 FormFeature::MoveToNext
,
1198 FormFeature::MoveToInsertRow
,
1199 FormFeature::SaveRecordChanges
,
1200 FormFeature::UndoRecordChanges
1202 size_t nFeatureCount
= SAL_N_ELEMENTS( pModifyDependentFeatures
);
1203 s_aModifyDependentFeatures
= Sequence
< sal_Int16
>( pModifyDependentFeatures
, nFeatureCount
);
1206 Reference
< XFeatureInvalidation
> xInvalidation
= m_xFeatureInvalidation
;
1207 _rClearForCallback
.clear();
1209 xInvalidation
->invalidateFeatures( s_aModifyDependentFeatures
);
1213 void FormOperations::impl_ensureInitializedParser_nothrow()
1215 OSL_PRECOND( m_xCursorProperties
.is(), "FormOperations::impl_ensureInitializedParser_nothrow: we're disposed!" );
1216 if ( m_bInitializedParser
)
1221 bool bUseEscapeProcessing
= false;
1222 m_xCursorProperties
->getPropertyValue( PROPERTY_ESCAPE_PROCESSING
) >>= bUseEscapeProcessing
;
1223 if ( bUseEscapeProcessing
)
1225 Reference
< XMultiServiceFactory
> xFactory( ::dbtools::getConnection( m_xCursor
), UNO_QUERY
);
1226 if ( xFactory
.is() )
1228 m_xParser
.set( xFactory
->createInstance("com.sun.star.sdb.SingleSelectQueryComposer"), UNO_QUERY
);
1229 OSL_ENSURE( m_xParser
.is(), "FormOperations::impl_ensureInitializedParser_nothrow: factory did not create a parser for us!" );
1233 if ( m_xParser
.is() )
1235 if ( m_xLoadableForm
.is() && m_xLoadableForm
->isLoaded() )
1237 OUString sStatement
;
1241 m_xCursorProperties
->getPropertyValue( PROPERTY_ACTIVECOMMAND
) >>= sStatement
;
1242 m_xCursorProperties
->getPropertyValue( PROPERTY_FILTER
) >>= sFilter
;
1243 m_xCursorProperties
->getPropertyValue( PROPERTY_SORT
) >>= sSort
;
1245 m_xParser
->setElementaryQuery( sStatement
);
1246 m_xParser
->setFilter ( sFilter
);
1247 m_xParser
->setOrder ( sSort
);
1250 // start listening at the order/sort properties at the form, so
1251 // we can keep our parser in sync
1252 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_ACTIVECOMMAND
, this );
1253 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_FILTER
, this );
1254 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_SORT
, this );
1257 catch( const Exception
& )
1259 OSL_FAIL( "FormOperations::impl_ensureInitializedParser_nothrow: caught an exception!" );
1262 m_bInitializedParser
= true;
1266 void FormOperations::impl_disposeParser_nothrow()
1270 // if we have a parser (and a cursor), then we're listening at the cursor's
1271 // properties to keep the parser in sync with the cursor
1272 if ( m_xParser
.is() && m_xCursorProperties
.is() )
1274 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_FILTER
, this );
1275 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_ACTIVECOMMAND
, this );
1276 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_SORT
, this );
1279 Reference
< XComponent
> xParserComp( m_xParser
, UNO_QUERY
);
1280 if ( xParserComp
.is() )
1281 xParserComp
->dispose();
1284 m_bInitializedParser
= false;
1286 catch( const Exception
& )
1288 OSL_FAIL( "FormOperations::impl_disposeParser_nothrow: caught an exception!" );
1293 bool FormOperations::impl_canMoveLeft_throw( ) const
1295 if ( !impl_hasCursor_nothrow() )
1298 return impl_getRowCount_throw() && ( !m_xCursor
->isFirst() || impl_isInsertionRow_throw() );
1302 bool FormOperations::impl_canMoveRight_throw( ) const
1304 if ( !impl_hasCursor_nothrow() )
1307 bool bIsNew
= impl_isInsertionRow_throw();
1309 if ( impl_getRowCount_throw() && !m_xCursor
->isLast() && !bIsNew
)
1312 if ( ::dbtools::canInsert( m_xCursorProperties
) )
1313 if ( !bIsNew
|| impl_isModifiedRow_throw() )
1316 if ( bIsNew
&& m_bActiveControlModified
)
1323 bool FormOperations::impl_isInsertionRow_throw() const
1325 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_ISNEW
, false );
1329 sal_Int32
FormOperations::impl_getRowCount_throw() const
1331 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_ROWCOUNT
, (sal_Int32
)0 );
1334 bool FormOperations::impl_isRowCountFinal_throw() const
1336 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_ROWCOUNTFINAL
, false );
1340 bool FormOperations::impl_isModifiedRow_throw() const
1342 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_ISMODIFIED
, false );
1346 bool FormOperations::impl_isParseable_throw() const
1348 const_cast< FormOperations
* >( this )->impl_ensureInitializedParser_nothrow();
1349 return m_xParser
.is() && !m_xParser
->getQuery().isEmpty();
1353 bool FormOperations::impl_hasFilterOrOrder_throw() const
1355 return impl_isParseable_throw() && ( !m_xParser
->getFilter().isEmpty() || !m_xParser
->getOrder().isEmpty() );
1359 bool FormOperations::impl_isInsertOnlyForm_throw() const
1361 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_INSERTONLY
, true );
1365 Reference
< XControlModel
> FormOperations::impl_getCurrentControlModel_throw() const
1367 Reference
< XControl
> xControl( m_xController
->getCurrentControl() );
1369 // special handling for grid controls
1370 Reference
< XGrid
> xGrid( xControl
, UNO_QUERY
);
1371 Reference
< XControlModel
> xControlModel
;
1375 Reference
< XIndexAccess
> xColumns( xControl
->getModel(), UNO_QUERY_THROW
);
1376 sal_Int16 nCurrentPos
= xGrid
->getCurrentColumnPosition();
1377 nCurrentPos
= impl_gridView2ModelPos_nothrow( xColumns
, nCurrentPos
);
1379 if ( nCurrentPos
!= (sal_Int16
)-1 )
1380 xColumns
->getByIndex( nCurrentPos
) >>= xControlModel
;
1382 else if ( xControl
.is() )
1384 xControlModel
= xControl
->getModel();
1386 return xControlModel
;
1390 Reference
< XPropertySet
> FormOperations::impl_getCurrentBoundField_nothrow( ) const
1392 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_getCurrentBoundField_nothrow: no controller -> no control!" );
1393 if ( !m_xController
.is() )
1396 Reference
< XPropertySet
> xField
;
1399 Reference
< XPropertySet
> xControlModel( impl_getCurrentControlModel_throw(), UNO_QUERY
);
1401 if ( xControlModel
.is() && ::comphelper::hasProperty( PROPERTY_BOUNDFIELD
, xControlModel
) )
1402 xControlModel
->getPropertyValue( PROPERTY_BOUNDFIELD
) >>= xField
;
1405 catch( const Exception
& )
1407 DBG_UNHANDLED_EXCEPTION();
1414 sal_Int16
FormOperations::impl_gridView2ModelPos_nothrow( const Reference
< XIndexAccess
>& _rxColumns
, sal_Int16 _nViewPos
)
1416 OSL_PRECOND( _rxColumns
.is(), "FormOperations::impl_gridView2ModelPos_nothrow: invalid columns container!" );
1419 // loop through all columns
1421 Reference
< XPropertySet
> xCol
;
1422 bool bHidden( false );
1423 for ( col
= 0; col
< _rxColumns
->getCount(); ++col
)
1425 _rxColumns
->getByIndex( col
) >>= xCol
;
1426 OSL_VERIFY( xCol
->getPropertyValue( PROPERTY_HIDDEN
) >>= bHidden
);
1430 // for every visible col : if nViewPos is greater zero, decrement it, else we
1431 // have found the model position
1437 if ( col
< _rxColumns
->getCount() )
1440 catch( const Exception
& )
1442 DBG_UNHANDLED_EXCEPTION();
1444 return (sal_Int16
)-1;
1448 bool FormOperations::impl_moveLeft_throw( ) const
1450 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_moveLeft_throw: no cursor!" );
1451 if ( !impl_hasCursor_nothrow() )
1454 sal_Bool bRecordInserted
= sal_False
;
1455 bool bSuccess
= impl_commitCurrentRecord_throw( &bRecordInserted
);
1460 if ( bRecordInserted
)
1462 // retrieve the bookmark of the new record and move to the record preceding this bookmark
1463 Reference
< XRowLocate
> xLocate( m_xCursor
, UNO_QUERY
);
1464 OSL_ENSURE( xLocate
.is(), "FormOperations::impl_moveLeft_throw: no XRowLocate!" );
1466 xLocate
->moveRelativeToBookmark( xLocate
->getBookmark(), -1 );
1470 if ( impl_isInsertionRow_throw() )
1472 // we assume that the inserted record is now the last record in the
1477 m_xCursor
->previous();
1484 bool FormOperations::impl_moveRight_throw( ) const
1486 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_moveRight_throw: no cursor!" );
1487 if ( !impl_hasCursor_nothrow() )
1490 sal_Bool bRecordInserted
= sal_False
;
1491 bool bSuccess
= impl_commitCurrentRecord_throw( &bRecordInserted
);
1496 if ( bRecordInserted
)
1499 m_xUpdateCursor
->moveToInsertRow();
1503 if ( m_xCursor
->isLast() )
1504 m_xUpdateCursor
->moveToInsertRow();
1506 (void)m_xCursor
->next();
1513 void FormOperations::impl_resetAllControls_nothrow() const
1515 Reference
< XIndexAccess
> xContainer( m_xCursor
, UNO_QUERY
);
1516 if ( !xContainer
.is() )
1521 Reference
< XReset
> xReset
;
1522 sal_Int32
nCount( xContainer
->getCount() );
1523 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
1525 if ( xContainer
->getByIndex( i
) >>= xReset
)
1527 // no resets on sub forms
1528 Reference
< XForm
> xAsForm( xReset
, UNO_QUERY
);
1529 if ( !xAsForm
.is() )
1534 catch( const Exception
& )
1536 DBG_UNHANDLED_EXCEPTION();
1541 void FormOperations::impl_executeAutoSort_throw( bool _bUp
) const
1543 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_executeAutoSort_throw: need a controller for this!" );
1544 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeAutoSort_throw: need a cursor for this!" );
1545 OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeAutoSort_throw: need a parseable statement for this!" );
1546 if ( !m_xController
.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
1551 Reference
< XControl
> xControl
= m_xController
->getCurrentControl();
1552 if ( !xControl
.is() || !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
1555 Reference
< XPropertySet
> xBoundField( impl_getCurrentBoundField_nothrow() );
1556 if ( !xBoundField
.is() )
1559 OUString sOriginalSort
;
1560 m_xCursorProperties
->getPropertyValue( PROPERTY_SORT
) >>= sOriginalSort
;
1562 // automatic sort by field is expected to always resets the previous sort order
1563 m_xParser
->setOrder( OUString() );
1565 impl_appendOrderByColumn_throw
aAction(this, xBoundField
, _bUp
);
1566 impl_doActionInSQLContext_throw(aAction
, RID_STR_COULD_NOT_SET_ORDER
);
1568 WaitObject
aWO( NULL
);
1571 m_xCursorProperties
->setPropertyValue( PROPERTY_SORT
, makeAny( m_xParser
->getOrder() ) );
1572 m_xLoadableForm
->reload();
1574 catch( const Exception
& )
1576 OSL_FAIL( "FormOperations::impl_executeAutoSort_throw: caught an exception while setting the parser properties!" );
1580 if ( !m_xLoadableForm
->isLoaded() )
1581 { // something went wrong -> restore the original state
1584 m_xParser
->setOrder( sOriginalSort
);
1585 m_xCursorProperties
->setPropertyValue( PROPERTY_SORT
, makeAny( m_xParser
->getOrder() ) );
1586 m_xLoadableForm
->reload();
1588 catch( const Exception
& )
1590 OSL_FAIL( "FormOperations::impl_executeAutoSort_throw: could not reset the form to it's original state!" );
1595 catch( const RuntimeException
& ) { throw; }
1596 catch( const SQLException
& ) { throw; }
1597 catch( const Exception
& )
1599 throw WrappedTargetException( OUString(), *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
1604 void FormOperations::impl_executeAutoFilter_throw( ) const
1606 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_executeAutoFilter_throw: need a controller for this!" );
1607 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeAutoFilter_throw: need a cursor for this!" );
1608 OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeAutoFilter_throw: need a parseable statement for this!" );
1609 if ( !m_xController
.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
1614 Reference
< XControl
> xControl
= m_xController
->getCurrentControl();
1615 if ( !xControl
.is() || !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
1618 Reference
< XPropertySet
> xBoundField( impl_getCurrentBoundField_nothrow() );
1619 if ( !xBoundField
.is() )
1622 OUString sOriginalFilter
;
1623 m_xCursorProperties
->getPropertyValue( PROPERTY_FILTER
) >>= sOriginalFilter
;
1624 bool bApplied
= true;
1625 m_xCursorProperties
->getPropertyValue( PROPERTY_APPLYFILTER
) >>= bApplied
;
1627 // if we have a filter, but it's not applied, then we have to overwrite it, else append one
1629 m_xParser
->setFilter( OUString() );
1631 impl_appendFilterByColumn_throw
aAction(this, xBoundField
);
1632 impl_doActionInSQLContext_throw( aAction
, RID_STR_COULD_NOT_SET_FILTER
);
1634 WaitObject
aWO( NULL
);
1637 m_xCursorProperties
->setPropertyValue( PROPERTY_FILTER
, makeAny( m_xParser
->getFilter() ) );
1638 m_xCursorProperties
->setPropertyValue( PROPERTY_APPLYFILTER
, makeAny( true ) );
1640 m_xLoadableForm
->reload();
1642 catch( const Exception
& )
1644 OSL_FAIL( "FormOperations::impl_executeAutoFilter_throw: caught an exception while setting the parser properties!" );
1648 if ( !m_xLoadableForm
->isLoaded() )
1649 { // something went wrong -> restore the original state
1652 m_xParser
->setOrder( sOriginalFilter
);
1653 m_xCursorProperties
->setPropertyValue( PROPERTY_APPLYFILTER
, makeAny( bApplied
) );
1654 m_xCursorProperties
->setPropertyValue( PROPERTY_FILTER
, makeAny( m_xParser
->getFilter() ) );
1655 m_xLoadableForm
->reload();
1657 catch( const Exception
& )
1659 OSL_FAIL( "FormOperations::impl_executeAutoFilter_throw: could not reset the form to it's original state!" );
1664 catch( const RuntimeException
& ) { throw; }
1665 catch( const SQLException
& ) { throw; }
1666 catch( const Exception
& )
1668 throw WrappedTargetException( OUString(), *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
1673 void FormOperations::impl_executeFilterOrSort_throw( bool _bFilter
) const
1675 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_executeFilterOrSort_throw: need a controller for this!" );
1676 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeFilterOrSort_throw: need a cursor for this!" );
1677 OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeFilterOrSort_throw: need a parseable statement for this!" );
1678 if ( !m_xController
.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
1681 if ( !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
1685 Reference
< XExecutableDialog
> xDialog
;
1688 xDialog
= com::sun::star::sdb::FilterDialog::createWithQuery(m_xContext
, m_xParser
, m_xCursor
,
1689 Reference
<com::sun::star::awt::XWindow
>());
1693 xDialog
= com::sun::star::sdb::OrderDialog::createWithQuery(m_xContext
, m_xParser
, m_xCursorProperties
);
1697 if ( RET_OK
== xDialog
->execute() )
1699 WaitObject
aWO( NULL
);
1701 m_xCursorProperties
->setPropertyValue( PROPERTY_FILTER
, makeAny( m_xParser
->getFilter() ) );
1703 m_xCursorProperties
->setPropertyValue( PROPERTY_SORT
, makeAny( m_xParser
->getOrder() ) );
1704 m_xLoadableForm
->reload();
1708 catch( const RuntimeException
& ) { throw; }
1709 catch( const SQLException
& ) { throw; }
1710 catch( const Exception
& )
1712 throw WrappedTargetException( OUString(), *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
1717 template < typename FunctObj
>
1718 void FormOperations::impl_doActionInSQLContext_throw( FunctObj f
, sal_uInt16 _nErrorResourceId
) const
1724 #if HAVE_FEATURE_DBCONNECTIVITY
1725 catch( const SQLException
& e
)
1728 if ( !_nErrorResourceId
)
1729 // no information to prepend
1732 SQLExceptionInfo
aInfo( ::cppu::getCaughtException() );
1733 OUString
sAdditionalError( FRM_RES_STRING( _nErrorResourceId
) );
1734 aInfo
.prepend( sAdditionalError
);
1738 catch( const RuntimeException
& ) { throw; }
1739 catch( const Exception
& )
1741 OUString
sAdditionalError( FRM_RES_STRING( _nErrorResourceId
) );
1742 throw WrappedTargetException( sAdditionalError
, *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
1750 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
* SAL_CALL
1751 com_sun_star_comp_forms_FormOperations_get_implementation(css::uno::XComponentContext
* context
,
1752 css::uno::Sequence
<css::uno::Any
> const &)
1754 return cppu::acquire(new frm::FormOperations(context
));
1757 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */