sc/source/ui/docshell/docfunc.cxx |   25 +++++--------------------
 sc/source/ui/inc/undoblk.hxx      |    6 ++++--
 sc/source/ui/undo/undoblk.cxx     |   26 +++++++++++++++++++++-----
 3 files changed, 30 insertions(+), 27 deletions(-)

New commits:
commit c2979145899db161e2659d69ad2f478123254694
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Sun Mar 17 13:31:42 2024 +0500
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon Mar 18 20:45:23 2024 +0100

    tdf#160149: save and restore the whole set of tab's conditional formats
    
    ... instead of restoring it only for a range, and then have troubles
    deciding how to join the range's formatting with the rest of tab's
    formatting.
    
    Change-Id: Ie422893c7847b1473a86c0cd8fc3916144eb24ae
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164937
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    (cherry picked from commit c492de66a077f3a2a960209b0b8b278b3901f361)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164886
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sc/source/ui/docshell/docfunc.cxx 
b/sc/source/ui/docshell/docfunc.cxx
index 1a8d902bea19..4c333b0502a0 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -5611,26 +5611,12 @@ void ScDocFunc::ReplaceConditionalFormat( sal_uLong 
nOldFormat, std::unique_ptr<
     bool bUndo = rDoc.IsUndoEnabled();
     ScDocumentUniquePtr pUndoDoc;
     ScRange aCombinedRange = rRanges.Combine();
-    ScRange aCompleteRange;
     if(bUndo)
     {
         pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
         pUndoDoc->InitUndo( rDoc, nTab, nTab );
-
-        if(pFormat)
-        {
-            aCompleteRange = aCombinedRange;
-        }
-        if(nOldFormat)
-        {
-            ScConditionalFormat* pOldFormat = 
rDoc.GetCondFormList(nTab)->GetFormat(nOldFormat);
-            if(pOldFormat)
-                aCompleteRange.ExtendTo(pOldFormat->GetRange().Combine());
-        }
-
-        
rDoc.CopyToDocument(aCompleteRange.aStart.Col(),aCompleteRange.aStart.Row(),nTab,
-                            
aCompleteRange.aEnd.Col(),aCompleteRange.aEnd.Row(),nTab,
-                            InsertDeleteFlags::ALL, false, *pUndoDoc);
+        if (const auto* pList = rDoc.GetCondFormList(nTab))
+            pUndoDoc->SetCondFormList(new ScConditionalFormatList(*pUndoDoc, 
*pList), nTab);
     }
 
     std::unique_ptr<ScRange> pRepaintRange;
@@ -5663,11 +5649,10 @@ void ScDocFunc::ReplaceConditionalFormat( sal_uLong 
nOldFormat, std::unique_ptr<
     {
         ScDocumentUniquePtr pRedoDoc(new ScDocument(SCDOCMODE_UNDO));
         pRedoDoc->InitUndo( rDoc, nTab, nTab );
-        
rDoc.CopyToDocument(aCompleteRange.aStart.Col(),aCompleteRange.aStart.Row(),nTab,
-                            
aCompleteRange.aEnd.Col(),aCompleteRange.aEnd.Row(),nTab,
-                            InsertDeleteFlags::ALL, false, *pRedoDoc);
+        if (const auto* pList = rDoc.GetCondFormList(nTab))
+            pRedoDoc->SetCondFormList(new ScConditionalFormatList(*pRedoDoc, 
*pList), nTab);
         rDocShell.GetUndoManager()->AddUndoAction(
-                std::make_unique<ScUndoConditionalFormat>(&rDocShell, 
std::move(pUndoDoc), std::move(pRedoDoc), aCompleteRange));
+                std::make_unique<ScUndoConditionalFormat>(&rDocShell, 
std::move(pUndoDoc), std::move(pRedoDoc), nTab));
     }
 
     if(pRepaintRange)
diff --git a/sc/source/ui/inc/undoblk.hxx b/sc/source/ui/inc/undoblk.hxx
index 9bda36a1e176..c6cb432d8e24 100644
--- a/sc/source/ui/inc/undoblk.hxx
+++ b/sc/source/ui/inc/undoblk.hxx
@@ -613,11 +613,13 @@ private:
     void            DoChange( ScDocument* pSrcDoc ) const;
 };
 
+// This class only uses conditional format lists in the undo/redo documents;
+// no other tab data is needed in the documents
 class ScUndoConditionalFormat : public ScSimpleUndo
 {
 public:
     ScUndoConditionalFormat( ScDocShell* pNewDocShell,
-            ScDocumentUniquePtr pUndoDoc, ScDocumentUniquePtr pRedoDoc, const 
ScRange& rRange);
+            ScDocumentUniquePtr pUndoDoc, ScDocumentUniquePtr pRedoDoc, SCTAB 
nTab);
     virtual         ~ScUndoConditionalFormat() override;
 
     virtual void    Undo() override;
@@ -631,7 +633,7 @@ private:
     void DoChange(ScDocument* pDoc);
     ScDocumentUniquePtr mpUndoDoc;
     ScDocumentUniquePtr mpRedoDoc;
-    ScRange maRange;
+    SCTAB mnTab;
 };
 
 class ScUndoConditionalFormatList : public ScSimpleUndo
diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx
index d352ba143ba8..c74d23f6e7a7 100644
--- a/sc/source/ui/undo/undoblk.cxx
+++ b/sc/source/ui/undo/undoblk.cxx
@@ -1563,11 +1563,11 @@ bool ScUndoListNames::CanRepeat(SfxRepeatTarget& 
rTarget) const
 }
 
 ScUndoConditionalFormat::ScUndoConditionalFormat(ScDocShell* pNewDocShell,
-        ScDocumentUniquePtr pUndoDoc, ScDocumentUniquePtr pRedoDoc, const 
ScRange& rRange):
+        ScDocumentUniquePtr pUndoDoc, ScDocumentUniquePtr pRedoDoc, SCTAB 
nTab):
     ScSimpleUndo( pNewDocShell ),
     mpUndoDoc(std::move(pUndoDoc)),
     mpRedoDoc(std::move(pRedoDoc)),
-    maRange(rRange)
+    mnTab(nTab)
 {
 }
 
@@ -1594,9 +1594,25 @@ void ScUndoConditionalFormat::DoChange(ScDocument* 
pSrcDoc)
 {
     ScDocument& rDoc = pDocShell->GetDocument();
 
-    rDoc.DeleteAreaTab( maRange, InsertDeleteFlags::ALL );
-    pSrcDoc->CopyToDocument(maRange, InsertDeleteFlags::ALL, false, rDoc);
-    pDocShell->PostPaint( maRange, PaintPartFlags::Grid );
+    // Restore all conditional formats in the tab. This is simpler and more 
reliable, than
+    // restoring formats in a specific range, and then trying to join 
selectively the restored
+    // formats with the other formats in the tab, to get the correct state.
+    ScRangeList aCombinedRange;
+    if (const auto* pOldList = rDoc.GetCondFormList(mnTab))
+        aCombinedRange = pOldList->GetCombinedRange();
+
+    if (const auto* pNewList = pSrcDoc->GetCondFormList(mnTab))
+    {
+        for (const auto& cond : *pNewList)
+            for (const auto& range : cond->GetRange())
+                aCombinedRange.Join(range);
+        rDoc.SetCondFormList(new ScConditionalFormatList(rDoc, *pNewList), 
mnTab);
+    }
+    else
+    {
+        rDoc.SetCondFormList(nullptr, mnTab);
+    }
+    pDocShell->PostPaint(aCombinedRange, PaintPartFlags::Grid);
     pDocShell->PostDataChanged();
     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
     if (pViewShell)

Reply via email to