[Libreoffice-commits] .: formula/source sc/inc sc/qa sc/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Tue Dec 11 12:54:51 PST 2012


 formula/source/core/api/FormulaCompiler.cxx |    5 ++++-
 sc/inc/document.hxx                         |   19 ++++++++++++++++---
 sc/qa/unit/ucalc.cxx                        |   10 +++++-----
 sc/source/core/data/cell.cxx                |    5 +++++
 sc/source/core/data/documen7.cxx            |    6 +++---
 sc/source/filter/oox/workbookfragment.cxx   |    2 +-
 sc/source/ui/docshell/docsh.cxx             |    2 +-
 7 files changed, 35 insertions(+), 14 deletions(-)

New commits:
commit a67906259a748b658daa6ee33f23a04755e21b66
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue Dec 11 15:46:59 2012 -0500

    fdo#58149: Recalculate HYPERLINK formula cells on load.
    
    The current implementation of HYPERLINK relies on its result being
    1x2 matrix while only the first element is displayed visibly.  The
    second element stores the URL which is only used when querying for
    the URL (tooltip or launch URL event).
    
    Starting with 4.0 we load cached formula results to avoid full
    recalculation on load.  That unfortuntely ended up breaking the
    HYPERLINK because the result was a simple string value rather than
    a matrix; hence the need to recalculate it on load.
    
    But unlike volatile formula cells, cells with HYPERLINK don't need
    to be recalculated on every cell input change; only once when the file
    is loaded.
    
    P.S. This commit also reverses the logic of bNoProgressBar flag for
    CalcFormulaTree(), to make it easier for human brain to process what
    it means.
    
    Change-Id: I7a24d96d225910b88071a8fe6320f59bf7a47163

diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index 2a48678..29b6694 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -1069,7 +1069,10 @@ void FormulaCompiler::Factor()
                     pArr->SetRecalcModeOnRefMove();
                 break;
                 case ocHyperLink :
-                pArr->SetHyperLink(true);
+                    // cell with hyperlink needs to be calculated on load to
+                    // get its matrix result generated.
+                    pArr->SetRecalcModeOnLoad();
+                    pArr->SetHyperLink(true);
                 break;
                 default:
                     ;   // nothing
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index d38142c..41afbf2 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1646,9 +1646,22 @@ public:
                                             SvtListener* pListener );
     void                PutInFormulaTree( ScFormulaCell* pCell );
     void                RemoveFromFormulaTree( ScFormulaCell* pCell );
-    SC_DLLPUBLIC void CalcFormulaTree( bool bOnlyForced = false,
-                                       bool bNoProgressBar = false,
-                                       bool bDirtyFlag=true );
+
+    /**
+     * Calculate formula cells that are on the formula tree either partially,
+     * or in full.
+     *
+     * @param bOnlyForced when true, it only calculates those formula cells
+     *                    that are marked "recalc forced".
+     * @param bProgressBar whether or not to use progress bar.
+     * @param bSetAllDirty when true, it marks all formula cells currently on
+     *                     the formula tree dirty, which forces all of them to
+     *                     be recalculated.  When false, only those cells
+     *                     that are marked dirty prior to this call get
+     *                     recalculated.
+     */
+    SC_DLLPUBLIC void CalcFormulaTree(
+        bool bOnlyForced = false, bool bProgressBar = true, bool bSetAllDirty = true );
     void                ClearFormulaTree();
     void                AppendToFormulaTrack( ScFormulaCell* pCell );
     void                RemoveFromFormulaTrack( ScFormulaCell* pCell );
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 2509400..842a13c 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -1060,7 +1060,7 @@ void Test::testSheetsFunc()
                             m_pDoc->InsertTab (SC_TAB_APPEND, aTabName1));
 
     m_pDoc->SetString(0, 0, 0, OUString("=SHEETS()"));
-    m_pDoc->CalcFormulaTree(false, true);
+    m_pDoc->CalcFormulaTree(false, false);
     double original;
     m_pDoc->GetValue(0, 0, 0, original);
 
@@ -1100,14 +1100,14 @@ void Test::testVolatileFunc()
 
     val = 0;
     m_pDoc->SetValue(0, 0, 0, val);
-    m_pDoc->CalcFormulaTree(false, true);
+    m_pDoc->CalcFormulaTree(false, false);
     double zero;
     m_pDoc->GetValue(0, 1, 0, zero);
     CPPUNIT_ASSERT_MESSAGE("Result should equal the 3rd parameter of IF, which is zero.", zero == 0.0);
 
     val = 1;
     m_pDoc->SetValue(0, 0, 0, val);
-    m_pDoc->CalcFormulaTree(false, true);
+    m_pDoc->CalcFormulaTree(false, false);
     double now2;
     m_pDoc->GetValue(0, 1, 0, now2);
     CPPUNIT_ASSERT_MESSAGE("Result should be the value of NOW() again.", (now2 - now1) >= 0.0);
@@ -1231,7 +1231,7 @@ void Test::testFuncParam()
 
     // First, the normal case, with no missing parameters.
     m_pDoc->SetString(0, 0, 0, OUString("=AVERAGE(1;2;3)"));
-    m_pDoc->CalcFormulaTree(false, true);
+    m_pDoc->CalcFormulaTree(false, false);
     double val;
     m_pDoc->GetValue(0, 0, 0, val);
     CPPUNIT_ASSERT_MESSAGE("incorrect result", val == 2);
@@ -1239,7 +1239,7 @@ void Test::testFuncParam()
     // Now function with missing parameters.  Missing values should be treated
     // as zeros.
     m_pDoc->SetString(0, 0, 0, OUString("=AVERAGE(1;;;)"));
-    m_pDoc->CalcFormulaTree(false, true);
+    m_pDoc->CalcFormulaTree(false, false);
     m_pDoc->GetValue(0, 0, 0, val);
     CPPUNIT_ASSERT_MESSAGE("incorrect result", val == 0.25);
 
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index 0641c02..bbf8976 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -1097,7 +1097,12 @@ void ScFormulaCell::CompileXML( ScProgress& rProgress )
     //volatile cells must be added here for import
     if( pCode->IsRecalcModeAlways() || pCode->IsRecalcModeForced() ||
         pCode->IsRecalcModeOnLoad() || pCode->IsRecalcModeOnLoadOnce() )
+    {
+        // During load, only those cells that are marked explicitly dirty get
+        // recalculated.  So we need to set it dirty here.
+        SetDirtyVar();
         pDocument->PutInFormulaTree(this);
+    }
 }
 
 
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index ea1cc24..c67d372 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -271,7 +271,7 @@ bool ScDocument::IsInFormulaTree( ScFormulaCell* pCell ) const
 }
 
 
-void ScDocument::CalcFormulaTree( bool bOnlyForced, bool bNoProgress, bool bDirtyFlag )
+void ScDocument::CalcFormulaTree( bool bOnlyForced, bool bProgressBar, bool bSetAllDirty )
 {
     OSL_ENSURE( !IsCalculatingFormulaTree(), "CalcFormulaTree recursion" );
     // never ever recurse into this, might end up lost in infinity
@@ -308,13 +308,13 @@ void ScDocument::CalcFormulaTree( bool bOnlyForced, bool bNoProgress, bool bDirt
                 }
                 else
                 {   // andere simpel berechnen
-                    if( bDirtyFlag )
+                    if( bSetAllDirty )
                         pCell->SetDirtyVar();
                     pCell = pCell->GetNext();
                 }
             }
         }
-        bool bProgress = !bOnlyForced && nFormulaCodeInTree && !bNoProgress;
+        bool bProgress = !bOnlyForced && nFormulaCodeInTree && bProgressBar;
         if ( bProgress )
             ScProgress::CreateInterpretProgress( this, true );
 
diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx
index 5c12d5b..0e92e2a 100644
--- a/sc/source/filter/oox/workbookfragment.cxx
+++ b/sc/source/filter/oox/workbookfragment.cxx
@@ -379,7 +379,7 @@ void WorkbookFragment::finalizeImport()
     if (bHardRecalc)
         pDocSh->DoHardRecalc(false);
     else
-        rDoc.CalcFormulaTree(false, false, false);
+        rDoc.CalcFormulaTree(false, true, false);
 }
 
 // private --------------------------------------------------------------------
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index d801b9b..1a7ec1a 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -444,7 +444,7 @@ sal_Bool ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::un
         DoHardRecalc(false);
     else
         // still need to recalc volatile formula cells.
-        aDocument.CalcFormulaTree(false, false, false);
+        aDocument.CalcFormulaTree(false, true, false);
 
     aDocument.EnableAdjustHeight(false);
 


More information about the Libreoffice-commits mailing list