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
+@section forms
+
+@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@mamane.lu>
Context
- [PATCH libreoffice-4-0] commit subforms before moving in parent form · Lionel Elie Mamane (via Code Review)
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.