[Libreoffice-commits] core.git: 2 commits - sc/inc sc/qa sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Wed Mar 12 19:01:36 PDT 2014


 sc/inc/column.hxx                        |    3 +
 sc/inc/document.hxx                      |    8 ++--
 sc/inc/refupdatecontext.hxx              |   14 +++++++
 sc/inc/table.hxx                         |    3 +
 sc/inc/tokenarray.hxx                    |   12 ++++++
 sc/qa/unit/ucalc.hxx                     |    2 +
 sc/qa/unit/ucalc_sharedformula.cxx       |   59 +++++++++++++++++++++++++++++++
 sc/source/core/data/column.cxx           |   18 +++++++--
 sc/source/core/data/documen2.cxx         |    7 ++-
 sc/source/core/data/documen3.cxx         |    8 ++--
 sc/source/core/data/document.cxx         |   34 +++++++++++++----
 sc/source/core/data/refupdatecontext.cxx |    3 +
 sc/source/core/data/table2.cxx           |    9 ++--
 sc/source/core/tool/token.cxx            |   46 ++++++++++++++++++++++++
 sc/source/ui/docshell/dbdocimp.cxx       |    4 +-
 sc/source/ui/docshell/docsh.cxx          |   14 +++++--
 sc/source/ui/docshell/docsh5.cxx         |    5 ++
 sc/source/ui/undo/refundo.cxx            |   10 +++--
 sc/source/ui/undo/undotab.cxx            |    8 ++--
 sc/source/ui/view/spelldialog.cxx        |    8 ++--
 sc/source/ui/view/viewfun4.cxx           |    6 ++-
 21 files changed, 235 insertions(+), 46 deletions(-)

New commits:
commit 18909ddb30db7ca9416ee2bfb0503753e877f002
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Mar 12 21:53:34 2014 -0400

    fdo#75977: Clear sheet deleted flags for affected references when undoing.
    
    This will allow formula cells to restore deleted references when they get
    recalculated.  With this change, SetDirty() that previosly took no argument
    has been renamed to SetAllFormulasDirty(), and it now takes one argument that
    stores context information.
    
    Change-Id: If0de5dc1737a2722b6d61a87644b10a4f921edc5

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 0e4c1d7..de28214 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -60,6 +60,7 @@ class CellValues;
 struct RowSpan;
 class RowHeightContext;
 class CompileFormulaContext;
+struct SetFormulaDirtyContext;
 
 }
 
@@ -330,7 +331,7 @@ public:
 
     bool IsFormulaDirty( SCROW nRow ) const;
 
-    void        SetDirty();
+    void SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt );
     void        SetDirty( SCROW nRow1, SCROW nRow2 );
     void        SetDirtyVar();
     void        SetDirtyAfterLoad();
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 82b4d23..d8b4d7c 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -75,6 +75,7 @@ class DocumentStreamAccess;
 class DocumentLinkManager;
 class CellValues;
 class RowHeightContext;
+struct SetFormulaDirtyContext;
 
 }
 
@@ -618,8 +619,9 @@ public:
     void SetTabNameOnLoad(SCTAB nTab, const OUString& rName);
     void InvalidateStreamOnSave();
 
-    SC_DLLPUBLIC bool           InsertTab( SCTAB nPos, const OUString& rName,
-                                        bool bExternalDocument = false );
+    SC_DLLPUBLIC bool InsertTab(
+        SCTAB nPos, const OUString& rName, bool bExternalDocument = false, bool bUndoDeleteTab = false );
+
     SC_DLLPUBLIC bool           InsertTabs( SCTAB nPos, const std::vector<OUString>& rNames,
                                 bool bExternalDocument = false, bool bNamesValid = false );
     SC_DLLPUBLIC bool DeleteTabs( SCTAB nTab, SCTAB nSheets );
@@ -977,7 +979,7 @@ public:
 
     void            ResetChanged( const ScRange& rRange );
 
-    void            SetDirty();
+    void SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt );
     void            SetDirty( const ScRange& );
     void            SetTableOpDirty( const ScRange& );  // for Interpreter TableOp
     void            InterpretDirtyCells( const ScRangeList& rRanges );
diff --git a/sc/inc/refupdatecontext.hxx b/sc/inc/refupdatecontext.hxx
index c8e52d8..bd87792 100644
--- a/sc/inc/refupdatecontext.hxx
+++ b/sc/inc/refupdatecontext.hxx
@@ -130,6 +130,20 @@ struct RefUpdateMoveTabContext
     SCTAB getNewTab(SCTAB nOldTab) const;
 };
 
+struct SetFormulaDirtyContext
+{
+    SCTAB mnTabDeletedStart;
+    SCTAB mnTabDeletedEnd;
+
+    /**
+     * When true, go through all reference tokens and clears "sheet deleted"
+     * flag if its corresponding index falls within specified sheet range.
+     */
+    bool mbClearTabDeletedFlag;
+
+    SetFormulaDirtyContext();
+};
+
 }
 
 #endif
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index fd8fbdd..8cf0fb1 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -71,6 +71,7 @@ class DocumentStreamAccess;
 class CellValues;
 class RowHeightContext;
 class CompileFormulaContext;
+struct SetFormulaDirtyContext;
 
 }
 
@@ -512,7 +513,7 @@ public:
 
     void        ResetChanged( const ScRange& rRange );
 
-    void        SetDirty();
+    void SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt );
     void        SetDirty( const ScRange& );
     void        SetDirtyAfterLoad();
     void        SetDirtyVar();
diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx
index c151cdb..312e63a 100644
--- a/sc/inc/tokenarray.hxx
+++ b/sc/inc/tokenarray.hxx
@@ -168,6 +168,18 @@ public:
 
     sc::RefUpdateResult AdjustReferenceOnMovedTab( sc::RefUpdateMoveTabContext& rCxt, const ScAddress& rOldPos );
 
+    /**
+     * Clear sheet deleted flag from internal reference tokens if the sheet
+     * index falls within specified range.  Note that when a reference is on a
+     * sheet that's been deleted, its referenced sheet index retains the
+     * original index of the deleted sheet.
+     *
+     * @param rPos position of formula cell
+     * @param nStartTab index of first sheet, inclusive.
+     * @param nEndTab index of last sheet, inclusive.
+     */
+    void ClearTabDeleted( const ScAddress& rPos, SCTAB nStartTab, SCTAB nEndTab );
+
     void CheckRelativeReferenceBounds(
         const sc::RefUpdateContext& rCxt, const ScAddress& rPos, SCROW nGroupLen, std::vector<SCROW>& rBounds ) const;
 
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 200d088..1fa7120 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2959,11 +2959,23 @@ struct SetDirtyVarHandler
 class SetDirtyHandler
 {
     ScDocument& mrDoc;
+    const sc::SetFormulaDirtyContext& mrCxt;
 public:
-    SetDirtyHandler(ScDocument& rDoc) : mrDoc(rDoc) {}
+    SetDirtyHandler( ScDocument& rDoc, const sc::SetFormulaDirtyContext& rCxt ) :
+        mrDoc(rDoc), mrCxt(rCxt) {}
 
     void operator() (size_t /*nRow*/, ScFormulaCell* p)
     {
+        if (mrCxt.mbClearTabDeletedFlag)
+        {
+            if (!p->IsShared() || p->IsSharedTop())
+            {
+                ScTokenArray* pCode = p->GetCode();
+                pCode->ClearTabDeleted(
+                    p->aPos, mrCxt.mnTabDeletedStart, mrCxt.mnTabDeletedEnd);
+            }
+        }
+
         p->SetDirtyVar();
         if (!mrDoc.IsInFormulaTree(p))
             mrDoc.PutInFormulaTree(p);
@@ -3357,11 +3369,11 @@ bool ScColumn::IsFormulaDirty( SCROW nRow ) const
     return p->GetDirty();
 }
 
-void ScColumn::SetDirty()
+void ScColumn::SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt )
 {
     // is only done documentwide, no FormulaTracking
     sc::AutoCalcSwitch aSwitch(*pDocument, false);
-    SetDirtyHandler aFunc(*pDocument);
+    SetDirtyHandler aFunc(*pDocument, rCxt);
     sc::ProcessFormula(maCells, aFunc);
 }
 
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 3e4f8e4..c23ccc0 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -774,7 +774,9 @@ bool ScDocument::MoveTab( SCTAB nOldPos, SCTAB nNewPos, ScProgress* pProgress )
                     (*it)->StartAllListeners();
             // sheet names of references may not be valid until sheet is moved
             pChartListenerCollection->UpdateScheduledSeriesRanges();
-            SetDirty();
+
+            sc::SetFormulaDirtyContext aFormulaDirtyCxt;
+            SetAllFormulasDirty(aFormulaDirtyCxt);
 
             if (pDrawLayer)
                 DrawMovePage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
@@ -898,7 +900,8 @@ bool ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM
         pNewList->UpdateReference(aRefCxt);
         maTabs[nNewPos]->SetCondFormList( pNewList );
 
-        SetDirty();
+        sc::SetFormulaDirtyContext aCxt;
+        SetAllFormulasDirty(aCxt);
 
         if (pDrawLayer)
             DrawCopyPage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index b1aeefd..4dd1222 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -804,11 +804,11 @@ void ScDocument::CopyScenario( SCTAB nSrcTab, SCTAB nDestTab, bool bNewScenario
         maTabs[nSrcTab]->SetActiveScenario(true);       // da kommt's her...
         if (!bNewScenario)                          // Daten aus dem ausgewaehlten Szenario kopieren
         {
-            bool bOldAutoCalc = GetAutoCalc();
-            SetAutoCalc( false );   // Mehrfachberechnungen vermeiden
+            sc::AutoCalcSwitch aACSwitch(*this, false);
             maTabs[nSrcTab]->CopyScenarioTo( maTabs[nDestTab] );
-            SetDirty();
-            SetAutoCalc( bOldAutoCalc );
+
+            sc::SetFormulaDirtyContext aCxt;
+            SetAllFormulasDirty(aCxt);
         }
     }
 }
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 2ba1bf1..6ff1f7a 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -460,8 +460,8 @@ void ScDocument::InvalidateStreamOnSave()
     }
 }
 
-bool ScDocument::InsertTab( SCTAB nPos, const OUString& rName,
-            bool bExternalDocument )
+bool ScDocument::InsertTab(
+    SCTAB nPos, const OUString& rName, bool bExternalDocument, bool bUndoDeleteTab )
 {
     SCTAB   nTabCount = static_cast<SCTAB>(maTabs.size());
     bool    bValid = ValidTab(nTabCount);
@@ -471,6 +471,7 @@ bool ScDocument::InsertTab( SCTAB nPos, const OUString& rName,
     {
         if (nPos == SC_TAB_APPEND || nPos >= nTabCount)
         {
+            nPos = maTabs.size();
             maTabs.push_back( new ScTable(this, nTabCount, rName) );
             if ( bExternalDocument )
                 maTabs[nTabCount]->SetVisible( false );
@@ -538,7 +539,13 @@ bool ScDocument::InsertTab( SCTAB nPos, const OUString& rName,
     }
 
     if (bValid)
-        SetDirty();
+    {
+        sc::SetFormulaDirtyContext aCxt;
+        aCxt.mbClearTabDeletedFlag = bUndoDeleteTab;
+        aCxt.mnTabDeletedStart = nPos;
+        aCxt.mnTabDeletedEnd = nPos;
+        SetAllFormulasDirty(aCxt);
+    }
 
     return bValid;
 }
@@ -625,7 +632,10 @@ bool ScDocument::InsertTabs( SCTAB nPos, const std::vector<OUString>& rNames,
     }
 
     if (bValid)
-        SetDirty();
+    {
+        sc::SetFormulaDirtyContext aCxt;
+        SetAllFormulasDirty(aCxt);
+    }
 
     return bValid;
 }
@@ -702,7 +712,9 @@ bool ScDocument::DeleteTab( SCTAB nTab )
                     for (; it != maTabs.end(); ++it)
                         if ( *it )
                             (*it)->StartAllListeners();
-                    SetDirty();
+
+                    sc::SetFormulaDirtyContext aFormulaDirtyCxt;
+                    SetAllFormulasDirty(aFormulaDirtyCxt);
                 }
                 // sheet names of references are not valid until sheet is deleted
                 pChartListenerCollection->UpdateScheduledSeriesRanges();
@@ -791,7 +803,9 @@ bool ScDocument::DeleteTabs( SCTAB nTab, SCTAB nSheets )
                     for (; it != maTabs.end(); ++it)
                         if ( *it )
                             (*it)->StartAllListeners();
-                    SetDirty();
+
+                    sc::SetFormulaDirtyContext aFormulaDirtyCxt;
+                    SetAllFormulasDirty(aFormulaDirtyCxt);
                 }
                 // sheet names of references are not valid until sheet is deleted
                 pChartListenerCollection->UpdateScheduledSeriesRanges();
@@ -3590,7 +3604,7 @@ bool ScDocument::HasSelectionData( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
 }
 
 
-void ScDocument::SetDirty()
+void ScDocument::SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt )
 {
     bool bOldAutoCalc = GetAutoCalc();
     bAutoCalc = false;      // keine Mehrfachberechnung
@@ -3599,7 +3613,7 @@ void ScDocument::SetDirty()
         TableContainer::iterator it = maTabs.begin();
         for (;it != maTabs.end(); ++it)
             if (*it)
-                (*it)->SetDirty();
+                (*it)->SetAllFormulasDirty(rCxt);
     }
 
     //  Charts werden zwar auch ohne AutoCalc im Tracking auf Dirty gesetzt,
@@ -3705,7 +3719,9 @@ void ScDocument::CompileAll()
     for (; it != maTabs.end(); ++it)
         if (*it)
             (*it)->CompileAll(aCxt);
-    SetDirty();
+
+    sc::SetFormulaDirtyContext aFormulaDirtyCxt;
+    SetAllFormulasDirty(aFormulaDirtyCxt);
 }
 
 
diff --git a/sc/source/core/data/refupdatecontext.cxx b/sc/source/core/data/refupdatecontext.cxx
index ca550d1..8bf5298 100644
--- a/sc/source/core/data/refupdatecontext.cxx
+++ b/sc/source/core/data/refupdatecontext.cxx
@@ -94,6 +94,9 @@ SCTAB RefUpdateMoveTabContext::getNewTab(SCTAB nOldTab) const
     return nOldTab + 1;
 }
 
+SetFormulaDirtyContext::SetFormulaDirtyContext() :
+    mnTabDeletedStart(-1), mnTabDeletedEnd(-1), mbClearTabDeletedFlag(false) {}
+
 }
 
 
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 9320de2..a1e9bf1 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1659,13 +1659,12 @@ void ScTable::SetDirtyVar()
 }
 
 
-void ScTable::SetDirty()
+void ScTable::SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt )
 {
-    bool bOldAutoCalc = pDocument->GetAutoCalc();
-    pDocument->SetAutoCalc( false );    // Mehrfachberechnungen vermeiden
+    sc::AutoCalcSwitch aACSwitch(*pDocument, false);
+
     for (SCCOL i=0; i<=MAXCOL; i++)
-        aCol[i].SetDirty();
-    pDocument->SetAutoCalc( bOldAutoCalc );
+        aCol[i].SetAllFormulasDirty(rCxt);
 }
 
 
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 8057224..3856bac 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -3198,6 +3198,52 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnMovedTab( sc::RefUpdateMoveTa
 
 namespace {
 
+void clearTabDeletedFlag( ScSingleRefData& rRef, const ScAddress& rPos, SCTAB nStartTab, SCTAB nEndTab )
+{
+    if (!rRef.IsTabDeleted())
+        return;
+
+    ScAddress aAbs = rRef.toAbs(rPos);
+    if (nStartTab <=  aAbs.Tab() && aAbs.Tab() <= nEndTab)
+        rRef.SetTabDeleted(false);
+}
+
+}
+
+void ScTokenArray::ClearTabDeleted( const ScAddress& rPos, SCTAB nStartTab, SCTAB nEndTab )
+{
+    if (nEndTab < nStartTab)
+        return;
+
+    FormulaToken** p = pCode;
+    FormulaToken** pEnd = p + static_cast<size_t>(nLen);
+    for (; p != pEnd; ++p)
+    {
+        switch ((*p)->GetType())
+        {
+            case svSingleRef:
+            {
+                ScToken* pToken = static_cast<ScToken*>(*p);
+                ScSingleRefData& rRef = pToken->GetSingleRef();
+                clearTabDeletedFlag(rRef, rPos, nStartTab, nEndTab);
+            }
+            break;
+            case svDoubleRef:
+            {
+                ScToken* pToken = static_cast<ScToken*>(*p);
+                ScComplexRefData& rRef = pToken->GetDoubleRef();
+                clearTabDeletedFlag(rRef.Ref1, rPos, nStartTab, nEndTab);
+                clearTabDeletedFlag(rRef.Ref2, rPos, nStartTab, nEndTab);
+            }
+            break;
+            default:
+                ;
+        }
+    }
+}
+
+namespace {
+
 void checkBounds(
     const sc::RefUpdateContext& rCxt, const ScAddress& rPos, SCROW nGroupLen,
     const ScSingleRefData& rRef, std::vector<SCROW>& rBounds)
diff --git a/sc/source/ui/docshell/dbdocimp.cxx b/sc/source/ui/docshell/dbdocimp.cxx
index 3b8ee69..62e4e51 100644
--- a/sc/source/ui/docshell/dbdocimp.cxx
+++ b/sc/source/ui/docshell/dbdocimp.cxx
@@ -53,6 +53,7 @@
 #include "hints.hxx"
 #include "miscuno.hxx"
 #include "chgtrack.hxx"
+#include <refupdatecontext.hxx>
 
 using namespace com::sun::star;
 
@@ -626,7 +627,8 @@ bool ScDBDocFunc::DoImport( SCTAB nTab, const ScImportParam& rParam,
                                         pUndoDoc, pRedoDoc, pUndoDBData, pRedoDBData ) );
         }
 
-        pDoc->SetDirty();
+        sc::SetFormulaDirtyContext aCxt;
+        pDoc->SetAllFormulasDirty(aCxt);
         rDocShell.PostPaint(ScRange(0, 0, nTab, MAXCOL, MAXROW, nTab), PAINT_GRID);
         aModificator.SetDocumentModified();
 
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index b42162c..9d42671 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -121,6 +121,7 @@
 #include "orcusfilters.hxx"
 #include <datastream.hxx>
 #include <documentlinkmgr.hxx>
+#include <refupdatecontext.hxx>
 
 #include <config_telepathy.h>
 
@@ -1204,7 +1205,8 @@ sal_Bool ScDocShell::ConvertFrom( SfxMedium& rMedium )
                     bRet = aImpEx.ImportStream( *pInStream, rMedium.GetBaseURL() );
                     eError = bRet ? eERR_OK : SCERR_IMPORT_CONNECT;
                     aDocument.StartAllListeners();
-                    aDocument.SetDirty();
+                    sc::SetFormulaDirtyContext aCxt;
+                    aDocument.SetAllFormulasDirty(aCxt);
                     bOverflowRow = aImpEx.IsOverflowRow();
                     bOverflowCol = aImpEx.IsOverflowCol();
                     bOverflowCell = aImpEx.IsOverflowCell();
@@ -1322,7 +1324,8 @@ sal_Bool ScDocShell::ConvertFrom( SfxMedium& rMedium )
                     bRet = aImpEx.ImportStream( *pInStream, rMedium.GetBaseURL(), SOT_FORMATSTR_ID_SYLK );
                     eError = bRet ? eERR_OK : SCERR_IMPORT_UNKNOWN;
                     aDocument.StartAllListeners();
-                    aDocument.SetDirty();
+                    sc::SetFormulaDirtyContext aCxt;
+                    aDocument.SetAllFormulasDirty(aCxt);
                 }
                 else
                 {
@@ -1376,7 +1379,8 @@ sal_Bool ScDocShell::ConvertFrom( SfxMedium& rMedium )
                     else
                         bRet = sal_True;
                     aDocument.StartAllListeners();
-                    aDocument.SetDirty();
+                    sc::SetFormulaDirtyContext aCxt;
+                    aDocument.SetAllFormulasDirty(aCxt);
                     bSetColWidths = sal_True;
                     bSetRowHeights = sal_True;
                 }
@@ -1427,7 +1431,9 @@ sal_Bool ScDocShell::ConvertFrom( SfxMedium& rMedium )
                     else
                         bRet = sal_True;
                     aDocument.StartAllListeners();
-                    aDocument.SetDirty();
+
+                    sc::SetFormulaDirtyContext aCxt;
+                    aDocument.SetAllFormulasDirty(aCxt);
                 }
                 else
                 {
diff --git a/sc/source/ui/docshell/docsh5.cxx b/sc/source/ui/docshell/docsh5.cxx
index f3c9f39..5ad9284 100644
--- a/sc/source/ui/docshell/docsh5.cxx
+++ b/sc/source/ui/docshell/docsh5.cxx
@@ -52,6 +52,7 @@
 #include "sizedev.hxx"
 #include "clipparam.hxx"
 #include <rowheightcontext.hxx>
+#include <refupdatecontext.hxx>
 
 // defined in docfunc.cxx
 void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, const OUString& sModuleName, const OUString& sModuleSource );
@@ -694,7 +695,9 @@ void ScDocShell::UseScenario( SCTAB nTab, const OUString& rName, bool bRecord )
                 }
 
                 aDocument.CopyScenario( nSrcTab, nTab );
-                aDocument.SetDirty();
+
+                sc::SetFormulaDirtyContext aCxt;
+                aDocument.SetAllFormulasDirty(aCxt);
 
                 //  alles painten, weil in anderen Bereichen das aktive Szenario
                 //  geaendert sein kann
diff --git a/sc/source/ui/undo/refundo.cxx b/sc/source/ui/undo/refundo.cxx
index c87a1ee..623e7b6 100644
--- a/sc/source/ui/undo/refundo.cxx
+++ b/sc/source/ui/undo/refundo.cxx
@@ -31,6 +31,8 @@
 #include "dpobject.hxx"
 #include "areasave.hxx"
 #include "unoreflist.hxx"
+#include <scopetools.hxx>
+#include <refupdatecontext.hxx>
 
 ScRefUndoData::ScRefUndoData( const ScDocument* pDoc ) :
     pUnoRefs( NULL )
@@ -162,11 +164,11 @@ void ScRefUndoData::DoUndo( ScDocument* pDoc, bool bUndoRefFirst )
 
     if (pDBCollection || pRangeName)
     {
-        sal_Bool bOldAutoCalc = pDoc->GetAutoCalc();
-        pDoc->SetAutoCalc( false ); // Avoid multiple calculations
+        sc::AutoCalcSwitch aACSwitch(*pDoc, false);
         pDoc->CompileAll();
-        pDoc->SetDirty();
-        pDoc->SetAutoCalc( bOldAutoCalc );
+
+        sc::SetFormulaDirtyContext aCxt;
+        pDoc->SetAllFormulasDirty(aCxt);
     }
 
     if (pAreaLinks)
diff --git a/sc/source/ui/undo/undotab.cxx b/sc/source/ui/undo/undotab.cxx
index 7740bd8..6c9403e 100644
--- a/sc/source/ui/undo/undotab.cxx
+++ b/sc/source/ui/undo/undotab.cxx
@@ -315,7 +315,7 @@ void ScUndoDeleteTab::Undo()
     unsigned int i=0;
     ScDocument* pDoc = pDocShell->GetDocument();
 
-    sal_Bool bLink = false;
+    bool bLink = false;
     OUString aName;
 
     for(i=0; i<theTabs.size(); ++i)
@@ -323,8 +323,8 @@ void ScUndoDeleteTab::Undo()
         SCTAB nTab = theTabs[i];
         pRefUndoDoc->GetName( nTab, aName );
 
-        bDrawIsInUndo = sal_True;
-        sal_Bool bOk = pDoc->InsertTab( nTab, aName );
+        bDrawIsInUndo = true;
+        bool bOk = pDoc->InsertTab(nTab, aName, false, true);
         bDrawIsInUndo = false;
         if (bOk)
         {
@@ -338,7 +338,7 @@ void ScUndoDeleteTab::Undo()
                 pDoc->SetLink( nTab, pRefUndoDoc->GetLinkMode(nTab), pRefUndoDoc->GetLinkDoc(nTab),
                                      pRefUndoDoc->GetLinkFlt(nTab), pRefUndoDoc->GetLinkOpt(nTab),
                                      pRefUndoDoc->GetLinkTab(nTab), pRefUndoDoc->GetLinkRefreshDelay(nTab) );
-                bLink = sal_True;
+                bLink = true;
             }
 
             if ( pRefUndoDoc->IsScenario(nTab) )
diff --git a/sc/source/ui/view/spelldialog.cxx b/sc/source/ui/view/spelldialog.cxx
index 664be16..9c37e66 100644
--- a/sc/source/ui/view/spelldialog.cxx
+++ b/sc/source/ui/view/spelldialog.cxx
@@ -34,8 +34,7 @@
 #include "scmod.hxx"
 #include "editable.hxx"
 #include "undoblk.hxx"
-
-
+#include <refupdatecontext.hxx>
 
 SFX_IMPL_CHILDWINDOW_WITHID( ScSpellDialogChildWindow, SID_SPELL_DIALOG )
 
@@ -133,7 +132,10 @@ void ScSpellDialogChildWindow::Reset()
                 nOldCol, nOldRow, nTab, mxUndoDoc.release(),
                 nNewCol, nNewRow, nTab, mxRedoDoc.release(),
                 ScConversionParam( SC_CONVERSION_SPELLCHECK ) ) );
-            mpDoc->SetDirty();
+
+            sc::SetFormulaDirtyContext aCxt;
+            mpDoc->SetAllFormulasDirty(aCxt);
+
             mpDocShell->SetDocumentModified();
         }
 
diff --git a/sc/source/ui/view/viewfun4.cxx b/sc/source/ui/view/viewfun4.cxx
index b892b0e..1492e19 100644
--- a/sc/source/ui/view/viewfun4.cxx
+++ b/sc/source/ui/view/viewfun4.cxx
@@ -66,6 +66,7 @@
 #include "reffind.hxx"
 #include "compiler.hxx"
 #include "tokenarray.hxx"
+#include <refupdatecontext.hxx>
 
 #include <boost/scoped_ptr.hpp>
 
@@ -544,7 +545,10 @@ void ScViewFunc::DoSheetConversion( const ScConversionParam& rConvParam, bool bR
                         nCol, nRow, nTab, pUndoDoc,
                         nNewCol, nNewRow, nTab, pRedoDoc, rConvParam ) );
         }
-        pDoc->SetDirty();
+
+        sc::SetFormulaDirtyContext aCxt;
+        pDoc->SetAllFormulasDirty(aCxt);
+
         pDocSh->SetDocumentModified();
     }
     else
commit c9058f25e97b58a05eb25b7b769f6406423186b6
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Mar 12 17:39:38 2014 -0400

    fdo#75977: Write test for this.
    
    Change-Id: I96bd008759a2a06ffeea46f2b25b847bc895e9eb

diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 58dc083..d17c8f5 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -267,6 +267,7 @@ public:
     void testSharedFormulasDeleteColumns();
     void testSharedFormulasRefUpdateMoveSheets();
     void testSharedFormulasRefUpdateCopySheets();
+    void testSharedFormulasRefUpdateDeleteSheets();
     void testSharedFormulasCopyPaste();
     void testSharedFormulaInsertColumn();
     void testSharedFormulaMoveBlock();
@@ -441,6 +442,7 @@ public:
     CPPUNIT_TEST(testSharedFormulasDeleteColumns);
     CPPUNIT_TEST(testSharedFormulasRefUpdateMoveSheets);
     CPPUNIT_TEST(testSharedFormulasRefUpdateCopySheets);
+    CPPUNIT_TEST(testSharedFormulasRefUpdateDeleteSheets);
     CPPUNIT_TEST(testSharedFormulasCopyPaste);
     CPPUNIT_TEST(testSharedFormulaInsertColumn);
     CPPUNIT_TEST(testSharedFormulaMoveBlock);
diff --git a/sc/qa/unit/ucalc_sharedformula.cxx b/sc/qa/unit/ucalc_sharedformula.cxx
index 98d087d..eb7b598 100644
--- a/sc/qa/unit/ucalc_sharedformula.cxx
+++ b/sc/qa/unit/ucalc_sharedformula.cxx
@@ -819,6 +819,65 @@ void Test::testSharedFormulasRefUpdateCopySheets()
     m_pDoc->DeleteTab(0);
 }
 
+void Test::testSharedFormulasRefUpdateDeleteSheets()
+{
+    sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // make sure auto calc is on.
+
+    m_pDoc->InsertTab(0, "Sheet1");
+    m_pDoc->InsertTab(1, "Sheet2");
+
+    // Set values to B2:B4 on Sheet2.
+    m_pDoc->SetValue(ScAddress(1,1,1), 1.0);
+    m_pDoc->SetValue(ScAddress(1,2,1), 2.0);
+    m_pDoc->SetValue(ScAddress(1,3,1), 3.0);
+
+    // Set formulas in A1:A3 on Sheet1 that reference B2:B4 on Sheet2.
+    m_pDoc->SetString(ScAddress(0,0,0), "=Sheet2.B2");
+    m_pDoc->SetString(ScAddress(0,1,0), "=Sheet2.B3");
+    m_pDoc->SetString(ScAddress(0,2,0), "=Sheet2.B4");
+
+    // Check the formula results.
+    CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(0,0,0)));
+    CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(0,1,0)));
+    CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(0,2,0)));
+
+    if (!checkFormula(*m_pDoc, ScAddress(0,0,0), "Sheet2.B2"))
+        CPPUNIT_FAIL("Wrong formula");
+    if (!checkFormula(*m_pDoc, ScAddress(0,1,0), "Sheet2.B3"))
+        CPPUNIT_FAIL("Wrong formula");
+    if (!checkFormula(*m_pDoc, ScAddress(0,2,0), "Sheet2.B4"))
+        CPPUNIT_FAIL("Wrong formula");
+
+    // Delete Sheet2.
+    ScDocFunc& rFunc = getDocShell().GetDocFunc();
+    rFunc.DeleteTable(1, true, true);
+
+    if (!checkFormula(*m_pDoc, ScAddress(0,0,0), "#REF!.B2"))
+        CPPUNIT_FAIL("Wrong formula");
+    if (!checkFormula(*m_pDoc, ScAddress(0,1,0), "#REF!.B3"))
+        CPPUNIT_FAIL("Wrong formula");
+    if (!checkFormula(*m_pDoc, ScAddress(0,2,0), "#REF!.B4"))
+        CPPUNIT_FAIL("Wrong formula");
+
+    // Undo the deletion and make sure the formulas are back to the way they were.
+    SfxUndoManager* pUndoMgr = m_pDoc->GetUndoManager();
+    CPPUNIT_ASSERT(pUndoMgr);
+    pUndoMgr->Undo();
+
+    if (!checkFormula(*m_pDoc, ScAddress(0,0,0), "Sheet2.B2"))
+        CPPUNIT_FAIL("Wrong formula");
+    if (!checkFormula(*m_pDoc, ScAddress(0,1,0), "Sheet2.B3"))
+        CPPUNIT_FAIL("Wrong formula");
+    if (!checkFormula(*m_pDoc, ScAddress(0,2,0), "Sheet2.B4"))
+        CPPUNIT_FAIL("Wrong formula");
+
+    // TODO: We can't test redo yet as ScUndoDeleteTab::Redo() relies on
+    // view shell to do its thing.
+
+    m_pDoc->DeleteTab(1);
+    m_pDoc->DeleteTab(0);
+}
+
 void Test::testSharedFormulasCopyPaste()
 {
     m_pDoc->InsertTab(0, "Test");


More information about the Libreoffice-commits mailing list