Date: prev next · Thread: first prev next last
2013 Archives by date, by thread · List index


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


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.