summaryrefslogtreecommitdiff
path: root/forms
diff options
context:
space:
mode:
authorLionel Elie Mamane <lionel@mamane.lu>2013-05-12 04:06:32 +0200
committerLionel Elie Mamane <lionel@mamane.lu>2013-05-12 05:07:53 +0200
commit28cacb44009a1d2cb5fdb3b81c1a7c665463d38d (patch)
tree0c99810c3c9a399609e26e2dd5cdef32b2389bec /forms
parent7fd1cc18130464a9f09cb7a866e88c4d52e4716d (diff)
commit subforms before moving in parent form
else, all pending changes in the subforms are lost Change-Id: I82b0967729c71a4f01eff9f823a1961fad999679
Diffstat (limited to 'forms')
-rw-r--r--forms/source/component/errorbroadcaster.cxx4
-rw-r--r--forms/source/runtime/formoperations.cxx173
2 files changed, 139 insertions, 38 deletions
diff --git a/forms/source/component/errorbroadcaster.cxx b/forms/source/component/errorbroadcaster.cxx
index 3fae840e2fa0..f9a010ba112f 100644
--- a/forms/source/component/errorbroadcaster.cxx
+++ b/forms/source/component/errorbroadcaster.cxx
@@ -45,11 +45,11 @@ namespace frm
//---------------------------------------------------------------------
OErrorBroadcaster::~OErrorBroadcaster( )
{
- SAL_WARN_IF( !m_rBHelper.bDisposed && !m_rBHelper.bInDispose, "forms",
+ SAL_WARN_IF( !m_rBHelper.bDisposed && !m_rBHelper.bInDispose, "forms.component",
"OErrorBroadcaster::~OErrorBroadcaster: not disposed!" );
// herein, we don't have a chance to do the dispose ourself ....
- SAL_WARN_IF( m_aErrorListeners.getLength(), "forms",
+ SAL_WARN_IF( m_aErrorListeners.getLength(), "forms.component",
"OErrorBroadcaster::~OErrorBroadcaster: still have listeners!" );
// either we're not disposed, or the derived class did not call our dispose from within their dispose
}
diff --git a/forms/source/runtime/formoperations.cxx b/forms/source/runtime/formoperations.cxx
index 914ae6af5180..f36394c81d40 100644
--- a/forms/source/runtime/formoperations.cxx
+++ b/forms/source/runtime/formoperations.cxx
@@ -81,6 +81,7 @@ namespace frm
using ::com::sun::star::sdbc::XRowSet;
using ::com::sun::star::sdbc::XResultSetUpdate;
using ::com::sun::star::form::runtime::XFormController;
+ using ::com::sun::star::form::runtime::XFormOperations;
using ::com::sun::star::form::runtime::XFeatureInvalidation;
using ::com::sun::star::form::runtime::FeatureState;
using ::com::sun::star::lang::IllegalArgumentException;
@@ -452,8 +453,128 @@ namespace frm
{
return ( _nFeature != FormFeature::TotalRecords );
}
- }
+ template < typename TYPE >
+ TYPE lcl_safeGetPropertyValue_throw( const Reference< XPropertySet >& _rxProperties, const OUString& _rPropertyName, TYPE _Default )
+ {
+ TYPE value( _Default );
+ OSL_PRECOND( _rxProperties.is(), "FormOperations::<foo>: no cursor (already disposed?)!" );
+ if ( _rxProperties.is() )
+ OSL_VERIFY( _rxProperties->getPropertyValue( _rPropertyName ) >>= value );
+ return value;
+ }
+
+ // returns false if parent should *abort* (user pressed cancel)
+ bool checkConfirmation(bool &needConfirmation, bool &shouldCommit)
+ {
+ if(needConfirmation)
+ {
+ // TODO: shouldn't this be done with an interaction handler?
+ QueryBox aQuery( NULL, WB_YES_NO_CANCEL | WB_DEF_YES, FRM_RES_STRING( RID_STR_QUERY_SAVE_MODIFIED_ROW ) );
+ switch ( aQuery.Execute() )
+ {
+ case RET_NO:
+ shouldCommit = false;
+ // no break on purpose: don't ask again!
+ case RET_YES:
+ needConfirmation = false;
+ return true;
+ case RET_CANCEL:
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool commit1Form(Reference< XFormController > xCntrl, bool &needConfirmation, bool &shouldCommit)
+ {
+ Reference< XFormOperations > xFrmOps(xCntrl->getFormOperations());
+ if (!xFrmOps->commitCurrentControl())
+ return false;
+
+ if(xFrmOps->isModifiedRow())
+ {
+ if(!checkConfirmation(needConfirmation, shouldCommit))
+ return false;
+ sal_Bool _;
+ if (shouldCommit && !xFrmOps->commitCurrentRecord(_))
+ return false;
+ }
+ return true;
+ }
+
+ bool commitFormAndSubforms(Reference< XFormController > xCntrl, bool needConfirmation)
+ {
+ bool shouldCommit(true);
+ assert(xCntrl.is());
+ Reference< XIndexAccess > xSubForms(xCntrl, UNO_QUERY);
+ assert(xSubForms.is());
+ if(xSubForms.is())
+ {
+ const sal_Int32 cnt = xSubForms->getCount();
+ for(int i=0; i < cnt; ++i)
+ {
+ Reference< XFormController > xSubForm(xSubForms->getByIndex(i), UNO_QUERY);
+ assert(xSubForm.is());
+ if (xSubForm.is())
+ {
+ if (!commit1Form(xSubForm, needConfirmation, shouldCommit))
+ return false;
+ }
+ }
+ }
+
+ if(!commit1Form(xCntrl, needConfirmation, shouldCommit))
+ return false;
+
+ return true;
+ }
+
+ bool commit1Form(Reference< XForm > xFrm, bool &needConfirmation, bool &shouldCommit)
+ {
+ Reference< XPropertySet > xProps(xFrm, UNO_QUERY_THROW);
+ // nothing to do if the record is not modified
+ if(!lcl_safeGetPropertyValue_throw( xProps, PROPERTY_ISMODIFIED, false ))
+ return true;
+
+ if(!checkConfirmation(needConfirmation, shouldCommit))
+ return false;
+ if(shouldCommit)
+ {
+ Reference< XResultSetUpdate > xUpd(xFrm, UNO_QUERY_THROW);
+ // insert respectively update the row
+ if ( lcl_safeGetPropertyValue_throw( xProps, PROPERTY_ISNEW, false ) )
+ xUpd->insertRow();
+ else
+ xUpd->updateRow();
+ }
+ return true;
+ }
+
+ bool commitFormAndSubforms(Reference< XForm > xFrm, bool needConfirmation)
+ {
+ // No control... do what we can with the models
+ bool shouldCommit(true);
+ Reference< XIndexAccess > xFormComps(xFrm, UNO_QUERY_THROW);
+ assert( xFormComps.is() );
+
+ const sal_Int32 cnt = xFormComps->getCount();
+ for(int i=0; i < cnt; ++i)
+ {
+ Reference< XForm > xSubForm(xFormComps->getByIndex(i), UNO_QUERY);
+ if(xSubForm.is())
+ {
+ if(!commit1Form(xSubForm, needConfirmation, shouldCommit))
+ return false;
+ }
+ }
+
+ if(!commit1Form(xFrm, needConfirmation, shouldCommit))
+ return false;
+
+ return true;
+ }
+ }
//--------------------------------------------------------------------
void SAL_CALL FormOperations::execute( ::sal_Int16 _nFeature ) throw (RuntimeException, IllegalArgumentException, SQLException, WrappedTargetException)
{
@@ -462,30 +583,24 @@ namespace frm
if ( ( _nFeature != FormFeature::DeleteRecord ) && ( _nFeature != FormFeature::UndoRecordChanges ) )
{
- // if we have a controller, commit the current control
- if ( m_xController.is() )
- if ( !impl_commitCurrentControl_throw() )
- return;
- // commit the current record
- bool bCommitCurrentRecord = true;
- // (but before, let the user confirm if necessary)
- if ( impl_isModifiedRow_throw() )
+
+ if(m_xController.is())
{
- if ( lcl_needConfirmCommit( _nFeature ) )
- {
- // TODO: shouldn't this be done with an interaction handler?
- QueryBox aQuery( NULL, WB_YES_NO_CANCEL | WB_DEF_YES, FRM_RES_STRING( RID_STR_QUERY_SAVE_MODIFIED_ROW ) );
- switch ( aQuery.Execute() )
- {
- case RET_NO: bCommitCurrentRecord = false; break;
- case RET_CANCEL: return;
- }
- }
+ if(!commitFormAndSubforms(m_xController, lcl_needConfirmCommit( _nFeature )))
+ return;
+ }
+ else if(m_xCursor.is())
+ {
+ Reference< XForm > xForm(m_xCursor, UNO_QUERY);
+ assert(xForm.is());
+ if(!commitFormAndSubforms(xForm, lcl_needConfirmCommit( _nFeature )))
+ return;
+ }
+ else
+ {
+ SAL_WARN( "forms.runtime", "No cursor, but trying to execute form operation " << _nFeature );
}
-
- if ( bCommitCurrentRecord && !impl_commitCurrentRecord_throw() )
- return;
}
try
@@ -1230,20 +1345,6 @@ namespace frm
}
//--------------------------------------------------------------------
- namespace
- {
- template < typename TYPE >
- TYPE lcl_safeGetPropertyValue_throw( const Reference< XPropertySet >& _rxProperties, const OUString& _rPropertyName, TYPE _Default )
- {
- TYPE value( _Default );
- OSL_PRECOND( _rxProperties.is(), "FormOperations::<foo>: no cursor (already disposed?)!" );
- if ( _rxProperties.is() )
- OSL_VERIFY( _rxProperties->getPropertyValue( _rPropertyName ) >>= value );
- return value;
- }
- }
-
- //--------------------------------------------------------------------
bool FormOperations::impl_isInsertionRow_throw() const
{
return lcl_safeGetPropertyValue_throw( m_xCursorProperties, PROPERTY_ISNEW, false );