[Libreoffice-commits] core.git: Branch 'libreoffice-7-2' - sc/inc sc/qa sc/source

Tünde Tóth (via logerrit) logerrit at kemper.freedesktop.org
Tue Aug 17 14:02:56 UTC 2021


 sc/inc/dbdata.hxx                |    8 ++--
 sc/qa/unit/uicalc/uicalc.cxx     |   26 +++++++++++++
 sc/source/core/tool/dbdata.cxx   |   77 ++++++++++++++++++---------------------
 sc/source/core/tool/refupdat.cxx |   10 ++++-
 4 files changed, 74 insertions(+), 47 deletions(-)

New commits:
commit 957d1e977d25385151c99e401124ad58217e53dd
Author:     Tünde Tóth <toth.tunde at nisz.hu>
AuthorDate: Wed Jul 21 16:04:37 2021 +0200
Commit:     Xisco Fauli <xiscofauli at libreoffice.org>
CommitDate: Tue Aug 17 16:02:17 2021 +0200

    tdf#126926 sc DBData: delete the database range
    
    if some part of the reference became invalid.
    
    Change-Id: I4b10af46e92a0a1ba9b6eb5e49df1d3f9a4be6a4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119354
    Tested-by: Jenkins
    Reviewed-by: Eike Rathke <erack at redhat.com>
    (cherry picked from commit 0c0444c44107f1a18f23dd0833d462d8dbf56569)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120235
    Reviewed-by: Xisco Fauli <xiscofauli at libreoffice.org>

diff --git a/sc/inc/dbdata.hxx b/sc/inc/dbdata.hxx
index c1e714fc3e9f..8ecd2faf602f 100644
--- a/sc/inc/dbdata.hxx
+++ b/sc/inc/dbdata.hxx
@@ -208,10 +208,9 @@ public:
     void        SetModified(bool bMod)      { bModified = bMod; }
 
     void    UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );
-    void    UpdateReference(const ScDocument* pDoc, UpdateRefMode eUpdateRefMode,
-                        SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
-                        SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
-                        SCCOL nDx, SCROW nDy, SCTAB nDz);
+    bool    UpdateReference(const ScDocument* pDoc, UpdateRefMode eUpdateRefMode, SCCOL nCol1,
+                            SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
+                            SCCOL nDx, SCROW nDy, SCTAB nDz);
 
     void ExtendDataArea(const ScDocument& rDoc);
     void CalcSaveFilteredCount(SCSIZE nNonFilteredRowCount);
@@ -296,6 +295,7 @@ public:
         void deleteOnTab(SCTAB nTab);
         ScDBData* getByRange(const ScRange& rRange);
         void insert(ScDBData* p);
+        void erase(const iterator& itr);
         bool empty() const;
         bool has( const ScDBData* p ) const;
         bool operator== (const AnonDBs& r) const;
diff --git a/sc/qa/unit/uicalc/uicalc.cxx b/sc/qa/unit/uicalc/uicalc.cxx
index 432d4d600771..7e089d16dc82 100644
--- a/sc/qa/unit/uicalc/uicalc.cxx
+++ b/sc/qa/unit/uicalc/uicalc.cxx
@@ -1675,6 +1675,32 @@ CPPUNIT_TEST_FIXTURE(ScUiCalcTest, testTdf126540_GridToggleModifiesTheDocument)
     CPPUNIT_ASSERT(pDocSh->IsModified());
 }
 
+CPPUNIT_TEST_FIXTURE(ScUiCalcTest, testTdf126926)
+{
+    mxComponent = loadFromDesktop("private:factory/scalc");
+    ScModelObj* pModelObj = dynamic_cast<ScModelObj*>(mxComponent.get());
+    CPPUNIT_ASSERT(pModelObj);
+    ScDocument* pDoc = pModelObj->GetDocument();
+    CPPUNIT_ASSERT(pDoc);
+
+    insertStringToCell(*pModelObj, "A1", "1");
+    insertStringToCell(*pModelObj, "A2", "2");
+    insertStringToCell(*pModelObj, "B1", "3");
+    insertStringToCell(*pModelObj, "B2", "4");
+
+    ScDBData* pDBData = new ScDBData("testDB", 0, 0, 0, 1, 1);
+    bool bInserted
+        = pDoc->GetDBCollection()->getNamedDBs().insert(std::unique_ptr<ScDBData>(pDBData));
+    CPPUNIT_ASSERT(bInserted);
+
+    goToCell("A1:B1");
+
+    dispatchCommand(mxComponent, ".uno:DeleteColumns", {});
+
+    ScDBCollection* pDBs = pDoc->GetDBCollection();
+    CPPUNIT_ASSERT(pDBs->empty());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx
index ba68d1aa0d8a..4e38b2aaa676 100644
--- a/sc/source/core/tool/dbdata.cxx
+++ b/sc/source/core/tool/dbdata.cxx
@@ -586,7 +586,7 @@ void ScDBData::UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos)
 
 }
 
-void ScDBData::UpdateReference(const ScDocument* pDoc, UpdateRefMode eUpdateRefMode,
+bool ScDBData::UpdateReference(const ScDocument* pDoc, UpdateRefMode eUpdateRefMode,
                                 SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
                                 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
                                 SCCOL nDx, SCROW nDy, SCTAB nDz)
@@ -601,10 +601,13 @@ void ScDBData::UpdateReference(const ScDocument* pDoc, UpdateRefMode eUpdateRefM
     theTab2 = theTab1;
     SCCOL nOldCol1 = theCol1, nOldCol2 = theCol2;
 
-    bool bDoUpdate = ScRefUpdate::Update( pDoc, eUpdateRefMode,
-                                            nCol1,nRow1,nTab1, nCol2,nRow2,nTab2, nDx,nDy,nDz,
-                                            theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 ) != UR_NOTHING;
-    if (bDoUpdate)
+    ScRefUpdateRes eRet
+        = ScRefUpdate::Update(pDoc, eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx,
+                              nDy, nDz, theCol1, theRow1, theTab1, theCol2, theRow2, theTab2);
+
+    bool bDoUpdate = eRet != UR_NOTHING;
+
+    if (bDoUpdate && eRet != UR_INVALID)
     {
         // MoveTo() invalidates column names via SetArea(); adjust, remember and set new.
         AdjustTableColumnNames( eUpdateRefMode, nDx, nCol1, nOldCol1, nOldCol2, theCol1, theCol2);
@@ -639,6 +642,8 @@ void ScDBData::UpdateReference(const ScDocument* pDoc, UpdateRefMode eUpdateRefM
 
     SetModified(bDoUpdate);
 
+    return eRet == UR_INVALID;
+
     //TODO: check if something was deleted/inserted with-in the range !!!
 }
 
@@ -978,36 +983,6 @@ public:
     }
 };
 
-class UpdateRefFunc
-{
-    ScDocument* mpDoc;
-    UpdateRefMode meMode;
-    SCCOL mnCol1;
-    SCROW mnRow1;
-    SCTAB mnTab1;
-    SCCOL mnCol2;
-    SCROW mnRow2;
-    SCTAB mnTab2;
-    SCCOL mnDx;
-    SCROW mnDy;
-    SCTAB mnDz;
-
-public:
-    UpdateRefFunc(ScDocument* pDoc, UpdateRefMode eMode,
-                    SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
-                    SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
-                    SCCOL nDx, SCROW nDy, SCTAB nDz) :
-        mpDoc(pDoc), meMode(eMode),
-        mnCol1(nCol1), mnRow1(nRow1), mnTab1(nTab1),
-        mnCol2(nCol2), mnRow2(nRow2), mnTab2(nTab2),
-        mnDx(nDx), mnDy(nDy), mnDz(nDz) {}
-
-    void operator() (std::unique_ptr<ScDBData> const& p)
-    {
-        p->UpdateReference(mpDoc, meMode, mnCol1, mnRow1, mnTab1, mnCol2, mnRow2, mnTab2, mnDx, mnDy, mnDz);
-    }
-};
-
 class UpdateMoveTabFunc
 {
     SCTAB mnOldTab;
@@ -1281,6 +1256,10 @@ void ScDBCollection::AnonDBs::insert(ScDBData* p)
     m_DBs.push_back(std::unique_ptr<ScDBData>(p));
 }
 
+void ScDBCollection::AnonDBs::erase(const iterator& itr) {
+    m_DBs.erase(itr);
+}
+
 bool ScDBCollection::AnonDBs::empty() const
 {
     return m_DBs.empty();
@@ -1466,9 +1445,10 @@ void ScDBCollection::UpdateReference(UpdateRefMode eUpdateRefMode,
     {
         if (nTab1 == nTab2 && nDz == 0)
         {
-            pData->UpdateReference(
-                &rDoc, eUpdateRefMode,
-                nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz);
+            // Delete the database range, if some part of the reference became invalid.
+            if (pData->UpdateReference(&rDoc, eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2,
+                                       nTab2, nDx, nDy, nDz))
+                rDoc.SetAnonymousDBData(nTab1, nullptr);
         }
         else
         {
@@ -1476,9 +1456,24 @@ void ScDBCollection::UpdateReference(UpdateRefMode eUpdateRefMode,
         }
     }
 
-    UpdateRefFunc func(&rDoc, eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz);
-    for_each(maNamedDBs.begin(), maNamedDBs.end(), func);
-    for_each(maAnonDBs.begin(), maAnonDBs.end(), func);
+    for (auto it = maNamedDBs.begin(); it != maNamedDBs.end(); )
+    {
+        // Delete the database range, if some part of the reference became invalid.
+        if (it->get()->UpdateReference(&rDoc, eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2,
+                                       nTab2, nDx, nDy, nDz))
+            maNamedDBs.erase(it++);
+        else
+            ++it;
+    }
+    for (auto it = maAnonDBs.begin(); it != maAnonDBs.end(); )
+    {
+        // Delete the database range, if some part of the reference became invalid.
+        if (it->get()->UpdateReference(&rDoc, eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2,
+                                       nTab2, nDx, nDy, nDz))
+            maAnonDBs.erase(it++);
+        else
+            ++it;
+    }
 }
 
 void ScDBCollection::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
diff --git a/sc/source/core/tool/refupdat.cxx b/sc/source/core/tool/refupdat.cxx
index 80229cf03dde..a0c3fe31716d 100644
--- a/sc/source/core/tool/refupdat.cxx
+++ b/sc/source/core/tool/refupdat.cxx
@@ -53,12 +53,12 @@ static bool lcl_MoveEnd( R& rRef, U nStart, S nDelta, U nMask )
         rRef = sal::static_int_cast<R>( rRef + nDelta );
     else if ( nDelta < 0 && rRef >= nStart + nDelta )
         rRef = nStart + nDelta - 1;         //TODO: limit ???
-    if ( rRef < 0 )
+    if (rRef < 0)
     {
         rRef = 0;
         bCut = true;
     }
-    else if ( rRef > nMask )
+    else if(rRef > nMask)
     {
         rRef = nMask;
         bCut = true;
@@ -217,6 +217,8 @@ ScRefUpdateRes ScRefUpdate::Update( const ScDocument* pDoc, UpdateRefMode eUpdat
                 eRet = UR_INVALID;
                 theCol2 = theCol1;
             }
+            else if (bCut2 && theCol2 == 0)
+                eRet = UR_INVALID;
             else if ( bCut1 || bCut2 )
                 eRet = UR_UPDATED;
             if ( bExp )
@@ -251,6 +253,8 @@ ScRefUpdateRes ScRefUpdate::Update( const ScDocument* pDoc, UpdateRefMode eUpdat
                 eRet = UR_INVALID;
                 theRow2 = theRow1;
             }
+            else if (bCut2 && theRow2 == 0)
+                eRet = UR_INVALID;
             else if ( bCut1 || bCut2 )
                 eRet = UR_UPDATED;
             if ( bExp )
@@ -287,6 +291,8 @@ ScRefUpdateRes ScRefUpdate::Update( const ScDocument* pDoc, UpdateRefMode eUpdat
                 eRet = UR_INVALID;
                 theTab2 = theTab1;
             }
+            else if (bCut2 && theTab2 == 0)
+                eRet = UR_INVALID;
             else if ( bCut1 || bCut2 )
                 eRet = UR_UPDATED;
             if ( bExp )


More information about the Libreoffice-commits mailing list