1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: formoperations.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_forms.hxx"
34 #include "formoperations.hxx"
35 #include "frm_strings.hxx"
36 #include "frm_resource.hxx"
37 #include "frm_resource.hrc"
38 #include "frm_module.hxx"
40 /** === begin UNO includes === **/
41 #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
42 #include <com/sun/star/util/XModifyBroadcaster.hpp>
43 #include <com/sun/star/form/runtime/FormFeature.hpp>
44 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
45 #include <com/sun/star/lang/DisposedException.hpp>
46 #include <com/sun/star/awt/XControl.hpp>
47 #include <com/sun/star/form/XGrid.hpp>
48 #include <com/sun/star/form/XBoundControl.hpp>
49 #include <com/sun/star/form/XBoundComponent.hpp>
50 #include <com/sun/star/sdbcx/XRowLocate.hpp>
51 #include <com/sun/star/form/XConfirmDeleteListener.hpp>
52 #include <com/sun/star/sdb/RowChangeEvent.hpp>
53 #include <com/sun/star/sdb/RowChangeAction.hpp>
54 #include <com/sun/star/form/XReset.hpp>
55 #include <com/sun/star/beans/XMultiPropertySet.hpp>
56 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
57 #include <com/sun/star/util/XRefreshable.hpp>
58 /** === end UNO includes === **/
60 #include <connectivity/dbtools.hxx>
61 #include <connectivity/dbexception.hxx>
62 #include <vcl/svapp.hxx>
63 #include <vcl/stdtext.hxx>
64 #include <vcl/msgbox.hxx>
65 #include <vcl/waitobj.hxx>
66 #include <tools/diagnose_ex.h>
67 #include <comphelper/container.hxx>
68 #include <comphelper/property.hxx>
69 #include <comphelper/namedvaluecollection.hxx>
70 #include <cppuhelper/exc_hlp.hxx>
71 #include <vos/mutex.hxx>
73 //--------------------------------------------------------------------------
74 extern "C" void SAL_CALL
createRegistryInfo_FormOperations()
76 static ::frm::OMultiInstanceAutoRegistration
< ::frm::FormOperations
> aAutoRegistration
;
79 //........................................................................
82 //........................................................................
84 using ::dbtools::SQLExceptionInfo
;
85 /** === begin UNO using === **/
86 using ::com::sun::star::uno::Reference
;
87 using ::com::sun::star::uno::XComponentContext
;
88 using ::com::sun::star::uno::RuntimeException
;
89 using ::com::sun::star::uno::Sequence
;
90 using ::com::sun::star::uno::Exception
;
91 using ::com::sun::star::uno::Any
;
92 using ::com::sun::star::uno::XInterface
;
93 using ::com::sun::star::sdbc::XRowSet
;
94 using ::com::sun::star::sdbc::XResultSetUpdate
;
95 using ::com::sun::star::form::XFormController
;
96 using ::com::sun::star::form::runtime::XFeatureInvalidation
;
97 using ::com::sun::star::form::runtime::FeatureState
;
98 using ::com::sun::star::lang::IllegalArgumentException
;
99 using ::com::sun::star::sdbc::SQLException
;
100 using ::com::sun::star::form::XForm
;
101 using ::com::sun::star::ucb::AlreadyInitializedException
;
102 using ::com::sun::star::util::XModifyBroadcaster
;
103 using ::com::sun::star::uno::UNO_QUERY
;
104 using ::com::sun::star::lang::EventObject
;
105 using ::com::sun::star::beans::PropertyChangeEvent
;
106 using ::com::sun::star::lang::XMultiServiceFactory
;
107 using ::com::sun::star::lang::DisposedException
;
108 using ::com::sun::star::beans::XPropertySet
;
109 using ::com::sun::star::awt::XControl
;
110 using ::com::sun::star::form::XGrid
;
111 using ::com::sun::star::container::XIndexAccess
;
112 using ::com::sun::star::uno::UNO_QUERY_THROW
;
113 using ::com::sun::star::form::XBoundControl
;
114 using ::com::sun::star::form::XBoundComponent
;
115 using ::com::sun::star::sdbcx::XRowLocate
;
116 using ::com::sun::star::form::XConfirmDeleteListener
;
117 using ::com::sun::star::sdb::RowChangeEvent
;
118 using ::com::sun::star::form::XReset
;
119 using ::com::sun::star::beans::XMultiPropertySet
;
120 using ::com::sun::star::uno::makeAny
;
121 using ::com::sun::star::lang::WrappedTargetException
;
122 using ::com::sun::star::beans::PropertyValue
;
123 using ::com::sun::star::ui::dialogs::XExecutableDialog
;
124 using ::com::sun::star::beans::NamedValue
;
126 using ::com::sun::star::util::XRefreshable
;
127 using ::com::sun::star::awt::XControlModel
;
128 /** === end UNO using === **/
129 namespace FormFeature
= ::com::sun::star::form::runtime::FormFeature
;
130 namespace RowChangeAction
= ::com::sun::star::sdb::RowChangeAction
;
132 //====================================================================
134 //====================================================================
135 //--------------------------------------------------------------------
136 FormOperations::FormOperations( const Reference
< XMultiServiceFactory
>& _rxContext
)
137 :FormOperations_Base( m_aMutex
)
138 ,m_aContext( _rxContext
)
139 ,m_bInitializedParser( false )
140 ,m_bActiveControlModified( false )
141 ,m_bConstructed( false )
143 ,m_nMethodNestingLevel( false )
148 //--------------------------------------------------------------------
149 FormOperations::~FormOperations()
153 //--------------------------------------------------------------------
154 ::rtl::OUString
FormOperations::getImplementationName_Static( ) throw(RuntimeException
)
156 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.forms.FormOperations" ) );
159 //--------------------------------------------------------------------
160 Sequence
< ::rtl::OUString
> FormOperations::getSupportedServiceNames_Static( ) throw(RuntimeException
)
162 Sequence
< ::rtl::OUString
> aNames(1);
163 aNames
[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.runtime.FormOperations" ) );
167 //--------------------------------------------------------------------
168 Reference
< XInterface
> SAL_CALL
FormOperations::Create(const Reference
< XMultiServiceFactory
>& _rxFactory
)
170 return *new FormOperations( _rxFactory
);
173 //--------------------------------------------------------------------
174 void SAL_CALL
FormOperations::initialize( const Sequence
< Any
>& _arguments
) throw (Exception
, RuntimeException
)
176 if ( m_bConstructed
)
177 throw AlreadyInitializedException();
179 if ( _arguments
.getLength() == 1 )
181 Reference
< XFormController
> xController
;
182 Reference
< XForm
> xForm
;
183 if ( _arguments
[0] >>= xController
)
184 createWithFormController( xController
);
185 else if ( _arguments
[0] >>= xForm
)
186 createWithForm( xForm
);
188 throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
192 throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
195 //--------------------------------------------------------------------
196 ::rtl::OUString SAL_CALL
FormOperations::getImplementationName( ) throw (RuntimeException
)
198 return getImplementationName_Static();
201 //--------------------------------------------------------------------
202 ::sal_Bool SAL_CALL
FormOperations::supportsService( const ::rtl::OUString
& _ServiceName
) throw (RuntimeException
)
204 Sequence
< ::rtl::OUString
> aSupportedServiceNames( getSupportedServiceNames() );
205 const ::rtl::OUString
* pBegin
= aSupportedServiceNames
.getConstArray();
206 const ::rtl::OUString
* pEnd
= aSupportedServiceNames
.getConstArray() + aSupportedServiceNames
.getLength();
207 return ::std::find( pBegin
, pEnd
, _ServiceName
) != pEnd
;
210 //--------------------------------------------------------------------
211 Sequence
< ::rtl::OUString
> SAL_CALL
FormOperations::getSupportedServiceNames( ) throw (RuntimeException
)
213 return getSupportedServiceNames_Static();
216 //--------------------------------------------------------------------
217 Reference
< XRowSet
> SAL_CALL
FormOperations::getCursor() throw (RuntimeException
)
219 MethodGuard
aGuard( *this );
223 //--------------------------------------------------------------------
224 Reference
< XResultSetUpdate
> SAL_CALL
FormOperations::getUpdateCursor() throw (RuntimeException
)
226 MethodGuard
aGuard( *this );
227 return m_xUpdateCursor
;
230 //--------------------------------------------------------------------
231 Reference
< XFormController
> SAL_CALL
FormOperations::getController() throw (RuntimeException
)
233 MethodGuard
aGuard( *this );
234 return m_xController
;
237 //--------------------------------------------------------------------
238 Reference
< XFeatureInvalidation
> SAL_CALL
FormOperations::getFeatureInvalidation() throw (RuntimeException
)
240 MethodGuard
aGuard( *this );
241 return m_xFeatureInvalidation
;
244 //--------------------------------------------------------------------
245 void SAL_CALL
FormOperations::setFeatureInvalidation( const Reference
< XFeatureInvalidation
> & _rxFeatureInvalidation
) throw (RuntimeException
)
247 MethodGuard
aGuard( *this );
248 m_xFeatureInvalidation
= _rxFeatureInvalidation
;
251 //--------------------------------------------------------------------
252 FeatureState SAL_CALL
FormOperations::getState( ::sal_Int16 _nFeature
) throw (RuntimeException
)
254 MethodGuard
aGuard( *this );
257 aState
.Enabled
= sal_False
;
261 // some checks for basic pre-requisites
262 if ( !m_xLoadableForm
.is()
263 || !m_xLoadableForm
->isLoaded()
264 || !m_xCursorProperties
.is()
272 case FormFeature::MoveToFirst
:
273 case FormFeature::MoveToPrevious
:
274 aState
.Enabled
= impl_canMoveLeft_throw( );
277 case FormFeature::MoveToNext
:
278 aState
.Enabled
= impl_canMoveRight_throw();
281 case FormFeature::MoveToLast
:
282 aState
.Enabled
= impl_getRowCount_throw() && ( !m_xCursor
->isLast() || impl_isInsertionRow_throw() );
285 case FormFeature::DeleteRecord
:
287 if ( m_xCursor
->rowDeleted() )
288 aState
.Enabled
= sal_False
;
291 // allowed to delete the row ?
292 aState
.Enabled
= !impl_isInsertionRow_throw() && ::dbtools::canDelete( m_xCursorProperties
);
296 case FormFeature::MoveToInsertRow
:
297 // if we are inserting we can move to the next row if the current record or control is modified
298 aState
.Enabled
= impl_isInsertionRow_throw()
299 ? impl_isModifiedRow_throw() || m_bActiveControlModified
300 : ::dbtools::canInsert( m_xCursorProperties
);
303 case FormFeature::ReloadForm
:
305 // there must be an active connection
306 Reference
< XRowSet
> xCursorRowSet( m_xCursor
, UNO_QUERY
);
307 aState
.Enabled
= ::dbtools::getConnection( xCursorRowSet
).is();
309 // and an active command
310 ::rtl::OUString sActiveCommand
;
311 m_xCursorProperties
->getPropertyValue( PROPERTY_ACTIVECOMMAND
) >>= sActiveCommand
;
312 aState
.Enabled
&= sActiveCommand
.getLength() > 0;
316 case FormFeature::RefreshCurrentControl
:
318 Reference
< XRefreshable
> xControlModelRefresh( impl_getCurrentControlModel_throw(), UNO_QUERY
);
319 aState
.Enabled
= xControlModelRefresh
.is();
323 case FormFeature::SaveRecordChanges
:
324 case FormFeature::UndoRecordChanges
:
325 aState
.Enabled
= impl_isModifiedRow_throw() || m_bActiveControlModified
;
328 case FormFeature::RemoveFilterAndSort
:
329 if ( impl_isParseable_throw() && impl_hasFilterOrOrder_throw() )
330 aState
.Enabled
= !impl_isInsertOnlyForm_throw();
333 case FormFeature::SortAscending
:
334 case FormFeature::SortDescending
:
335 case FormFeature::AutoFilter
:
336 if ( m_xController
.is() && impl_isParseable_throw() )
338 sal_Bool bIsDeleted
= m_xCursor
->rowDeleted();
340 if ( !bIsDeleted
&& !impl_isInsertOnlyForm_throw() )
342 Reference
< XPropertySet
> xBoundField
= impl_getCurrentBoundField_nothrow( );
343 if ( xBoundField
.is() )
344 xBoundField
->getPropertyValue( PROPERTY_SEARCHABLE
) >>= aState
.Enabled
;
349 case FormFeature::InteractiveSort
:
350 case FormFeature::InteractiveFilter
:
351 if ( impl_isParseable_throw() )
352 aState
.Enabled
= !impl_isInsertOnlyForm_throw();
355 case FormFeature::ToggleApplyFilter
:
357 ::rtl::OUString sFilter
;
358 m_xCursorProperties
->getPropertyValue( PROPERTY_FILTER
) >>= sFilter
;
359 if ( sFilter
.getLength() )
361 aState
.State
= m_xCursorProperties
->getPropertyValue( PROPERTY_APPLYFILTER
);
362 aState
.Enabled
= !impl_isInsertOnlyForm_throw();
365 aState
.State
<<= (sal_Bool
)sal_False
;
369 case FormFeature::MoveAbsolute
:
371 sal_Int32 nPosition
= m_xCursor
->getRow();
372 sal_Bool bIsNew
= impl_isInsertionRow_throw();
373 sal_Int32 nCount
= impl_getRowCount_throw();
374 sal_Bool bFinalCount
= impl_isRowCountFinal_throw();
376 if ( ( nPosition
>= 0 ) || bIsNew
)
380 // special case: there are no records at all, and we
381 // can't insert records -> disabled
382 if ( !nCount
&& !::dbtools::canInsert( m_xCursorProperties
) )
384 aState
.Enabled
= sal_False
;
389 nPosition
= ++nCount
;
390 aState
.State
<<= (sal_Int32
)nPosition
;
391 aState
.Enabled
= sal_True
;
396 aState
.State
<<= (sal_Int32
)nPosition
;
397 aState
.Enabled
= sal_True
;
403 case FormFeature::TotalRecords
:
405 sal_Bool bIsNew
= impl_isInsertionRow_throw();
406 sal_Int32 nCount
= impl_getRowCount_throw();
407 sal_Bool bFinalCount
= impl_isRowCountFinal_throw();
412 ::rtl::OUString sValue
= ::rtl::OUString::valueOf( sal_Int32( nCount
) );
414 sValue
+= ::rtl::OUString::createFromAscii( " *" );
416 aState
.State
<<= sValue
;
417 aState
.Enabled
= sal_True
;
422 OSL_ENSURE( sal_False
, "FormOperations::getState: unknown feature id!" );
426 catch( const Exception
& )
428 OSL_ENSURE( sal_False
, "FormOperations::getState: caught an exception!" );
434 //--------------------------------------------------------------------
435 ::sal_Bool SAL_CALL
FormOperations::isEnabled( ::sal_Int16 _nFeature
) throw (RuntimeException
)
437 MethodGuard
aGuard( *this );
439 FeatureState
aState( getState( _nFeature
) );
440 return aState
.Enabled
;
443 //--------------------------------------------------------------------
446 static bool lcl_needConfirmCommit( sal_Int32 _nFeature
)
448 return ( ( _nFeature
== FormFeature::ReloadForm
)
449 || ( _nFeature
== FormFeature::RemoveFilterAndSort
)
450 || ( _nFeature
== FormFeature::ToggleApplyFilter
)
451 || ( _nFeature
== FormFeature::SortAscending
)
452 || ( _nFeature
== FormFeature::SortDescending
)
453 || ( _nFeature
== FormFeature::AutoFilter
)
454 || ( _nFeature
== FormFeature::InteractiveSort
)
455 || ( _nFeature
== FormFeature::InteractiveFilter
)
458 static bool lcl_requiresArguments( sal_Int32 _nFeature
)
460 return ( _nFeature
== FormFeature::MoveAbsolute
);
462 static bool lcl_isExecutableFeature( sal_Int32 _nFeature
)
464 return ( _nFeature
!= FormFeature::TotalRecords
);
468 //--------------------------------------------------------------------
469 void SAL_CALL
FormOperations::execute( ::sal_Int16 _nFeature
) throw (RuntimeException
, IllegalArgumentException
, SQLException
, WrappedTargetException
)
471 ::vos::OGuard
aSolarGuard( Application::GetSolarMutex() );
472 MethodGuard
aGuard( *this );
474 if ( ( _nFeature
!= FormFeature::DeleteRecord
) && ( _nFeature
!= FormFeature::UndoRecordChanges
) )
476 // if we have a controller, commit the current control
477 if ( m_xController
.is() )
478 if ( !impl_commitCurrentControl_throw() )
481 // commit the current record
482 bool bCommitCurrentRecord
= true;
483 // (but before, let the user confirm if necessary)
484 if ( impl_isModifiedRow_throw() )
486 if ( lcl_needConfirmCommit( _nFeature
) )
488 // TODO: shouldn't this be done with an interaction handler?
489 QueryBox
aQuery( NULL
, WB_YES_NO_CANCEL
| WB_DEF_YES
, FRM_RES_STRING( RID_STR_QUERY_SAVE_MODIFIED_ROW
) );
490 switch ( aQuery
.Execute() )
492 case RET_NO
: bCommitCurrentRecord
= false; break;
493 case RET_CANCEL
: return;
498 if ( bCommitCurrentRecord
&& !impl_commitCurrentRecord_throw() )
506 case FormFeature::MoveToFirst
:
510 case FormFeature::MoveToNext
:
511 impl_moveRight_throw( );
514 case FormFeature::MoveToPrevious
:
515 impl_moveLeft_throw( );
518 case FormFeature::MoveToLast
:
521 // TODO: re-implement this .....
522 // run in an own thread if ...
523 // ... the data source is thread safe ...
524 sal_Bool bAllowOwnThread = sal_False;
525 if ( ::comphelper::hasProperty( PROPERTY_THREADSAFE, m_xCursorProperties ) )
526 m_xCursorProperties->getPropertyValue( PROPERTY_THREADSAFE ) >>= bAllowOwnThread;
528 // ... the record count is unknown
529 sal_Bool bNeedOwnThread sal_False;
530 if ( ::comphelper::hasProperty( PROPERTY_ROWCOUNTFINAL, m_xCursorProperties ) )
531 m_xCursorProperties->getPropertyValue( PROPERTY_ROWCOUNTFINAL ) >>= bNeedOwnThread;
533 if ( bNeedOwnThread && bAllowOwnThread )
541 case FormFeature::ReloadForm
:
542 if ( m_xLoadableForm
.is() )
544 WaitObject
aWO( NULL
);
545 m_xLoadableForm
->reload();
547 // refresh all controls in the form (and sub forms) which can be refreshed
548 // #i90914# / 2008-07-02 / frank.schoenheit@sun.com
549 ::comphelper::IndexAccessIterator
aIter( m_xLoadableForm
);
550 Reference
< XInterface
> xElement( aIter
.Next() );
551 while ( xElement
.is() )
553 Reference
< XRefreshable
> xRefresh( xElement
, UNO_QUERY
);
556 xElement
= aIter
.Next();
561 case FormFeature::RefreshCurrentControl
:
563 Reference
< XRefreshable
> xControlModelRefresh( impl_getCurrentControlModel_throw(), UNO_QUERY
);
564 OSL_ENSURE( xControlModelRefresh
.is(), "FormOperations::execute: how did you reach this?" );
565 if ( xControlModelRefresh
.is() )
566 xControlModelRefresh
->refresh();
570 case FormFeature::DeleteRecord
:
572 sal_uInt32 nCount
= impl_getRowCount_throw();
575 sal_Bool bLeft
= m_xCursor
->isLast() && ( nCount
> 1 );
576 sal_Bool bRight
= !m_xCursor
->isLast();
577 sal_Bool bSuccess
= sal_False
;
580 // ask for confirmation
581 Reference
< XConfirmDeleteListener
> xConfirmDelete( m_xController
, UNO_QUERY
);
583 if ( xConfirmDelete
.is() )
585 RowChangeEvent aEvent
;
586 aEvent
.Source
= Reference
< XInterface
>( m_xCursor
, UNO_QUERY
);
587 aEvent
.Action
= RowChangeAction::DELETE
;
589 bSuccess
= xConfirmDelete
->confirmDelete( aEvent
);
594 m_xUpdateCursor
->deleteRow();
596 catch( const Exception
& )
598 bSuccess
= sal_False
;
603 if ( bLeft
|| bRight
)
604 m_xCursor
->relative( bRight
? 1 : -1 );
607 sal_Bool bCanInsert
= ::dbtools::canInsert( m_xCursorProperties
);
608 // is it possible to insert another record?
610 m_xUpdateCursor
->moveToInsertRow();
612 // move record to update stati
619 case FormFeature::SaveRecordChanges
:
620 case FormFeature::UndoRecordChanges
:
622 sal_Bool bInserting
= impl_isInsertionRow_throw();
624 if ( FormFeature::UndoRecordChanges
== _nFeature
)
627 m_xUpdateCursor
->cancelRowUpdates();
629 // reset all controls for this form
630 impl_resetAllControls_nothrow( );
632 if ( bInserting
) // back to insertion mode for this form
633 m_xUpdateCursor
->moveToInsertRow();
639 m_xUpdateCursor
->insertRow();
643 m_xUpdateCursor
->updateRow();
648 case FormFeature::MoveToInsertRow
:
649 // move to the last row before moving to the insert row
650 // 21.01.2002 - 96480 - fs@openoffice.org
652 m_xUpdateCursor
->moveToInsertRow();
655 case FormFeature::RemoveFilterAndSort
:
657 // simultaneously reset Filter and Order property
658 Reference
< XMultiPropertySet
> xProperties( m_xCursorProperties
, UNO_QUERY
);
659 OSL_ENSURE( xProperties
.is(), "FormOperations::execute: no multi property access!" );
660 if ( xProperties
.is() )
662 Sequence
< ::rtl::OUString
> aNames( 2 );
663 aNames
[0] = PROPERTY_FILTER
;
664 aNames
[1] = PROPERTY_SORT
;
666 Sequence
< Any
> aValues( 2 );
667 aValues
[0] <<= ::rtl::OUString();
668 aValues
[1] <<= ::rtl::OUString();
670 WaitObject
aWO( NULL
);
671 xProperties
->setPropertyValues( aNames
, aValues
);
673 if ( m_xLoadableForm
.is() )
674 m_xLoadableForm
->reload();
679 case FormFeature::ToggleApplyFilter
:
680 if ( impl_commitCurrentControl_throw() && impl_commitCurrentRecord_throw() )
682 // simply toggle the value
683 sal_Bool bApplied
= sal_False
;
684 m_xCursorProperties
->getPropertyValue( PROPERTY_APPLYFILTER
) >>= bApplied
;
685 m_xCursorProperties
->setPropertyValue( PROPERTY_APPLYFILTER
, makeAny( (sal_Bool
)!bApplied
) );
688 WaitObject
aWO( NULL
);
689 m_xLoadableForm
->reload();
693 case FormFeature::SortAscending
:
694 impl_executeAutoSort_throw( true );
697 case FormFeature::SortDescending
:
698 impl_executeAutoSort_throw( false );
701 case FormFeature::AutoFilter
:
702 impl_executeAutoFilter_throw();
705 case FormFeature::InteractiveSort
:
706 impl_executeFilterOrSort_throw( false );
709 case FormFeature::InteractiveFilter
:
710 impl_executeFilterOrSort_throw( true );
715 sal_uInt16 nErrorResourceId
= RID_STR_FEATURE_UNKNOWN
;
716 if ( lcl_requiresArguments( _nFeature
) )
717 nErrorResourceId
= RID_STR_FEATURE_REQUIRES_PARAMETERS
;
718 else if ( !lcl_isExecutableFeature( _nFeature
) )
719 nErrorResourceId
= RID_STR_FEATURE_NOT_EXECUTABLE
;
720 throw IllegalArgumentException( FRM_RES_STRING( nErrorResourceId
), *this, 1 );
724 catch( const RuntimeException
& ) { throw; }
725 catch( const SQLException
& ) { throw; }
726 catch( const IllegalArgumentException
& ) { throw; }
727 catch( const Exception
& )
729 throw WrappedTargetException( ::rtl::OUString(), *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
732 impl_invalidateAllSupportedFeatures_nothrow( aGuard
);
735 //--------------------------------------------------------------------
736 void SAL_CALL
FormOperations::executeWithArguments( ::sal_Int16 _nFeature
, const Sequence
< NamedValue
>& _rArguments
) throw (RuntimeException
, IllegalArgumentException
, SQLException
, WrappedTargetException
)
738 if ( !lcl_requiresArguments( _nFeature
) )
740 execute( _nFeature
);
744 ::vos::OGuard
aSolarGuard( Application::GetSolarMutex() );
745 MethodGuard
aGuard( *this );
747 // at the moment we have only one feature which supports execution parameters
748 if ( !lcl_isExecutableFeature( _nFeature
) )
749 throw IllegalArgumentException( FRM_RES_STRING( RID_STR_FEATURE_NOT_EXECUTABLE
), *this, 1 );
753 case FormFeature::MoveAbsolute
:
755 sal_Int32 nPosition
= -1;
757 ::comphelper::NamedValueCollection
aArguments( _rArguments
);
758 aArguments
.get_ensureType( "Position", nPosition
);
765 // commit before doing anything else
766 if ( m_xController
.is() && !impl_commitCurrentControl_throw() )
768 if ( !impl_commitCurrentRecord_throw() )
771 sal_Int32 nCount
= impl_getRowCount_throw();
772 sal_Bool bFinalCount
= impl_isRowCountFinal_throw();
774 if ( bFinalCount
&& ( (sal_Int32
)nPosition
> nCount
) )
777 m_xCursor
->absolute( nPosition
);
779 catch( const RuntimeException
& ) { throw; }
780 catch( const SQLException
& ) { throw; }
781 catch( const Exception
& )
783 throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
788 throw IllegalArgumentException( FRM_RES_STRING( RID_STR_FEATURE_UNKNOWN
), *this, 1 );
792 //--------------------------------------------------------------------
793 ::sal_Bool SAL_CALL
FormOperations::commitCurrentRecord( ::sal_Bool
& _out_rRecordInserted
) throw (RuntimeException
, SQLException
)
795 MethodGuard
aGuard( *this );
796 _out_rRecordInserted
= sal_False
;
798 return impl_commitCurrentRecord_throw( &_out_rRecordInserted
);
801 //--------------------------------------------------------------------
802 bool FormOperations::impl_commitCurrentRecord_throw( ::sal_Bool
* _pRecordInserted
) const
804 DBG_ASSERT( m_nMethodNestingLevel
, "FormOperations::impl_commitCurrentRecord_throw: to be called within a MethodGuard'ed section only!" );
806 if ( !impl_hasCursor_nothrow() )
809 // nothing to do if the record is not modified
810 sal_Bool bResult
= !impl_isModifiedRow_throw();
813 // insert respectively update the row
814 if ( impl_isInsertionRow_throw() )
816 m_xUpdateCursor
->insertRow();
817 if ( _pRecordInserted
)
818 *_pRecordInserted
= sal_True
;
821 m_xUpdateCursor
->updateRow();
827 //--------------------------------------------------------------------
828 ::sal_Bool SAL_CALL
FormOperations::commitCurrentControl() throw (RuntimeException
, SQLException
)
830 MethodGuard
aGuard( *this );
831 return impl_commitCurrentControl_throw();
834 //--------------------------------------------------------------------
835 bool FormOperations::impl_commitCurrentControl_throw() const
837 DBG_ASSERT( m_nMethodNestingLevel
, "FormOperations::impl_commitCurrentRecord_throw: to be called within a MethodGuard'ed section only!" );
838 OSL_PRECOND( m_xController
.is(), "FormOperations::commitCurrentControl: no controller!" );
839 if ( !m_xController
.is() )
842 bool bSuccess
= false;
845 Reference
< XControl
> xCurrentControl( m_xController
->getCurrentControl() );
847 // check whether the control is locked
848 Reference
< XBoundControl
> xCheckLock( xCurrentControl
, UNO_QUERY
);
849 sal_Bool bControlIsLocked
= xCheckLock
.is() && xCheckLock
->getLock();
851 // commit if necessary
853 if ( xCurrentControl
.is() && !bControlIsLocked
)
855 // both the control and it's model can be committable, so try both
856 Reference
< XBoundComponent
> xBound( xCurrentControl
, UNO_QUERY
);
858 xBound
= xBound
.query( xCurrentControl
->getModel() );
859 // and now really commit
861 bSuccess
= xBound
->commit();
865 catch( const RuntimeException
& ) { throw; }
866 catch( const SQLException
& ) { throw; }
867 catch( const Exception
& )
869 DBG_UNHANDLED_EXCEPTION();
876 //--------------------------------------------------------------------
877 ::sal_Bool SAL_CALL
FormOperations::isInsertionRow() throw (RuntimeException
, WrappedTargetException
)
879 sal_Bool bIs
= sal_False
;
882 bIs
= impl_isInsertionRow_throw();
884 catch( const RuntimeException
& ) { throw; }
885 catch( const Exception
& )
887 throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
892 //--------------------------------------------------------------------
893 ::sal_Bool SAL_CALL
FormOperations::isModifiedRow() throw (RuntimeException
, WrappedTargetException
)
895 sal_Bool bIs
= sal_False
;
898 bIs
= impl_isModifiedRow_throw();
900 catch( const RuntimeException
& ) { throw; }
901 catch( const Exception
& )
903 throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
908 //--------------------------------------------------------------------
909 void SAL_CALL
FormOperations::cursorMoved( const EventObject
& /*_Event*/ ) throw (RuntimeException
)
911 MethodGuard
aGuard( *this );
912 m_bActiveControlModified
= sal_False
;
914 impl_invalidateAllSupportedFeatures_nothrow( aGuard
);
917 //--------------------------------------------------------------------
918 void SAL_CALL
FormOperations::rowChanged( const EventObject
& /*_Event*/ ) throw (RuntimeException
)
923 //--------------------------------------------------------------------
924 void SAL_CALL
FormOperations::rowSetChanged( const EventObject
& /*_Event*/ ) throw (RuntimeException
)
929 //--------------------------------------------------------------------
930 void SAL_CALL
FormOperations::modified( const EventObject
& /*_Source*/ ) throw( RuntimeException
)
932 MethodGuard
aGuard( *this );
934 OSL_ENSURE( m_xCursor
.is(), "FormOperations::modified: already disposed!" );
935 if ( !m_bActiveControlModified
)
937 m_bActiveControlModified
= sal_True
;
938 impl_invalidateModifyDependentFeatures_nothrow( aGuard
);
942 //--------------------------------------------------------------------
943 void SAL_CALL
FormOperations::propertyChange( const PropertyChangeEvent
& _rEvent
) throw (RuntimeException
)
945 MethodGuard
aGuard( *this );
947 if ( m_xCursor
.is() && ( m_xCursor
== _rEvent
.Source
) )
949 sal_Bool bIs
= sal_False
;
950 if ( ( _rEvent
.PropertyName
== PROPERTY_ISMODIFIED
)
951 || ( _rEvent
.PropertyName
== PROPERTY_ISNEW
)
954 if ( ( _rEvent
.NewValue
>>= bIs
) && !bIs
)
955 m_bActiveControlModified
= sal_False
;
957 impl_invalidateAllSupportedFeatures_nothrow( aGuard
);
960 if ( m_xParser
.is() && ( m_xCursor
== _rEvent
.Source
) )
964 ::rtl::OUString sNewValue
;
965 _rEvent
.NewValue
>>= sNewValue
;
966 if ( _rEvent
.PropertyName
== PROPERTY_ACTIVECOMMAND
)
968 m_xParser
->setElementaryQuery( sNewValue
);
970 else if ( _rEvent
.PropertyName
== PROPERTY_FILTER
)
972 if ( m_xParser
->getFilter() != sNewValue
)
973 m_xParser
->setFilter( sNewValue
);
975 else if ( _rEvent
.PropertyName
== PROPERTY_SORT
)
977 _rEvent
.NewValue
>>= sNewValue
;
978 if ( m_xParser
->getOrder() != sNewValue
)
979 m_xParser
->setOrder( sNewValue
);
984 OSL_ENSURE( sal_False
, "FormOperations::propertyChange: caught an exception while updating the parser!" );
986 impl_invalidateAllSupportedFeatures_nothrow( aGuard
);
990 //--------------------------------------------------------------------
991 void SAL_CALL
FormOperations::disposing( const EventObject
& /*_Source*/ ) throw (RuntimeException
)
993 // TODO: should we react on this? Or is this the responsibility of our owner to dispose us?
996 //--------------------------------------------------------------------
997 void SAL_CALL
FormOperations::disposing()
999 ::osl::MutexGuard
aGuard( m_aMutex
);
1001 impl_disposeParser_nothrow();
1005 // revoke various listeners
1006 if ( m_xCursor
.is() )
1007 m_xCursor
->removeRowSetListener( this );
1009 if ( m_xCursorProperties
.is() )
1011 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_ISMODIFIED
,this );
1012 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_ISNEW
, this );
1015 Reference
< XModifyBroadcaster
> xBroadcaster( m_xController
, UNO_QUERY
);
1016 if ( xBroadcaster
.is() )
1017 xBroadcaster
->removeModifyListener( this );
1019 catch( const Exception
& )
1021 DBG_UNHANDLED_EXCEPTION();
1024 m_xController
.clear();
1026 m_xUpdateCursor
.clear();
1027 m_xCursorProperties
.clear();
1028 m_xLoadableForm
.clear();
1029 m_xFeatureInvalidation
.clear();
1031 m_bActiveControlModified
= true;
1034 //--------------------------------------------------------------------
1035 void FormOperations::impl_checkDisposed_throw() const
1037 if ( impl_isDisposed_nothrow() )
1038 throw DisposedException( ::rtl::OUString(), *const_cast< FormOperations
* >( this ) );
1041 //--------------------------------------------------------------------
1042 void FormOperations::impl_initFromController_throw()
1044 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_initFromController_throw: invalid controller!" );
1045 m_xCursor
= m_xCursor
.query( m_xController
->getModel() );
1046 if ( !m_xCursor
.is() )
1047 throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
1049 impl_initFromForm_throw();
1051 Reference
< XModifyBroadcaster
> xBroadcaster( m_xController
, UNO_QUERY
);
1052 if ( xBroadcaster
.is() )
1053 xBroadcaster
->addModifyListener( this );
1056 //--------------------------------------------------------------------
1057 void FormOperations::impl_initFromForm_throw()
1059 OSL_PRECOND( m_xCursor
.is(), "FormOperations::impl_initFromForm_throw: invalid form!" );
1060 m_xCursorProperties
= m_xCursorProperties
.query ( m_xCursor
);
1061 m_xUpdateCursor
= m_xUpdateCursor
.query ( m_xCursor
);
1062 m_xLoadableForm
= m_xLoadableForm
.query ( m_xCursor
);
1064 if ( !m_xCursor
.is() || !m_xCursorProperties
.is() || !m_xLoadableForm
.is() )
1065 throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
1067 m_xCursor
->addRowSetListener( this );
1068 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_ISMODIFIED
,this );
1069 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_ISNEW
, this );
1072 //--------------------------------------------------------------------
1073 void FormOperations::createWithFormController( const Reference
< XFormController
>& _rxController
)
1075 m_xController
= _rxController
;
1076 if ( !m_xController
.is() )
1077 throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
1079 impl_initFromController_throw();
1081 m_bConstructed
= true;
1084 //--------------------------------------------------------------------
1085 void FormOperations::createWithForm( const Reference
< XForm
>& _rxForm
)
1087 m_xCursor
= m_xCursor
.query( _rxForm
);
1088 if ( !m_xCursor
.is() )
1089 throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
1091 impl_initFromForm_throw();
1093 m_bConstructed
= true;
1096 //------------------------------------------------------------------------------
1097 void FormOperations::impl_invalidateAllSupportedFeatures_nothrow( MethodGuard
& _rClearForCallback
) const
1099 if ( !m_xFeatureInvalidation
.is() )
1100 // nobody's interested in ...
1103 Reference
< XFeatureInvalidation
> xInvalidation
= m_xFeatureInvalidation
;
1104 _rClearForCallback
.clear();
1105 xInvalidation
->invalidateAllFeatures();
1108 //------------------------------------------------------------------------------
1109 void FormOperations::impl_invalidateModifyDependentFeatures_nothrow( MethodGuard
& _rClearForCallback
) const
1111 if ( !m_xFeatureInvalidation
.is() )
1112 // nobody's interested in ...
1115 static Sequence
< sal_Int16
> s_aModifyDependentFeatures
;
1116 if ( s_aModifyDependentFeatures
.getLength() == 0 )
1118 sal_Int16 pModifyDependentFeatures
[] =
1120 FormFeature::MoveToNext
,
1121 FormFeature::MoveToInsertRow
,
1122 FormFeature::SaveRecordChanges
,
1123 FormFeature::UndoRecordChanges
1125 size_t nFeatureCount
= sizeof( pModifyDependentFeatures
) / sizeof( pModifyDependentFeatures
[ 0 ] );
1126 s_aModifyDependentFeatures
= Sequence
< sal_Int16
>( pModifyDependentFeatures
, nFeatureCount
);
1129 Reference
< XFeatureInvalidation
> xInvalidation
= m_xFeatureInvalidation
;
1130 _rClearForCallback
.clear();
1132 xInvalidation
->invalidateFeatures( s_aModifyDependentFeatures
);
1135 //--------------------------------------------------------------------
1136 void FormOperations::impl_ensureInitializedParser_nothrow()
1138 OSL_PRECOND( m_xCursorProperties
.is(), "FormOperations::impl_ensureInitializedParser_nothrow: we're disposed!" );
1139 if ( m_bInitializedParser
)
1144 sal_Bool bUseEscapeProcessing
= sal_False
;
1145 m_xCursorProperties
->getPropertyValue( PROPERTY_ESCAPE_PROCESSING
) >>= bUseEscapeProcessing
;
1146 if ( bUseEscapeProcessing
)
1148 Reference
< XMultiServiceFactory
> xFactory( ::dbtools::getConnection( m_xCursor
), UNO_QUERY
);
1149 if ( xFactory
.is() )
1151 m_xParser
.set( xFactory
->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.SingleSelectQueryComposer" ) ) ), UNO_QUERY
);
1152 OSL_ENSURE( m_xParser
.is(), "FormOperations::impl_ensureInitializedParser_nothrow: factory did not create a parser for us!" );
1156 if ( m_xParser
.is() )
1158 if ( m_xLoadableForm
.is() && m_xLoadableForm
->isLoaded() )
1160 ::rtl::OUString sStatement
;
1161 ::rtl::OUString sFilter
;
1162 ::rtl::OUString sSort
;
1164 m_xCursorProperties
->getPropertyValue( PROPERTY_ACTIVECOMMAND
) >>= sStatement
;
1165 m_xCursorProperties
->getPropertyValue( PROPERTY_FILTER
) >>= sFilter
;
1166 m_xCursorProperties
->getPropertyValue( PROPERTY_SORT
) >>= sSort
;
1168 m_xParser
->setElementaryQuery( sStatement
);
1169 m_xParser
->setFilter ( sFilter
);
1170 m_xParser
->setOrder ( sSort
);
1173 // start listening at the order/sort properties at the form, so
1174 // we can keep our parser in sync
1175 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_ACTIVECOMMAND
, this );
1176 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_FILTER
, this );
1177 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_SORT
, this );
1180 catch( const Exception
& )
1182 OSL_ENSURE( sal_False
, "FormOperations::impl_ensureInitializedParser_nothrow: caught an exception!" );
1185 m_bInitializedParser
= true;
1188 //--------------------------------------------------------------------
1189 void FormOperations::impl_disposeParser_nothrow()
1193 // if we have a parser (and a cursor), then we're listening at the cursor's
1194 // properties to keep the parser in sync with the cursor
1195 if ( m_xParser
.is() && m_xCursorProperties
.is() )
1197 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_FILTER
, this );
1198 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_ACTIVECOMMAND
, this );
1199 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_SORT
, this );
1202 Reference
< XComponent
> xParserComp( m_xParser
, UNO_QUERY
);
1203 if ( xParserComp
.is() )
1204 xParserComp
->dispose();
1207 m_bInitializedParser
= false;
1209 catch( const Exception
& )
1211 OSL_ENSURE( sal_False
, "FormOperations::impl_disposeParser_nothrow: caught an exception!" );
1215 //--------------------------------------------------------------------
1216 bool FormOperations::impl_canMoveLeft_throw( ) const
1218 if ( !impl_hasCursor_nothrow() )
1221 return impl_getRowCount_throw() && ( !m_xCursor
->isFirst() || impl_isInsertionRow_throw() );
1224 //--------------------------------------------------------------------
1225 bool FormOperations::impl_canMoveRight_throw( ) const
1227 if ( !impl_hasCursor_nothrow() )
1230 bool bIsNew
= impl_isInsertionRow_throw();
1232 if ( impl_getRowCount_throw() && !m_xCursor
->isLast() && !bIsNew
)
1235 if ( ::dbtools::canInsert( m_xCursorProperties
) )
1236 if ( !bIsNew
|| impl_isModifiedRow_throw() )
1239 if ( bIsNew
&& m_bActiveControlModified
)
1245 //--------------------------------------------------------------------
1248 template < typename TYPE
>
1249 TYPE
lcl_safeGetPropertyValue_throw( const Reference
< XPropertySet
>& _rxProperties
, const ::rtl::OUString
& _rPropertyName
, TYPE _Default
)
1251 TYPE
value( _Default
);
1252 OSL_PRECOND( _rxProperties
.is(), "FormOperations::<foo>: no cursor (already disposed?)!" );
1253 if ( _rxProperties
.is() )
1254 OSL_VERIFY( _rxProperties
->getPropertyValue( _rPropertyName
) >>= value
);
1259 //--------------------------------------------------------------------
1260 bool FormOperations::impl_isInsertionRow_throw() const
1262 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_ISNEW
, false );
1265 //--------------------------------------------------------------------
1266 sal_Int32
FormOperations::impl_getRowCount_throw() const
1268 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_ROWCOUNT
, (sal_Int32
)0 );
1270 //--------------------------------------------------------------------
1271 bool FormOperations::impl_isRowCountFinal_throw() const
1273 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_ROWCOUNTFINAL
, false );
1276 //--------------------------------------------------------------------
1277 bool FormOperations::impl_isModifiedRow_throw() const
1279 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_ISMODIFIED
, false );
1282 //--------------------------------------------------------------------
1283 bool FormOperations::impl_isParseable_throw() const
1285 const_cast< FormOperations
* >( this )->impl_ensureInitializedParser_nothrow();
1286 return m_xParser
.is() && m_xParser
->getQuery().getLength();
1289 //--------------------------------------------------------------------
1290 bool FormOperations::impl_hasFilterOrOrder_throw() const
1292 return impl_isParseable_throw() && ( m_xParser
->getFilter().getLength() || m_xParser
->getOrder().getLength() );
1295 //--------------------------------------------------------------------
1296 bool FormOperations::impl_isInsertOnlyForm_throw() const
1298 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_INSERTONLY
, true );
1301 //------------------------------------------------------------------------------
1302 Reference
< XControlModel
> FormOperations::impl_getCurrentControlModel_throw() const
1304 Reference
< XControl
> xControl( m_xController
->getCurrentControl() );
1306 // special handling for grid controls
1307 Reference
< XGrid
> xGrid( xControl
, UNO_QUERY
);
1308 Reference
< XControlModel
> xControlModel
;
1312 Reference
< XIndexAccess
> xColumns( xControl
->getModel(), UNO_QUERY_THROW
);
1313 sal_Int16 nCurrentPos
= xGrid
->getCurrentColumnPosition();
1314 nCurrentPos
= impl_gridView2ModelPos_nothrow( xColumns
, nCurrentPos
);
1316 if ( nCurrentPos
!= (sal_Int16
)-1 )
1317 xColumns
->getByIndex( nCurrentPos
) >>= xControlModel
;
1319 else if ( xControl
.is() )
1321 xControlModel
= xControl
->getModel();
1323 return xControlModel
;
1326 //------------------------------------------------------------------------------
1327 Reference
< XPropertySet
> FormOperations::impl_getCurrentBoundField_nothrow( ) const
1329 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_getCurrentBoundField_nothrow: no controller -> no control!" );
1330 if ( !m_xController
.is() )
1333 Reference
< XPropertySet
> xField
;
1336 Reference
< XPropertySet
> xControlModel( impl_getCurrentControlModel_throw(), UNO_QUERY
);
1338 if ( xControlModel
.is() && ::comphelper::hasProperty( PROPERTY_BOUNDFIELD
, xControlModel
) )
1339 xControlModel
->getPropertyValue( PROPERTY_BOUNDFIELD
) >>= xField
;
1342 catch( const Exception
& )
1344 DBG_UNHANDLED_EXCEPTION();
1350 //------------------------------------------------------------------------------
1351 sal_Int16
FormOperations::impl_gridView2ModelPos_nothrow( const Reference
< XIndexAccess
>& _rxColumns
, sal_Int16 _nViewPos
) const
1353 OSL_PRECOND( _rxColumns
.is(), "FormOperations::impl_gridView2ModelPos_nothrow: invalid columns container!" );
1356 // loop through all columns
1358 Reference
< XPropertySet
> xCol
;
1359 bool bHidden( false );
1360 for ( col
= 0; col
< _rxColumns
->getCount(); ++col
)
1362 _rxColumns
->getByIndex( col
) >>= xCol
;
1363 OSL_VERIFY( xCol
->getPropertyValue( PROPERTY_HIDDEN
) >>= bHidden
);
1367 // for every visible col : if nViewPos is greater zero, decrement it, else we
1368 // have found the model position
1374 if ( col
< _rxColumns
->getCount() )
1377 catch( const Exception
& )
1379 DBG_UNHANDLED_EXCEPTION();
1381 return (sal_Int16
)-1;
1384 //------------------------------------------------------------------------------
1385 bool FormOperations::impl_moveLeft_throw( ) const
1387 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_moveLeft_throw: no cursor!" );
1388 if ( !impl_hasCursor_nothrow() )
1391 sal_Bool bRecordInserted
= sal_False
;
1392 sal_Bool bSuccess
= impl_commitCurrentRecord_throw( &bRecordInserted
);
1397 if ( bRecordInserted
)
1399 // retrieve the bookmark of the new record and move to the record preceding this bookmark
1400 Reference
< XRowLocate
> xLocate( m_xCursor
, UNO_QUERY
);
1401 OSL_ENSURE( xLocate
.is(), "FormOperations::impl_moveLeft_throw: no XRowLocate!" );
1403 xLocate
->moveRelativeToBookmark( xLocate
->getBookmark(), -1 );
1407 if ( impl_isInsertionRow_throw() )
1409 // we assume that the inserted record is now the last record in the
1414 m_xCursor
->previous();
1420 //--------------------------------------------------------------------
1421 bool FormOperations::impl_moveRight_throw( ) const
1423 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_moveRight_throw: no cursor!" );
1424 if ( !impl_hasCursor_nothrow() )
1427 sal_Bool bRecordInserted
= sal_False
;
1428 sal_Bool bSuccess
= impl_commitCurrentRecord_throw( &bRecordInserted
);
1433 if ( bRecordInserted
)
1436 m_xUpdateCursor
->moveToInsertRow();
1440 if ( m_xCursor
->isLast() )
1441 m_xUpdateCursor
->moveToInsertRow();
1449 //--------------------------------------------------------------------
1450 void FormOperations::impl_resetAllControls_nothrow() const
1452 Reference
< XIndexAccess
> xContainer( m_xCursor
, UNO_QUERY
);
1453 if ( !xContainer
.is() )
1458 Reference
< XReset
> xReset
;
1459 sal_Int32
nCount( xContainer
->getCount() );
1460 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
1462 if ( xContainer
->getByIndex( i
) >>= xReset
)
1464 // no resets on sub forms
1465 Reference
< XForm
> xAsForm( xReset
, UNO_QUERY
);
1466 if ( !xAsForm
.is() )
1471 catch( const Exception
& )
1473 DBG_UNHANDLED_EXCEPTION();
1477 //------------------------------------------------------------------------------
1478 void FormOperations::impl_executeAutoSort_throw( bool _bUp
) const
1480 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_executeAutoSort_throw: need a controller for this!" );
1481 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeAutoSort_throw: need a cursor for this!" );
1482 OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeAutoSort_throw: need a parseable statement for this!" );
1483 if ( !m_xController
.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
1488 Reference
< XControl
> xControl
= m_xController
->getCurrentControl();
1489 if ( !xControl
.is() || !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
1492 Reference
< XPropertySet
> xBoundField( impl_getCurrentBoundField_nothrow() );
1493 if ( !xBoundField
.is() )
1496 ::rtl::OUString sOriginalSort
;
1497 m_xCursorProperties
->getPropertyValue( PROPERTY_SORT
) >>= sOriginalSort
;
1499 // automatic sort by field is expected to always resets the previous sort order
1500 m_xParser
->setOrder( ::rtl::OUString() );
1502 param_appendOrderByColumn aParam
;
1503 aParam
.xField
= xBoundField
;
1505 impl_doActionInSQLContext_throw(
1506 (Action
)&FormOperations::impl_appendOrderByColumn_throw
,
1507 static_cast< const void* >( &aParam
),
1508 (sal_uInt16
)RID_STR_COULD_NOT_SET_ORDER
1511 WaitObject
aWO( NULL
);
1514 m_xCursorProperties
->setPropertyValue( PROPERTY_SORT
, makeAny( m_xParser
->getOrder() ) );
1515 m_xLoadableForm
->reload();
1517 catch( const Exception
& )
1519 OSL_ENSURE( sal_False
, "FormOperations::impl_executeAutoSort_throw: caught an exception while setting the parser properties!" );
1523 if ( !m_xLoadableForm
->isLoaded() )
1524 { // something went wrong -> restore the original state
1527 m_xParser
->setOrder( sOriginalSort
);
1528 m_xCursorProperties
->setPropertyValue( PROPERTY_SORT
, makeAny( m_xParser
->getOrder() ) );
1529 m_xLoadableForm
->reload();
1531 catch( const Exception
& )
1533 OSL_ENSURE( sal_False
, "FormOperations::impl_executeAutoSort_throw: could not reset the form to it's original state!" );
1538 catch( const RuntimeException
& ) { throw; }
1539 catch( const SQLException
& ) { throw; }
1540 catch( const Exception
& )
1542 throw WrappedTargetException( ::rtl::OUString(), *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
1546 //------------------------------------------------------------------------------
1547 void FormOperations::impl_executeAutoFilter_throw( ) const
1549 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_executeAutoFilter_throw: need a controller for this!" );
1550 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeAutoFilter_throw: need a cursor for this!" );
1551 OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeAutoFilter_throw: need a parseable statement for this!" );
1552 if ( !m_xController
.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
1557 Reference
< XControl
> xControl
= m_xController
->getCurrentControl();
1558 if ( !xControl
.is() || !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
1561 Reference
< XPropertySet
> xBoundField( impl_getCurrentBoundField_nothrow() );
1562 if ( !xBoundField
.is() )
1565 ::rtl::OUString sOriginalFilter
;
1566 m_xCursorProperties
->getPropertyValue( PROPERTY_FILTER
) >>= sOriginalFilter
;
1567 sal_Bool bApplied
= sal_True
;
1568 m_xCursorProperties
->getPropertyValue( PROPERTY_APPLYFILTER
) >>= bApplied
;
1570 // if we have a filter, but it's not applied, then we have to overwrite it, else append one
1572 m_xParser
->setFilter( ::rtl::OUString() );
1574 param_appendFilterByColumn aParam
;
1575 aParam
.xField
= xBoundField
;
1576 impl_doActionInSQLContext_throw(
1577 (Action
)&FormOperations::impl_appendFilterByColumn_throw
,
1578 static_cast< const void* >( &aParam
),
1579 (sal_uInt16
)RID_STR_COULD_NOT_SET_FILTER
1582 WaitObject
aWO( NULL
);
1585 m_xCursorProperties
->setPropertyValue( PROPERTY_FILTER
, makeAny( m_xParser
->getFilter() ) );
1586 m_xCursorProperties
->setPropertyValue( PROPERTY_APPLYFILTER
, makeAny( (sal_Bool
)sal_True
) );
1588 m_xLoadableForm
->reload();
1590 catch( const Exception
& )
1592 OSL_ENSURE( sal_False
, "FormOperations::impl_executeAutoFilter_throw: caught an exception while setting the parser properties!" );
1596 if ( !m_xLoadableForm
->isLoaded() )
1597 { // something went wrong -> restore the original state
1600 m_xParser
->setOrder( sOriginalFilter
);
1601 m_xCursorProperties
->setPropertyValue( PROPERTY_APPLYFILTER
, makeAny( (sal_Bool
)bApplied
) );
1602 m_xCursorProperties
->setPropertyValue( PROPERTY_FILTER
, makeAny( m_xParser
->getFilter() ) );
1603 m_xLoadableForm
->reload();
1605 catch( const Exception
& )
1607 OSL_ENSURE( sal_False
, "FormOperations::impl_executeAutoFilter_throw: could not reset the form to it's original state!" );
1612 catch( const RuntimeException
& ) { throw; }
1613 catch( const SQLException
& ) { throw; }
1614 catch( const Exception
& )
1616 throw WrappedTargetException( ::rtl::OUString(), *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
1620 //--------------------------------------------------------------------
1621 void FormOperations::impl_executeFilterOrSort_throw( bool _bFilter
) const
1623 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_executeFilterOrSort_throw: need a controller for this!" );
1624 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeFilterOrSort_throw: need a cursor for this!" );
1625 OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeFilterOrSort_throw: need a parseable statement for this!" );
1626 if ( !m_xController
.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
1629 if ( !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
1633 PropertyValue aFirst
;
1634 aFirst
.Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "QueryComposer" ) );
1635 aFirst
.Value
<<= m_xParser
;
1637 PropertyValue aSecond
;
1638 aSecond
.Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RowSet" ) );
1639 aSecond
.Value
<<= m_xCursorProperties
;
1641 Sequence
<Any
> aInit(2);
1642 aInit
[0] <<= aFirst
;
1643 aInit
[1] <<= aSecond
;
1645 ::rtl::OUString sDialogServiceName
;
1647 sDialogServiceName
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.FilterDialog" ) );
1649 sDialogServiceName
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.OrderDialog" ) );
1651 Reference
< XExecutableDialog
> xDialog
;
1652 m_aContext
.createComponentWithArguments( sDialogServiceName
, aInit
, xDialog
);
1654 if ( !xDialog
.is() )
1656 ShowServiceNotAvailableError( NULL
, sDialogServiceName
, sal_True
);
1660 if ( RET_OK
== xDialog
->execute() )
1662 WaitObject
aWO( NULL
);
1664 m_xCursorProperties
->setPropertyValue( PROPERTY_FILTER
, makeAny( m_xParser
->getFilter() ) );
1666 m_xCursorProperties
->setPropertyValue( PROPERTY_SORT
, makeAny( m_xParser
->getOrder() ) );
1667 m_xLoadableForm
->reload();
1671 catch( const RuntimeException
& ) { throw; }
1672 catch( const SQLException
& ) { throw; }
1673 catch( const Exception
& )
1675 throw WrappedTargetException( ::rtl::OUString(), *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
1679 //------------------------------------------------------------------------------
1680 void FormOperations::impl_appendOrderByColumn_throw( const void* _pActionParam
) const
1682 const param_appendOrderByColumn
* pParam
= static_cast< const param_appendOrderByColumn
* >( _pActionParam
);
1683 m_xParser
->appendOrderByColumn( pParam
->xField
, pParam
->bUp
);
1686 //------------------------------------------------------------------------------
1687 void FormOperations::impl_appendFilterByColumn_throw( const void* _pActionParam
) const
1689 const param_appendFilterByColumn
* pParam
= static_cast< const param_appendFilterByColumn
* >( _pActionParam
);
1690 m_xParser
->appendFilterByColumn( pParam
->xField
, sal_True
);
1693 //------------------------------------------------------------------------------
1694 void FormOperations::impl_doActionInSQLContext_throw( Action _pAction
, const void* _pParam
, sal_uInt16 _nErrorResourceId
) const
1698 (this->*_pAction
)( _pParam
);
1700 catch( const SQLException
& e
)
1703 if ( !_nErrorResourceId
)
1704 // no information to prepend
1707 SQLExceptionInfo
aInfo( ::cppu::getCaughtException() );
1708 ::rtl::OUString
sAdditionalError( FRM_RES_STRING( _nErrorResourceId
) );
1709 aInfo
.prepend( sAdditionalError
);
1712 catch( const RuntimeException
& ) { throw; }
1713 catch( const Exception
& )
1715 ::rtl::OUString
sAdditionalError( FRM_RES_STRING( _nErrorResourceId
) );
1716 throw WrappedTargetException( sAdditionalError
, *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
1720 //........................................................................
1722 //........................................................................