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