[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