sc/inc/conditio.hxx               |    5 +++
 sc/inc/globstr.hrc                |    4 +-
 sc/qa/unit/ucalc.hxx              |    3 +
 sc/qa/unit/ucalc_condformat.cxx   |   41 +++++++++++++++++++++++++
 sc/source/core/data/conditio.cxx  |   37 +++++++++++++++++++++++
 sc/source/ui/docshell/docfunc.cxx |   36 +++++++++++++++++-----
 sc/source/ui/inc/undoblk.hxx      |   21 +++++++++++++
 sc/source/ui/src/globstr.src      |    5 +++
 sc/source/ui/undo/undoblk.cxx     |   60 ++++++++++++++++++++++++++++++++++++++
 9 files changed, 203 insertions(+), 9 deletions(-)

New commits:
commit 55f81ec93752a0b6f7ee2356db3c8d73d550d1e6
Author: Markus Mohrhard <markus.mohrh...@googlemail.com>
Date:   Sat Apr 8 20:29:45 2017 +0200

    add test for tdf#95617
    
    Change-Id: I8acab5af4dfc8f058eb9624abafe63e212ddb437
    Reviewed-on: https://gerrit.libreoffice.org/36296
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Markus Mohrhard <markus.mohrh...@googlemail.com>

diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index d616f8cb5b9b..de92fe9245ce 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -499,6 +499,8 @@ public:
     void testCondFormatEndsWithStr();
     void testCondFormatEndsWithVal();
 
+    void testCondFormatUndoList();
+
     void testImportStream();
     void testDeleteContents();
     void testTransliterateText();
@@ -762,6 +764,7 @@ public:
     CPPUNIT_TEST(testCondFormatEndsWithVal);
     CPPUNIT_TEST(testCondFormatUpdateReferenceDelRow);
     CPPUNIT_TEST(testCondFormatUpdateReferenceInsRow);
+    CPPUNIT_TEST(testCondFormatUndoList);
     CPPUNIT_TEST(testIconSet);
     CPPUNIT_TEST(testDataBarLengthAutomaticAxis);
     CPPUNIT_TEST(testDataBarLengthMiddleAxis);
diff --git a/sc/qa/unit/ucalc_condformat.cxx b/sc/qa/unit/ucalc_condformat.cxx
index 391766f9f146..c3fe3ed3afcf 100644
--- a/sc/qa/unit/ucalc_condformat.cxx
+++ b/sc/qa/unit/ucalc_condformat.cxx
@@ -980,4 +980,45 @@ void Test::testCondFormatUpdateReferenceInsRow()
     m_pDoc->DeleteTab(0);
 }
 
+void Test::testCondFormatUndoList()
+{
+    m_pDoc->InsertTab(0, "test");
+
+    ScConditionEntry* pEntry = new ScConditionEntry(SC_COND_EQUAL, "B6", "", 
m_pDoc, ScAddress(0, 5, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, 
formula::FormulaGrammar::GRAM_DEFAULT);
+
+    ScConditionalFormat* pFormat = new ScConditionalFormat(0, m_pDoc);
+    pFormat->AddEntry(pEntry);
+    pFormat->SetRange(ScRange(0, 0, 0, 0, 5, 0));
+    m_pDoc->AddCondFormat(pFormat, 0);
+    m_pDoc->AddCondFormatData(pFormat->GetRange(), 0, pFormat->GetKey());
+
+    ScDocFunc& rFunc = getDocShell().GetDocFunc();
+
+    CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc->GetCondFormList(0)->size());
+    for (SCROW nRow = 0; nRow <= 5; ++nRow)
+        CPPUNIT_ASSERT(m_pDoc->GetCondFormat(0, nRow, 0));
+
+    ScConditionalFormatList* pNewList = new ScConditionalFormatList();
+
+    rFunc.SetConditionalFormatList(pNewList, 0);
+
+    CPPUNIT_ASSERT_EQUAL(size_t(0), m_pDoc->GetCondFormList(0)->size());
+    for (SCROW nRow = 0; nRow <= 5; ++nRow)
+        CPPUNIT_ASSERT(!m_pDoc->GetCondFormat(0, nRow, 0));
+
+    m_pDoc->GetUndoManager()->Undo();
+
+    CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc->GetCondFormList(0)->size());
+    for (SCROW nRow = 0; nRow <= 5; ++nRow)
+        CPPUNIT_ASSERT(m_pDoc->GetCondFormat(0, nRow, 0));
+
+    m_pDoc->GetUndoManager()->Redo();
+
+    CPPUNIT_ASSERT_EQUAL(size_t(0), m_pDoc->GetCondFormList(0)->size());
+    for (SCROW nRow = 0; nRow <= 5; ++nRow)
+        CPPUNIT_ASSERT(!m_pDoc->GetCondFormat(0, nRow, 0));
+
+    m_pDoc->DeleteTab(0);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit effa6dcb553bd3fc6df89ac88604816feda98873
Author: Markus Mohrhard <markus.mohrh...@googlemail.com>
Date:   Sat Apr 8 19:57:04 2017 +0200

    support undo of whole conditional format list, tdf#95617
    
    Change-Id: I3ff0ddb05f794064e33164c60cd1b4e6b89dbcca
    Reviewed-on: https://gerrit.libreoffice.org/36295
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Markus Mohrhard <markus.mohrh...@googlemail.com>

diff --git a/sc/inc/conditio.hxx b/sc/inc/conditio.hxx
index bba11bc12378..631d0449cc13 100644
--- a/sc/inc/conditio.hxx
+++ b/sc/inc/conditio.hxx
@@ -511,6 +511,11 @@ public:
     typedef ConditionalFormatContainer::iterator iterator;
     typedef ConditionalFormatContainer::const_iterator const_iterator;
 
+    ScRangeList GetCombinedRange() const;
+
+    void RemoveFromDocument(ScDocument* pDoc) const;
+    void AddToDocument(ScDocument* pDoc) const;
+
     iterator begin();
     const_iterator begin() const;
     iterator end();
diff --git a/sc/inc/globstr.hrc b/sc/inc/globstr.hrc
index 793b59c9e24b..6696945b7b23 100644
--- a/sc/inc/globstr.hrc
+++ b/sc/inc/globstr.hrc
@@ -662,7 +662,9 @@
 
 #define STR_QUERY_PIVOTTABLE_DELTAB     535
 
-#define SC_GLOBSTR_STR_COUNT            536     /**< the count of permanently 
resident strings */
+#define STR_UNDO_CONDFORMAT_LIST        536
+
+#define SC_GLOBSTR_STR_COUNT            537     /**< the count of permanently 
resident strings */
 
 #endif
 
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index a692f27807d5..a2b2f1886b60 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -2245,6 +2245,43 @@ ScConditionalFormatList::const_iterator 
ScConditionalFormatList::end() const
     return m_ConditionalFormats.end();
 }
 
+ScRangeList ScConditionalFormatList::GetCombinedRange() const
+{
+    ScRangeList aRange;
+    for (auto& itr: m_ConditionalFormats)
+    {
+        const ScRangeList& rRange = itr->GetRange();
+        for (size_t i = 0, n = rRange.size(); i < n; ++i)
+        {
+            if (rRange[i])
+                aRange.Join(*rRange[i]);
+        }
+    }
+    return aRange;
+}
+
+void ScConditionalFormatList::RemoveFromDocument(ScDocument* pDoc) const
+{
+    ScRangeList aRange = GetCombinedRange();
+    ScMarkData aMark;
+    aMark.MarkFromRangeList(aRange, true);
+    sal_uInt16 pItems[2] = { ATTR_CONDITIONAL,0};
+    pDoc->ClearSelectionItems(pItems, aMark);
+}
+
+void ScConditionalFormatList::AddToDocument(ScDocument* pDoc) const
+{
+    for (auto& itr: m_ConditionalFormats)
+    {
+        const ScRangeList& rRange = itr->GetRange();
+        if (rRange.empty())
+            continue;
+
+        SCTAB nTab = rRange.front()->aStart.Tab();
+        pDoc->AddCondFormatData(rRange, nTab, itr->GetKey());
+    }
+}
+
 size_t ScConditionalFormatList::size() const
 {
     return m_ConditionalFormats.size();
diff --git a/sc/source/ui/docshell/docfunc.cxx 
b/sc/source/ui/docshell/docfunc.cxx
index dda9430eb37e..1619865cf7e9 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -5470,22 +5470,42 @@ void ScDocFunc::SetConditionalFormatList( 
ScConditionalFormatList* pList, SCTAB
     if(rDoc.IsTabProtected(nTab))
         return;
 
-    // first remove all old entries
-    ScConditionalFormatList* pOldList = rDoc.GetCondFormList(nTab);
-    for(ScConditionalFormatList::const_iterator itr = pOldList->begin(), 
itrEnd = pOldList->end(); itr != itrEnd; ++itr)
+    bool bUndo = rDoc.IsUndoEnabled();
+    ScDocument* pUndoDoc = nullptr;
+    if (bUndo)
     {
-        rDoc.RemoveCondFormatData((*itr)->GetRange(), nTab, (*itr)->GetKey());
+        pUndoDoc = new ScDocument(SCDOCMODE_UNDO);
+        pUndoDoc->InitUndo( &rDoc, nTab, nTab );
+
+        ScConditionalFormatList* pOld = rDoc.GetCondFormList(nTab);
+
+        if (pOld)
+            pUndoDoc->SetCondFormList(new ScConditionalFormatList(pUndoDoc, 
*pOld), nTab);
+        else
+            pUndoDoc->SetCondFormList(nullptr, nTab);
+
     }
 
+    // first remove all old entries
+    ScConditionalFormatList* pOldList = rDoc.GetCondFormList(nTab);
+    pOldList->RemoveFromDocument(&rDoc);
+
     // then set new entries
-    for(ScConditionalFormatList::iterator itr = pList->begin(); itr != 
pList->end(); ++itr)
-    {
-        rDoc.AddCondFormatData((*itr)->GetRange(), nTab, (*itr)->GetKey());
-    }
+    pList->AddToDocument(&rDoc);
 
     rDoc.SetCondFormList(pList, nTab);
     rDocShell.PostPaintGridAll();
 
+    if(bUndo)
+    {
+        ScDocument* pRedoDoc = new ScDocument(SCDOCMODE_UNDO);
+        pRedoDoc->InitUndo( &rDoc, nTab, nTab );
+        pRedoDoc->SetCondFormList(new ScConditionalFormatList(pRedoDoc, 
*pList), nTab);
+
+        rDocShell.GetUndoManager()->AddUndoAction(
+                new ScUndoConditionalFormatList(&rDocShell, pUndoDoc, 
pRedoDoc, nTab));
+    }
+
     rDoc.SetStreamValid(nTab, false);
     aModificator.SetDocumentModified();
     SfxGetpApp()->Broadcast(SfxHint(SfxHintId::ScAreasChanged));
diff --git a/sc/source/ui/inc/undoblk.hxx b/sc/source/ui/inc/undoblk.hxx
index c558b44227ab..b5cc4ad789c1 100644
--- a/sc/source/ui/inc/undoblk.hxx
+++ b/sc/source/ui/inc/undoblk.hxx
@@ -631,6 +631,27 @@ private:
     ScRange maRange;
 };
 
+class ScUndoConditionalFormatList : public ScSimpleUndo
+{
+public:
+    ScUndoConditionalFormatList( ScDocShell* pNewDocShell,
+            ScDocument* pUndoDoc, ScDocument* pRedoDoc, SCTAB nTab);
+    virtual         ~ScUndoConditionalFormatList() override;
+
+    virtual void    Undo() override;
+    virtual void    Redo() override;
+    virtual void    Repeat(SfxRepeatTarget& rTarget) override;
+    virtual bool    CanRepeat(SfxRepeatTarget& rTarget) const override;
+
+    virtual OUString GetComment() const override;
+
+private:
+    void DoChange(ScDocument* pDoc);
+    std::unique_ptr<ScDocument> mpUndoDoc;
+    std::unique_ptr<ScDocument> mpRedoDoc;
+    SCTAB mnTab;
+};
+
 class ScUndoUseScenario: public ScSimpleUndo
 {
 public:
diff --git a/sc/source/ui/src/globstr.src b/sc/source/ui/src/globstr.src
index 0a26724c0a7b..79365253deb6 100644
--- a/sc/source/ui/src/globstr.src
+++ b/sc/source/ui/src/globstr.src
@@ -1873,6 +1873,11 @@ String STR_UNDO_CONDFORMAT+RID_GLOBSTR_OFFSET
     Text [ en-US ] = "Conditional Format";
 };
 
+String STR_UNDO_CONDFORMAT_LIST+RID_GLOBSTR_OFFSET
+{
+    Text [ en-US ] = "Conditional Formats";
+};
+
 String STR_UNDO_FORMULA_TO_VALUE+RID_GLOBSTR_OFFSET
 {
     Text [ en-US ] = "Convert Formula To Value";
diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx
index 217022845109..dccc583e1317 100644
--- a/sc/source/ui/undo/undoblk.cxx
+++ b/sc/source/ui/undo/undoblk.cxx
@@ -1535,6 +1535,66 @@ bool ScUndoConditionalFormat::CanRepeat(SfxRepeatTarget& 
) const
     return false;
 }
 
+ScUndoConditionalFormatList::ScUndoConditionalFormatList(ScDocShell* 
pNewDocShell,
+        ScDocument* pUndoDoc, ScDocument* pRedoDoc, SCTAB nTab):
+    ScSimpleUndo( pNewDocShell ),
+    mpUndoDoc(pUndoDoc),
+    mpRedoDoc(pRedoDoc),
+    mnTab(nTab)
+{
+}
+
+ScUndoConditionalFormatList::~ScUndoConditionalFormatList()
+{
+}
+
+OUString ScUndoConditionalFormatList::GetComment() const
+{
+    return ScGlobal::GetRscString( STR_UNDO_CONDFORMAT_LIST );
+}
+
+void ScUndoConditionalFormatList::Undo()
+{
+    DoChange(mpUndoDoc.get());
+}
+
+void ScUndoConditionalFormatList::Redo()
+{
+    DoChange(mpRedoDoc.get());
+}
+
+void ScUndoConditionalFormatList::DoChange(ScDocument* pSrcDoc)
+{
+    ScDocument& rDoc = pDocShell->GetDocument();
+
+    if (pSrcDoc == mpUndoDoc.get())
+    {
+        mpRedoDoc->GetCondFormList(mnTab)->RemoveFromDocument(&rDoc);
+        mpUndoDoc->GetCondFormList(mnTab)->AddToDocument(&rDoc);
+    }
+    else
+    {
+        mpUndoDoc->GetCondFormList(mnTab)->RemoveFromDocument(&rDoc);
+        mpRedoDoc->GetCondFormList(mnTab)->AddToDocument(&rDoc);
+    }
+    rDoc.SetCondFormList(new ScConditionalFormatList(&rDoc, 
*pSrcDoc->GetCondFormList(mnTab)), mnTab);
+
+    pDocShell->PostPaintGridAll();
+    pDocShell->PostDataChanged();
+    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+    if (pViewShell)
+        pViewShell->CellContentChanged();
+}
+
+void ScUndoConditionalFormatList::Repeat(SfxRepeatTarget& )
+{
+}
+
+bool ScUndoConditionalFormatList::CanRepeat(SfxRepeatTarget& ) const
+{
+    return false;
+}
+
 ScUndoUseScenario::ScUndoUseScenario( ScDocShell* pNewDocShell,
                         const ScMarkData& rMark,
 /*C*/                   const ScArea& rDestArea,
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to