[PATCH libreoffice-4-0] commit subforms before moving in parent form
Lionel Elie Mamane (via Code Review)
gerrit at gerrit.libreoffice.org
Sat May 11 20:30:30 PDT 2013
Hi,
I have submitted a patch for review:
https://gerrit.libreoffice.org/3865
To pull it, you can do:
git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/65/3865/1
commit subforms before moving in parent form
else, all pending changes in the subforms are lost
(cherry picked from commit 28cacb44009a1d2cb5fdb3b81c1a7c665463d38d)
Conflicts:
forms/source/component/errorbroadcaster.cxx
forms/source/runtime/formoperations.cxx
sal/inc/sal/log-areas.dox
Change-Id: I82b0967729c71a4f01eff9f823a1961fad999679
---
M forms/source/runtime/formoperations.cxx
M sal/inc/sal/log-areas.dox
2 files changed, 141 insertions(+), 36 deletions(-)
diff --git a/forms/source/runtime/formoperations.cxx b/forms/source/runtime/formoperations.cxx
index 6ba363e..1ea05d2 100644
--- a/forms/source/runtime/formoperations.cxx
+++ b/forms/source/runtime/formoperations.cxx
@@ -80,6 +80,7 @@
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 @@
{
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 @@
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;
}
-
- if ( bCommitCurrentRecord && !impl_commitCurrentRecord_throw() )
- 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 );
+ }
}
try
@@ -1227,20 +1342,6 @@
return true;
return false;
- }
-
- //--------------------------------------------------------------------
- namespace
- {
- template < typename TYPE >
- TYPE lcl_safeGetPropertyValue_throw( const Reference< XPropertySet >& _rxProperties, const ::rtl::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;
- }
}
//--------------------------------------------------------------------
diff --git a/sal/inc/sal/log-areas.dox b/sal/inc/sal/log-areas.dox
index b5fa6f9..d943703 100644
--- a/sal/inc/sal/log-areas.dox
+++ b/sal/inc/sal/log-areas.dox
@@ -86,6 +86,10 @@
@li @c oox.xmlstream - XmlStream class
@li @c oox.storage - ZipStorage class
+ at section forms
+
+ at li @c forms.runtime
+
@section formula
@li @c formula.core
--
To view, visit https://gerrit.libreoffice.org/3865
To unsubscribe, visit https://gerrit.libreoffice.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I82b0967729c71a4f01eff9f823a1961fad999679
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: libreoffice-4-0
Gerrit-Owner: Lionel Elie Mamane <lionel at mamane.lu>
More information about the LibreOffice
mailing list