sc/inc/stlpool.hxx | 2 sc/source/core/data/stlpool.cxx | 20 ++++++++- sc/source/core/tool/interpr2.cxx | 75 ++++++++++++++++++++++--------------- sc/source/ui/docshell/autostyl.cxx | 5 -- sc/source/ui/docshell/docsh4.cxx | 6 -- 5 files changed, 68 insertions(+), 40 deletions(-)
New commits: commit 95be711bfbcb733eb114d1ff842c0c69f393f81e Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Fri Feb 10 16:04:46 2023 +0300 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Tue Feb 21 13:09:17 2023 +0000 tdf#153510: STYLE: try harder to detect when there's nothing to do 1. Find the real style names early, to avoid re-triggering style application when STYLE arguments use wrong case; 2. Also check a (rare) case when both immediate and delayed styles are the same as currently applied. Change-Id: Id8ab2e321ede6d0f8f05ac5d1e63ade0212e5865 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146775 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> (cherry picked from commit 208a4ecafafa97ea7fcc5a135fa8160e91ea0a74) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146791 Tested-by: Mike Kaganski <mike.kagan...@collabora.com> Reviewed-by: Dennis Francis <dennis.fran...@collabora.com> diff --git a/sc/inc/stlpool.hxx b/sc/inc/stlpool.hxx index f4e3ac757094..51694a405202 100644 --- a/sc/inc/stlpool.hxx +++ b/sc/inc/stlpool.hxx @@ -51,6 +51,8 @@ public: bool HasStandardStyles() const { return bHasStandardStyles; } ScStyleSheet* FindCaseIns( const OUString& rName, SfxStyleFamily eFam ); + // Finds Para style with given name case-insensitively, or STR_STYLENAME_STANDARD + ScStyleSheet* FindAutoStyle(const OUString& rName); virtual SfxStyleSheetBase& Make( const OUString&, SfxStyleFamily eFam, SfxStyleSearchBits nMask = SfxStyleSearchBits::All) override; diff --git a/sc/source/core/data/stlpool.cxx b/sc/source/core/data/stlpool.cxx index 18f856aac2ae..7606190be84a 100644 --- a/sc/source/core/data/stlpool.cxx +++ b/sc/source/core/data/stlpool.cxx @@ -425,6 +425,16 @@ ScStyleSheet* ScStyleSheetPool::FindCaseIns( const OUString& rName, SfxStyleFami return first; } +ScStyleSheet* ScStyleSheetPool::FindAutoStyle(const OUString& rName) +{ + ScStyleSheet* pStyleSheet = FindCaseIns(rName, SfxStyleFamily::Para); + if (!pStyleSheet) + if (auto pFound = Find(ScResId(STR_STYLENAME_STANDARD), SfxStyleFamily::Para)) + if (pFound->isScStyleSheet()) // we do not know what kind of sheets we have + pStyleSheet = static_cast<ScStyleSheet*>(pFound); + return pStyleSheet; +} + void ScStyleSheetPool::setAllParaStandard() { SfxStyleSheetBase* pSheet = First(SfxStyleFamily::Para); diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx index 39f0c96014fa..b22fef03687c 100644 --- a/sc/source/core/tool/interpr2.cxx +++ b/sc/source/core/tool/interpr2.cxx @@ -41,6 +41,7 @@ #include <dpobject.hxx> #include <tokenarray.hxx> #include <globalnames.hxx> +#include <stlpool.hxx> #include <stlsheet.hxx> #include <dpcache.hxx> @@ -2599,38 +2600,54 @@ void ScInterpreter::ScStyle() if (!MustHaveParamCount(nParamCount, 1, 3)) return; - OUString aStyle2; // Template after timer + OUString aStyle2; // Style after timer if (nParamCount >= 3) aStyle2 = GetString().getString(); tools::Long nTimeOut = 0; // timeout if (nParamCount >= 2) nTimeOut = static_cast<tools::Long>(GetDouble()*1000.0); - OUString aStyle1 = GetString().getString(); // Template for immediate + OUString aStyle1 = GetString().getString(); // Style for immediate if (nTimeOut < 0) nTimeOut = 0; - // Execute request to apply template + // Execute request to apply style if ( !mrDoc.IsClipOrUndo() ) { SfxObjectShell* pShell = mrDoc.GetDocumentShell(); if (pShell) { + // Normalize style names right here, making sure that character case is correct, + // and that we only apply anything when there's something to apply + auto pPool = mrDoc.GetStyleSheetPool(); + if (!aStyle1.isEmpty()) + { + if (auto pNewStyle = pPool->FindAutoStyle(aStyle1)) + aStyle1 = pNewStyle->GetName(); + else + aStyle1.clear(); + } + if (!aStyle2.isEmpty()) + { + if (auto pNewStyle = pPool->FindAutoStyle(aStyle2)) + aStyle2 = pNewStyle->GetName(); + else + aStyle2.clear(); + } // notify object shell directly! - bool bNotify = true; - if (aStyle2.isEmpty()) + if (!aStyle1.isEmpty() || !aStyle2.isEmpty()) { const ScStyleSheet* pStyle = mrDoc.GetStyle(aPos.Col(), aPos.Row(), aPos.Tab()); - if (pStyle && pStyle->GetName() == aStyle1) - bNotify = false; - } - - if (bNotify) - { - ScRange aRange(aPos); - ScAutoStyleHint aHint( aRange, aStyle1, nTimeOut, aStyle2 ); - pShell->Broadcast( aHint ); + const bool bNotify = !pStyle + || (!aStyle1.isEmpty() && pStyle->GetName() != aStyle1) + || (!aStyle2.isEmpty() && pStyle->GetName() != aStyle2); + if (bNotify) + { + ScRange aRange(aPos); + ScAutoStyleHint aHint(aRange, aStyle1, nTimeOut, aStyle2); + pShell->Broadcast(aHint); + } } } } diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx index a97a47ecc6ec..a1846286a2db 100644 --- a/sc/source/ui/docshell/docsh4.cxx +++ b/sc/source/ui/docshell/docsh4.cxx @@ -1541,11 +1541,7 @@ void ScDocShell::DoHardRecalc() void ScDocShell::DoAutoStyle( const ScRange& rRange, const OUString& rStyle ) { ScStyleSheetPool* pStylePool = m_aDocument.GetStyleSheetPool(); - ScStyleSheet* pStyleSheet = - pStylePool->FindCaseIns( rStyle, SfxStyleFamily::Para ); - if (!pStyleSheet) - pStyleSheet = static_cast<ScStyleSheet*>( - pStylePool->Find( ScResId(STR_STYLENAME_STANDARD), SfxStyleFamily::Para )); + ScStyleSheet* pStyleSheet = pStylePool->FindAutoStyle(rStyle); if (!pStyleSheet) return; commit 747d528305e160fb6f4f9c6a66010b920c6cfe23 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Fri Feb 10 16:44:37 2023 +0300 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Tue Feb 21 13:09:12 2023 +0000 Flatten ScInterpreter::ScStyle Change-Id: I64c622d2c2cacccc7eda02e8739657fe345f9be8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146777 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> (cherry picked from commit 2844670d2a47c606cbebb99f73389f30154a3c5e) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146770 Tested-by: Mike Kaganski <mike.kagan...@collabora.com> Reviewed-by: Dennis Francis <dennis.fran...@collabora.com> diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx index 14d07ae7da98..39f0c96014fa 100644 --- a/sc/source/core/tool/interpr2.cxx +++ b/sc/source/core/tool/interpr2.cxx @@ -2596,48 +2596,46 @@ void ScInterpreter::ScCurrent() void ScInterpreter::ScStyle() { sal_uInt8 nParamCount = GetByte(); - if (nParamCount >= 1 && nParamCount <= 3) - { - OUString aStyle2; // Template after timer - if (nParamCount >= 3) - aStyle2 = GetString().getString(); - tools::Long nTimeOut = 0; // timeout - if (nParamCount >= 2) - nTimeOut = static_cast<tools::Long>(GetDouble()*1000.0); - OUString aStyle1 = GetString().getString(); // Template for immediate + if (!MustHaveParamCount(nParamCount, 1, 3)) + return; - if (nTimeOut < 0) - nTimeOut = 0; + OUString aStyle2; // Template after timer + if (nParamCount >= 3) + aStyle2 = GetString().getString(); + tools::Long nTimeOut = 0; // timeout + if (nParamCount >= 2) + nTimeOut = static_cast<tools::Long>(GetDouble()*1000.0); + OUString aStyle1 = GetString().getString(); // Template for immediate - // Execute request to apply template - if ( !mrDoc.IsClipOrUndo() ) + if (nTimeOut < 0) + nTimeOut = 0; + + // Execute request to apply template + if ( !mrDoc.IsClipOrUndo() ) + { + SfxObjectShell* pShell = mrDoc.GetDocumentShell(); + if (pShell) { - SfxObjectShell* pShell = mrDoc.GetDocumentShell(); - if (pShell) + // notify object shell directly! + bool bNotify = true; + if (aStyle2.isEmpty()) { - // notify object shell directly! - bool bNotify = true; - if (aStyle2.isEmpty()) - { - const ScStyleSheet* pStyle = mrDoc.GetStyle(aPos.Col(), aPos.Row(), aPos.Tab()); + const ScStyleSheet* pStyle = mrDoc.GetStyle(aPos.Col(), aPos.Row(), aPos.Tab()); - if (pStyle && pStyle->GetName() == aStyle1) - bNotify = false; - } + if (pStyle && pStyle->GetName() == aStyle1) + bNotify = false; + } - if (bNotify) - { - ScRange aRange(aPos); - ScAutoStyleHint aHint( aRange, aStyle1, nTimeOut, aStyle2 ); - pShell->Broadcast( aHint ); - } + if (bNotify) + { + ScRange aRange(aPos); + ScAutoStyleHint aHint( aRange, aStyle1, nTimeOut, aStyle2 ); + pShell->Broadcast( aHint ); } } - - PushDouble(0.0); } - else - PushIllegalParameter(); + + PushDouble(0.0); } static ScDdeLink* lcl_GetDdeLink( const sfx2::LinkManager* pLinkMgr, commit a8d01c66b823c3556081f8678059911f1264547f Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Fri Feb 10 13:25:53 2023 +0300 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Tue Feb 21 13:09:08 2023 +0000 tdf#153514: try to find exact match, even when searching case-insensitively Change-Id: Ib3bec382ef80a9078ffde8612c395cb0154fd476 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146747 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> (cherry picked from commit 2a984c77ccb1aa77d9bbd02218d4dc76aaff4a9e) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146769 Tested-by: Mike Kaganski <mike.kagan...@collabora.com> Reviewed-by: Dennis Francis <dennis.fran...@collabora.com> diff --git a/sc/source/core/data/stlpool.cxx b/sc/source/core/data/stlpool.cxx index a03cc61180ec..18f856aac2ae 100644 --- a/sc/source/core/data/stlpool.cxx +++ b/sc/source/core/data/stlpool.cxx @@ -409,14 +409,20 @@ ScStyleSheet* ScStyleSheetPool::FindCaseIns( const OUString& rName, SfxStyleFami CaseInsensitiveNamePredicate aPredicate(rName, eFam); std::vector<sal_Int32> aFoundPositions = GetIndexedStyleSheets().FindPositionsByPredicate(aPredicate); + ScStyleSheet* first = nullptr; // first case insensitive match found for (const auto& rPos : aFoundPositions) { SfxStyleSheetBase *pFound = GetStyleSheetByPositionInIndex(rPos); // we do not know what kind of sheets we have. if (pFound->isScStyleSheet()) - return static_cast<ScStyleSheet*>(pFound); + { + if (pFound->GetName() == rName) // exact case sensitive match + return static_cast<ScStyleSheet*>(pFound); + if (!first) + first = static_cast<ScStyleSheet*>(pFound); + } } - return nullptr; + return first; } void ScStyleSheetPool::setAllParaStandard() commit 2209762dcdae0424d8e8b83e0972246c8654d3d5 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Thu Feb 9 16:06:04 2023 +0300 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Tue Feb 21 13:09:03 2023 +0000 Related: tdf#153510 Avoid modification of iterated container A crash is seen when resizing a document locally; the problem is range-based for loop, which indirectly modifies its range: sclo.dll!ScAutoStyleList::AddInitial(const ScRange & rRange, const rtl::OUString & rStyle1, unsigned __int64 nTimeout, const rtl::OUString & rStyle2) Line 81 C++ sclo.dll!ScDocShell::Notify(SfxBroadcaster & __formal, const SfxHint & rHint) Line 685 C++ svllo.dll!SfxBroadcaster::Broadcast(const SfxHint & rHint) Line 41 C++ sclo.dll!ScInterpreter::ScStyle() Line 2628 C++ sclo.dll!ScInterpreter::Interpret() Line 4441 C++ sclo.dll!ScFormulaCell::InterpretTail(ScInterpreterContext & rContext, ScFormulaCell::ScInterpretTailParameter eTailParam) Line 1947 C++ sclo.dll!ScFormulaCell::Interpret(long nStartOffset, long nEndOffset) Line 1619 C++ sclo.dll!ScFormulaCell::MaybeInterpret() Line 470 C++ sclo.dll!ScFormulaCell::IsValue() Line 2763 C++ sclo.dll!ScConditionEntry::Interpret(const ScAddress & rPos) Line 670 C++ sclo.dll!ScConditionEntry::IsCellValid(ScRefCellValue & rCell, const ScAddress & rPos) Line 1238 C++ sclo.dll!ScConditionalFormat::GetData(ScRefCellValue & rCell, const ScAddress & rPos) Line 1836 C++ sclo.dll!`anonymous namespace'::handleConditionalFormat(ScConditionalFormatList & rCondFormList, const o3tl::sorted_vector<unsigned long,std::less<unsigned long>,o3tl::find_unique,1> & rCondFormats, ScCellInfo * pInfo, ScTableInfo * pTableInfo, ScStyleSheetPool * pStlPool, const ScAddress & rAddr, bool & bHidden, bool & bHideFormula, bool bTabProtect) Line 297 C++ sclo.dll!ScDocument::FillInfo(ScTableInfo & rTabInfo, short nCol1, long nRow1, short nCol2, long nRow2, short nTab, double fColScale, double fRowScale, bool bPageMode, bool bFormulaMode, const ScMarkData * pMarkData) Line 569 C++ sclo.dll!ScGridWindow::Draw(short nX1, long nY1, short nX2, long nY2, ScUpdateMode eMode) Line 556 C++ sclo.dll!ScGridWindow::Paint(OutputDevice & __formal, const tools::Rectangle & rRect) Line 458 C++ vcllo.dll!PaintHelper::DoPaint(const vcl::Region * pRegion) Line 313 C++ vcllo.dll!vcl::Window::ImplCallPaint(const vcl::Region * pRegion, ImplPaintFlags nPaintFlags) Line 617 C++ vcllo.dll!PaintHelper::~PaintHelper() Line 553 C++ vcllo.dll!vcl::Window::ImplCallPaint(const vcl::Region * pRegion, ImplPaintFlags nPaintFlags) Line 623 C++ vcllo.dll!PaintHelper::~PaintHelper() Line 553 C++ vcllo.dll!vcl::Window::ImplCallPaint(const vcl::Region * pRegion, ImplPaintFlags nPaintFlags) Line 623 C++ vcllo.dll!PaintHelper::~PaintHelper() Line 553 C++ vcllo.dll!vcl::Window::ImplCallPaint(const vcl::Region * pRegion, ImplPaintFlags nPaintFlags) Line 623 C++ vcllo.dll!PaintHelper::~PaintHelper() Line 553 C++ vcllo.dll!vcl::Window::ImplCallPaint(const vcl::Region * pRegion, ImplPaintFlags nPaintFlags) Line 623 C++ vcllo.dll!PaintHelper::~PaintHelper() Line 553 C++ vcllo.dll!vcl::Window::ImplCallPaint(const vcl::Region * pRegion, ImplPaintFlags nPaintFlags) Line 623 C++ vcllo.dll!vcl::Window::ImplCallOverlapPaint() Line 646 C++ vcllo.dll!vcl::Window::ImplHandlePaintHdl(Timer * __formal) Line 668 C++ vcllo.dll!vcl::Window::LinkStubImplHandlePaintHdl(void * instance, Timer * data) Line 648 C++ vcllo.dll!Link<Timer *,void>::Call(Timer * data) Line 111 C++ vcllo.dll!Timer::Invoke(Timer * arg) Line 81 C++ vcllo.dll!vcl::Window::ImplHandleResizeTimerHdl(Timer * __formal) Line 684 C++ vcllo.dll!vcl::Window::LinkStubImplHandleResizeTimerHdl(void * instance, Timer * data) Line 674 C++ vcllo.dll!Link<Timer *,void>::Call(Timer * data) Line 111 C++ vcllo.dll!Timer::Invoke(Timer * arg) Line 81 C++ vcllo.dll!vcl::Window::GetSizePixel() Line 2420 C++ sclo.dll!ScTabView::GetGridWidth(ScHSplitPos eWhich) Line 3032 C++ sclo.dll!ScViewData::CellsAtX(short nPosX, short nDir, ScHSplitPos eWhichX, unsigned short nScrSizeX) Line 2634 C++ sclo.dll!ScViewData::VisibleCellsX(ScHSplitPos eWhichX) Line 2710 C++ sclo.dll!ScTabView::PaintArea(short nStartCol, long nStartRow, short nEndCol, long nEndRow, ScUpdateMode eMode) Line 2386 C++ sclo.dll!ScTabViewShell::Notify(SfxBroadcaster & rBC, const SfxHint & rHint) Line 63 C++ svllo.dll!SfxBroadcaster::Broadcast(const SfxHint & rHint) Line 41 C++ sclo.dll!ScDocShell::PostPaint(const ScRangeList & rRanges, PaintPartFlags nPart, unsigned short nExtFlags) Line 172 C++ sclo.dll!ScDocShell::PostPaint(short nStartCol, long nStartRow, short nStartTab, short nEndCol, long nEndRow, short nEndTab, PaintPartFlags nPart, unsigned short nExtFlags) Line 106 C++ sclo.dll!ScDocShell::DoAutoStyle(const ScRange & rRange, const rtl::OUString & rStyle) Line 1580 C++ sclo.dll!ScAutoStyleList::InitHdl(Timer * __formal) Line 92 C++ sclo.dll!ScAutoStyleList::LinkStubInitHdl(void * instance, Timer * data) Line 84 C++ vcllo.dll!Link<Timer *,void>::Call(Timer * data) Line 111 C++ vcllo.dll!Timer::Invoke() Line 76 C++ vcllo.dll!Scheduler::CallbackTaskScheduling() Line 481 C++ vcllo.dll!SalTimer::CallCallback() Line 55 C++ vclplug_winlo.dll!WinSalTimer::ImplHandleElapsedTimer() Line 166 C++ vclplug_winlo.dll!ImplSalYield(bool bWait, bool bHandleAllCurrentEvents) Line 525 C++ vclplug_winlo.dll!WinSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents) Line 581 C++ vcllo.dll!ImplYield(bool i_bWait, bool i_bAllEvents) Line 475 C++ vcllo.dll!Application::Yield() Line 560 C++ vcllo.dll!Application::Execute() Line 453 C++ sofficeapp.dll!desktop::Desktop::Main() Line 1604 C++ vcllo.dll!ImplSVMain() Line 203 C++ vcllo.dll!SVMain() Line 236 C++ sofficeapp.dll!soffice_main() Line 94 C++ soffice.bin!sal_main() Line 51 C soffice.bin!main(int argc, char * * argv) Line 49 C ScAutoStyleList::InitHdl iterated over aInitials, and called pDocSh->DoAutoStyle, which eventually called ScAutoStyleList::AddInitial, which modified aInitials, resulting in dangling reference rInitial back in the ScAutoStyleList::InitHdl. Change-Id: Id4e2aac2f5b0b27a7a57f22c0c9cdf8a1e950f30 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146690 Tested-by: Mike Kaganski <mike.kagan...@collabora.com> Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> (cherry picked from commit a80630b6ee6e7636d2c93c42724ce815c991311c) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146709 Reviewed-by: Michael Stahl <michael.st...@allotropia.de> Tested-by: Jenkins (cherry picked from commit a01f4a1c317520a7a3090cfb2f1c9f21bbc50922) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146761 Reviewed-by: Dennis Francis <dennis.fran...@collabora.com> diff --git a/sc/source/ui/docshell/autostyl.cxx b/sc/source/ui/docshell/autostyl.cxx index 24c9bade1c50..5b6eaa30c296 100644 --- a/sc/source/ui/docshell/autostyl.cxx +++ b/sc/source/ui/docshell/autostyl.cxx @@ -83,7 +83,8 @@ void ScAutoStyleList::AddInitial( const ScRange& rRange, const OUString& rStyle1 IMPL_LINK_NOARG(ScAutoStyleList, InitHdl, Timer *, void) { - for (const auto& rInitial : aInitials) + std::vector<ScAutoStyleInitData> aLocalInitials(std::move(aInitials)); + for (const auto& rInitial : aLocalInitials) { // apply first style immediately pDocSh->DoAutoStyle(rInitial.aRange, rInitial.aStyle1); @@ -92,8 +93,6 @@ IMPL_LINK_NOARG(ScAutoStyleList, InitHdl, Timer *, void) if (rInitial.nTimeout) AddEntry(rInitial.nTimeout, rInitial.aRange, rInitial.aStyle2 ); } - - aInitials.clear(); } void ScAutoStyleList::AddEntry( sal_uLong nTimeout, const ScRange& rRange, const OUString& rStyle )