sw/qa/extras/tiledrendering2/tiledrendering2.cxx | 34 +++++++++++++++++++++ sw/source/uibase/dochdl/swdtflvr.cxx | 36 +++++++++++++++++++++-- 2 files changed, 68 insertions(+), 2 deletions(-)
New commits: commit 8af3bab06ed27a01df370bb5f79e5f15892e778d Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed Jul 17 10:00:43 2024 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Jul 17 11:51:28 2024 +0200 Related: cool#9504 sw: don't invalidate num rules when pasting into bullets Open the bugdoc, navigate to the last para of the first page, enable bullets for that paragraph, paste a one-liner plain text string, observe a 274 ms hang. Commit dc3e022866893d8c0950f2269c0c8d61c24ed9bf (cool#9504 sw: don't invalidate num rules when pasting into a non-num paragraph, 2024-07-15) already fixed a not needed invalidation when pasting plain text at a non-list paragraph, but here the insert point is part of a list, so we still invalidate. Improve this further to also not invalidate when we paste a paragraph which is part of a list, but the numbering type is a bullet, which again doesn't need an invalidation. If the invalidation still happens, then the LOK case still calcs the entire layout in one go, that's not yet fixed here. Change-Id: I97c92aebb67ba8ca66b5820943dc1550d62bb467 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170606 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/sw/qa/extras/tiledrendering2/tiledrendering2.cxx b/sw/qa/extras/tiledrendering2/tiledrendering2.cxx index 779192bdc250..efe53e64bcec 100644 --- a/sw/qa/extras/tiledrendering2/tiledrendering2.cxx +++ b/sw/qa/extras/tiledrendering2/tiledrendering2.cxx @@ -231,6 +231,40 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, testPasteInvalidateNumRules) SwFrame* pPage3 = pPage2->GetNext(); CPPUNIT_ASSERT(!aView.m_aInvalidations.Overlaps(pPage3->getFrameArea().SVRect())); } + +CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, testPasteInvalidateNumRulesBullet) +{ + // Given a document with 3 pages: first page is ~empty, then page break, then pages 2 & 3 have + // bullets: + SwXTextDocument* pXTextDocument = createDoc("numrules.odt"); + CPPUNIT_ASSERT(pXTextDocument); + ViewCallback aView; + SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell(); + pWrtShell->SttEndDoc(/*bStt=*/true); + pWrtShell->Down(/*bSelect=*/false); + pWrtShell->Insert(u"test"_ustr); + pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 4, /*bBasicCall=*/false); + dispatchCommand(mxComponent, u".uno:Cut"_ustr, {}); + dispatchCommand(mxComponent, u".uno:DefaultBullet"_ustr, {}); + aView.m_aInvalidations = tools::Rectangle(); + aView.m_bFullInvalidateSeen = false; + + // When pasting at the end of page 1, in a paragraph that is a bullet (a list, but not a + // numbering): + dispatchCommand(mxComponent, u".uno:PasteUnformatted"_ustr, {}); + + // Then make sure we only invalidate page 1, not page 2 or page 3: + CPPUNIT_ASSERT(!aView.m_bFullInvalidateSeen); + SwRootFrame* pLayout = pWrtShell->GetLayout(); + SwFrame* pPage1 = pLayout->GetLower(); + CPPUNIT_ASSERT(aView.m_aInvalidations.Overlaps(pPage1->getFrameArea().SVRect())); + SwFrame* pPage2 = pPage1->GetNext(); + // Without the accompanying fix in place, this test would have failed, we invalidated page 2 and + // page 3 as well. + CPPUNIT_ASSERT(!aView.m_aInvalidations.Overlaps(pPage2->getFrameArea().SVRect())); + SwFrame* pPage3 = pPage2->GetNext(); + CPPUNIT_ASSERT(!aView.m_aInvalidations.Overlaps(pPage3->getFrameArea().SVRect())); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx index e9cbe2fe675d..b5cd76930891 100644 --- a/sw/source/uibase/dochdl/swdtflvr.cxx +++ b/sw/source/uibase/dochdl/swdtflvr.cxx @@ -2140,6 +2140,39 @@ SotExchangeDest SwTransferable::GetSotDestination( const SwWrtShell& rSh ) return nRet; } +namespace +{ +bool CanSkipInvalidateNumRules(const SwPosition& rInsertPosition) +{ + SwTextNode* pTextNode = rInsertPosition.GetNode().GetTextNode(); + if (!pTextNode) + { + return false; + } + + const SwNodeNum* pNum = pTextNode->GetNum(); + if (pNum) + { + SwNumRule* pNumRule = pNum->GetNumRule(); + if (pNumRule) + { + const SvxNumberType rType = pNumRule->Get(pTextNode->GetActualListLevel()); + if (rType.GetNumberingType() == SVX_NUM_CHAR_SPECIAL) + { + // Bullet list, skip invalidation. + return true; + } + } + + // Numbered list, invalidate. + return false; + } + + // Not a list, skip invalidation. + return true; +} +} + bool SwTransferable::PasteFileContent( const TransferableDataHelper& rData, SwWrtShell& rSh, SotClipboardFormatId nFormat, bool bMsg, bool bIgnoreComments ) { @@ -2160,8 +2193,7 @@ bool SwTransferable::PasteFileContent( const TransferableDataHelper& rData, pRead = ReadAscii; const SwPosition& rInsertPosition = *rSh.GetCursor()->Start(); - SwTextNode* pTextNode = rInsertPosition.GetNode().GetTextNode(); - if (pTextNode && !pTextNode->GetNum()) + if (CanSkipInvalidateNumRules(rInsertPosition)) { // Insertion point is not a numbering and we paste plain text: then no need to // invalidate all numberings.