[Libreoffice-commits] core.git: 6 commits - sc/inc sc/qa sc/source

Markus Mohrhard markus.mohrhard at googlemail.com
Sat Mar 26 16:00:38 UTC 2016


 sc/inc/colorscale.hxx                     |    4 
 sc/inc/conditio.hxx                       |   46 +++++-
 sc/inc/document.hxx                       |    3 
 sc/qa/unit/ucalc.hxx                      |   19 ++
 sc/qa/unit/ucalc_condformat.cxx           |  208 ++++++++++++++++++++++++++++++
 sc/source/core/data/colorscale.cxx        |  112 +++++++++-------
 sc/source/core/data/conditio.cxx          |  189 ++++++++++-----------------
 sc/source/core/data/documen7.cxx          |   58 --------
 sc/source/core/data/documen9.cxx          |    7 +
 sc/source/ui/condformat/condformatdlg.cxx |    4 
 10 files changed, 413 insertions(+), 237 deletions(-)

New commits:
commit ae5bf728937a9233a5090adca94c2ffc106ea8b6
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sat Mar 26 16:52:02 2016 +0100

    no need to iterate through all cells
    
    Change-Id: I4621e58032a79b8438b4094b8c66d5d7a104e8af

diff --git a/sc/source/core/data/colorscale.cxx b/sc/source/core/data/colorscale.cxx
index bb3eb0e..d478823 100644
--- a/sc/source/core/data/colorscale.cxx
+++ b/sc/source/core/data/colorscale.cxx
@@ -134,19 +134,7 @@ struct StopListeningCell
     // TODO: moggi: use EndListeningArea
     void operator()(const ScRange& rRange)
     {
-        for(SCTAB nTab = rRange.aStart.Tab(),
-                nTabEnd = rRange.aEnd.Tab(); nTab <= nTabEnd; ++nTab)
-        {
-            for(SCCOL nCol = rRange.aStart.Col(),
-                    nColEnd = rRange.aEnd.Col(); nCol <= nColEnd; ++nCol)
-            {
-                for(SCROW nRow = rRange.aStart.Row(),
-                        nRowEnd = rRange.aEnd.Row(); nRow <= nRowEnd; ++nRow)
-                {
-                    mpDoc->EndListeningCell(ScAddress(nCol, nRow, nTab), mpListener);
-                }
-            }
-        }
+        mpDoc->EndListeningArea(rRange, false, mpListener);
     }
 
 private:
commit 59003139bd336dc4a85d537c9befe3204638d476
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sat Mar 26 16:38:18 2016 +0100

    also test that we are not still listening to the old area
    
    Change-Id: I7ad84ec75f435e3171b064eaaf60a819b09aeb02

diff --git a/sc/qa/unit/ucalc_condformat.cxx b/sc/qa/unit/ucalc_condformat.cxx
index 6d75c02..f77208b 100644
--- a/sc/qa/unit/ucalc_condformat.cxx
+++ b/sc/qa/unit/ucalc_condformat.cxx
@@ -770,6 +770,9 @@ void Test::testCondFormatUpdateMoveTab()
     {
         m_pDoc->SetValue(ScAddress(0, nRow, 1), 1.0);
         CPPUNIT_ASSERT(pEntry->NeedsRepaint());
+
+        m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
+        CPPUNIT_ASSERT(!pEntry->NeedsRepaint());
     }
 
     m_pDoc->DeleteTab(1);
@@ -793,6 +796,9 @@ void Test::testCondFormatUpdateInsertTab()
     {
         m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
         CPPUNIT_ASSERT(pEntry->NeedsRepaint());
+
+        m_pDoc->SetValue(ScAddress(0, nRow, 1), 1.0);
+        CPPUNIT_ASSERT(!pEntry->NeedsRepaint());
     }
 
     m_pDoc->InsertTab(0, "test2");
@@ -802,6 +808,9 @@ void Test::testCondFormatUpdateInsertTab()
     {
         m_pDoc->SetValue(ScAddress(0, nRow, 1), 1.0);
         CPPUNIT_ASSERT(pEntry->NeedsRepaint());
+
+        m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
+        CPPUNIT_ASSERT(!pEntry->NeedsRepaint());
     }
 
     m_pDoc->DeleteTab(1);
commit ba64def7776e592a37fbb1833edacb397ba373a2
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sat Mar 26 16:34:48 2016 +0100

    add a few unit tests for conditional format reference listening
    
    Change-Id: I0609bf9033a7a2dd40afaae9effbfa06de5e4c83

diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 59a445b..d284597 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -432,6 +432,8 @@ public:
     void testCellTextWidth();
     void testEditTextIterator();
 
+    // conditional format tests
+    // mostly in ucalc_condformat.cxx
     void testCondFormatINSDEL();
     void testCondFormatInsertRow();
     void testCondFormatInsertCol();
@@ -444,11 +446,20 @@ public:
     void testIconSet();
     void testDataBarLengthAutomaticAxis();
     void testDataBarLengthMiddleAxis();
+
+    // Tests for the ScFormulaListener class
     void testFormulaListenerSingleCellToSingleCell();
     void testFormulaListenerMultipleCellsToSingleCell();
     void testFormulaListenerSingleCellToMultipleCells();
     void testFormulaListenerMultipleCellsToMultipleCells();
 
+    // Check that the Listeners are correctly updated when we
+    // call a operation
+    void testCondFormatUpdateMoveTab();
+    void testCondFormatUpdateDeleteTab();
+    void testCondFormatUpdateInsertTab();
+    void testCondFormatUpdateReference();
+
     void testCondFormatEndsWithStr();
     void testCondFormatEndsWithVal();
 
diff --git a/sc/qa/unit/ucalc_condformat.cxx b/sc/qa/unit/ucalc_condformat.cxx
index aa21471..6d75c02 100644
--- a/sc/qa/unit/ucalc_condformat.cxx
+++ b/sc/qa/unit/ucalc_condformat.cxx
@@ -743,4 +743,125 @@ void Test::testFormulaListenerMultipleCellsToMultipleCells()
     m_pDoc->DeleteTab(0);
 }
 
+void Test::testCondFormatUpdateMoveTab()
+{
+    m_pDoc->InsertTab(0, "test");
+    m_pDoc->InsertTab(1, "Test2");
+
+    ScConditionEntry* pEntry = new ScConditionEntry(SC_COND_EQUAL, "A1", "", m_pDoc, ScAddress(10, 10, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
+
+    ScConditionalFormat* pFormat = new ScConditionalFormat(0, m_pDoc);
+    pFormat->SetRange(ScRange(10, 10, 0, 10, 12, 0));
+    m_pDoc->AddCondFormat(pFormat, 0);
+
+    pFormat->AddEntry(pEntry);
+
+    // the conditional format should listen to A1:A3
+    for (SCROW nRow = 0; nRow < 3; ++nRow)
+    {
+        m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
+        CPPUNIT_ASSERT(pEntry->NeedsRepaint());
+    }
+
+    m_pDoc->MoveTab(0, 1);
+
+    // the conditional format should listen to A1:A3 on the second sheet
+    for (SCROW nRow = 0; nRow < 3; ++nRow)
+    {
+        m_pDoc->SetValue(ScAddress(0, nRow, 1), 1.0);
+        CPPUNIT_ASSERT(pEntry->NeedsRepaint());
+    }
+
+    m_pDoc->DeleteTab(1);
+    m_pDoc->DeleteTab(0);
+}
+
+void Test::testCondFormatUpdateInsertTab()
+{
+    m_pDoc->InsertTab(0, "test");
+
+    ScConditionEntry* pEntry = new ScConditionEntry(SC_COND_EQUAL, "A1", "", m_pDoc, ScAddress(10, 10, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
+
+    ScConditionalFormat* pFormat = new ScConditionalFormat(0, m_pDoc);
+    pFormat->SetRange(ScRange(10, 10, 0, 10, 12, 0));
+    m_pDoc->AddCondFormat(pFormat, 0);
+
+    pFormat->AddEntry(pEntry);
+
+    // the conditional format should listen to A1:A3
+    for (SCROW nRow = 0; nRow < 3; ++nRow)
+    {
+        m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
+        CPPUNIT_ASSERT(pEntry->NeedsRepaint());
+    }
+
+    m_pDoc->InsertTab(0, "test2");
+
+    // the conditional format should listen to A1:A3 on the second sheet
+    for (SCROW nRow = 0; nRow < 3; ++nRow)
+    {
+        m_pDoc->SetValue(ScAddress(0, nRow, 1), 1.0);
+        CPPUNIT_ASSERT(pEntry->NeedsRepaint());
+    }
+
+    m_pDoc->DeleteTab(1);
+    m_pDoc->DeleteTab(0);
+}
+
+void Test::testCondFormatUpdateDeleteTab()
+{
+    m_pDoc->InsertTab(0, "test");
+    m_pDoc->InsertTab(1, "Test2");
+
+    ScConditionEntry* pEntry = new ScConditionEntry(SC_COND_EQUAL, "A1", "", m_pDoc, ScAddress(10, 10, 1), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
+
+    ScConditionalFormat* pFormat = new ScConditionalFormat(0, m_pDoc);
+    pFormat->SetRange(ScRange(10, 10, 1, 10, 12, 1));
+    m_pDoc->AddCondFormat(pFormat, 1);
+
+    pFormat->AddEntry(pEntry);
+
+    // the conditional format should listen to A1:A3 on the second sheet
+    for (SCROW nRow = 0; nRow < 3; ++nRow)
+    {
+        m_pDoc->SetValue(ScAddress(0, nRow, 1), 1.0);
+        CPPUNIT_ASSERT(pEntry->NeedsRepaint());
+    }
+
+    m_pDoc->DeleteTab(0);
+
+    // the conditional format should listen to A1:A3 on the second sheet
+    for (SCROW nRow = 0; nRow < 3; ++nRow)
+    {
+        m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
+        CPPUNIT_ASSERT(pEntry->NeedsRepaint());
+    }
+
+    m_pDoc->DeleteTab(0);
+}
+
+void Test::testCondFormatUpdateReference()
+{
+    m_pDoc->InsertTab(0, "test");
+    m_pDoc->InsertTab(1, "Test2");
+
+    ScConditionEntry* pEntry = new ScConditionEntry(SC_COND_EQUAL, "A1", "", m_pDoc, ScAddress(10, 10, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
+
+    ScConditionalFormat* pFormat = new ScConditionalFormat(0, m_pDoc);
+    pFormat->SetRange(ScRange(10, 10, 0, 10, 12, 0));
+    m_pDoc->AddCondFormat(pFormat, 0);
+
+    pFormat->AddEntry(pEntry);
+
+    // the conditional format should listen to A1:A3
+    for (SCROW nRow = 0; nRow < 3; ++nRow)
+    {
+        m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
+        CPPUNIT_ASSERT(pEntry->NeedsRepaint());
+    }
+
+    m_pDoc->DeleteTab(1);
+    m_pDoc->DeleteTab(0);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 988a49426f42c1445bc26677cf8041b7a233015c
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sat Mar 26 16:34:32 2016 +0100

    fix indentation
    
    Change-Id: Ibd65797b70cac33eb3302ad2020ffe38a01a2d85

diff --git a/sc/inc/conditio.hxx b/sc/inc/conditio.hxx
index 6c630f1..624e16a 100644
--- a/sc/inc/conditio.hxx
+++ b/sc/inc/conditio.hxx
@@ -415,8 +415,8 @@ class SC_DLLPUBLIC ScConditionalFormat: private boost::noncopyable
     ScRangeList maRanges;            // Ranges for conditional format
 
 public:
-            ScConditionalFormat(sal_uInt32 nNewKey, ScDocument* pDocument);
-            ~ScConditionalFormat();
+    ScConditionalFormat(sal_uInt32 nNewKey, ScDocument* pDocument);
+    ~ScConditionalFormat();
 
     // true copy of formulas (for Ref-Undo / between documents)
     ScConditionalFormat* Clone(ScDocument* pNewDoc = nullptr) const;
commit 931c6a095c5f26dc78c531b127aed2ebc86af98d
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sat Mar 26 13:12:16 2016 +0100

    add a few unit tests for ScFormulaListener
    
    Change-Id: Ie6c26967167a2dffa0e2047a78eb2b44b6c502f3

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 15130a5..6c313a9 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1906,8 +1906,7 @@ public:
     void EndListeningArea( const ScRange& rRange, bool bGroupListening, SvtListener* pListener );
                         /** Broadcast wrapper, calls
                             rHint.GetCell()->Broadcast() and AreaBroadcast()
-                            and TrackFormulas() and conditional format list
-                            SourceChanged().
+                            and TrackFormulas()
                             Preferred.
                          */
     void                Broadcast( const ScHint& rHint );
diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 848521d..59a445b 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -444,6 +444,10 @@ public:
     void testIconSet();
     void testDataBarLengthAutomaticAxis();
     void testDataBarLengthMiddleAxis();
+    void testFormulaListenerSingleCellToSingleCell();
+    void testFormulaListenerMultipleCellsToSingleCell();
+    void testFormulaListenerSingleCellToMultipleCells();
+    void testFormulaListenerMultipleCellsToMultipleCells();
 
     void testCondFormatEndsWithStr();
     void testCondFormatEndsWithVal();
@@ -691,6 +695,10 @@ public:
     CPPUNIT_TEST(testIconSet);
     CPPUNIT_TEST(testDataBarLengthAutomaticAxis);
     CPPUNIT_TEST(testDataBarLengthMiddleAxis);
+    CPPUNIT_TEST(testFormulaListenerSingleCellToSingleCell);
+    CPPUNIT_TEST(testFormulaListenerSingleCellToMultipleCells);
+    CPPUNIT_TEST(testFormulaListenerMultipleCellsToSingleCell);
+    CPPUNIT_TEST(testFormulaListenerMultipleCellsToMultipleCells);
     CPPUNIT_TEST(testImportStream);
     CPPUNIT_TEST(testDeleteContents);
     CPPUNIT_TEST(testTransliterateText);
diff --git a/sc/qa/unit/ucalc_condformat.cxx b/sc/qa/unit/ucalc_condformat.cxx
index 7af25cf..aa21471 100644
--- a/sc/qa/unit/ucalc_condformat.cxx
+++ b/sc/qa/unit/ucalc_condformat.cxx
@@ -18,6 +18,8 @@
 #include "scitems.hxx"
 #include "attrib.hxx"
 #include "fillinfo.hxx"
+#include "compiler.hxx"
+#include "tokenarray.hxx"
 
 #include <svl/sharedstringpool.hxx>
 #include <o3tl/make_unique.hxx>
@@ -665,4 +667,80 @@ void Test::testCondFormatEndsWithVal()
     m_pDoc->DeleteTab(0);
 }
 
+void Test::testFormulaListenerSingleCellToSingleCell()
+{
+    m_pDoc->InsertTab(0, "test");
+
+    ScCompiler aCompiler(m_pDoc, ScAddress(10, 10, 0));
+    aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH);
+
+    std::unique_ptr<ScTokenArray> pTokenArray(aCompiler.CompileString("A1"));
+
+    ScFormulaListener aListener(m_pDoc);
+
+    aListener.addTokenArray(pTokenArray.get(), ScAddress(10, 10, 0));
+
+    m_pDoc->SetValue(ScAddress(0, 0, 0), 1.0);
+    CPPUNIT_ASSERT(aListener.NeedsRepaint());
+
+    m_pDoc->DeleteTab(0);
+}
+
+void Test::testFormulaListenerSingleCellToMultipleCells()
+{
+    m_pDoc->InsertTab(0, "test");
+
+    ScCompiler aCompiler(m_pDoc, ScAddress(10, 10, 0));
+    aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH);
+
+    std::unique_ptr<ScTokenArray> pTokenArray(aCompiler.CompileString("A1"));
+
+    ScFormulaListener aListener(m_pDoc);
+
+    aListener.addTokenArray(pTokenArray.get(), ScAddress(10, 10, 0));
+
+    m_pDoc->SetValue(ScAddress(0, 0, 0), 1.0);
+    CPPUNIT_ASSERT(aListener.NeedsRepaint());
+
+    m_pDoc->DeleteTab(0);
+}
+
+void Test::testFormulaListenerMultipleCellsToSingleCell()
+{
+    m_pDoc->InsertTab(0, "test");
+
+    ScCompiler aCompiler(m_pDoc, ScAddress(10, 10, 0));
+    aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH);
+
+    std::unique_ptr<ScTokenArray> pTokenArray(aCompiler.CompileString("A1"));
+
+    ScFormulaListener aListener(m_pDoc);
+
+    aListener.addTokenArray(pTokenArray.get(), ScAddress(10, 10, 0));
+
+    m_pDoc->SetValue(ScAddress(0, 0, 0), 1.0);
+    CPPUNIT_ASSERT(aListener.NeedsRepaint());
+
+    m_pDoc->DeleteTab(0);
+}
+
+void Test::testFormulaListenerMultipleCellsToMultipleCells()
+{
+    m_pDoc->InsertTab(0, "test");
+
+    ScCompiler aCompiler(m_pDoc, ScAddress(10, 10, 0));
+    aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH);
+
+    std::unique_ptr<ScTokenArray> pTokenArray(aCompiler.CompileString("A1"));
+
+    ScFormulaListener aListener(m_pDoc);
+
+    aListener.addTokenArray(pTokenArray.get(), ScAddress(10, 10, 0));
+
+    m_pDoc->SetValue(ScAddress(0, 0, 0), 1.0);
+    CPPUNIT_ASSERT(aListener.NeedsRepaint());
+
+    m_pDoc->DeleteTab(0);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 88a0c7d01b7dfd085a0569030f97cc7de0f0d106
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sat Mar 26 13:11:53 2016 +0100

    switch to a listener based cond format update, tdf#95437
    
    Change-Id: Iaee665a37a9637c40cd02a89a19240ade6e5af37

diff --git a/sc/inc/colorscale.hxx b/sc/inc/colorscale.hxx
index 427bf53..992b532 100644
--- a/sc/inc/colorscale.hxx
+++ b/sc/inc/colorscale.hxx
@@ -15,9 +15,6 @@
 #include "rangelst.hxx"
 #include "conditio.hxx"
 
-#include <svl/listener.hxx>
-#include <svl/broadcast.hxx>
-
 #include <memory>
 #include <vector>
 
@@ -28,7 +25,6 @@ class ScFormulaCell;
 class ScTokenArray;
 struct ScDataBarInfo;
 class BitmapEx;
-class ScFormulaListener;
 
 namespace sc {
     class IconSetBitmapMap : public std::map<sal_Int32, BitmapEx> {};
diff --git a/sc/inc/conditio.hxx b/sc/inc/conditio.hxx
index 5114bd2..6c630f1 100644
--- a/sc/inc/conditio.hxx
+++ b/sc/inc/conditio.hxx
@@ -26,6 +26,10 @@
 #include "scdllapi.h"
 #include "rangelst.hxx"
 
+#include <svl/hint.hxx>
+#include <svl/listener.hxx>
+#include <svl/broadcast.hxx>
+
 #include <comphelper/stl_types.hxx>
 
 #include <rtl/math.hxx>
@@ -83,6 +87,31 @@ enum ScConditionMode
     SC_COND_NONE
 };
 
+class ScFormulaListener : public SvtListener
+{
+private:
+    std::vector<ScRange> maCells;
+    mutable bool mbDirty;
+    ScDocument* mpDoc;
+    std::function<void()> maCallbackFunction;
+
+    void startListening(ScTokenArray* pTokens, const ScRange& rPos);
+
+public:
+    explicit ScFormulaListener(ScFormulaCell* pCell);
+    explicit ScFormulaListener(ScDocument* pDoc);
+    virtual ~ScFormulaListener();
+
+    void Notify( const SfxHint& rHint ) override;
+
+    bool NeedsRepaint() const;
+
+    void resetTokenArray(ScTokenArray* pTokens, const ScRange& rRange);
+    void addTokenArray(ScTokenArray* pTokens, const ScRange& rRange);
+    void stopListening();
+    void setCallback(std::function<void()> aCallbackFunction);
+};
+
 class ScConditionalFormat;
 struct ScDataBarInfo;
 struct ScIconSetInfo;
@@ -176,6 +205,7 @@ class SC_DLLPUBLIC ScConditionEntry : public ScFormatEntry
     bool                bRelRef1;
     bool                bRelRef2;
     bool                bFirstRun;
+    std::unique_ptr<ScFormulaListener> mpListener;
 
     void    MakeCells( const ScAddress& rPos );
     void    Compile( const OUString& rExpr1, const OUString& rExpr2,
@@ -187,6 +217,7 @@ class SC_DLLPUBLIC ScConditionEntry : public ScFormatEntry
 
     bool    IsValid( double nArg, const ScAddress& rPos ) const;
     bool    IsValidStr( const OUString& rArg, const ScAddress& rPos ) const;
+    void    StartListening();
 
 public:
             ScConditionEntry( ScConditionMode eOper,
@@ -205,7 +236,7 @@ public:
 
     bool            operator== ( const ScConditionEntry& r ) const;
 
-    virtual void SetParent( ScConditionalFormat* pNew ) override  { pCondFormat = pNew; }
+    virtual void SetParent( ScConditionalFormat* pNew ) override;
 
     bool IsCellValid( ScRefCellValue& rCell, const ScAddress& rPos ) const;
 
@@ -234,8 +265,6 @@ public:
     virtual void UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt ) override;
     virtual void UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt ) override;
 
-    void            SourceChanged( const ScAddress& rChanged );
-
     bool            MarkUsedExternalReferences() const;
 
     virtual condformat::ScFormatEntryType GetType() const override { return condformat::CONDITION; }
@@ -247,6 +276,8 @@ public:
     virtual void endRendering() override;
     virtual void startRendering() override;
 
+    bool NeedsRepaint() const;
+
 protected:
     virtual void    DataChanged( const ScRange* pModified ) const;
     ScDocument*     GetDocument() const     { return mpDoc; }
@@ -413,8 +444,6 @@ public:
     void            DeleteArea( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
     void            RenameCellStyle( const OUString& rOld, const OUString& rNew );
 
-    void            SourceChanged( const ScAddress& rAddr );
-
     const ScFormatEntry* GetEntry( sal_uInt16 nPos ) const;
 
     const OUString& GetCellStyle( ScRefCellValue& rCell, const ScAddress& rPos ) const;
@@ -478,8 +507,6 @@ public:
     void    RenameCellStyle( const OUString& rOld, const OUString& rNew );
     void    DeleteArea( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
 
-    void    SourceChanged( const ScAddress& rAddr );
-
     typedef ConditionalFormatContainer::iterator iterator;
     typedef ConditionalFormatContainer::const_iterator const_iterator;
 
@@ -492,6 +519,7 @@ public:
     bool empty() const;
 
     void erase(sal_uLong nIndex);
+    void clear();
 
     void startRendering();
     void endRendering();
diff --git a/sc/source/core/data/colorscale.cxx b/sc/source/core/data/colorscale.cxx
index bfa1c4d..bb3eb0e 100644
--- a/sc/source/core/data/colorscale.cxx
+++ b/sc/source/core/data/colorscale.cxx
@@ -21,44 +21,54 @@
 
 #include <algorithm>
 
-class ScFormulaListener : public SvtListener
+ScFormulaListener::ScFormulaListener(ScFormulaCell* pCell):
+    mbDirty(false),
+    mpDoc(pCell->GetDocument())
 {
-private:
-    std::vector<ScRange> maCells;
-    mutable bool mbDirty;
-    ScDocument* mpDoc;
-
-    void startListening(ScTokenArray* pTokens, const ScAddress& rPos);
+    startListening( pCell->GetCode(), pCell->aPos );
+}
 
-public:
-    explicit ScFormulaListener(ScFormulaCell* pCell);
-    virtual ~ScFormulaListener();
+ScFormulaListener::ScFormulaListener(ScDocument* pDoc):
+    mbDirty(false),
+    mpDoc(pDoc)
+{
+}
 
-    void Notify( const SfxHint& rHint ) override;
+namespace {
 
-    bool NeedsRepaint() const;
-};
+std::ostream& operator<<(std::ostream& rStrm, const ScAddress& rAddr)
+{
+    rStrm << "Col: " << rAddr.Col() << ", Row: " << rAddr.Row() << ", Tab: " << rAddr.Tab();
+    return rStrm;
+}
 
-ScFormulaListener::ScFormulaListener(ScFormulaCell* pCell):
-    mbDirty(false),
-    mpDoc(pCell->GetDocument())
+std::ostream& operator<<(std::ostream& rStrm, const ScRange& rRange)
 {
-    startListening( pCell->GetCode(), pCell->aPos );
+    rStrm << "Start: " << rRange.aStart << std::endl;
+    rStrm << "End: " << rRange.aEnd << std::endl;
+    return rStrm;
+}
+
 }
 
-void ScFormulaListener::startListening(ScTokenArray* pArr, const ScAddress& rPos)
+void ScFormulaListener::startListening(ScTokenArray* pArr, const ScRange& rRange)
 {
+    if (!pArr)
+        return;
+
     pArr->Reset();
     formula::FormulaToken* t;
-    while ( ( t = pArr->GetNextReferenceRPN() ) != nullptr )
+    while ( ( t = pArr->GetNextReference() ) != nullptr )
     {
         switch (t->GetType())
         {
             case formula::svSingleRef:
             {
-                ScAddress aCell =  t->GetSingleRef()->toAbs(rPos);
-                if (aCell.IsValid())
-                    mpDoc->StartListeningCell(aCell, this);
+                ScAddress aCell = t->GetSingleRef()->toAbs(rRange.aStart);
+                ScAddress aCell2 = t->GetSingleRef()->toAbs(rRange.aEnd);
+                ScRange aRange(aCell, aCell2);
+                if (aRange.IsValid())
+                    mpDoc->StartListeningArea(aRange, false, this);
 
                 maCells.push_back(aCell);
             }
@@ -67,23 +77,28 @@ void ScFormulaListener::startListening(ScTokenArray* pArr, const ScAddress& rPos
             {
                 const ScSingleRefData& rRef1 = *t->GetSingleRef();
                 const ScSingleRefData& rRef2 = *t->GetSingleRef2();
-                ScAddress aCell1 = rRef1.toAbs(rPos);
-                ScAddress aCell2 = rRef2.toAbs(rPos);
-                if (aCell1.IsValid() && aCell2.IsValid())
+                ScAddress aCell1 = rRef1.toAbs(rRange.aStart);
+                ScAddress aCell2 = rRef2.toAbs(rRange.aStart);
+                ScAddress aCell3 = rRef1.toAbs(rRange.aEnd);
+                ScAddress aCell4 = rRef2.toAbs(rRange.aEnd);
+                ScRange aRange1(aCell1, aCell3);
+                ScRange aRange2(aCell2, aCell4);
+                aRange1.ExtendTo(aRange2);
+                if (aRange1.IsValid())
                 {
                     if (t->GetOpCode() == ocColRowNameAuto)
                     {   // automagically
                         if ( rRef1.IsColRel() )
                         {   // ColName
-                            aCell2.SetRow(MAXROW);
+                            aRange1.aEnd.SetRow(MAXROW);
                         }
                         else
                         {   // RowName
-                            aCell2.SetCol(MAXCOL);
+                            aRange1.aEnd.SetCol(MAXCOL);
                         }
                     }
-                    mpDoc->StartListeningArea(ScRange(aCell1, aCell2), false, this);
-                    maCells.push_back(ScRange(aCell1, aCell2));
+                    mpDoc->StartListeningArea(aRange1, false, this);
+                    maCells.push_back(aRange1);
                 }
             }
             break;
@@ -91,7 +106,22 @@ void ScFormulaListener::startListening(ScTokenArray* pArr, const ScAddress& rPos
                 ;   // nothing
         }
     }
+}
+
+void ScFormulaListener::resetTokenArray(ScTokenArray* pArray, const ScRange& rRange)
+{
+    stopListening();
+    startListening(pArray, rRange);
+}
 
+void ScFormulaListener::addTokenArray(ScTokenArray* pArray, const ScRange& rRange)
+{
+    startListening(pArray, rRange);
+}
+
+void ScFormulaListener::setCallback(std::function<void()> aCallback)
+{
+    maCallbackFunction = aCallback;
 }
 
 namespace {
@@ -101,6 +131,7 @@ struct StopListeningCell
     StopListeningCell(ScDocument* pDoc, SvtListener* pListener):
         mpDoc(pDoc), mpListener(pListener) {}
 
+    // TODO: moggi: use EndListeningArea
     void operator()(const ScRange& rRange)
     {
         for(SCTAB nTab = rRange.aStart.Tab(),
@@ -125,14 +156,21 @@ private:
 
 }
 
-ScFormulaListener::~ScFormulaListener()
+void ScFormulaListener::stopListening()
 {
     std::for_each(maCells.begin(), maCells.end(), StopListeningCell(mpDoc, this));
 }
 
+ScFormulaListener::~ScFormulaListener()
+{
+    stopListening();
+}
+
 void ScFormulaListener::Notify( const SfxHint& )
 {
     mbDirty = true;
+    if (maCallbackFunction)
+        maCallbackFunction();
 }
 
 bool ScFormulaListener::NeedsRepaint() const
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index 84de73c..57f3718 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -141,6 +141,42 @@ static bool lcl_HasRelRef( ScDocument* pDoc, ScTokenArray* pFormula, sal_uInt16
     return false;
 }
 
+namespace {
+
+void start_listen_to(ScFormulaListener& rListener, ScTokenArray* pTokens, const ScRangeList& rRangeList)
+{
+    size_t n = rRangeList.size();
+    for (size_t i = 0; i < n; ++i)
+    {
+        const ScRange* pRange = rRangeList[i];
+        if (!pRange)
+            continue;
+
+        rListener.addTokenArray(pTokens, *pRange);
+    }
+}
+
+}
+
+void ScConditionEntry::StartListening()
+{
+    if (!pCondFormat)
+        return;
+
+    const ScRangeList& rRanges = pCondFormat->GetRange();
+    mpListener->stopListening();
+    start_listen_to(*mpListener, pFormula1, rRanges);
+    start_listen_to(*mpListener, pFormula2, rRanges);
+
+    mpListener->setCallback([&]() { pCondFormat->DoRepaint(nullptr);});
+}
+
+void ScConditionEntry::SetParent(ScConditionalFormat* pParent)
+{
+    pCondFormat = pParent;
+    StartListening();
+}
+
 ScConditionEntry::ScConditionEntry( const ScConditionEntry& r ) :
     ScFormatEntry(r.mpDoc),
     eOp(r.eOp),
@@ -164,6 +200,7 @@ ScConditionEntry::ScConditionEntry( const ScConditionEntry& r ) :
     bRelRef1(r.bRelRef1),
     bRelRef2(r.bRelRef2),
     bFirstRun(true),
+    mpListener(new ScFormulaListener(r.mpDoc)),
     pCondFormat(r.pCondFormat)
 {
     // ScTokenArray copy ctor creates a flat copy
@@ -172,6 +209,7 @@ ScConditionEntry::ScConditionEntry( const ScConditionEntry& r ) :
     if (r.pFormula2)
         pFormula2 = new ScTokenArray( *r.pFormula2 );
 
+    StartListening();
     // Formula cells are created at IsValid
 }
 
@@ -198,6 +236,7 @@ ScConditionEntry::ScConditionEntry( ScDocument* pDocument, const ScConditionEntr
     bRelRef1(r.bRelRef1),
     bRelRef2(r.bRelRef2),
     bFirstRun(true),
+    mpListener(new ScFormulaListener(pDocument)),
     pCondFormat(r.pCondFormat)
 {
     // Real copy of the formulas (for Ref Undo)
@@ -233,6 +272,7 @@ ScConditionEntry::ScConditionEntry( ScConditionMode eOper,
     bRelRef1(false),
     bRelRef2(false),
     bFirstRun(true),
+    mpListener(new ScFormulaListener(pDocument)),
     pCondFormat(nullptr)
 {
     Compile( rExpr1, rExpr2, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2, false );
@@ -260,6 +300,7 @@ ScConditionEntry::ScConditionEntry( ScConditionMode eOper,
     bRelRef1(false),
     bRelRef2(false),
     bFirstRun(true),
+    mpListener(new ScFormulaListener(pDocument)),
     pCondFormat(nullptr)
 {
     if ( pArr1 )
@@ -311,6 +352,8 @@ ScConditionEntry::ScConditionEntry( ScConditionMode eOper,
         bRelRef2 = lcl_HasRelRef( mpDoc, pFormula2 );
     }
 
+    StartListening();
+
     // Formula cells are created at IsValid
 }
 
@@ -412,6 +455,8 @@ void ScConditionEntry::Compile( const OUString& rExpr1, const OUString& rExpr2,
             }
         }
     }
+
+    StartListening();
 }
 
 /**
@@ -490,6 +535,8 @@ void ScConditionEntry::SetFormula1( const ScTokenArray& rArray )
         pFormula1 = new ScTokenArray( rArray );
         bRelRef1 = lcl_HasRelRef( mpDoc, pFormula1 );
     }
+
+    StartListening();
 }
 
 void ScConditionEntry::SetFormula2( const ScTokenArray& rArray )
@@ -500,6 +547,8 @@ void ScConditionEntry::SetFormula2( const ScTokenArray& rArray )
         pFormula2 = new ScTokenArray( rArray );
         bRelRef2 = lcl_HasRelRef( mpDoc, pFormula2 );
     }
+
+    StartListening();
 }
 
 void ScConditionEntry::UpdateReference( sc::RefUpdateContext& rCxt )
@@ -555,6 +604,8 @@ void ScConditionEntry::UpdateReference( sc::RefUpdateContext& rCxt )
         if (aRes.mbReferenceModified || bChangedPos)
             DELETEZ(pFCell2);       // is created again in IsValid
     }
+
+    StartListening();
 }
 
 void ScConditionEntry::UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt )
@@ -570,6 +621,8 @@ void ScConditionEntry::UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt )
         pFormula2->AdjustReferenceOnInsertedTab(rCxt, aSrcPos);
         DELETEZ(pFCell2);
     }
+
+    StartListening();
 }
 
 void ScConditionEntry::UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt )
@@ -585,6 +638,8 @@ void ScConditionEntry::UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt )
         pFormula2->AdjustReferenceOnDeletedTab(rCxt, aSrcPos);
         DELETEZ(pFCell2);
     }
+
+    StartListening();
 }
 
 void ScConditionEntry::UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt )
@@ -600,6 +655,8 @@ void ScConditionEntry::UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt )
         pFormula2->AdjustReferenceOnMovedTab(rCxt, aSrcPos);
         DELETEZ(pFCell2);
     }
+
+    StartListening();
 }
 
 //FIXME: Make this a comparison operator at the TokenArray?
@@ -1359,89 +1416,6 @@ ScTokenArray* ScConditionEntry::CreateTokenArry( sal_uInt16 nIndex ) const
     return pRet;
 }
 
-void ScConditionEntry::SourceChanged( const ScAddress& rChanged )
-{
-    for (sal_uInt16 nPass = 0; nPass < 2; nPass++)
-    {
-        ScTokenArray* pFormula = nPass ? pFormula2 : pFormula1;
-        if (pFormula)
-        {
-            pFormula->Reset();
-            formula::FormulaToken* t;
-            while ( ( t = pFormula->GetNextReference() ) != nullptr )
-            {
-                SingleDoubleRefProvider aProv( *t );
-                if ( aProv.Ref1.IsColRel() || aProv.Ref1.IsRowRel() || aProv.Ref1.IsTabRel() ||
-                     aProv.Ref2.IsColRel() || aProv.Ref2.IsRowRel() || aProv.Ref2.IsTabRel() )
-                {
-                    // Absolute must be reached, relative determines range
-                    bool bHit = true;
-                    SCsCOL nCol1;
-                    SCsROW nRow1;
-                    SCsTAB nTab1;
-                    SCsCOL nCol2;
-                    SCsROW nRow2;
-                    SCsTAB nTab2;
-
-                    if ( aProv.Ref1.IsColRel() )
-                        nCol2 = rChanged.Col() - aProv.Ref1.Col();
-                    else
-                    {
-                        bHit &= (rChanged.Col() >= aProv.Ref1.Col());
-                        nCol2 = MAXCOL;
-                    }
-                    if ( aProv.Ref1.IsRowRel() )
-                        nRow2 = rChanged.Row() - aProv.Ref1.Row();
-                    else
-                    {
-                        bHit &= ( rChanged.Row() >= aProv.Ref1.Row() );
-                        nRow2 = MAXROW;
-                    }
-                    if ( aProv.Ref1.IsTabRel() )
-                        nTab2 = rChanged.Tab() - aProv.Ref1.Tab();
-                    else
-                    {
-                        bHit &= (rChanged.Tab() >= aProv.Ref1.Tab());
-                        nTab2 = MAXTAB;
-                    }
-
-                    if ( aProv.Ref2.IsColRel() )
-                        nCol1 = rChanged.Col() - aProv.Ref2.Col();
-                    else
-                    {
-                        bHit &= ( rChanged.Col() <= aProv.Ref2.Col() );
-                        nCol1 = 0;
-                    }
-                    if ( aProv.Ref2.IsRowRel() )
-                        nRow1 = rChanged.Row() - aProv.Ref2.Row();
-                    else
-                    {
-                        bHit &= (rChanged.Row() <= aProv.Ref2.Row());
-                        nRow1 = 0;
-                    }
-                    if ( aProv.Ref2.IsTabRel() )
-                        nTab1 = rChanged.Tab() - aProv.Ref2.Tab();
-                    else
-                    {
-                        bHit &= (rChanged.Tab() <= aProv.Ref2.Tab());
-                        nTab1 = 0;
-                    }
-
-                    if ( bHit )
-                    {
-                        // Limit paint!
-                        ScRange aPaint( nCol1,nRow1,nTab1, nCol2,nRow2,nTab2 );
-
-                        // No paint if it's the cell itself
-                        if ( aPaint.IsValid() && (aPaint.aStart != rChanged || aPaint.aEnd != rChanged ))
-                            DataChanged( &aPaint );
-                    }
-                }
-            }
-        }
-    }
-}
-
 /**
  * Return a position that's adjusted to allow textual representation
  * of expressions if possible
@@ -1572,6 +1546,11 @@ void ScConditionEntry::endRendering()
     mpCache.reset();
 }
 
+bool ScConditionEntry::NeedsRepaint() const
+{
+    return mpListener->NeedsRepaint();
+}
+
 ScCondFormatEntry::ScCondFormatEntry( ScConditionMode eOper,
                                         const OUString& rExpr1, const OUString& rExpr2,
                                         ScDocument* pDocument, const ScAddress& rPos,
@@ -1962,13 +1941,13 @@ void ScConditionalFormat::CompileXML()
 
 void ScConditionalFormat::UpdateReference( sc::RefUpdateContext& rCxt, bool bCopyAsMove )
 {
-    for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
-        (*itr)->UpdateReference(rCxt);
-
     if (rCxt.meMode == URM_COPY && bCopyAsMove)
         maRanges.UpdateReference(URM_MOVE, pDoc, rCxt.maRange, rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
     else
         maRanges.UpdateReference(rCxt.meMode, pDoc, rCxt.maRange, rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
+
+    for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
+        (*itr)->UpdateReference(rCxt);
 }
 
 void ScConditionalFormat::InsertRow(SCTAB nTab, SCCOL nColStart, SCCOL nColEnd, SCROW nRowPos, SCSIZE nSize)
@@ -2087,31 +2066,6 @@ void ScConditionalFormat::RenameCellStyle(const OUString& rOld, const OUString&
         }
 }
 
-void ScConditionalFormat::SourceChanged( const ScAddress& rAddr )
-{
-    for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
-    {
-        condformat::ScFormatEntryType eEntryType = (*itr)->GetType();
-        if( eEntryType == condformat::CONDITION)
-        {
-            ScCondFormatEntry& rFormat = static_cast<ScCondFormatEntry&>(**itr);
-            rFormat.SourceChanged( rAddr );
-        }
-        else if( eEntryType == condformat::COLORSCALE ||
-                eEntryType == condformat::DATABAR ||
-                eEntryType == condformat::ICONSET )
-        {
-            ScColorFormat& rFormat = static_cast<ScColorFormat&>(**itr);
-            if(rFormat.NeedsRepaint())
-            {
-                // we need to repaint the whole range anyway
-                DoRepaint(nullptr);
-                return;
-            }
-        }
-    }
-}
-
 bool ScConditionalFormat::MarkUsedExternalReferences() const
 {
     bool bAllMarked = false;
@@ -2286,14 +2240,6 @@ void ScConditionalFormatList::DeleteArea( SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
     CheckAllEntries();
 }
 
-void ScConditionalFormatList::SourceChanged( const ScAddress& rAddr )
-{
-    for (auto const& it : m_ConditionalFormats)
-    {
-        it->SourceChanged( rAddr );
-    }
-}
-
 ScConditionalFormatList::iterator ScConditionalFormatList::begin()
 {
     return m_ConditionalFormats.begin();
@@ -2352,4 +2298,9 @@ void ScConditionalFormatList::endRendering()
     }
 }
 
+void ScConditionalFormatList::clear()
+{
+    m_ConditionalFormats.clear();
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index 82afce2..98025ec 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -74,18 +74,6 @@ void ScDocument::Broadcast( const ScHint& rHint )
             TrackFormulas( rHint.GetId() );
     }
 
-    // Repaint for conditional formats with relative references:
-    for(SCTAB nTab = 0; nTab < static_cast<SCTAB>(maTabs.size()); ++nTab)
-    {
-        if(!maTabs[nTab])
-            continue;
-
-        ScConditionalFormatList* pCondFormList = GetCondFormList(nTab);
-        if ( pCondFormList && rHint.GetAddress() != BCA_BRDCST_ALWAYS )
-            pCondFormList->SourceChanged( rHint.GetAddress() );
-
-    }
-
     if ( rHint.GetAddress() != BCA_BRDCST_ALWAYS )
     {
         SCTAB nTab = rHint.GetAddress().Tab();
@@ -131,32 +119,6 @@ void ScDocument::BroadcastCells( const ScRange& rRange, sal_uInt32 nHint, bool b
             TrackFormulas(nHint);
     }
 
-    // Repaint for conditional formats with relative references:
-    for (SCTAB nTab = nTab1; nTab <= nTab2; ++nTab)
-    {
-        ScTable* pTab = FetchTable(nTab);
-        if (!pTab)
-            continue;
-
-        ScConditionalFormatList* pCondFormList = GetCondFormList(nTab);
-        if (pCondFormList && !pCondFormList->empty())
-        {
-            /* TODO: looping over all possible cells is a terrible bottle neck,
-             * for each cell looping over all conditional formats even worse,
-             * this certainly needs a better method. */
-            ScAddress aAddress( 0, 0, nTab);
-            for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
-            {
-                aAddress.SetRow(nRow);
-                for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
-                {
-                    aAddress.SetCol(nCol);
-                    pCondFormList->SourceChanged(aAddress);
-                }
-            }
-        }
-    }
-
     for (SCTAB nTab = nTab1; nTab <= nTab2; ++nTab)
     {
         ScTable* pTab = FetchTable(nTab);
@@ -268,16 +230,6 @@ void ScDocument::AreaBroadcast( const ScHint& rHint )
         if ( pBASM->AreaBroadcast( rHint ) )
             TrackFormulas( rHint.GetId() );
     }
-
-    for(SCTAB nTab = 0; nTab < static_cast<SCTAB>(maTabs.size()); ++nTab)
-    {
-        if(!maTabs[nTab])
-            continue;
-
-        ScConditionalFormatList* pCondFormList = GetCondFormList(nTab);
-        if ( pCondFormList && rHint.GetAddress() != BCA_BRDCST_ALWAYS )
-            pCondFormList->SourceChanged( rHint.GetAddress() );
-    }
 }
 
 void ScDocument::DelBroadcastAreasInRange( const ScRange& rRange )
@@ -608,16 +560,6 @@ void ScDocument::TrackFormulas( sal_uInt32 nHintId )
             if (pBC)
                 pBC->Broadcast( aHint );
             pBASM->AreaBroadcast( aHint );
-            // Repaint for conditional formats with relative references:
-            TableContainer::iterator itr = maTabs.begin();
-            for(; itr != maTabs.end(); ++itr)
-            {
-                if(!*itr)
-                    continue;
-                ScConditionalFormatList* pCondFormList = (*itr)->GetCondFormList();
-                if ( pCondFormList )
-                    pCondFormList->SourceChanged( pTrack->aPos );
-            }
             // for "calculate" event, keep track of which sheets are affected by tracked formulas
             if ( bCalcEvent )
                 SetCalcNotification( pTrack->aPos.Tab() );
diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx
index e438b1e..090b016 100644
--- a/sc/source/core/data/documen9.cxx
+++ b/sc/source/core/data/documen9.cxx
@@ -54,6 +54,7 @@
 #include "postit.hxx"
 #include "charthelper.hxx"
 #include "interpre.hxx"
+#include "conditio.hxx"
 #include <documentlinkmgr.hxx>
 
 using namespace ::com::sun::star;
@@ -517,7 +518,13 @@ void ScDocument::Clear( bool bFromDestructor )
 {
     TableContainer::iterator it = maTabs.begin();
     for (;it != maTabs.end(); ++it)
+        if (*it)
+            (*it)->GetCondFormList()->clear();
+
+    it = maTabs.begin();
+    for (;it != maTabs.end(); ++it)
         delete *it;
+
     maTabs.clear();
     delete pSelectionAttr;
     pSelectionAttr = nullptr;
diff --git a/sc/source/ui/condformat/condformatdlg.cxx b/sc/source/ui/condformat/condformatdlg.cxx
index 0884f33..8f0d621 100644
--- a/sc/source/ui/condformat/condformatdlg.cxx
+++ b/sc/source/ui/condformat/condformatdlg.cxx
@@ -172,6 +172,8 @@ ScConditionalFormat* ScCondFormatList::GetConditionalFormat() const
         return nullptr;
 
     ScConditionalFormat* pFormat = new ScConditionalFormat(0, mpDoc);
+    pFormat->SetRange(maRanges);
+
     for(EntryContainer::const_iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
     {
         ScFormatEntry* pEntry = (*itr)->GetEntry();
@@ -179,8 +181,6 @@ ScConditionalFormat* ScCondFormatList::GetConditionalFormat() const
             pFormat->AddEntry(pEntry);
     }
 
-    pFormat->SetRange(maRanges);
-
     return pFormat;
 }
 


More information about the Libreoffice-commits mailing list