From dcd369ceff53c77ba26b91f580d3be2ea105a132 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Szymon=20K=C5=82os?= Date: Wed, 13 Sep 2023 14:57:23 +0200 Subject: [PATCH] Schedule conditional formating repaint after filtering is completed MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit When we have sheet with lots of data with applied conditional formatting and that data is used with autofilter feature - filtering is very slow. That was caused by repaints synchronously called on every row show/hide. ScConditionalFormat::DoRepaint() called by ScFormulaListener callback ... ScDocument::Broadcast ScColumn::BroadcastRows ScTable::SetRowHidden ScTable::DBShowRows This patch schedules repaint in the Idle so we do that after all changes are already applied. Change-Id: If0876ada0f336a41b69560db6a581d6e24d7ac16 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156897 Tested-by: Jenkins CollaboraOffice Reviewed-by: Caolán McNamara (cherry picked from commit c838c24a7e1eee9709789aab99b242f0a0c8c419) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156969 --- sc/inc/conditio.hxx | 20 ++++++++++++++++++++ sc/qa/unit/subsequent_filters_test2.cxx | 3 +++ sc/source/core/data/conditio.cxx | 15 ++++++++++----- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/sc/inc/conditio.hxx b/sc/inc/conditio.hxx index 08f188a7c5a9..4300c80ba190 100644 --- a/sc/inc/conditio.hxx +++ b/sc/inc/conditio.hxx @@ -41,6 +41,7 @@ #include #include +class RepaintInIdle; class ScFormulaCell; class ScTokenArray; struct ScRefCellValue; @@ -443,6 +444,8 @@ private: }; mutable std::unique_ptr mpCache; + + std::unique_ptr mpRepaintTask; }; // single condition entry for conditional formatting @@ -606,6 +609,23 @@ public: void CalcAll(); }; +class RepaintInIdle final : public Idle +{ + ScConditionalFormat* mpCondFormat; + +public: + RepaintInIdle(ScConditionalFormat* pCondFormat) + : Idle("Contitional Format Repaint Idle") + , mpCondFormat(pCondFormat) + {} + + void Invoke() override + { + if (mpCondFormat) + mpCondFormat->DoRepaint(); + } +}; + struct CompareScConditionalFormat { using is_transparent = void; diff --git a/sc/qa/unit/subsequent_filters_test2.cxx b/sc/qa/unit/subsequent_filters_test2.cxx index ce84c891649f..df7f60aded32 100644 --- a/sc/qa/unit/subsequent_filters_test2.cxx +++ b/sc/qa/unit/subsequent_filters_test2.cxx @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -2319,6 +2320,8 @@ void ScFiltersTest2::testCondFormatFormulaListenerXLSX() rDoc.SetDocVisible(true); rDoc.SetValue(0, 0, 0, 2.0); + Scheduler::ProcessEventsToIdle(); + CPPUNIT_ASSERT(aListener.mbCalled); xDocSh->DoClose(); diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx index dba0710f2448..6e2e53d32e90 100644 --- a/sc/source/core/data/conditio.cxx +++ b/sc/source/core/data/conditio.cxx @@ -160,12 +160,13 @@ void ScConditionEntry::StartListening() if (!pCondFormat) return; + mpRepaintTask = std::make_unique(pCondFormat); const ScRangeList& rRanges = pCondFormat->GetRange(); mpListener->stopListening(); start_listen_to(*mpListener, pFormula1.get(), rRanges); start_listen_to(*mpListener, pFormula2.get(), rRanges); - mpListener->setCallback([&]() { pCondFormat->DoRepaint();}); + mpListener->setCallback([&]() { mpRepaintTask->Start();}); } void ScConditionEntry::SetParent(ScConditionalFormat* pParent) @@ -195,7 +196,8 @@ ScConditionEntry::ScConditionEntry( const ScConditionEntry& r ) : bFirstRun(true), mpListener(new ScFormulaListener(*r.mpDoc)), eConditionType( r.eConditionType ), - pCondFormat(r.pCondFormat) + pCondFormat(r.pCondFormat), + mpRepaintTask() { // ScTokenArray copy ctor creates a flat copy if (r.pFormula1) @@ -228,7 +230,8 @@ ScConditionEntry::ScConditionEntry( ScDocument& rDocument, const ScConditionEntr bFirstRun(true), mpListener(new ScFormulaListener(rDocument)), eConditionType( r.eConditionType), - pCondFormat(r.pCondFormat) + pCondFormat(r.pCondFormat), + mpRepaintTask() { // Real copy of the formulas (for Ref Undo) if (r.pFormula1) @@ -262,7 +265,8 @@ ScConditionEntry::ScConditionEntry( ScConditionMode eOper, bFirstRun(true), mpListener(new ScFormulaListener(rDocument)), eConditionType(eType), - pCondFormat(nullptr) + pCondFormat(nullptr), + mpRepaintTask() { Compile( rExpr1, rExpr2, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2, false ); @@ -287,7 +291,8 @@ ScConditionEntry::ScConditionEntry( ScConditionMode eOper, bFirstRun(true), mpListener(new ScFormulaListener(rDocument)), eConditionType(ScFormatEntry::Type::Condition), - pCondFormat(nullptr) + pCondFormat(nullptr), + mpRepaintTask() { if ( pArr1 ) { -- 2.11.4.GIT