sw/qa/extras/tiledrendering/tiledrendering.cxx |   34 +++++++++++++++++++++++
 sw/source/uibase/dochdl/swdtflvr.cxx           |   36 +++++++++++++++++++++++--
 2 files changed, 68 insertions(+), 2 deletions(-)

New commits:
commit b57fd970d0255d45dea472957abf471eb537d3d3
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Jul 17 10:00:43 2024 +0200
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Thu Jul 18 09:51:08 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.
    
    (cherry picked from commit 8af3bab06ed27a01df370bb5f79e5f15892e778d)
    
    Conflicts:
            sw/qa/extras/tiledrendering2/tiledrendering2.cxx
    
    Change-Id: I97c92aebb67ba8ca66b5820943dc1550d62bb467
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170675
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx 
b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index c7d0a61754ec..471f4183388b 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -4413,6 +4413,40 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, 
testPasteInvalidateNumRules)
     
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();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx 
b/sw/source/uibase/dochdl/swdtflvr.cxx
index f815355987b4..80be5fc31189 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -2145,6 +2145,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 )
 {
@@ -2165,8 +2198,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.

Reply via email to