1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_forms.hxx"
31 #include "formoperations.hxx"
32 #include "frm_strings.hxx"
33 #include "frm_resource.hxx"
34 #include "frm_resource.hrc"
35 #include "frm_module.hxx"
37 /** === begin UNO includes === **/
38 #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
39 #include <com/sun/star/util/XModifyBroadcaster.hpp>
40 #include <com/sun/star/form/runtime/FormFeature.hpp>
41 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
42 #include <com/sun/star/lang/DisposedException.hpp>
43 #include <com/sun/star/awt/XControl.hpp>
44 #include <com/sun/star/form/XGrid.hpp>
45 #include <com/sun/star/form/XBoundControl.hpp>
46 #include <com/sun/star/form/XBoundComponent.hpp>
47 #include <com/sun/star/sdbcx/XRowLocate.hpp>
48 #include <com/sun/star/form/XConfirmDeleteListener.hpp>
49 #include <com/sun/star/sdb/RowChangeEvent.hpp>
50 #include <com/sun/star/sdb/RowChangeAction.hpp>
51 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
52 #include <com/sun/star/sdbc/DataType.hpp>
53 #include <com/sun/star/form/XReset.hpp>
54 #include <com/sun/star/beans/XMultiPropertySet.hpp>
55 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
56 #include <com/sun/star/util/XRefreshable.hpp>
57 /** === end UNO includes === **/
59 #include <connectivity/dbtools.hxx>
60 #include <connectivity/dbexception.hxx>
61 #include <vcl/svapp.hxx>
62 #include <vcl/stdtext.hxx>
63 #include <vcl/msgbox.hxx>
64 #include <vcl/waitobj.hxx>
65 #include <tools/diagnose_ex.h>
66 #include <comphelper/container.hxx>
67 #include <comphelper/property.hxx>
68 #include <comphelper/namedvaluecollection.hxx>
69 #include <cppuhelper/exc_hlp.hxx>
70 #include <vos/mutex.hxx>
72 //--------------------------------------------------------------------------
73 extern "C" void SAL_CALL
createRegistryInfo_FormOperations()
75 static ::frm::OMultiInstanceAutoRegistration
< ::frm::FormOperations
> aAutoRegistration
;
78 //........................................................................
81 //........................................................................
83 using ::dbtools::SQLExceptionInfo
;
84 /** === begin UNO using === **/
85 using ::com::sun::star::uno::Reference
;
86 using ::com::sun::star::uno::XComponentContext
;
87 using ::com::sun::star::uno::RuntimeException
;
88 using ::com::sun::star::uno::Sequence
;
89 using ::com::sun::star::uno::Exception
;
90 using ::com::sun::star::uno::Any
;
91 using ::com::sun::star::uno::XInterface
;
92 using ::com::sun::star::sdbc::XRowSet
;
93 using ::com::sun::star::sdbc::XResultSetUpdate
;
94 using ::com::sun::star::form::runtime::XFormController
;
95 using ::com::sun::star::form::runtime::XFeatureInvalidation
;
96 using ::com::sun::star::form::runtime::FeatureState
;
97 using ::com::sun::star::lang::IllegalArgumentException
;
98 using ::com::sun::star::sdbc::SQLException
;
99 using namespace ::com::sun::star::sdbc
;
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 namespace ::com::sun::star::sdb
;
119 using ::com::sun::star::form::XReset
;
120 using ::com::sun::star::beans::XMultiPropertySet
;
121 using ::com::sun::star::uno::makeAny
;
122 using ::com::sun::star::lang::WrappedTargetException
;
123 using ::com::sun::star::beans::PropertyValue
;
124 using ::com::sun::star::ui::dialogs::XExecutableDialog
;
125 using ::com::sun::star::beans::NamedValue
;
127 using ::com::sun::star::util::XRefreshable
;
128 using ::com::sun::star::awt::XControlModel
;
129 /** === end UNO using === **/
130 namespace FormFeature
= ::com::sun::star::form::runtime::FormFeature
;
131 namespace RowChangeAction
= ::com::sun::star::sdb::RowChangeAction
;
133 //====================================================================
135 //====================================================================
136 //--------------------------------------------------------------------
137 FormOperations::FormOperations( const Reference
< XMultiServiceFactory
>& _rxContext
)
138 :FormOperations_Base( m_aMutex
)
139 ,m_aContext( _rxContext
)
140 ,m_bInitializedParser( false )
141 ,m_bActiveControlModified( false )
142 ,m_bConstructed( false )
144 ,m_nMethodNestingLevel( false )
149 //--------------------------------------------------------------------
150 FormOperations::~FormOperations()
154 //--------------------------------------------------------------------
155 ::rtl::OUString
FormOperations::getImplementationName_Static( ) throw(RuntimeException
)
157 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.forms.FormOperations" ) );
160 //--------------------------------------------------------------------
161 Sequence
< ::rtl::OUString
> FormOperations::getSupportedServiceNames_Static( ) throw(RuntimeException
)
163 Sequence
< ::rtl::OUString
> aNames(1);
164 aNames
[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.runtime.FormOperations" ) );
168 //--------------------------------------------------------------------
169 Reference
< XInterface
> SAL_CALL
FormOperations::Create(const Reference
< XMultiServiceFactory
>& _rxFactory
)
171 return *new FormOperations( _rxFactory
);
174 //--------------------------------------------------------------------
175 void SAL_CALL
FormOperations::initialize( const Sequence
< Any
>& _arguments
) throw (Exception
, RuntimeException
)
177 if ( m_bConstructed
)
178 throw AlreadyInitializedException();
180 if ( _arguments
.getLength() == 1 )
182 Reference
< XFormController
> xController
;
183 Reference
< XForm
> xForm
;
184 if ( _arguments
[0] >>= xController
)
185 createWithFormController( xController
);
186 else if ( _arguments
[0] >>= xForm
)
187 createWithForm( xForm
);
189 throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
193 throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
196 //--------------------------------------------------------------------
197 ::rtl::OUString SAL_CALL
FormOperations::getImplementationName( ) throw (RuntimeException
)
199 return getImplementationName_Static();
202 //--------------------------------------------------------------------
203 ::sal_Bool SAL_CALL
FormOperations::supportsService( const ::rtl::OUString
& _ServiceName
) throw (RuntimeException
)
205 Sequence
< ::rtl::OUString
> aSupportedServiceNames( getSupportedServiceNames() );
206 const ::rtl::OUString
* pBegin
= aSupportedServiceNames
.getConstArray();
207 const ::rtl::OUString
* pEnd
= aSupportedServiceNames
.getConstArray() + aSupportedServiceNames
.getLength();
208 return ::std::find( pBegin
, pEnd
, _ServiceName
) != pEnd
;
211 //--------------------------------------------------------------------
212 Sequence
< ::rtl::OUString
> SAL_CALL
FormOperations::getSupportedServiceNames( ) throw (RuntimeException
)
214 return getSupportedServiceNames_Static();
217 //--------------------------------------------------------------------
218 Reference
< XRowSet
> SAL_CALL
FormOperations::getCursor() throw (RuntimeException
)
220 MethodGuard
aGuard( *this );
224 //--------------------------------------------------------------------
225 Reference
< XResultSetUpdate
> SAL_CALL
FormOperations::getUpdateCursor() throw (RuntimeException
)
227 MethodGuard
aGuard( *this );
228 return m_xUpdateCursor
;
231 //--------------------------------------------------------------------
232 Reference
< XFormController
> SAL_CALL
FormOperations::getController() throw (RuntimeException
)
234 MethodGuard
aGuard( *this );
235 return m_xController
;
238 //--------------------------------------------------------------------
239 Reference
< XFeatureInvalidation
> SAL_CALL
FormOperations::getFeatureInvalidation() throw (RuntimeException
)
241 MethodGuard
aGuard( *this );
242 return m_xFeatureInvalidation
;
245 //--------------------------------------------------------------------
246 void SAL_CALL
FormOperations::setFeatureInvalidation( const Reference
< XFeatureInvalidation
> & _rxFeatureInvalidation
) throw (RuntimeException
)
248 MethodGuard
aGuard( *this );
249 m_xFeatureInvalidation
= _rxFeatureInvalidation
;
252 //--------------------------------------------------------------------
253 FeatureState SAL_CALL
FormOperations::getState( ::sal_Int16 _nFeature
) throw (RuntimeException
)
255 MethodGuard
aGuard( *this );
258 aState
.Enabled
= sal_False
;
262 // some checks for basic pre-requisites
263 if ( !m_xLoadableForm
.is()
264 || !m_xLoadableForm
->isLoaded()
265 || !m_xCursorProperties
.is()
273 case FormFeature::MoveToFirst
:
274 case FormFeature::MoveToPrevious
:
275 aState
.Enabled
= impl_canMoveLeft_throw( );
278 case FormFeature::MoveToNext
:
279 aState
.Enabled
= impl_canMoveRight_throw();
282 case FormFeature::MoveToLast
:
283 aState
.Enabled
= impl_getRowCount_throw() && ( !m_xCursor
->isLast() || impl_isInsertionRow_throw() );
286 case FormFeature::DeleteRecord
:
288 if ( m_xCursor
->rowDeleted() )
289 aState
.Enabled
= sal_False
;
292 // allowed to delete the row ?
293 aState
.Enabled
= !impl_isInsertionRow_throw() && ::dbtools::canDelete( m_xCursorProperties
);
297 case FormFeature::MoveToInsertRow
:
298 // if we are inserting we can move to the next row if the current record or control is modified
299 aState
.Enabled
= impl_isInsertionRow_throw()
300 ? impl_isModifiedRow_throw() || m_bActiveControlModified
301 : ::dbtools::canInsert( m_xCursorProperties
);
304 case FormFeature::ReloadForm
:
306 // there must be an active connection
307 Reference
< XRowSet
> xCursorRowSet( m_xCursor
, UNO_QUERY
);
308 aState
.Enabled
= ::dbtools::getConnection( xCursorRowSet
).is();
310 // and an active command
311 ::rtl::OUString sActiveCommand
;
312 m_xCursorProperties
->getPropertyValue( PROPERTY_ACTIVECOMMAND
) >>= sActiveCommand
;
313 aState
.Enabled
&= sActiveCommand
.getLength() > 0;
317 case FormFeature::RefreshCurrentControl
:
319 Reference
< XRefreshable
> xControlModelRefresh( impl_getCurrentControlModel_throw(), UNO_QUERY
);
320 aState
.Enabled
= xControlModelRefresh
.is();
324 case FormFeature::SaveRecordChanges
:
325 case FormFeature::UndoRecordChanges
:
326 aState
.Enabled
= impl_isModifiedRow_throw() || m_bActiveControlModified
;
329 case FormFeature::RemoveFilterAndSort
:
330 if ( impl_isParseable_throw() && impl_hasFilterOrOrder_throw() )
331 aState
.Enabled
= !impl_isInsertOnlyForm_throw();
334 case FormFeature::SortAscending
:
335 case FormFeature::SortDescending
:
336 case FormFeature::AutoFilter
:
337 if ( m_xController
.is() && impl_isParseable_throw() )
339 sal_Bool bIsDeleted
= m_xCursor
->rowDeleted();
341 if ( !bIsDeleted
&& !impl_isInsertOnlyForm_throw() )
343 Reference
< XPropertySet
> xBoundField
= impl_getCurrentBoundField_nothrow( );
344 if ( xBoundField
.is() )
345 xBoundField
->getPropertyValue( PROPERTY_SEARCHABLE
) >>= aState
.Enabled
;
350 case FormFeature::InteractiveSort
:
351 case FormFeature::InteractiveFilter
:
352 if ( impl_isParseable_throw() )
353 aState
.Enabled
= !impl_isInsertOnlyForm_throw();
356 case FormFeature::ToggleApplyFilter
:
358 ::rtl::OUString sFilter
;
359 m_xCursorProperties
->getPropertyValue( PROPERTY_FILTER
) >>= sFilter
;
360 if ( sFilter
.getLength() )
362 aState
.State
= m_xCursorProperties
->getPropertyValue( PROPERTY_APPLYFILTER
);
363 aState
.Enabled
= !impl_isInsertOnlyForm_throw();
366 aState
.State
<<= (sal_Bool
)sal_False
;
370 case FormFeature::MoveAbsolute
:
372 sal_Int32 nPosition
= m_xCursor
->getRow();
373 sal_Bool bIsNew
= impl_isInsertionRow_throw();
374 sal_Int32 nCount
= impl_getRowCount_throw();
375 sal_Bool bFinalCount
= impl_isRowCountFinal_throw();
377 if ( ( nPosition
>= 0 ) || bIsNew
)
381 // special case: there are no records at all, and we
382 // can't insert records -> disabled
383 if ( !nCount
&& !::dbtools::canInsert( m_xCursorProperties
) )
385 aState
.Enabled
= sal_False
;
390 nPosition
= ++nCount
;
391 aState
.State
<<= (sal_Int32
)nPosition
;
392 aState
.Enabled
= sal_True
;
397 aState
.State
<<= (sal_Int32
)nPosition
;
398 aState
.Enabled
= sal_True
;
404 case FormFeature::TotalRecords
:
406 sal_Bool bIsNew
= impl_isInsertionRow_throw();
407 sal_Int32 nCount
= impl_getRowCount_throw();
408 sal_Bool bFinalCount
= impl_isRowCountFinal_throw();
413 ::rtl::OUString sValue
= ::rtl::OUString::valueOf( sal_Int32( nCount
) );
415 sValue
+= ::rtl::OUString::createFromAscii( " *" );
417 aState
.State
<<= sValue
;
418 aState
.Enabled
= sal_True
;
423 OSL_ENSURE( sal_False
, "FormOperations::getState: unknown feature id!" );
427 catch( const Exception
& )
429 OSL_ENSURE( sal_False
, "FormOperations::getState: caught an exception!" );
435 //--------------------------------------------------------------------
436 ::sal_Bool SAL_CALL
FormOperations::isEnabled( ::sal_Int16 _nFeature
) throw (RuntimeException
)
438 MethodGuard
aGuard( *this );
440 FeatureState
aState( getState( _nFeature
) );
441 return aState
.Enabled
;
444 //--------------------------------------------------------------------
447 static bool lcl_needConfirmCommit( sal_Int32 _nFeature
)
449 return ( ( _nFeature
== FormFeature::ReloadForm
)
450 || ( _nFeature
== FormFeature::RemoveFilterAndSort
)
451 || ( _nFeature
== FormFeature::ToggleApplyFilter
)
452 || ( _nFeature
== FormFeature::SortAscending
)
453 || ( _nFeature
== FormFeature::SortDescending
)
454 || ( _nFeature
== FormFeature::AutoFilter
)
455 || ( _nFeature
== FormFeature::InteractiveSort
)
456 || ( _nFeature
== FormFeature::InteractiveFilter
)
459 static bool lcl_requiresArguments( sal_Int32 _nFeature
)
461 return ( _nFeature
== FormFeature::MoveAbsolute
);
463 static bool lcl_isExecutableFeature( sal_Int32 _nFeature
)
465 return ( _nFeature
!= FormFeature::TotalRecords
);
469 //--------------------------------------------------------------------
470 void SAL_CALL
FormOperations::execute( ::sal_Int16 _nFeature
) throw (RuntimeException
, IllegalArgumentException
, SQLException
, WrappedTargetException
)
472 ::vos::OGuard
aSolarGuard( Application::GetSolarMutex() );
473 MethodGuard
aGuard( *this );
475 if ( ( _nFeature
!= FormFeature::DeleteRecord
) && ( _nFeature
!= FormFeature::UndoRecordChanges
) )
477 // if we have a controller, commit the current control
478 if ( m_xController
.is() )
479 if ( !impl_commitCurrentControl_throw() )
482 // commit the current record
483 bool bCommitCurrentRecord
= true;
484 // (but before, let the user confirm if necessary)
485 if ( impl_isModifiedRow_throw() )
487 if ( lcl_needConfirmCommit( _nFeature
) )
489 // TODO: shouldn't this be done with an interaction handler?
490 QueryBox
aQuery( NULL
, WB_YES_NO_CANCEL
| WB_DEF_YES
, FRM_RES_STRING( RID_STR_QUERY_SAVE_MODIFIED_ROW
) );
491 switch ( aQuery
.Execute() )
493 case RET_NO
: bCommitCurrentRecord
= false; break;
494 case RET_CANCEL
: return;
499 if ( bCommitCurrentRecord
&& !impl_commitCurrentRecord_throw() )
507 case FormFeature::MoveToFirst
:
511 case FormFeature::MoveToNext
:
512 impl_moveRight_throw( );
515 case FormFeature::MoveToPrevious
:
516 impl_moveLeft_throw( );
519 case FormFeature::MoveToLast
:
522 // TODO: re-implement this .....
523 // run in an own thread if ...
524 // ... the data source is thread safe ...
525 sal_Bool bAllowOwnThread = sal_False;
526 if ( ::comphelper::hasProperty( PROPERTY_THREADSAFE, m_xCursorProperties ) )
527 m_xCursorProperties->getPropertyValue( PROPERTY_THREADSAFE ) >>= bAllowOwnThread;
529 // ... the record count is unknown
530 sal_Bool bNeedOwnThread sal_False;
531 if ( ::comphelper::hasProperty( PROPERTY_ROWCOUNTFINAL, m_xCursorProperties ) )
532 m_xCursorProperties->getPropertyValue( PROPERTY_ROWCOUNTFINAL ) >>= bNeedOwnThread;
534 if ( bNeedOwnThread && bAllowOwnThread )
542 case FormFeature::ReloadForm
:
543 if ( m_xLoadableForm
.is() )
545 WaitObject
aWO( NULL
);
546 m_xLoadableForm
->reload();
548 // refresh all controls in the form (and sub forms) which can be refreshed
549 // #i90914# / 2008-07-02 / frank.schoenheit@sun.com
550 ::comphelper::IndexAccessIterator
aIter( m_xLoadableForm
);
551 Reference
< XInterface
> xElement( aIter
.Next() );
552 while ( xElement
.is() )
554 Reference
< XRefreshable
> xRefresh( xElement
, UNO_QUERY
);
557 xElement
= aIter
.Next();
562 case FormFeature::RefreshCurrentControl
:
564 Reference
< XRefreshable
> xControlModelRefresh( impl_getCurrentControlModel_throw(), UNO_QUERY
);
565 OSL_ENSURE( xControlModelRefresh
.is(), "FormOperations::execute: how did you reach this?" );
566 if ( xControlModelRefresh
.is() )
567 xControlModelRefresh
->refresh();
571 case FormFeature::DeleteRecord
:
573 sal_uInt32 nCount
= impl_getRowCount_throw();
576 sal_Bool bLeft
= m_xCursor
->isLast() && ( nCount
> 1 );
577 sal_Bool bRight
= !m_xCursor
->isLast();
578 sal_Bool bSuccess
= sal_False
;
581 // ask for confirmation
582 Reference
< XConfirmDeleteListener
> xConfirmDelete( m_xController
, UNO_QUERY
);
584 if ( xConfirmDelete
.is() )
586 RowChangeEvent aEvent
;
587 aEvent
.Source
= Reference
< XInterface
>( m_xCursor
, UNO_QUERY
);
588 aEvent
.Action
= RowChangeAction::DELETE
;
590 bSuccess
= xConfirmDelete
->confirmDelete( aEvent
);
595 m_xUpdateCursor
->deleteRow();
597 catch( const Exception
& )
599 bSuccess
= sal_False
;
604 if ( bLeft
|| bRight
)
605 m_xCursor
->relative( bRight
? 1 : -1 );
608 sal_Bool bCanInsert
= ::dbtools::canInsert( m_xCursorProperties
);
609 // is it possible to insert another record?
611 m_xUpdateCursor
->moveToInsertRow();
613 // move record to update stati
620 case FormFeature::SaveRecordChanges
:
621 case FormFeature::UndoRecordChanges
:
623 sal_Bool bInserting
= impl_isInsertionRow_throw();
625 if ( FormFeature::UndoRecordChanges
== _nFeature
)
628 m_xUpdateCursor
->cancelRowUpdates();
630 // reset all controls for this form
631 impl_resetAllControls_nothrow( );
633 if ( bInserting
) // back to insertion mode for this form
634 m_xUpdateCursor
->moveToInsertRow();
640 m_xUpdateCursor
->insertRow();
644 m_xUpdateCursor
->updateRow();
649 case FormFeature::MoveToInsertRow
:
650 // move to the last row before moving to the insert row
651 // 21.01.2002 - 96480 - fs@openoffice.org
653 m_xUpdateCursor
->moveToInsertRow();
656 case FormFeature::RemoveFilterAndSort
:
658 // simultaneously reset Filter and Order property
659 Reference
< XMultiPropertySet
> xProperties( m_xCursorProperties
, UNO_QUERY
);
660 OSL_ENSURE( xProperties
.is(), "FormOperations::execute: no multi property access!" );
661 if ( xProperties
.is() )
663 Sequence
< ::rtl::OUString
> aNames( 2 );
664 aNames
[0] = PROPERTY_FILTER
;
665 aNames
[1] = PROPERTY_SORT
;
667 Sequence
< Any
> aValues( 2 );
668 aValues
[0] <<= ::rtl::OUString();
669 aValues
[1] <<= ::rtl::OUString();
671 WaitObject
aWO( NULL
);
672 xProperties
->setPropertyValues( aNames
, aValues
);
674 if ( m_xLoadableForm
.is() )
675 m_xLoadableForm
->reload();
680 case FormFeature::ToggleApplyFilter
:
681 if ( impl_commitCurrentControl_throw() && impl_commitCurrentRecord_throw() )
683 // simply toggle the value
684 sal_Bool bApplied
= sal_False
;
685 m_xCursorProperties
->getPropertyValue( PROPERTY_APPLYFILTER
) >>= bApplied
;
686 m_xCursorProperties
->setPropertyValue( PROPERTY_APPLYFILTER
, makeAny( (sal_Bool
)!bApplied
) );
689 WaitObject
aWO( NULL
);
690 m_xLoadableForm
->reload();
694 case FormFeature::SortAscending
:
695 impl_executeAutoSort_throw( true );
698 case FormFeature::SortDescending
:
699 impl_executeAutoSort_throw( false );
702 case FormFeature::AutoFilter
:
703 impl_executeAutoFilter_throw();
706 case FormFeature::InteractiveSort
:
707 impl_executeFilterOrSort_throw( false );
710 case FormFeature::InteractiveFilter
:
711 impl_executeFilterOrSort_throw( true );
716 sal_uInt16 nErrorResourceId
= RID_STR_FEATURE_UNKNOWN
;
717 if ( lcl_requiresArguments( _nFeature
) )
718 nErrorResourceId
= RID_STR_FEATURE_REQUIRES_PARAMETERS
;
719 else if ( !lcl_isExecutableFeature( _nFeature
) )
720 nErrorResourceId
= RID_STR_FEATURE_NOT_EXECUTABLE
;
721 throw IllegalArgumentException( FRM_RES_STRING( nErrorResourceId
), *this, 1 );
725 catch( const RuntimeException
& ) { throw; }
726 catch( const SQLException
& ) { throw; }
727 catch( const IllegalArgumentException
& ) { throw; }
728 catch( const Exception
& )
730 throw WrappedTargetException( ::rtl::OUString(), *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
733 impl_invalidateAllSupportedFeatures_nothrow( aGuard
);
736 //--------------------------------------------------------------------
737 void SAL_CALL
FormOperations::executeWithArguments( ::sal_Int16 _nFeature
, const Sequence
< NamedValue
>& _rArguments
) throw (RuntimeException
, IllegalArgumentException
, SQLException
, WrappedTargetException
)
739 if ( !lcl_requiresArguments( _nFeature
) )
741 execute( _nFeature
);
745 ::vos::OGuard
aSolarGuard( Application::GetSolarMutex() );
746 MethodGuard
aGuard( *this );
748 // at the moment we have only one feature which supports execution parameters
749 if ( !lcl_isExecutableFeature( _nFeature
) )
750 throw IllegalArgumentException( FRM_RES_STRING( RID_STR_FEATURE_NOT_EXECUTABLE
), *this, 1 );
754 case FormFeature::MoveAbsolute
:
756 sal_Int32 nPosition
= -1;
758 ::comphelper::NamedValueCollection
aArguments( _rArguments
);
759 aArguments
.get_ensureType( "Position", nPosition
);
766 // commit before doing anything else
767 if ( m_xController
.is() && !impl_commitCurrentControl_throw() )
769 if ( !impl_commitCurrentRecord_throw() )
772 sal_Int32 nCount
= impl_getRowCount_throw();
773 sal_Bool bFinalCount
= impl_isRowCountFinal_throw();
775 if ( bFinalCount
&& ( (sal_Int32
)nPosition
> nCount
) )
778 m_xCursor
->absolute( nPosition
);
780 catch( const RuntimeException
& ) { throw; }
781 catch( const SQLException
& ) { throw; }
782 catch( const Exception
& )
784 throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
789 throw IllegalArgumentException( FRM_RES_STRING( RID_STR_FEATURE_UNKNOWN
), *this, 1 );
793 //--------------------------------------------------------------------
794 ::sal_Bool SAL_CALL
FormOperations::commitCurrentRecord( ::sal_Bool
& _out_rRecordInserted
) throw (RuntimeException
, SQLException
)
796 MethodGuard
aGuard( *this );
797 _out_rRecordInserted
= sal_False
;
799 return impl_commitCurrentRecord_throw( &_out_rRecordInserted
);
802 //--------------------------------------------------------------------
803 bool FormOperations::impl_commitCurrentRecord_throw( ::sal_Bool
* _pRecordInserted
) const
805 DBG_ASSERT( m_nMethodNestingLevel
, "FormOperations::impl_commitCurrentRecord_throw: to be called within a MethodGuard'ed section only!" );
807 if ( !impl_hasCursor_nothrow() )
810 // nothing to do if the record is not modified
811 sal_Bool bResult
= !impl_isModifiedRow_throw();
814 // insert respectively update the row
815 if ( impl_isInsertionRow_throw() )
817 m_xUpdateCursor
->insertRow();
818 if ( _pRecordInserted
)
819 *_pRecordInserted
= sal_True
;
822 m_xUpdateCursor
->updateRow();
828 //--------------------------------------------------------------------
829 ::sal_Bool SAL_CALL
FormOperations::commitCurrentControl() throw (RuntimeException
, SQLException
)
831 MethodGuard
aGuard( *this );
832 return impl_commitCurrentControl_throw();
835 //--------------------------------------------------------------------
836 bool FormOperations::impl_commitCurrentControl_throw() const
838 DBG_ASSERT( m_nMethodNestingLevel
, "FormOperations::impl_commitCurrentRecord_throw: to be called within a MethodGuard'ed section only!" );
839 OSL_PRECOND( m_xController
.is(), "FormOperations::commitCurrentControl: no controller!" );
840 if ( !m_xController
.is() )
843 bool bSuccess
= false;
846 Reference
< XControl
> xCurrentControl( m_xController
->getCurrentControl() );
848 // check whether the control is locked
849 Reference
< XBoundControl
> xCheckLock( xCurrentControl
, UNO_QUERY
);
850 sal_Bool bControlIsLocked
= xCheckLock
.is() && xCheckLock
->getLock();
852 // commit if necessary
854 if ( xCurrentControl
.is() && !bControlIsLocked
)
856 // both the control and it's model can be committable, so try both
857 Reference
< XBoundComponent
> xBound( xCurrentControl
, UNO_QUERY
);
859 xBound
= xBound
.query( xCurrentControl
->getModel() );
860 // and now really commit
862 bSuccess
= xBound
->commit();
866 catch( const RuntimeException
& ) { throw; }
867 catch( const SQLException
& ) { throw; }
868 catch( const Exception
& )
870 DBG_UNHANDLED_EXCEPTION();
877 //--------------------------------------------------------------------
878 ::sal_Bool SAL_CALL
FormOperations::isInsertionRow() throw (RuntimeException
, WrappedTargetException
)
880 sal_Bool bIs
= sal_False
;
883 bIs
= impl_isInsertionRow_throw();
885 catch( const RuntimeException
& ) { throw; }
886 catch( const Exception
& )
888 throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
893 //--------------------------------------------------------------------
894 ::sal_Bool SAL_CALL
FormOperations::isModifiedRow() throw (RuntimeException
, WrappedTargetException
)
896 sal_Bool bIs
= sal_False
;
899 bIs
= impl_isModifiedRow_throw();
901 catch( const RuntimeException
& ) { throw; }
902 catch( const Exception
& )
904 throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
909 //--------------------------------------------------------------------
910 void SAL_CALL
FormOperations::cursorMoved( const EventObject
& /*_Event*/ ) throw (RuntimeException
)
912 MethodGuard
aGuard( *this );
913 m_bActiveControlModified
= sal_False
;
915 impl_invalidateAllSupportedFeatures_nothrow( aGuard
);
918 //--------------------------------------------------------------------
919 void SAL_CALL
FormOperations::rowChanged( const EventObject
& /*_Event*/ ) throw (RuntimeException
)
924 //--------------------------------------------------------------------
925 void SAL_CALL
FormOperations::rowSetChanged( const EventObject
& /*_Event*/ ) throw (RuntimeException
)
930 //--------------------------------------------------------------------
931 void SAL_CALL
FormOperations::modified( const EventObject
& /*_Source*/ ) throw( RuntimeException
)
933 MethodGuard
aGuard( *this );
935 OSL_ENSURE( m_xCursor
.is(), "FormOperations::modified: already disposed!" );
936 if ( !m_bActiveControlModified
)
938 m_bActiveControlModified
= sal_True
;
939 impl_invalidateModifyDependentFeatures_nothrow( aGuard
);
943 //--------------------------------------------------------------------
944 void SAL_CALL
FormOperations::propertyChange( const PropertyChangeEvent
& _rEvent
) throw (RuntimeException
)
946 MethodGuard
aGuard( *this );
948 if ( m_xCursor
.is() && ( m_xCursor
== _rEvent
.Source
) )
950 sal_Bool bIs
= sal_False
;
951 if ( ( _rEvent
.PropertyName
== PROPERTY_ISMODIFIED
)
952 || ( _rEvent
.PropertyName
== PROPERTY_ISNEW
)
955 if ( ( _rEvent
.NewValue
>>= bIs
) && !bIs
)
956 m_bActiveControlModified
= sal_False
;
958 impl_invalidateAllSupportedFeatures_nothrow( aGuard
);
961 if ( m_xParser
.is() && ( m_xCursor
== _rEvent
.Source
) )
965 ::rtl::OUString sNewValue
;
966 _rEvent
.NewValue
>>= sNewValue
;
967 if ( _rEvent
.PropertyName
== PROPERTY_ACTIVECOMMAND
)
969 m_xParser
->setElementaryQuery( sNewValue
);
971 else if ( _rEvent
.PropertyName
== PROPERTY_FILTER
)
973 if ( m_xParser
->getFilter() != sNewValue
)
974 m_xParser
->setFilter( sNewValue
);
976 else if ( _rEvent
.PropertyName
== PROPERTY_SORT
)
978 _rEvent
.NewValue
>>= sNewValue
;
979 if ( m_xParser
->getOrder() != sNewValue
)
980 m_xParser
->setOrder( sNewValue
);
985 OSL_ENSURE( sal_False
, "FormOperations::propertyChange: caught an exception while updating the parser!" );
987 impl_invalidateAllSupportedFeatures_nothrow( aGuard
);
991 //--------------------------------------------------------------------
992 void SAL_CALL
FormOperations::disposing( const EventObject
& /*_Source*/ ) throw (RuntimeException
)
994 // TODO: should we react on this? Or is this the responsibility of our owner to dispose us?
997 //--------------------------------------------------------------------
998 void SAL_CALL
FormOperations::disposing()
1000 ::osl::MutexGuard
aGuard( m_aMutex
);
1002 impl_disposeParser_nothrow();
1006 // revoke various listeners
1007 if ( m_xCursor
.is() )
1008 m_xCursor
->removeRowSetListener( this );
1010 if ( m_xCursorProperties
.is() )
1012 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_ISMODIFIED
,this );
1013 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_ISNEW
, this );
1016 Reference
< XModifyBroadcaster
> xBroadcaster( m_xController
, UNO_QUERY
);
1017 if ( xBroadcaster
.is() )
1018 xBroadcaster
->removeModifyListener( this );
1020 catch( const Exception
& )
1022 DBG_UNHANDLED_EXCEPTION();
1025 m_xController
.clear();
1027 m_xUpdateCursor
.clear();
1028 m_xCursorProperties
.clear();
1029 m_xLoadableForm
.clear();
1030 m_xFeatureInvalidation
.clear();
1032 m_bActiveControlModified
= true;
1035 //--------------------------------------------------------------------
1036 void FormOperations::impl_checkDisposed_throw() const
1038 if ( impl_isDisposed_nothrow() )
1039 throw DisposedException( ::rtl::OUString(), *const_cast< FormOperations
* >( this ) );
1042 //--------------------------------------------------------------------
1043 void FormOperations::impl_initFromController_throw()
1045 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_initFromController_throw: invalid controller!" );
1046 m_xCursor
= m_xCursor
.query( m_xController
->getModel() );
1047 if ( !m_xCursor
.is() )
1048 throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
1050 impl_initFromForm_throw();
1052 Reference
< XModifyBroadcaster
> xBroadcaster( m_xController
, UNO_QUERY
);
1053 if ( xBroadcaster
.is() )
1054 xBroadcaster
->addModifyListener( this );
1057 //--------------------------------------------------------------------
1058 void FormOperations::impl_initFromForm_throw()
1060 OSL_PRECOND( m_xCursor
.is(), "FormOperations::impl_initFromForm_throw: invalid form!" );
1061 m_xCursorProperties
= m_xCursorProperties
.query ( m_xCursor
);
1062 m_xUpdateCursor
= m_xUpdateCursor
.query ( m_xCursor
);
1063 m_xLoadableForm
= m_xLoadableForm
.query ( m_xCursor
);
1065 if ( !m_xCursor
.is() || !m_xCursorProperties
.is() || !m_xLoadableForm
.is() )
1066 throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
1068 m_xCursor
->addRowSetListener( this );
1069 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_ISMODIFIED
,this );
1070 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_ISNEW
, this );
1073 //--------------------------------------------------------------------
1074 void FormOperations::createWithFormController( const Reference
< XFormController
>& _rxController
)
1076 m_xController
= _rxController
;
1077 if ( !m_xController
.is() )
1078 throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
1080 impl_initFromController_throw();
1082 m_bConstructed
= true;
1085 //--------------------------------------------------------------------
1086 void FormOperations::createWithForm( const Reference
< XForm
>& _rxForm
)
1088 m_xCursor
= m_xCursor
.query( _rxForm
);
1089 if ( !m_xCursor
.is() )
1090 throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
1092 impl_initFromForm_throw();
1094 m_bConstructed
= true;
1097 //------------------------------------------------------------------------------
1098 void FormOperations::impl_invalidateAllSupportedFeatures_nothrow( MethodGuard
& _rClearForCallback
) const
1100 if ( !m_xFeatureInvalidation
.is() )
1101 // nobody's interested in ...
1104 Reference
< XFeatureInvalidation
> xInvalidation
= m_xFeatureInvalidation
;
1105 _rClearForCallback
.clear();
1106 xInvalidation
->invalidateAllFeatures();
1109 //------------------------------------------------------------------------------
1110 void FormOperations::impl_invalidateModifyDependentFeatures_nothrow( MethodGuard
& _rClearForCallback
) const
1112 if ( !m_xFeatureInvalidation
.is() )
1113 // nobody's interested in ...
1116 static Sequence
< sal_Int16
> s_aModifyDependentFeatures
;
1117 if ( s_aModifyDependentFeatures
.getLength() == 0 )
1119 sal_Int16 pModifyDependentFeatures
[] =
1121 FormFeature::MoveToNext
,
1122 FormFeature::MoveToInsertRow
,
1123 FormFeature::SaveRecordChanges
,
1124 FormFeature::UndoRecordChanges
1126 size_t nFeatureCount
= sizeof( pModifyDependentFeatures
) / sizeof( pModifyDependentFeatures
[ 0 ] );
1127 s_aModifyDependentFeatures
= Sequence
< sal_Int16
>( pModifyDependentFeatures
, nFeatureCount
);
1130 Reference
< XFeatureInvalidation
> xInvalidation
= m_xFeatureInvalidation
;
1131 _rClearForCallback
.clear();
1133 xInvalidation
->invalidateFeatures( s_aModifyDependentFeatures
);
1136 //--------------------------------------------------------------------
1137 void FormOperations::impl_ensureInitializedParser_nothrow()
1139 OSL_PRECOND( m_xCursorProperties
.is(), "FormOperations::impl_ensureInitializedParser_nothrow: we're disposed!" );
1140 if ( m_bInitializedParser
)
1145 sal_Bool bUseEscapeProcessing
= sal_False
;
1146 m_xCursorProperties
->getPropertyValue( PROPERTY_ESCAPE_PROCESSING
) >>= bUseEscapeProcessing
;
1147 if ( bUseEscapeProcessing
)
1149 Reference
< XMultiServiceFactory
> xFactory( ::dbtools::getConnection( m_xCursor
), UNO_QUERY
);
1150 if ( xFactory
.is() )
1152 m_xParser
.set( xFactory
->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.SingleSelectQueryComposer" ) ) ), UNO_QUERY
);
1153 OSL_ENSURE( m_xParser
.is(), "FormOperations::impl_ensureInitializedParser_nothrow: factory did not create a parser for us!" );
1157 if ( m_xParser
.is() )
1159 if ( m_xLoadableForm
.is() && m_xLoadableForm
->isLoaded() )
1161 ::rtl::OUString sStatement
;
1162 ::rtl::OUString sFilter
;
1163 ::rtl::OUString sSort
;
1165 m_xCursorProperties
->getPropertyValue( PROPERTY_ACTIVECOMMAND
) >>= sStatement
;
1166 m_xCursorProperties
->getPropertyValue( PROPERTY_FILTER
) >>= sFilter
;
1167 m_xCursorProperties
->getPropertyValue( PROPERTY_SORT
) >>= sSort
;
1169 m_xParser
->setElementaryQuery( sStatement
);
1170 m_xParser
->setFilter ( sFilter
);
1171 m_xParser
->setOrder ( sSort
);
1174 // start listening at the order/sort properties at the form, so
1175 // we can keep our parser in sync
1176 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_ACTIVECOMMAND
, this );
1177 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_FILTER
, this );
1178 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_SORT
, this );
1181 catch( const Exception
& )
1183 OSL_ENSURE( sal_False
, "FormOperations::impl_ensureInitializedParser_nothrow: caught an exception!" );
1186 m_bInitializedParser
= true;
1189 //--------------------------------------------------------------------
1190 void FormOperations::impl_disposeParser_nothrow()
1194 // if we have a parser (and a cursor), then we're listening at the cursor's
1195 // properties to keep the parser in sync with the cursor
1196 if ( m_xParser
.is() && m_xCursorProperties
.is() )
1198 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_FILTER
, this );
1199 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_ACTIVECOMMAND
, this );
1200 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_SORT
, this );
1203 Reference
< XComponent
> xParserComp( m_xParser
, UNO_QUERY
);
1204 if ( xParserComp
.is() )
1205 xParserComp
->dispose();
1208 m_bInitializedParser
= false;
1210 catch( const Exception
& )
1212 OSL_ENSURE( sal_False
, "FormOperations::impl_disposeParser_nothrow: caught an exception!" );
1216 //--------------------------------------------------------------------
1217 bool FormOperations::impl_canMoveLeft_throw( ) const
1219 if ( !impl_hasCursor_nothrow() )
1222 return impl_getRowCount_throw() && ( !m_xCursor
->isFirst() || impl_isInsertionRow_throw() );
1225 //--------------------------------------------------------------------
1226 bool FormOperations::impl_canMoveRight_throw( ) const
1228 if ( !impl_hasCursor_nothrow() )
1231 bool bIsNew
= impl_isInsertionRow_throw();
1233 if ( impl_getRowCount_throw() && !m_xCursor
->isLast() && !bIsNew
)
1236 if ( ::dbtools::canInsert( m_xCursorProperties
) )
1237 if ( !bIsNew
|| impl_isModifiedRow_throw() )
1240 if ( bIsNew
&& m_bActiveControlModified
)
1246 //--------------------------------------------------------------------
1249 template < typename TYPE
>
1250 TYPE
lcl_safeGetPropertyValue_throw( const Reference
< XPropertySet
>& _rxProperties
, const ::rtl::OUString
& _rPropertyName
, TYPE _Default
)
1252 TYPE
value( _Default
);
1253 OSL_PRECOND( _rxProperties
.is(), "FormOperations::<foo>: no cursor (already disposed?)!" );
1254 if ( _rxProperties
.is() )
1255 OSL_VERIFY( _rxProperties
->getPropertyValue( _rPropertyName
) >>= value
);
1260 //--------------------------------------------------------------------
1261 bool FormOperations::impl_isInsertionRow_throw() const
1263 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_ISNEW
, false );
1266 //--------------------------------------------------------------------
1267 sal_Int32
FormOperations::impl_getRowCount_throw() const
1269 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_ROWCOUNT
, (sal_Int32
)0 );
1271 //--------------------------------------------------------------------
1272 bool FormOperations::impl_isRowCountFinal_throw() const
1274 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_ROWCOUNTFINAL
, false );
1277 //--------------------------------------------------------------------
1278 bool FormOperations::impl_isModifiedRow_throw() const
1280 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_ISMODIFIED
, false );
1283 //--------------------------------------------------------------------
1284 bool FormOperations::impl_isParseable_throw() const
1286 const_cast< FormOperations
* >( this )->impl_ensureInitializedParser_nothrow();
1287 return m_xParser
.is() && m_xParser
->getQuery().getLength();
1290 //--------------------------------------------------------------------
1291 bool FormOperations::impl_hasFilterOrOrder_throw() const
1293 return impl_isParseable_throw() && ( m_xParser
->getFilter().getLength() || m_xParser
->getOrder().getLength() );
1296 //--------------------------------------------------------------------
1297 bool FormOperations::impl_isInsertOnlyForm_throw() const
1299 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_INSERTONLY
, true );
1302 //------------------------------------------------------------------------------
1303 Reference
< XControlModel
> FormOperations::impl_getCurrentControlModel_throw() const
1305 Reference
< XControl
> xControl( m_xController
->getCurrentControl() );
1307 // special handling for grid controls
1308 Reference
< XGrid
> xGrid( xControl
, UNO_QUERY
);
1309 Reference
< XControlModel
> xControlModel
;
1313 Reference
< XIndexAccess
> xColumns( xControl
->getModel(), UNO_QUERY_THROW
);
1314 sal_Int16 nCurrentPos
= xGrid
->getCurrentColumnPosition();
1315 nCurrentPos
= impl_gridView2ModelPos_nothrow( xColumns
, nCurrentPos
);
1317 if ( nCurrentPos
!= (sal_Int16
)-1 )
1318 xColumns
->getByIndex( nCurrentPos
) >>= xControlModel
;
1320 else if ( xControl
.is() )
1322 xControlModel
= xControl
->getModel();
1324 return xControlModel
;
1327 //------------------------------------------------------------------------------
1328 Reference
< XPropertySet
> FormOperations::impl_getCurrentBoundField_nothrow( ) const
1330 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_getCurrentBoundField_nothrow: no controller -> no control!" );
1331 if ( !m_xController
.is() )
1334 Reference
< XPropertySet
> xField
;
1337 Reference
< XPropertySet
> xControlModel( impl_getCurrentControlModel_throw(), UNO_QUERY
);
1339 if ( xControlModel
.is() && ::comphelper::hasProperty( PROPERTY_BOUNDFIELD
, xControlModel
) )
1340 xControlModel
->getPropertyValue( PROPERTY_BOUNDFIELD
) >>= xField
;
1343 catch( const Exception
& )
1345 DBG_UNHANDLED_EXCEPTION();
1351 //------------------------------------------------------------------------------
1352 sal_Int16
FormOperations::impl_gridView2ModelPos_nothrow( const Reference
< XIndexAccess
>& _rxColumns
, sal_Int16 _nViewPos
) const
1354 OSL_PRECOND( _rxColumns
.is(), "FormOperations::impl_gridView2ModelPos_nothrow: invalid columns container!" );
1357 // loop through all columns
1359 Reference
< XPropertySet
> xCol
;
1360 bool bHidden( false );
1361 for ( col
= 0; col
< _rxColumns
->getCount(); ++col
)
1363 _rxColumns
->getByIndex( col
) >>= xCol
;
1364 OSL_VERIFY( xCol
->getPropertyValue( PROPERTY_HIDDEN
) >>= bHidden
);
1368 // for every visible col : if nViewPos is greater zero, decrement it, else we
1369 // have found the model position
1375 if ( col
< _rxColumns
->getCount() )
1378 catch( const Exception
& )
1380 DBG_UNHANDLED_EXCEPTION();
1382 return (sal_Int16
)-1;
1385 //------------------------------------------------------------------------------
1386 bool FormOperations::impl_moveLeft_throw( ) const
1388 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_moveLeft_throw: no cursor!" );
1389 if ( !impl_hasCursor_nothrow() )
1392 sal_Bool bRecordInserted
= sal_False
;
1393 sal_Bool bSuccess
= impl_commitCurrentRecord_throw( &bRecordInserted
);
1398 if ( bRecordInserted
)
1400 // retrieve the bookmark of the new record and move to the record preceding this bookmark
1401 Reference
< XRowLocate
> xLocate( m_xCursor
, UNO_QUERY
);
1402 OSL_ENSURE( xLocate
.is(), "FormOperations::impl_moveLeft_throw: no XRowLocate!" );
1404 xLocate
->moveRelativeToBookmark( xLocate
->getBookmark(), -1 );
1408 if ( impl_isInsertionRow_throw() )
1410 // we assume that the inserted record is now the last record in the
1415 m_xCursor
->previous();
1421 //--------------------------------------------------------------------
1422 bool FormOperations::impl_moveRight_throw( ) const
1424 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_moveRight_throw: no cursor!" );
1425 if ( !impl_hasCursor_nothrow() )
1428 sal_Bool bRecordInserted
= sal_False
;
1429 sal_Bool bSuccess
= impl_commitCurrentRecord_throw( &bRecordInserted
);
1434 if ( bRecordInserted
)
1437 m_xUpdateCursor
->moveToInsertRow();
1441 if ( m_xCursor
->isLast() )
1442 m_xUpdateCursor
->moveToInsertRow();
1450 //--------------------------------------------------------------------
1451 void FormOperations::impl_resetAllControls_nothrow() const
1453 Reference
< XIndexAccess
> xContainer( m_xCursor
, UNO_QUERY
);
1454 if ( !xContainer
.is() )
1459 Reference
< XReset
> xReset
;
1460 sal_Int32
nCount( xContainer
->getCount() );
1461 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
1463 if ( xContainer
->getByIndex( i
) >>= xReset
)
1465 // no resets on sub forms
1466 Reference
< XForm
> xAsForm( xReset
, UNO_QUERY
);
1467 if ( !xAsForm
.is() )
1472 catch( const Exception
& )
1474 DBG_UNHANDLED_EXCEPTION();
1478 //------------------------------------------------------------------------------
1479 void FormOperations::impl_executeAutoSort_throw( bool _bUp
) const
1481 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_executeAutoSort_throw: need a controller for this!" );
1482 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeAutoSort_throw: need a cursor for this!" );
1483 OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeAutoSort_throw: need a parseable statement for this!" );
1484 if ( !m_xController
.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
1489 Reference
< XControl
> xControl
= m_xController
->getCurrentControl();
1490 if ( !xControl
.is() || !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
1493 Reference
< XPropertySet
> xBoundField( impl_getCurrentBoundField_nothrow() );
1494 if ( !xBoundField
.is() )
1497 ::rtl::OUString sOriginalSort
;
1498 m_xCursorProperties
->getPropertyValue( PROPERTY_SORT
) >>= sOriginalSort
;
1500 // automatic sort by field is expected to always resets the previous sort order
1501 m_xParser
->setOrder( ::rtl::OUString() );
1503 param_appendOrderByColumn aParam
;
1504 aParam
.xField
= xBoundField
;
1506 impl_doActionInSQLContext_throw(
1507 (Action
)&FormOperations::impl_appendOrderByColumn_throw
,
1508 static_cast< const void* >( &aParam
),
1509 (sal_uInt16
)RID_STR_COULD_NOT_SET_ORDER
1512 WaitObject
aWO( NULL
);
1515 m_xCursorProperties
->setPropertyValue( PROPERTY_SORT
, makeAny( m_xParser
->getOrder() ) );
1516 m_xLoadableForm
->reload();
1518 catch( const Exception
& )
1520 OSL_ENSURE( sal_False
, "FormOperations::impl_executeAutoSort_throw: caught an exception while setting the parser properties!" );
1524 if ( !m_xLoadableForm
->isLoaded() )
1525 { // something went wrong -> restore the original state
1528 m_xParser
->setOrder( sOriginalSort
);
1529 m_xCursorProperties
->setPropertyValue( PROPERTY_SORT
, makeAny( m_xParser
->getOrder() ) );
1530 m_xLoadableForm
->reload();
1532 catch( const Exception
& )
1534 OSL_ENSURE( sal_False
, "FormOperations::impl_executeAutoSort_throw: could not reset the form to it's original state!" );
1539 catch( const RuntimeException
& ) { throw; }
1540 catch( const SQLException
& ) { throw; }
1541 catch( const Exception
& )
1543 throw WrappedTargetException( ::rtl::OUString(), *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
1547 //------------------------------------------------------------------------------
1548 void FormOperations::impl_executeAutoFilter_throw( ) const
1550 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_executeAutoFilter_throw: need a controller for this!" );
1551 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeAutoFilter_throw: need a cursor for this!" );
1552 OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeAutoFilter_throw: need a parseable statement for this!" );
1553 if ( !m_xController
.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
1558 Reference
< XControl
> xControl
= m_xController
->getCurrentControl();
1559 if ( !xControl
.is() || !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
1562 Reference
< XPropertySet
> xBoundField( impl_getCurrentBoundField_nothrow() );
1563 if ( !xBoundField
.is() )
1566 ::rtl::OUString sOriginalFilter
;
1567 m_xCursorProperties
->getPropertyValue( PROPERTY_FILTER
) >>= sOriginalFilter
;
1568 sal_Bool bApplied
= sal_True
;
1569 m_xCursorProperties
->getPropertyValue( PROPERTY_APPLYFILTER
) >>= bApplied
;
1571 // if we have a filter, but it's not applied, then we have to overwrite it, else append one
1573 m_xParser
->setFilter( ::rtl::OUString() );
1575 param_appendFilterByColumn aParam
;
1576 aParam
.xField
= xBoundField
;
1577 impl_doActionInSQLContext_throw(
1578 (Action
)&FormOperations::impl_appendFilterByColumn_throw
,
1579 static_cast< const void* >( &aParam
),
1580 (sal_uInt16
)RID_STR_COULD_NOT_SET_FILTER
1583 WaitObject
aWO( NULL
);
1586 m_xCursorProperties
->setPropertyValue( PROPERTY_FILTER
, makeAny( m_xParser
->getFilter() ) );
1587 m_xCursorProperties
->setPropertyValue( PROPERTY_APPLYFILTER
, makeAny( (sal_Bool
)sal_True
) );
1589 m_xLoadableForm
->reload();
1591 catch( const Exception
& )
1593 OSL_ENSURE( sal_False
, "FormOperations::impl_executeAutoFilter_throw: caught an exception while setting the parser properties!" );
1597 if ( !m_xLoadableForm
->isLoaded() )
1598 { // something went wrong -> restore the original state
1601 m_xParser
->setOrder( sOriginalFilter
);
1602 m_xCursorProperties
->setPropertyValue( PROPERTY_APPLYFILTER
, makeAny( (sal_Bool
)bApplied
) );
1603 m_xCursorProperties
->setPropertyValue( PROPERTY_FILTER
, makeAny( m_xParser
->getFilter() ) );
1604 m_xLoadableForm
->reload();
1606 catch( const Exception
& )
1608 OSL_ENSURE( sal_False
, "FormOperations::impl_executeAutoFilter_throw: could not reset the form to it's original state!" );
1613 catch( const RuntimeException
& ) { throw; }
1614 catch( const SQLException
& ) { throw; }
1615 catch( const Exception
& )
1617 throw WrappedTargetException( ::rtl::OUString(), *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
1621 //--------------------------------------------------------------------
1622 void FormOperations::impl_executeFilterOrSort_throw( bool _bFilter
) const
1624 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_executeFilterOrSort_throw: need a controller for this!" );
1625 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeFilterOrSort_throw: need a cursor for this!" );
1626 OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeFilterOrSort_throw: need a parseable statement for this!" );
1627 if ( !m_xController
.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
1630 if ( !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
1634 PropertyValue aFirst
;
1635 aFirst
.Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "QueryComposer" ) );
1636 aFirst
.Value
<<= m_xParser
;
1638 PropertyValue aSecond
;
1639 aSecond
.Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RowSet" ) );
1640 aSecond
.Value
<<= m_xCursorProperties
;
1642 Sequence
<Any
> aInit(2);
1643 aInit
[0] <<= aFirst
;
1644 aInit
[1] <<= aSecond
;
1646 ::rtl::OUString sDialogServiceName
;
1648 sDialogServiceName
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.FilterDialog" ) );
1650 sDialogServiceName
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.OrderDialog" ) );
1652 Reference
< XExecutableDialog
> xDialog
;
1653 m_aContext
.createComponentWithArguments( sDialogServiceName
, aInit
, xDialog
);
1655 if ( !xDialog
.is() )
1657 ShowServiceNotAvailableError( NULL
, sDialogServiceName
, sal_True
);
1661 if ( RET_OK
== xDialog
->execute() )
1663 WaitObject
aWO( NULL
);
1665 m_xCursorProperties
->setPropertyValue( PROPERTY_FILTER
, makeAny( m_xParser
->getFilter() ) );
1667 m_xCursorProperties
->setPropertyValue( PROPERTY_SORT
, makeAny( m_xParser
->getOrder() ) );
1668 m_xLoadableForm
->reload();
1672 catch( const RuntimeException
& ) { throw; }
1673 catch( const SQLException
& ) { throw; }
1674 catch( const Exception
& )
1676 throw WrappedTargetException( ::rtl::OUString(), *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
1680 //------------------------------------------------------------------------------
1681 void FormOperations::impl_appendOrderByColumn_throw( const void* _pActionParam
) const
1683 const param_appendOrderByColumn
* pParam
= static_cast< const param_appendOrderByColumn
* >( _pActionParam
);
1684 m_xParser
->appendOrderByColumn( pParam
->xField
, pParam
->bUp
);
1687 //------------------------------------------------------------------------------
1688 void FormOperations::impl_appendFilterByColumn_throw( const void* _pActionParam
) const
1690 const param_appendFilterByColumn
* pParam
= static_cast< const param_appendFilterByColumn
* >( _pActionParam
);
1691 sal_Int32 nOp
= SQLFilterOperator::EQUAL
;
1692 if ( pParam
->xField
.is() )
1694 sal_Int32 nType
= 0;
1695 pParam
->xField
->getPropertyValue(PROPERTY_FIELDTYPE
) >>= nType
;
1698 case DataType::VARCHAR
:
1699 case DataType::CHAR
:
1700 case DataType::LONGVARCHAR
:
1701 nOp
= SQLFilterOperator::LIKE
;
1704 nOp
= SQLFilterOperator::EQUAL
;
1707 m_xParser
->appendFilterByColumn( pParam
->xField
, sal_True
,nOp
);
1710 //------------------------------------------------------------------------------
1711 void FormOperations::impl_doActionInSQLContext_throw( Action _pAction
, const void* _pParam
, sal_uInt16 _nErrorResourceId
) const
1715 (this->*_pAction
)( _pParam
);
1717 catch( const SQLException
& e
)
1720 if ( !_nErrorResourceId
)
1721 // no information to prepend
1724 SQLExceptionInfo
aInfo( ::cppu::getCaughtException() );
1725 ::rtl::OUString
sAdditionalError( FRM_RES_STRING( _nErrorResourceId
) );
1726 aInfo
.prepend( sAdditionalError
);
1729 catch( const RuntimeException
& ) { throw; }
1730 catch( const Exception
& )
1732 ::rtl::OUString
sAdditionalError( FRM_RES_STRING( _nErrorResourceId
) );
1733 throw WrappedTargetException( sAdditionalError
, *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
1737 //........................................................................
1739 //........................................................................