include/svx/svdpagv.hxx                               |   10 ++++--
 sc/qa/unit/tiledrendering/data/invalidate-on-save.ods |binary
 sc/qa/unit/tiledrendering/tiledrendering.cxx          |   30 ++++++++++++++++++
 svx/source/svdraw/svdpagv.cxx                         |   17 +++++++---
 svx/source/svdraw/svdpntv.cxx                         |   15 ++-------
 5 files changed, 53 insertions(+), 19 deletions(-)

New commits:
commit 7ed159d9fc75de09fb581f6f338ba5ec0bb3292e
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Thu Jan 18 09:31:17 2024 +0000
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Fri Jan 19 12:59:41 2024 +0100

    cool#7769 Reduce unnecessary invalidations on calc save
    
    https://github.com/CollaboraOnline/online/issues/7769
    
    Reduce unnecessary invalidations. Don't invalidate windows
    if layer visibility didn't really change.
    
    Change-Id: Ic2abd78d60aea2e8676c8e56608cf51e941f5918
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162242
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/include/svx/svdpagv.hxx b/include/svx/svdpagv.hxx
index 777ca7d9b1b2..58354a3d8d50 100644
--- a/include/svx/svdpagv.hxx
+++ b/include/svx/svdpagv.hxx
@@ -102,7 +102,8 @@ public:
 private:
     void ImpInvalidateHelpLineArea(sal_uInt16 nNum) const;
 
-    void SetLayer(const OUString& rName, SdrLayerIDSet& rBS, bool bJa);
+    // return true if changed, false if unchanged
+    bool SetLayer(const OUString& rName, SdrLayerIDSet& rBS, bool bJa);
     bool IsLayer(const OUString& rName, const SdrLayerIDSet& rBS) const;
 
     /// Let's see if the current Group (pCurrentGroup) is still inserted
@@ -182,10 +183,13 @@ public:
     tools::Rectangle& MarkBound() { return aMarkBound; }
     tools::Rectangle& MarkSnap() { return aMarkSnap; }
 
-    void SetLayerVisible(const OUString& rName, bool bShow) {
-        SetLayer(rName, aLayerVisi, bShow);
+    bool SetLayerVisible(const OUString& rName, bool bShow) {
+        const bool bChanged = SetLayer(rName, aLayerVisi, bShow);
+        if (!bChanged)
+            return false;
         if(!bShow) AdjHdl();
         InvalidateAllWin();
+        return true;
     }
     bool IsLayerVisible(const OUString& rName) const { return IsLayer(rName, 
aLayerVisi); }
 
diff --git a/sc/qa/unit/tiledrendering/data/invalidate-on-save.ods 
b/sc/qa/unit/tiledrendering/data/invalidate-on-save.ods
new file mode 100644
index 000000000000..efe2c225a410
Binary files /dev/null and 
b/sc/qa/unit/tiledrendering/data/invalidate-on-save.ods differ
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx 
b/sc/qa/unit/tiledrendering/tiledrendering.cxx
index 5c51046de950..44c15e18e1da 100644
--- a/sc/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx
@@ -3324,6 +3324,36 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, 
testInvalidateForSplitPanes)
     CPPUNIT_ASSERT_MESSAGE("The cell visible in the bottom left pane should be 
redrawn", bFoundBottomLeftPane);
 }
 
+// Saving shouldn't trigger an invalidation
+CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testNoInvalidateOnSave)
+{
+    comphelper::LibreOfficeKit::setCompatFlag(
+        comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs);
+
+    loadFromFile(u"invalidate-on-save.ods");
+
+    // .uno:Save modifies the original file, make a copy first
+    saveAndReload("calc8");
+    ScModelObj* pModelObj = 
comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
+    CPPUNIT_ASSERT(pModelObj);
+    
pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
+
+    ScTabViewShell* pView = 
dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
+    CPPUNIT_ASSERT(pView);
+
+    Scheduler::ProcessEventsToIdle();
+
+    // track invalidations
+    ViewCallback aView;
+
+    uno::Sequence<beans::PropertyValue> aArgs;
+    dispatchCommand(mxComponent, ".uno:Save", aArgs);
+
+    Scheduler::ProcessEventsToIdle();
+
+    CPPUNIT_ASSERT(!aView.m_bInvalidateTiles);
+}
+
 CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testStatusBarLocale)
 {
     // Given 2 views, the second's locale is set to German:
diff --git a/svx/source/svdraw/svdpagv.cxx b/svx/source/svdraw/svdpagv.cxx
index 86210865e72c..4e5d7a47286c 100644
--- a/svx/source/svdraw/svdpagv.cxx
+++ b/svx/source/svdraw/svdpagv.cxx
@@ -557,15 +557,22 @@ void SdrPageView::AdjHdl()
     GetView().AdjustMarkHdl();
 }
 
-void SdrPageView::SetLayer(const OUString& rName, SdrLayerIDSet& rBS, bool bJa)
+// return true if changed, false if unchanged
+bool SdrPageView::SetLayer(const OUString& rName, SdrLayerIDSet& rBS, bool bJa)
 {
-    if(!GetPage())
-        return;
+    if (!GetPage())
+        return false;
 
     SdrLayerID nID = GetPage()->GetLayerAdmin().GetLayerID(rName);
 
-    if(SDRLAYER_NOTFOUND != nID)
-        rBS.Set(nID, bJa);
+    if (SDRLAYER_NOTFOUND == nID)
+        return false;
+
+    if (rBS.IsSet(nID) == bJa)
+        return false;
+
+    rBS.Set(nID, bJa);
+    return true;
 }
 
 bool SdrPageView::IsLayer(const OUString& rName, const SdrLayerIDSet& rBS) 
const
diff --git a/svx/source/svdraw/svdpntv.cxx b/svx/source/svdraw/svdpntv.cxx
index ae8a968d1dc8..86535232d288 100644
--- a/svx/source/svdraw/svdpntv.cxx
+++ b/svx/source/svdraw/svdpntv.cxx
@@ -414,22 +414,15 @@ void 
SdrPaintView::DeleteDeviceFromPaintView(OutputDevice& rOldDev)
 
 void SdrPaintView::SetLayerVisible(const OUString& rName, bool bShow)
 {
-    if(mpPageView)
-    {
-        mpPageView->SetLayerVisible(rName, bShow);
-    }
-
+    const bool bChanged = mpPageView && mpPageView->SetLayerVisible(rName, 
bShow);
+    if (!bChanged)
+        return;
     InvalidateAllWin();
 }
 
 bool SdrPaintView::IsLayerVisible(const OUString& rName) const
 {
-    if(mpPageView)
-    {
-        return mpPageView->IsLayerVisible(rName);
-    }
-
-    return false;
+    return mpPageView && mpPageView->IsLayerVisible(rName);
 }
 
 void SdrPaintView::SetLayerLocked(const OUString& rName, bool bLock)

Reply via email to