1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "formoperations.hxx"
22 #include "frm_strings.hxx"
23 #include "frm_resource.hxx"
24 #include "frm_resource.hrc"
25 #include "frm_module.hxx"
27 #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
28 #include <com/sun/star/util/XModifyBroadcaster.hpp>
29 #include <com/sun/star/form/runtime/FormFeature.hpp>
30 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
31 #include <com/sun/star/lang/DisposedException.hpp>
32 #include <com/sun/star/awt/XControl.hpp>
33 #include <com/sun/star/form/XGrid.hpp>
34 #include <com/sun/star/form/XBoundControl.hpp>
35 #include <com/sun/star/form/XBoundComponent.hpp>
36 #include <com/sun/star/sdbcx/XRowLocate.hpp>
37 #include <com/sun/star/form/XConfirmDeleteListener.hpp>
38 #include <com/sun/star/sdb/RowChangeEvent.hpp>
39 #include <com/sun/star/sdb/RowChangeAction.hpp>
40 #include <com/sun/star/sdb/OrderDialog.hpp>
41 #include <com/sun/star/sdb/FilterDialog.hpp>
42 #include <com/sun/star/sdbc/DataType.hpp>
43 #include <com/sun/star/form/XReset.hpp>
44 #include <com/sun/star/beans/XMultiPropertySet.hpp>
45 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
46 #include <com/sun/star/util/XRefreshable.hpp>
48 #include <connectivity/dbtools.hxx>
49 #include <connectivity/dbexception.hxx>
50 #include <vcl/svapp.hxx>
51 #include <vcl/stdtext.hxx>
52 #include <vcl/msgbox.hxx>
53 #include <vcl/waitobj.hxx>
54 #include <tools/diagnose_ex.h>
55 #include <comphelper/container.hxx>
56 #include <comphelper/property.hxx>
57 #include <comphelper/namedvaluecollection.hxx>
58 #include <cppuhelper/exc_hlp.hxx>
59 #include <osl/mutex.hxx>
60 #include <sal/macros.h>
62 //--------------------------------------------------------------------------
63 extern "C" void SAL_CALL
createRegistryInfo_FormOperations()
65 static ::frm::OMultiInstanceAutoRegistration
< ::frm::FormOperations
> aAutoRegistration
;
68 //........................................................................
71 //........................................................................
73 using ::dbtools::SQLExceptionInfo
;
74 using ::com::sun::star::uno::Reference
;
75 using ::com::sun::star::uno::XComponentContext
;
76 using ::com::sun::star::uno::RuntimeException
;
77 using ::com::sun::star::uno::Sequence
;
78 using ::com::sun::star::uno::Exception
;
79 using ::com::sun::star::uno::Any
;
80 using ::com::sun::star::uno::XInterface
;
81 using ::com::sun::star::sdbc::XRowSet
;
82 using ::com::sun::star::sdbc::XResultSetUpdate
;
83 using ::com::sun::star::form::runtime::XFormController
;
84 using ::com::sun::star::form::runtime::XFormOperations
;
85 using ::com::sun::star::form::runtime::XFeatureInvalidation
;
86 using ::com::sun::star::form::runtime::FeatureState
;
87 using ::com::sun::star::lang::IllegalArgumentException
;
88 using ::com::sun::star::sdbc::SQLException
;
89 using namespace ::com::sun::star::sdbc
;
90 using ::com::sun::star::form::XForm
;
91 using ::com::sun::star::ucb::AlreadyInitializedException
;
92 using ::com::sun::star::util::XModifyBroadcaster
;
93 using ::com::sun::star::uno::UNO_QUERY
;
94 using ::com::sun::star::lang::EventObject
;
95 using ::com::sun::star::beans::PropertyChangeEvent
;
96 using ::com::sun::star::lang::XMultiServiceFactory
;
97 using ::com::sun::star::lang::DisposedException
;
98 using ::com::sun::star::beans::XPropertySet
;
99 using ::com::sun::star::awt::XControl
;
100 using ::com::sun::star::form::XGrid
;
101 using ::com::sun::star::container::XIndexAccess
;
102 using ::com::sun::star::uno::UNO_QUERY_THROW
;
103 using ::com::sun::star::form::XBoundControl
;
104 using ::com::sun::star::form::XBoundComponent
;
105 using ::com::sun::star::sdbcx::XRowLocate
;
106 using ::com::sun::star::form::XConfirmDeleteListener
;
107 using ::com::sun::star::sdb::RowChangeEvent
;
108 using namespace ::com::sun::star::sdb
;
109 using ::com::sun::star::form::XReset
;
110 using ::com::sun::star::beans::XMultiPropertySet
;
111 using ::com::sun::star::uno::makeAny
;
112 using ::com::sun::star::lang::WrappedTargetException
;
113 using ::com::sun::star::beans::PropertyValue
;
114 using ::com::sun::star::ui::dialogs::XExecutableDialog
;
115 using ::com::sun::star::beans::NamedValue
;
116 using ::com::sun::star::util::XRefreshable
;
117 using ::com::sun::star::awt::XControlModel
;
119 namespace FormFeature
= ::com::sun::star::form::runtime::FormFeature
;
120 namespace RowChangeAction
= ::com::sun::star::sdb::RowChangeAction
;
122 //====================================================================
124 //====================================================================
125 //--------------------------------------------------------------------
126 FormOperations::FormOperations( const Reference
< XMultiServiceFactory
>& _rxContext
)
127 :FormOperations_Base( m_aMutex
)
128 ,m_aContext( _rxContext
)
129 ,m_bInitializedParser( false )
130 ,m_bActiveControlModified( false )
131 ,m_bConstructed( false )
133 ,m_nMethodNestingLevel( false )
138 //--------------------------------------------------------------------
139 FormOperations::~FormOperations()
143 //--------------------------------------------------------------------
144 OUString
FormOperations::getImplementationName_Static( ) throw(RuntimeException
)
146 return OUString( "com.sun.star.comp.forms.FormOperations" );
149 //--------------------------------------------------------------------
150 Sequence
< OUString
> FormOperations::getSupportedServiceNames_Static( ) throw(RuntimeException
)
152 Sequence
< OUString
> aNames(1);
153 aNames
[0] = OUString( "com.sun.star.form.runtime.FormOperations" );
157 //--------------------------------------------------------------------
158 Reference
< XInterface
> SAL_CALL
FormOperations::Create(const Reference
< XMultiServiceFactory
>& _rxFactory
)
160 return *new FormOperations( _rxFactory
);
163 //--------------------------------------------------------------------
164 void SAL_CALL
FormOperations::initialize( const Sequence
< Any
>& _arguments
) throw (Exception
, RuntimeException
)
166 if ( m_bConstructed
)
167 throw AlreadyInitializedException();
169 if ( _arguments
.getLength() == 1 )
171 Reference
< XFormController
> xController
;
172 Reference
< XForm
> xForm
;
173 if ( _arguments
[0] >>= xController
)
174 createWithFormController( xController
);
175 else if ( _arguments
[0] >>= xForm
)
176 createWithForm( xForm
);
178 throw IllegalArgumentException( OUString(), *this, 1 );
182 throw IllegalArgumentException( OUString(), *this, 0 );
185 //--------------------------------------------------------------------
186 OUString SAL_CALL
FormOperations::getImplementationName( ) throw (RuntimeException
)
188 return getImplementationName_Static();
191 //--------------------------------------------------------------------
192 ::sal_Bool SAL_CALL
FormOperations::supportsService( const OUString
& _ServiceName
) throw (RuntimeException
)
194 Sequence
< OUString
> aSupportedServiceNames( getSupportedServiceNames() );
195 const OUString
* pBegin
= aSupportedServiceNames
.getConstArray();
196 const OUString
* pEnd
= aSupportedServiceNames
.getConstArray() + aSupportedServiceNames
.getLength();
197 return ::std::find( pBegin
, pEnd
, _ServiceName
) != pEnd
;
200 //--------------------------------------------------------------------
201 Sequence
< OUString
> SAL_CALL
FormOperations::getSupportedServiceNames( ) throw (RuntimeException
)
203 return getSupportedServiceNames_Static();
206 //--------------------------------------------------------------------
207 Reference
< XRowSet
> SAL_CALL
FormOperations::getCursor() throw (RuntimeException
)
209 MethodGuard
aGuard( *this );
213 //--------------------------------------------------------------------
214 Reference
< XResultSetUpdate
> SAL_CALL
FormOperations::getUpdateCursor() throw (RuntimeException
)
216 MethodGuard
aGuard( *this );
217 return m_xUpdateCursor
;
220 //--------------------------------------------------------------------
221 Reference
< XFormController
> SAL_CALL
FormOperations::getController() throw (RuntimeException
)
223 MethodGuard
aGuard( *this );
224 return m_xController
;
227 //--------------------------------------------------------------------
228 Reference
< XFeatureInvalidation
> SAL_CALL
FormOperations::getFeatureInvalidation() throw (RuntimeException
)
230 MethodGuard
aGuard( *this );
231 return m_xFeatureInvalidation
;
234 //--------------------------------------------------------------------
235 void SAL_CALL
FormOperations::setFeatureInvalidation( const Reference
< XFeatureInvalidation
> & _rxFeatureInvalidation
) throw (RuntimeException
)
237 MethodGuard
aGuard( *this );
238 m_xFeatureInvalidation
= _rxFeatureInvalidation
;
241 //--------------------------------------------------------------------
242 FeatureState SAL_CALL
FormOperations::getState( ::sal_Int16 _nFeature
) throw (RuntimeException
)
244 MethodGuard
aGuard( *this );
247 aState
.Enabled
= sal_False
;
251 // some checks for basic pre-requisites
252 if ( !m_xLoadableForm
.is()
253 || !m_xLoadableForm
->isLoaded()
254 || !m_xCursorProperties
.is()
262 case FormFeature::MoveToFirst
:
263 case FormFeature::MoveToPrevious
:
264 aState
.Enabled
= impl_canMoveLeft_throw( );
267 case FormFeature::MoveToNext
:
268 aState
.Enabled
= impl_canMoveRight_throw();
271 case FormFeature::MoveToLast
:
272 aState
.Enabled
= impl_getRowCount_throw() && ( !m_xCursor
->isLast() || impl_isInsertionRow_throw() );
275 case FormFeature::DeleteRecord
:
277 if ( m_xCursor
->rowDeleted() )
278 aState
.Enabled
= sal_False
;
281 // allowed to delete the row ?
282 aState
.Enabled
= !impl_isInsertionRow_throw() && ::dbtools::canDelete( m_xCursorProperties
);
286 case FormFeature::MoveToInsertRow
:
287 // if we are inserting we can move to the next row if the current record or control is modified
288 aState
.Enabled
= impl_isInsertionRow_throw()
289 ? impl_isModifiedRow_throw() || m_bActiveControlModified
290 : ::dbtools::canInsert( m_xCursorProperties
);
293 case FormFeature::ReloadForm
:
295 // there must be an active connection
296 Reference
< XRowSet
> xCursorRowSet( m_xCursor
, UNO_QUERY
);
297 aState
.Enabled
= ::dbtools::getConnection( xCursorRowSet
).is();
299 // and an active command
300 OUString sActiveCommand
;
301 m_xCursorProperties
->getPropertyValue( PROPERTY_ACTIVECOMMAND
) >>= sActiveCommand
;
302 aState
.Enabled
&= !sActiveCommand
.isEmpty();
306 case FormFeature::RefreshCurrentControl
:
308 Reference
< XRefreshable
> xControlModelRefresh( impl_getCurrentControlModel_throw(), UNO_QUERY
);
309 aState
.Enabled
= xControlModelRefresh
.is();
313 case FormFeature::SaveRecordChanges
:
314 case FormFeature::UndoRecordChanges
:
315 aState
.Enabled
= impl_isModifiedRow_throw() || m_bActiveControlModified
;
318 case FormFeature::RemoveFilterAndSort
:
319 if ( impl_isParseable_throw() && impl_hasFilterOrOrder_throw() )
320 aState
.Enabled
= !impl_isInsertOnlyForm_throw();
323 case FormFeature::SortAscending
:
324 case FormFeature::SortDescending
:
325 case FormFeature::AutoFilter
:
326 if ( m_xController
.is() && impl_isParseable_throw() )
328 sal_Bool bIsDeleted
= m_xCursor
->rowDeleted();
330 if ( !bIsDeleted
&& !impl_isInsertOnlyForm_throw() )
332 Reference
< XPropertySet
> xBoundField
= impl_getCurrentBoundField_nothrow( );
333 if ( xBoundField
.is() )
334 xBoundField
->getPropertyValue( PROPERTY_SEARCHABLE
) >>= aState
.Enabled
;
339 case FormFeature::InteractiveSort
:
340 case FormFeature::InteractiveFilter
:
341 if ( impl_isParseable_throw() )
342 aState
.Enabled
= !impl_isInsertOnlyForm_throw();
345 case FormFeature::ToggleApplyFilter
:
348 m_xCursorProperties
->getPropertyValue( PROPERTY_FILTER
) >>= sFilter
;
349 if ( !sFilter
.isEmpty() )
351 aState
.State
= m_xCursorProperties
->getPropertyValue( PROPERTY_APPLYFILTER
);
352 aState
.Enabled
= !impl_isInsertOnlyForm_throw();
355 aState
.State
<<= (sal_Bool
)sal_False
;
359 case FormFeature::MoveAbsolute
:
361 sal_Int32 nPosition
= m_xCursor
->getRow();
362 sal_Bool bIsNew
= impl_isInsertionRow_throw();
363 sal_Int32 nCount
= impl_getRowCount_throw();
364 sal_Bool bFinalCount
= impl_isRowCountFinal_throw();
366 if ( ( nPosition
>= 0 ) || bIsNew
)
370 // special case: there are no records at all, and we
371 // can't insert records -> disabled
372 if ( !nCount
&& !::dbtools::canInsert( m_xCursorProperties
) )
374 aState
.Enabled
= sal_False
;
379 nPosition
= ++nCount
;
380 aState
.State
<<= (sal_Int32
)nPosition
;
381 aState
.Enabled
= sal_True
;
386 aState
.State
<<= (sal_Int32
)nPosition
;
387 aState
.Enabled
= sal_True
;
393 case FormFeature::TotalRecords
:
395 sal_Bool bIsNew
= impl_isInsertionRow_throw();
396 sal_Int32 nCount
= impl_getRowCount_throw();
397 sal_Bool bFinalCount
= impl_isRowCountFinal_throw();
402 OUString sValue
= OUString::valueOf( sal_Int32( nCount
) );
404 sValue
+= OUString(" *");
406 aState
.State
<<= sValue
;
407 aState
.Enabled
= sal_True
;
412 OSL_FAIL( "FormOperations::getState: unknown feature id!" );
416 catch( const Exception
& )
418 OSL_FAIL( "FormOperations::getState: caught an exception!" );
424 //--------------------------------------------------------------------
425 ::sal_Bool SAL_CALL
FormOperations::isEnabled( ::sal_Int16 _nFeature
) throw (RuntimeException
)
427 MethodGuard
aGuard( *this );
429 FeatureState
aState( getState( _nFeature
) );
430 return aState
.Enabled
;
433 //--------------------------------------------------------------------
436 static bool lcl_needConfirmCommit( sal_Int32 _nFeature
)
438 return ( ( _nFeature
== FormFeature::ReloadForm
)
439 || ( _nFeature
== FormFeature::RemoveFilterAndSort
)
440 || ( _nFeature
== FormFeature::ToggleApplyFilter
)
441 || ( _nFeature
== FormFeature::SortAscending
)
442 || ( _nFeature
== FormFeature::SortDescending
)
443 || ( _nFeature
== FormFeature::AutoFilter
)
444 || ( _nFeature
== FormFeature::InteractiveSort
)
445 || ( _nFeature
== FormFeature::InteractiveFilter
)
448 static bool lcl_requiresArguments( sal_Int32 _nFeature
)
450 return ( _nFeature
== FormFeature::MoveAbsolute
);
452 static bool lcl_isExecutableFeature( sal_Int32 _nFeature
)
454 return ( _nFeature
!= FormFeature::TotalRecords
);
457 template < typename TYPE
>
458 TYPE
lcl_safeGetPropertyValue_throw( const Reference
< XPropertySet
>& _rxProperties
, const OUString
& _rPropertyName
, TYPE _Default
)
460 TYPE
value( _Default
);
461 OSL_PRECOND( _rxProperties
.is(), "FormOperations::<foo>: no cursor (already disposed?)!" );
462 if ( _rxProperties
.is() )
463 OSL_VERIFY( _rxProperties
->getPropertyValue( _rPropertyName
) >>= value
);
467 // returns false if parent should *abort* (user pressed cancel)
468 bool checkConfirmation(bool &needConfirmation
, bool &shouldCommit
)
472 // TODO: shouldn't this be done with an interaction handler?
473 QueryBox
aQuery( NULL
, WB_YES_NO_CANCEL
| WB_DEF_YES
, FRM_RES_STRING( RID_STR_QUERY_SAVE_MODIFIED_ROW
) );
474 switch ( aQuery
.Execute() )
477 shouldCommit
= false;
478 // no break on purpose: don't ask again!
480 needConfirmation
= false;
489 bool commit1Form(Reference
< XFormController
> xCntrl
, bool &needConfirmation
, bool &shouldCommit
)
491 Reference
< XFormOperations
> xFrmOps(xCntrl
->getFormOperations());
492 if (!xFrmOps
->commitCurrentControl())
495 if(xFrmOps
->isModifiedRow())
497 if(!checkConfirmation(needConfirmation
, shouldCommit
))
500 if (shouldCommit
&& !xFrmOps
->commitCurrentRecord(_
))
506 bool commitFormAndSubforms(Reference
< XFormController
> xCntrl
, bool needConfirmation
)
508 bool shouldCommit(true);
510 Reference
< XIndexAccess
> xSubForms(xCntrl
, UNO_QUERY
);
511 assert(xSubForms
.is());
514 const sal_Int32 cnt
= xSubForms
->getCount();
515 for(int i
=0; i
< cnt
; ++i
)
517 Reference
< XFormController
> xSubForm(xSubForms
->getByIndex(i
), UNO_QUERY
);
518 assert(xSubForm
.is());
521 if (!commit1Form(xSubForm
, needConfirmation
, shouldCommit
))
527 if(!commit1Form(xCntrl
, needConfirmation
, shouldCommit
))
533 bool commit1Form(Reference
< XForm
> xFrm
, bool &needConfirmation
, bool &shouldCommit
)
535 Reference
< XPropertySet
> xProps(xFrm
, UNO_QUERY_THROW
);
536 // nothing to do if the record is not modified
537 if(!lcl_safeGetPropertyValue_throw( xProps
, PROPERTY_ISMODIFIED
, false ))
540 if(!checkConfirmation(needConfirmation
, shouldCommit
))
544 Reference
< XResultSetUpdate
> xUpd(xFrm
, UNO_QUERY_THROW
);
545 // insert respectively update the row
546 if ( lcl_safeGetPropertyValue_throw( xProps
, PROPERTY_ISNEW
, false ) )
554 bool commitFormAndSubforms(Reference
< XForm
> xFrm
, bool needConfirmation
)
556 // No control... do what we can with the models
557 bool shouldCommit(true);
558 Reference
< XIndexAccess
> xFormComps(xFrm
, UNO_QUERY_THROW
);
559 assert( xFormComps
.is() );
561 const sal_Int32 cnt
= xFormComps
->getCount();
562 for(int i
=0; i
< cnt
; ++i
)
564 Reference
< XForm
> xSubForm(xFormComps
->getByIndex(i
), UNO_QUERY
);
567 if(!commit1Form(xSubForm
, needConfirmation
, shouldCommit
))
572 if(!commit1Form(xFrm
, needConfirmation
, shouldCommit
))
578 //--------------------------------------------------------------------
579 void SAL_CALL
FormOperations::execute( ::sal_Int16 _nFeature
) throw (RuntimeException
, IllegalArgumentException
, SQLException
, WrappedTargetException
)
581 SolarMutexGuard aSolarGuard
;
582 MethodGuard
aGuard( *this );
584 if ( ( _nFeature
!= FormFeature::DeleteRecord
) && ( _nFeature
!= FormFeature::UndoRecordChanges
) )
588 if(m_xController
.is())
590 if(!commitFormAndSubforms(m_xController
, lcl_needConfirmCommit( _nFeature
)))
593 else if(m_xCursor
.is())
595 Reference
< XForm
> xForm(m_xCursor
, UNO_QUERY
);
597 if(!commitFormAndSubforms(xForm
, lcl_needConfirmCommit( _nFeature
)))
602 SAL_WARN( "forms.runtime", "No cursor, but trying to execute form operation " << _nFeature
);
610 case FormFeature::MoveToFirst
:
614 case FormFeature::MoveToNext
:
615 impl_moveRight_throw( );
618 case FormFeature::MoveToPrevious
:
619 impl_moveLeft_throw( );
622 case FormFeature::MoveToLast
:
625 // TODO: re-implement this .....
626 // run in an own thread if ...
627 // ... the data source is thread safe ...
628 sal_Bool bAllowOwnThread = sal_False;
629 if ( ::comphelper::hasProperty( PROPERTY_THREADSAFE, m_xCursorProperties ) )
630 m_xCursorProperties->getPropertyValue( PROPERTY_THREADSAFE ) >>= bAllowOwnThread;
632 // ... the record count is unknown
633 sal_Bool bNeedOwnThread sal_False;
634 if ( ::comphelper::hasProperty( PROPERTY_ROWCOUNTFINAL, m_xCursorProperties ) )
635 m_xCursorProperties->getPropertyValue( PROPERTY_ROWCOUNTFINAL ) >>= bNeedOwnThread;
637 if ( bNeedOwnThread && bAllowOwnThread )
645 case FormFeature::ReloadForm
:
646 if ( m_xLoadableForm
.is() )
648 WaitObject
aWO( NULL
);
649 m_xLoadableForm
->reload();
651 // refresh all controls in the form (and sub forms) which can be refreshed
653 ::comphelper::IndexAccessIterator
aIter( m_xLoadableForm
);
654 Reference
< XInterface
> xElement( aIter
.Next() );
655 while ( xElement
.is() )
657 Reference
< XRefreshable
> xRefresh( xElement
, UNO_QUERY
);
660 xElement
= aIter
.Next();
665 case FormFeature::RefreshCurrentControl
:
667 Reference
< XRefreshable
> xControlModelRefresh( impl_getCurrentControlModel_throw(), UNO_QUERY
);
668 OSL_ENSURE( xControlModelRefresh
.is(), "FormOperations::execute: how did you reach this?" );
669 if ( xControlModelRefresh
.is() )
670 xControlModelRefresh
->refresh();
674 case FormFeature::DeleteRecord
:
676 sal_uInt32 nCount
= impl_getRowCount_throw();
679 sal_Bool bLeft
= m_xCursor
->isLast() && ( nCount
> 1 );
680 sal_Bool bRight
= !m_xCursor
->isLast();
681 sal_Bool bSuccess
= sal_False
;
684 // ask for confirmation
685 Reference
< XConfirmDeleteListener
> xConfirmDelete( m_xController
, UNO_QUERY
);
687 if ( xConfirmDelete
.is() )
689 RowChangeEvent aEvent
;
690 aEvent
.Source
= Reference
< XInterface
>( m_xCursor
, UNO_QUERY
);
691 aEvent
.Action
= RowChangeAction::DELETE
;
693 bSuccess
= xConfirmDelete
->confirmDelete( aEvent
);
698 m_xUpdateCursor
->deleteRow();
700 catch( const Exception
& )
702 bSuccess
= sal_False
;
707 if ( bLeft
|| bRight
)
708 m_xCursor
->relative( bRight
? 1 : -1 );
711 sal_Bool bCanInsert
= ::dbtools::canInsert( m_xCursorProperties
);
712 // is it possible to insert another record?
714 m_xUpdateCursor
->moveToInsertRow();
716 // move record to update stati
723 case FormFeature::SaveRecordChanges
:
724 case FormFeature::UndoRecordChanges
:
726 sal_Bool bInserting
= impl_isInsertionRow_throw();
728 if ( FormFeature::UndoRecordChanges
== _nFeature
)
731 m_xUpdateCursor
->cancelRowUpdates();
733 // reset all controls for this form
734 impl_resetAllControls_nothrow( );
736 if ( bInserting
) // back to insertion mode for this form
737 m_xUpdateCursor
->moveToInsertRow();
743 m_xUpdateCursor
->insertRow();
747 m_xUpdateCursor
->updateRow();
752 case FormFeature::MoveToInsertRow
:
753 // move to the last row before moving to the insert row
755 m_xUpdateCursor
->moveToInsertRow();
758 case FormFeature::RemoveFilterAndSort
:
760 // simultaneously reset Filter and Order property
761 Reference
< XMultiPropertySet
> xProperties( m_xCursorProperties
, UNO_QUERY
);
762 OSL_ENSURE( xProperties
.is(), "FormOperations::execute: no multi property access!" );
763 if ( xProperties
.is() )
765 Sequence
< OUString
> aNames( 2 );
766 aNames
[0] = PROPERTY_FILTER
;
767 aNames
[1] = PROPERTY_SORT
;
769 Sequence
< Any
> aValues( 2 );
770 aValues
[0] <<= OUString();
771 aValues
[1] <<= OUString();
773 WaitObject
aWO( NULL
);
774 xProperties
->setPropertyValues( aNames
, aValues
);
776 if ( m_xLoadableForm
.is() )
777 m_xLoadableForm
->reload();
782 case FormFeature::ToggleApplyFilter
:
783 if ( impl_commitCurrentControl_throw() && impl_commitCurrentRecord_throw() )
785 // simply toggle the value
786 sal_Bool bApplied
= sal_False
;
787 m_xCursorProperties
->getPropertyValue( PROPERTY_APPLYFILTER
) >>= bApplied
;
788 m_xCursorProperties
->setPropertyValue( PROPERTY_APPLYFILTER
, makeAny( (sal_Bool
)!bApplied
) );
791 WaitObject
aWO( NULL
);
792 m_xLoadableForm
->reload();
796 case FormFeature::SortAscending
:
797 impl_executeAutoSort_throw( true );
800 case FormFeature::SortDescending
:
801 impl_executeAutoSort_throw( false );
804 case FormFeature::AutoFilter
:
805 impl_executeAutoFilter_throw();
808 case FormFeature::InteractiveSort
:
809 impl_executeFilterOrSort_throw( false );
812 case FormFeature::InteractiveFilter
:
813 impl_executeFilterOrSort_throw( true );
818 sal_uInt16 nErrorResourceId
= RID_STR_FEATURE_UNKNOWN
;
819 if ( lcl_requiresArguments( _nFeature
) )
820 nErrorResourceId
= RID_STR_FEATURE_REQUIRES_PARAMETERS
;
821 else if ( !lcl_isExecutableFeature( _nFeature
) )
822 nErrorResourceId
= RID_STR_FEATURE_NOT_EXECUTABLE
;
823 throw IllegalArgumentException( FRM_RES_STRING( nErrorResourceId
), *this, 1 );
827 catch( const RuntimeException
& ) { throw; }
828 catch( const SQLException
& ) { throw; }
829 catch( const Exception
& )
831 throw WrappedTargetException( OUString(), *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
834 impl_invalidateAllSupportedFeatures_nothrow( aGuard
);
837 //--------------------------------------------------------------------
838 void SAL_CALL
FormOperations::executeWithArguments( ::sal_Int16 _nFeature
, const Sequence
< NamedValue
>& _rArguments
) throw (RuntimeException
, IllegalArgumentException
, SQLException
, WrappedTargetException
)
840 if ( !lcl_requiresArguments( _nFeature
) )
842 execute( _nFeature
);
846 SolarMutexGuard aSolarGuard
;
847 MethodGuard
aGuard( *this );
849 // at the moment we have only one feature which supports execution parameters
850 if ( !lcl_isExecutableFeature( _nFeature
) )
851 throw IllegalArgumentException( FRM_RES_STRING( RID_STR_FEATURE_NOT_EXECUTABLE
), *this, 1 );
855 case FormFeature::MoveAbsolute
:
857 sal_Int32 nPosition
= -1;
859 ::comphelper::NamedValueCollection
aArguments( _rArguments
);
860 aArguments
.get_ensureType( "Position", nPosition
);
867 // commit before doing anything else
868 if ( m_xController
.is() && !impl_commitCurrentControl_throw() )
870 if ( !impl_commitCurrentRecord_throw() )
873 sal_Int32 nCount
= impl_getRowCount_throw();
874 sal_Bool bFinalCount
= impl_isRowCountFinal_throw();
876 if ( bFinalCount
&& ( (sal_Int32
)nPosition
> nCount
) )
879 m_xCursor
->absolute( nPosition
);
881 catch( const RuntimeException
& ) { throw; }
882 catch( const SQLException
& ) { throw; }
883 catch( const Exception
& )
885 throw WrappedTargetException( OUString(), *this, ::cppu::getCaughtException() );
890 throw IllegalArgumentException( FRM_RES_STRING( RID_STR_FEATURE_UNKNOWN
), *this, 1 );
894 //--------------------------------------------------------------------
895 ::sal_Bool SAL_CALL
FormOperations::commitCurrentRecord( ::sal_Bool
& _out_rRecordInserted
) throw (RuntimeException
, SQLException
)
897 MethodGuard
aGuard( *this );
898 _out_rRecordInserted
= sal_False
;
900 return impl_commitCurrentRecord_throw( &_out_rRecordInserted
);
903 //--------------------------------------------------------------------
904 bool FormOperations::impl_commitCurrentRecord_throw( ::sal_Bool
* _pRecordInserted
) const
906 DBG_ASSERT( m_nMethodNestingLevel
, "FormOperations::impl_commitCurrentRecord_throw: to be called within a MethodGuard'ed section only!" );
908 if ( !impl_hasCursor_nothrow() )
911 // nothing to do if the record is not modified
912 sal_Bool bResult
= !impl_isModifiedRow_throw();
915 // insert respectively update the row
916 if ( impl_isInsertionRow_throw() )
918 m_xUpdateCursor
->insertRow();
919 if ( _pRecordInserted
)
920 *_pRecordInserted
= sal_True
;
923 m_xUpdateCursor
->updateRow();
929 //--------------------------------------------------------------------
930 ::sal_Bool SAL_CALL
FormOperations::commitCurrentControl() throw (RuntimeException
, SQLException
)
932 MethodGuard
aGuard( *this );
933 return impl_commitCurrentControl_throw();
936 //--------------------------------------------------------------------
937 bool FormOperations::impl_commitCurrentControl_throw() const
939 DBG_ASSERT( m_nMethodNestingLevel
, "FormOperations::impl_commitCurrentControl_throw: to be called within a MethodGuard'ed section only!" );
940 OSL_PRECOND( m_xController
.is(), "FormOperations::commitCurrentControl: no controller!" );
941 if ( !m_xController
.is() )
944 bool bSuccess
= false;
947 Reference
< XControl
> xCurrentControl( m_xController
->getCurrentControl() );
949 // check whether the control is locked
950 Reference
< XBoundControl
> xCheckLock( xCurrentControl
, UNO_QUERY
);
951 sal_Bool bControlIsLocked
= xCheckLock
.is() && xCheckLock
->getLock();
953 // commit if necessary
955 if ( xCurrentControl
.is() && !bControlIsLocked
)
957 // both the control and it's model can be committable, so try both
958 Reference
< XBoundComponent
> xBound( xCurrentControl
, UNO_QUERY
);
960 xBound
= xBound
.query( xCurrentControl
->getModel() );
961 // and now really commit
963 bSuccess
= xBound
->commit();
967 catch( const RuntimeException
& ) { throw; }
968 catch( const SQLException
& ) { throw; }
969 catch( const Exception
& )
971 DBG_UNHANDLED_EXCEPTION();
978 //--------------------------------------------------------------------
979 ::sal_Bool SAL_CALL
FormOperations::isInsertionRow() throw (RuntimeException
, WrappedTargetException
)
981 sal_Bool bIs
= sal_False
;
984 bIs
= impl_isInsertionRow_throw();
986 catch( const RuntimeException
& ) { throw; }
987 catch( const Exception
& )
989 throw WrappedTargetException( OUString(), *this, ::cppu::getCaughtException() );
994 //--------------------------------------------------------------------
995 ::sal_Bool SAL_CALL
FormOperations::isModifiedRow() throw (RuntimeException
, WrappedTargetException
)
997 sal_Bool bIs
= sal_False
;
1000 bIs
= impl_isModifiedRow_throw();
1002 catch( const RuntimeException
& ) { throw; }
1003 catch( const Exception
& )
1005 throw WrappedTargetException( OUString(), *this, ::cppu::getCaughtException() );
1010 //--------------------------------------------------------------------
1011 void SAL_CALL
FormOperations::cursorMoved( const EventObject
& /*_Event*/ ) throw (RuntimeException
)
1013 MethodGuard
aGuard( *this );
1014 m_bActiveControlModified
= sal_False
;
1016 impl_invalidateAllSupportedFeatures_nothrow( aGuard
);
1019 //--------------------------------------------------------------------
1020 void SAL_CALL
FormOperations::rowChanged( const EventObject
& /*_Event*/ ) throw (RuntimeException
)
1022 // not interested in
1025 //--------------------------------------------------------------------
1026 void SAL_CALL
FormOperations::rowSetChanged( const EventObject
& /*_Event*/ ) throw (RuntimeException
)
1028 // not interested in
1031 //--------------------------------------------------------------------
1032 void SAL_CALL
FormOperations::modified( const EventObject
& /*_Source*/ ) throw( RuntimeException
)
1034 MethodGuard
aGuard( *this );
1036 OSL_ENSURE( m_xCursor
.is(), "FormOperations::modified: already disposed!" );
1037 if ( !m_bActiveControlModified
)
1039 m_bActiveControlModified
= sal_True
;
1040 impl_invalidateModifyDependentFeatures_nothrow( aGuard
);
1044 //--------------------------------------------------------------------
1045 void SAL_CALL
FormOperations::propertyChange( const PropertyChangeEvent
& _rEvent
) throw (RuntimeException
)
1047 MethodGuard
aGuard( *this );
1049 if ( m_xCursor
.is() && ( m_xCursor
== _rEvent
.Source
) )
1051 sal_Bool bIs
= sal_False
;
1052 if ( ( _rEvent
.PropertyName
== PROPERTY_ISMODIFIED
)
1053 || ( _rEvent
.PropertyName
== PROPERTY_ISNEW
)
1056 if ( ( _rEvent
.NewValue
>>= bIs
) && !bIs
)
1057 m_bActiveControlModified
= sal_False
;
1059 impl_invalidateAllSupportedFeatures_nothrow( aGuard
);
1062 if ( m_xParser
.is() && ( m_xCursor
== _rEvent
.Source
) )
1067 _rEvent
.NewValue
>>= sNewValue
;
1068 if ( _rEvent
.PropertyName
== PROPERTY_ACTIVECOMMAND
)
1070 m_xParser
->setElementaryQuery( sNewValue
);
1072 else if ( _rEvent
.PropertyName
== PROPERTY_FILTER
)
1074 if ( m_xParser
->getFilter() != sNewValue
)
1075 m_xParser
->setFilter( sNewValue
);
1077 else if ( _rEvent
.PropertyName
== PROPERTY_SORT
)
1079 _rEvent
.NewValue
>>= sNewValue
;
1080 if ( m_xParser
->getOrder() != sNewValue
)
1081 m_xParser
->setOrder( sNewValue
);
1084 catch( const Exception
& )
1086 OSL_FAIL( "FormOperations::propertyChange: caught an exception while updating the parser!" );
1088 impl_invalidateAllSupportedFeatures_nothrow( aGuard
);
1092 //--------------------------------------------------------------------
1093 void SAL_CALL
FormOperations::disposing( const EventObject
& /*_Source*/ ) throw (RuntimeException
)
1095 // TODO: should we react on this? Or is this the responsibility of our owner to dispose us?
1098 //--------------------------------------------------------------------
1099 void SAL_CALL
FormOperations::disposing()
1101 ::osl::MutexGuard
aGuard( m_aMutex
);
1103 impl_disposeParser_nothrow();
1107 // revoke various listeners
1108 if ( m_xCursor
.is() )
1109 m_xCursor
->removeRowSetListener( this );
1111 if ( m_xCursorProperties
.is() )
1113 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_ISMODIFIED
,this );
1114 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_ISNEW
, this );
1117 Reference
< XModifyBroadcaster
> xBroadcaster( m_xController
, UNO_QUERY
);
1118 if ( xBroadcaster
.is() )
1119 xBroadcaster
->removeModifyListener( this );
1121 catch( const Exception
& )
1123 DBG_UNHANDLED_EXCEPTION();
1126 m_xController
.clear();
1128 m_xUpdateCursor
.clear();
1129 m_xCursorProperties
.clear();
1130 m_xLoadableForm
.clear();
1131 m_xFeatureInvalidation
.clear();
1133 m_bActiveControlModified
= true;
1136 //--------------------------------------------------------------------
1137 void FormOperations::impl_checkDisposed_throw() const
1139 if ( impl_isDisposed_nothrow() )
1140 throw DisposedException( OUString(), *const_cast< FormOperations
* >( this ) );
1143 //--------------------------------------------------------------------
1144 void FormOperations::impl_initFromController_throw()
1146 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_initFromController_throw: invalid controller!" );
1147 m_xCursor
= m_xCursor
.query( m_xController
->getModel() );
1148 if ( !m_xCursor
.is() )
1149 throw IllegalArgumentException( OUString(), *this, 0 );
1151 impl_initFromForm_throw();
1153 Reference
< XModifyBroadcaster
> xBroadcaster( m_xController
, UNO_QUERY
);
1154 if ( xBroadcaster
.is() )
1155 xBroadcaster
->addModifyListener( this );
1158 //--------------------------------------------------------------------
1159 void FormOperations::impl_initFromForm_throw()
1161 OSL_PRECOND( m_xCursor
.is(), "FormOperations::impl_initFromForm_throw: invalid form!" );
1162 m_xCursorProperties
= m_xCursorProperties
.query ( m_xCursor
);
1163 m_xUpdateCursor
= m_xUpdateCursor
.query ( m_xCursor
);
1164 m_xLoadableForm
= m_xLoadableForm
.query ( m_xCursor
);
1166 if ( !m_xCursor
.is() || !m_xCursorProperties
.is() || !m_xLoadableForm
.is() )
1167 throw IllegalArgumentException( OUString(), *this, 0 );
1169 m_xCursor
->addRowSetListener( this );
1170 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_ISMODIFIED
,this );
1171 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_ISNEW
, this );
1174 //--------------------------------------------------------------------
1175 void FormOperations::createWithFormController( const Reference
< XFormController
>& _rxController
)
1177 m_xController
= _rxController
;
1178 if ( !m_xController
.is() )
1179 throw IllegalArgumentException( OUString(), *this, 0 );
1181 impl_initFromController_throw();
1183 m_bConstructed
= true;
1186 //--------------------------------------------------------------------
1187 void FormOperations::createWithForm( const Reference
< XForm
>& _rxForm
)
1189 m_xCursor
= m_xCursor
.query( _rxForm
);
1190 if ( !m_xCursor
.is() )
1191 throw IllegalArgumentException( OUString(), *this, 0 );
1193 impl_initFromForm_throw();
1195 m_bConstructed
= true;
1198 //------------------------------------------------------------------------------
1199 void FormOperations::impl_invalidateAllSupportedFeatures_nothrow( MethodGuard
& _rClearForCallback
) const
1201 if ( !m_xFeatureInvalidation
.is() )
1202 // nobody's interested in ...
1205 Reference
< XFeatureInvalidation
> xInvalidation
= m_xFeatureInvalidation
;
1206 _rClearForCallback
.clear();
1207 xInvalidation
->invalidateAllFeatures();
1210 //------------------------------------------------------------------------------
1211 void FormOperations::impl_invalidateModifyDependentFeatures_nothrow( MethodGuard
& _rClearForCallback
) const
1213 if ( !m_xFeatureInvalidation
.is() )
1214 // nobody's interested in ...
1217 static Sequence
< sal_Int16
> s_aModifyDependentFeatures
;
1218 if ( s_aModifyDependentFeatures
.getLength() == 0 )
1220 sal_Int16 pModifyDependentFeatures
[] =
1222 FormFeature::MoveToNext
,
1223 FormFeature::MoveToInsertRow
,
1224 FormFeature::SaveRecordChanges
,
1225 FormFeature::UndoRecordChanges
1227 size_t nFeatureCount
= SAL_N_ELEMENTS( pModifyDependentFeatures
);
1228 s_aModifyDependentFeatures
= Sequence
< sal_Int16
>( pModifyDependentFeatures
, nFeatureCount
);
1231 Reference
< XFeatureInvalidation
> xInvalidation
= m_xFeatureInvalidation
;
1232 _rClearForCallback
.clear();
1234 xInvalidation
->invalidateFeatures( s_aModifyDependentFeatures
);
1237 //--------------------------------------------------------------------
1238 void FormOperations::impl_ensureInitializedParser_nothrow()
1240 OSL_PRECOND( m_xCursorProperties
.is(), "FormOperations::impl_ensureInitializedParser_nothrow: we're disposed!" );
1241 if ( m_bInitializedParser
)
1246 sal_Bool bUseEscapeProcessing
= sal_False
;
1247 m_xCursorProperties
->getPropertyValue( PROPERTY_ESCAPE_PROCESSING
) >>= bUseEscapeProcessing
;
1248 if ( bUseEscapeProcessing
)
1250 Reference
< XMultiServiceFactory
> xFactory( ::dbtools::getConnection( m_xCursor
), UNO_QUERY
);
1251 if ( xFactory
.is() )
1253 m_xParser
.set( xFactory
->createInstance( OUString( "com.sun.star.sdb.SingleSelectQueryComposer" ) ), UNO_QUERY
);
1254 OSL_ENSURE( m_xParser
.is(), "FormOperations::impl_ensureInitializedParser_nothrow: factory did not create a parser for us!" );
1258 if ( m_xParser
.is() )
1260 if ( m_xLoadableForm
.is() && m_xLoadableForm
->isLoaded() )
1262 OUString sStatement
;
1266 m_xCursorProperties
->getPropertyValue( PROPERTY_ACTIVECOMMAND
) >>= sStatement
;
1267 m_xCursorProperties
->getPropertyValue( PROPERTY_FILTER
) >>= sFilter
;
1268 m_xCursorProperties
->getPropertyValue( PROPERTY_SORT
) >>= sSort
;
1270 m_xParser
->setElementaryQuery( sStatement
);
1271 m_xParser
->setFilter ( sFilter
);
1272 m_xParser
->setOrder ( sSort
);
1275 // start listening at the order/sort properties at the form, so
1276 // we can keep our parser in sync
1277 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_ACTIVECOMMAND
, this );
1278 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_FILTER
, this );
1279 m_xCursorProperties
->addPropertyChangeListener( PROPERTY_SORT
, this );
1282 catch( const Exception
& )
1284 OSL_FAIL( "FormOperations::impl_ensureInitializedParser_nothrow: caught an exception!" );
1287 m_bInitializedParser
= true;
1290 //--------------------------------------------------------------------
1291 void FormOperations::impl_disposeParser_nothrow()
1295 // if we have a parser (and a cursor), then we're listening at the cursor's
1296 // properties to keep the parser in sync with the cursor
1297 if ( m_xParser
.is() && m_xCursorProperties
.is() )
1299 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_FILTER
, this );
1300 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_ACTIVECOMMAND
, this );
1301 m_xCursorProperties
->removePropertyChangeListener( PROPERTY_SORT
, this );
1304 Reference
< XComponent
> xParserComp( m_xParser
, UNO_QUERY
);
1305 if ( xParserComp
.is() )
1306 xParserComp
->dispose();
1309 m_bInitializedParser
= false;
1311 catch( const Exception
& )
1313 OSL_FAIL( "FormOperations::impl_disposeParser_nothrow: caught an exception!" );
1317 //--------------------------------------------------------------------
1318 bool FormOperations::impl_canMoveLeft_throw( ) const
1320 if ( !impl_hasCursor_nothrow() )
1323 return impl_getRowCount_throw() && ( !m_xCursor
->isFirst() || impl_isInsertionRow_throw() );
1326 //--------------------------------------------------------------------
1327 bool FormOperations::impl_canMoveRight_throw( ) const
1329 if ( !impl_hasCursor_nothrow() )
1332 bool bIsNew
= impl_isInsertionRow_throw();
1334 if ( impl_getRowCount_throw() && !m_xCursor
->isLast() && !bIsNew
)
1337 if ( ::dbtools::canInsert( m_xCursorProperties
) )
1338 if ( !bIsNew
|| impl_isModifiedRow_throw() )
1341 if ( bIsNew
&& m_bActiveControlModified
)
1347 //--------------------------------------------------------------------
1348 bool FormOperations::impl_isInsertionRow_throw() const
1350 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_ISNEW
, false );
1353 //--------------------------------------------------------------------
1354 sal_Int32
FormOperations::impl_getRowCount_throw() const
1356 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_ROWCOUNT
, (sal_Int32
)0 );
1358 //--------------------------------------------------------------------
1359 bool FormOperations::impl_isRowCountFinal_throw() const
1361 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_ROWCOUNTFINAL
, false );
1364 //--------------------------------------------------------------------
1365 bool FormOperations::impl_isModifiedRow_throw() const
1367 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_ISMODIFIED
, false );
1370 //--------------------------------------------------------------------
1371 bool FormOperations::impl_isParseable_throw() const
1373 const_cast< FormOperations
* >( this )->impl_ensureInitializedParser_nothrow();
1374 return m_xParser
.is() && !m_xParser
->getQuery().isEmpty();
1377 //--------------------------------------------------------------------
1378 bool FormOperations::impl_hasFilterOrOrder_throw() const
1380 return impl_isParseable_throw() && ( !m_xParser
->getFilter().isEmpty() || !m_xParser
->getOrder().isEmpty() );
1383 //--------------------------------------------------------------------
1384 bool FormOperations::impl_isInsertOnlyForm_throw() const
1386 return lcl_safeGetPropertyValue_throw( m_xCursorProperties
, PROPERTY_INSERTONLY
, true );
1389 //------------------------------------------------------------------------------
1390 Reference
< XControlModel
> FormOperations::impl_getCurrentControlModel_throw() const
1392 Reference
< XControl
> xControl( m_xController
->getCurrentControl() );
1394 // special handling for grid controls
1395 Reference
< XGrid
> xGrid( xControl
, UNO_QUERY
);
1396 Reference
< XControlModel
> xControlModel
;
1400 Reference
< XIndexAccess
> xColumns( xControl
->getModel(), UNO_QUERY_THROW
);
1401 sal_Int16 nCurrentPos
= xGrid
->getCurrentColumnPosition();
1402 nCurrentPos
= impl_gridView2ModelPos_nothrow( xColumns
, nCurrentPos
);
1404 if ( nCurrentPos
!= (sal_Int16
)-1 )
1405 xColumns
->getByIndex( nCurrentPos
) >>= xControlModel
;
1407 else if ( xControl
.is() )
1409 xControlModel
= xControl
->getModel();
1411 return xControlModel
;
1414 //------------------------------------------------------------------------------
1415 Reference
< XPropertySet
> FormOperations::impl_getCurrentBoundField_nothrow( ) const
1417 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_getCurrentBoundField_nothrow: no controller -> no control!" );
1418 if ( !m_xController
.is() )
1421 Reference
< XPropertySet
> xField
;
1424 Reference
< XPropertySet
> xControlModel( impl_getCurrentControlModel_throw(), UNO_QUERY
);
1426 if ( xControlModel
.is() && ::comphelper::hasProperty( PROPERTY_BOUNDFIELD
, xControlModel
) )
1427 xControlModel
->getPropertyValue( PROPERTY_BOUNDFIELD
) >>= xField
;
1430 catch( const Exception
& )
1432 DBG_UNHANDLED_EXCEPTION();
1438 //------------------------------------------------------------------------------
1439 sal_Int16
FormOperations::impl_gridView2ModelPos_nothrow( const Reference
< XIndexAccess
>& _rxColumns
, sal_Int16 _nViewPos
) const
1441 OSL_PRECOND( _rxColumns
.is(), "FormOperations::impl_gridView2ModelPos_nothrow: invalid columns container!" );
1444 // loop through all columns
1446 Reference
< XPropertySet
> xCol
;
1447 bool bHidden( false );
1448 for ( col
= 0; col
< _rxColumns
->getCount(); ++col
)
1450 _rxColumns
->getByIndex( col
) >>= xCol
;
1451 OSL_VERIFY( xCol
->getPropertyValue( PROPERTY_HIDDEN
) >>= bHidden
);
1455 // for every visible col : if nViewPos is greater zero, decrement it, else we
1456 // have found the model position
1462 if ( col
< _rxColumns
->getCount() )
1465 catch( const Exception
& )
1467 DBG_UNHANDLED_EXCEPTION();
1469 return (sal_Int16
)-1;
1472 //------------------------------------------------------------------------------
1473 bool FormOperations::impl_moveLeft_throw( ) const
1475 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_moveLeft_throw: no cursor!" );
1476 if ( !impl_hasCursor_nothrow() )
1479 sal_Bool bRecordInserted
= sal_False
;
1480 sal_Bool bSuccess
= impl_commitCurrentRecord_throw( &bRecordInserted
);
1485 if ( bRecordInserted
)
1487 // retrieve the bookmark of the new record and move to the record preceding this bookmark
1488 Reference
< XRowLocate
> xLocate( m_xCursor
, UNO_QUERY
);
1489 OSL_ENSURE( xLocate
.is(), "FormOperations::impl_moveLeft_throw: no XRowLocate!" );
1491 xLocate
->moveRelativeToBookmark( xLocate
->getBookmark(), -1 );
1495 if ( impl_isInsertionRow_throw() )
1497 // we assume that the inserted record is now the last record in the
1502 m_xCursor
->previous();
1508 //--------------------------------------------------------------------
1509 bool FormOperations::impl_moveRight_throw( ) const
1511 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_moveRight_throw: no cursor!" );
1512 if ( !impl_hasCursor_nothrow() )
1515 sal_Bool bRecordInserted
= sal_False
;
1516 sal_Bool bSuccess
= impl_commitCurrentRecord_throw( &bRecordInserted
);
1521 if ( bRecordInserted
)
1524 m_xUpdateCursor
->moveToInsertRow();
1528 if ( m_xCursor
->isLast() )
1529 m_xUpdateCursor
->moveToInsertRow();
1537 //--------------------------------------------------------------------
1538 void FormOperations::impl_resetAllControls_nothrow() const
1540 Reference
< XIndexAccess
> xContainer( m_xCursor
, UNO_QUERY
);
1541 if ( !xContainer
.is() )
1546 Reference
< XReset
> xReset
;
1547 sal_Int32
nCount( xContainer
->getCount() );
1548 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
1550 if ( xContainer
->getByIndex( i
) >>= xReset
)
1552 // no resets on sub forms
1553 Reference
< XForm
> xAsForm( xReset
, UNO_QUERY
);
1554 if ( !xAsForm
.is() )
1559 catch( const Exception
& )
1561 DBG_UNHANDLED_EXCEPTION();
1565 //------------------------------------------------------------------------------
1566 void FormOperations::impl_executeAutoSort_throw( bool _bUp
) const
1568 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_executeAutoSort_throw: need a controller for this!" );
1569 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeAutoSort_throw: need a cursor for this!" );
1570 OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeAutoSort_throw: need a parseable statement for this!" );
1571 if ( !m_xController
.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
1576 Reference
< XControl
> xControl
= m_xController
->getCurrentControl();
1577 if ( !xControl
.is() || !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
1580 Reference
< XPropertySet
> xBoundField( impl_getCurrentBoundField_nothrow() );
1581 if ( !xBoundField
.is() )
1584 OUString sOriginalSort
;
1585 m_xCursorProperties
->getPropertyValue( PROPERTY_SORT
) >>= sOriginalSort
;
1587 // automatic sort by field is expected to always resets the previous sort order
1588 m_xParser
->setOrder( OUString() );
1590 impl_appendOrderByColumn_throw
aAction(this, xBoundField
, _bUp
);
1591 impl_doActionInSQLContext_throw(aAction
, RID_STR_COULD_NOT_SET_ORDER
);
1593 WaitObject
aWO( NULL
);
1596 m_xCursorProperties
->setPropertyValue( PROPERTY_SORT
, makeAny( m_xParser
->getOrder() ) );
1597 m_xLoadableForm
->reload();
1599 catch( const Exception
& )
1601 OSL_FAIL( "FormOperations::impl_executeAutoSort_throw: caught an exception while setting the parser properties!" );
1605 if ( !m_xLoadableForm
->isLoaded() )
1606 { // something went wrong -> restore the original state
1609 m_xParser
->setOrder( sOriginalSort
);
1610 m_xCursorProperties
->setPropertyValue( PROPERTY_SORT
, makeAny( m_xParser
->getOrder() ) );
1611 m_xLoadableForm
->reload();
1613 catch( const Exception
& )
1615 OSL_FAIL( "FormOperations::impl_executeAutoSort_throw: could not reset the form to it's original state!" );
1620 catch( const RuntimeException
& ) { throw; }
1621 catch( const SQLException
& ) { throw; }
1622 catch( const Exception
& )
1624 throw WrappedTargetException( OUString(), *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
1628 //------------------------------------------------------------------------------
1629 void FormOperations::impl_executeAutoFilter_throw( ) const
1631 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_executeAutoFilter_throw: need a controller for this!" );
1632 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeAutoFilter_throw: need a cursor for this!" );
1633 OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeAutoFilter_throw: need a parseable statement for this!" );
1634 if ( !m_xController
.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
1639 Reference
< XControl
> xControl
= m_xController
->getCurrentControl();
1640 if ( !xControl
.is() || !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
1643 Reference
< XPropertySet
> xBoundField( impl_getCurrentBoundField_nothrow() );
1644 if ( !xBoundField
.is() )
1647 OUString sOriginalFilter
;
1648 m_xCursorProperties
->getPropertyValue( PROPERTY_FILTER
) >>= sOriginalFilter
;
1649 sal_Bool bApplied
= sal_True
;
1650 m_xCursorProperties
->getPropertyValue( PROPERTY_APPLYFILTER
) >>= bApplied
;
1652 // if we have a filter, but it's not applied, then we have to overwrite it, else append one
1654 m_xParser
->setFilter( OUString() );
1656 impl_appendFilterByColumn_throw
aAction(this, xBoundField
);
1657 impl_doActionInSQLContext_throw( aAction
, RID_STR_COULD_NOT_SET_FILTER
);
1659 WaitObject
aWO( NULL
);
1662 m_xCursorProperties
->setPropertyValue( PROPERTY_FILTER
, makeAny( m_xParser
->getFilter() ) );
1663 m_xCursorProperties
->setPropertyValue( PROPERTY_APPLYFILTER
, makeAny( (sal_Bool
)sal_True
) );
1665 m_xLoadableForm
->reload();
1667 catch( const Exception
& )
1669 OSL_FAIL( "FormOperations::impl_executeAutoFilter_throw: caught an exception while setting the parser properties!" );
1673 if ( !m_xLoadableForm
->isLoaded() )
1674 { // something went wrong -> restore the original state
1677 m_xParser
->setOrder( sOriginalFilter
);
1678 m_xCursorProperties
->setPropertyValue( PROPERTY_APPLYFILTER
, makeAny( (sal_Bool
)bApplied
) );
1679 m_xCursorProperties
->setPropertyValue( PROPERTY_FILTER
, makeAny( m_xParser
->getFilter() ) );
1680 m_xLoadableForm
->reload();
1682 catch( const Exception
& )
1684 OSL_FAIL( "FormOperations::impl_executeAutoFilter_throw: could not reset the form to it's original state!" );
1689 catch( const RuntimeException
& ) { throw; }
1690 catch( const SQLException
& ) { throw; }
1691 catch( const Exception
& )
1693 throw WrappedTargetException( OUString(), *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
1697 //--------------------------------------------------------------------
1698 void FormOperations::impl_executeFilterOrSort_throw( bool _bFilter
) const
1700 OSL_PRECOND( m_xController
.is(), "FormOperations::impl_executeFilterOrSort_throw: need a controller for this!" );
1701 OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeFilterOrSort_throw: need a cursor for this!" );
1702 OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeFilterOrSort_throw: need a parseable statement for this!" );
1703 if ( !m_xController
.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
1706 if ( !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
1710 Reference
< XExecutableDialog
> xDialog
;
1713 xDialog
= com::sun::star::sdb::FilterDialog::createWithQuery(m_aContext
.getUNOContext(), m_xParser
, m_xCursor
,
1714 Reference
<com::sun::star::awt::XWindow
>());
1718 xDialog
= com::sun::star::sdb::OrderDialog::createWithQuery(m_aContext
.getUNOContext(), m_xParser
, m_xCursorProperties
);
1722 if ( RET_OK
== xDialog
->execute() )
1724 WaitObject
aWO( NULL
);
1726 m_xCursorProperties
->setPropertyValue( PROPERTY_FILTER
, makeAny( m_xParser
->getFilter() ) );
1728 m_xCursorProperties
->setPropertyValue( PROPERTY_SORT
, makeAny( m_xParser
->getOrder() ) );
1729 m_xLoadableForm
->reload();
1733 catch( const RuntimeException
& ) { throw; }
1734 catch( const SQLException
& ) { throw; }
1735 catch( const Exception
& )
1737 throw WrappedTargetException( OUString(), *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
1741 //------------------------------------------------------------------------------
1742 template < typename FunctObj
>
1743 void FormOperations::impl_doActionInSQLContext_throw( FunctObj f
, sal_uInt16 _nErrorResourceId
) const
1749 catch( const SQLException
& e
)
1752 if ( !_nErrorResourceId
)
1753 // no information to prepend
1756 SQLExceptionInfo
aInfo( ::cppu::getCaughtException() );
1757 OUString
sAdditionalError( FRM_RES_STRING( _nErrorResourceId
) );
1758 aInfo
.prepend( sAdditionalError
);
1761 catch( const RuntimeException
& ) { throw; }
1762 catch( const Exception
& )
1764 OUString
sAdditionalError( FRM_RES_STRING( _nErrorResourceId
) );
1765 throw WrappedTargetException( sAdditionalError
, *const_cast< FormOperations
* >( this ), ::cppu::getCaughtException() );
1769 //........................................................................
1771 //........................................................................
1773 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */