[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - 3 commits - sw/qa sw/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Tue Mar 30 09:08:38 UTC 2021


 sw/qa/extras/tiledrendering/tiledrendering.cxx |  129 +++++++++++++++++++++++--
 sw/source/core/docnode/nodes.cxx               |   13 ++
 sw/source/core/inc/txtfrm.hxx                  |    6 +
 sw/source/core/txtnode/ndtxt.cxx               |   46 ++++++++
 4 files changed, 182 insertions(+), 12 deletions(-)

New commits:
commit c2bb0186a9a9da50403e3974f1d2be80cac05d2d
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon Feb 1 10:09:19 2021 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Mar 30 11:08:04 2021 +0200

    sw: don't repaint all text frames on selecting and deleting several bullets
    
    This is similar to disabling bullets for a paragraph, but in this case
    the text nodes are deleted as well.
    
    It seems to me that both invalidations are only useful in the numberging
    (e.g. Arabic) case, and not in the bullet case.
    
    (cherry picked from commit e267fe1a3dffc39bf5076dd6413ed3b0e698378c)
    
    Change-Id: Ie03e2847e5e50d9464399f4ea0840910e43a663a

diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 250d685d5faa..a8fa06ba50c8 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -150,6 +150,7 @@ public:
     void testExtTextInputReadOnly();
     void testBulletDeleteInvalidation();
     void testBulletNoNumInvalidation();
+    void testBulletMultiDeleteInvalidation();
 
     CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
     CPPUNIT_TEST(testRegisterCallback);
@@ -225,6 +226,7 @@ public:
     CPPUNIT_TEST(testExtTextInputReadOnly);
     CPPUNIT_TEST(testBulletDeleteInvalidation);
     CPPUNIT_TEST(testBulletNoNumInvalidation);
+    CPPUNIT_TEST(testBulletMultiDeleteInvalidation);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -2987,6 +2989,42 @@ void SwTiledRenderingTest::testBulletNoNumInvalidation()
     CPPUNIT_ASSERT(!aFirstTextRect.IsOver(m_aInvalidations));
 }
 
+void SwTiledRenderingTest::testBulletMultiDeleteInvalidation()
+{
+    // Given a document with 5 paragraphs: all are bulleted.
+    SwXTextDocument* pXTextDocument = createDoc();
+    SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell();
+    pWrtShell->StartAllAction();
+    pWrtShell->BulletOn();
+    pWrtShell->EndAllAction();
+    // There is alredy an initial text node, so type 5 times, but split 4 times.
+    for (int i = 0; i < 4; ++i)
+    {
+        pWrtShell->Insert2("a");
+        pWrtShell->SplitNode();
+    }
+    pWrtShell->Insert2("a");
+    // Go to the end of the 4th para.
+    pWrtShell->Up(/*bSelect=*/false);
+    pWrtShell->GetLayout()->PaintSwFrame(*pWrtShell->GetOut(),
+                                         pWrtShell->GetLayout()->getFrameArea());
+    Scheduler::ProcessEventsToIdle();
+    pWrtShell->GetSfxViewShell()->registerLibreOfficeKitViewCallback(&SwTiledRenderingTest::callback, this);
+    m_aInvalidations = tools::Rectangle();
+
+    // When selecting and deleting several bullets: select till the end of the 2nd para and delete.
+    pWrtShell->Up(/*bSelect=*/true, /*nCount=*/2);
+    pWrtShell->DelRight();
+
+    // Then the first paragraph should not be invalidated.
+    SwRootFrame* pRoot = pWrtShell->GetLayout();
+    SwFrame* pPage = pRoot->GetLower();
+    SwFrame* pBody = pPage->GetLower();
+    SwFrame* pFirstText = pBody->GetLower();
+    tools::Rectangle aFirstTextRect = pFirstText->getFrameArea().SVRect();
+    CPPUNIT_ASSERT(!aFirstTextRect.IsOver(m_aInvalidations));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/docnode/nodes.cxx b/sw/source/core/docnode/nodes.cxx
index a7a2078b2091..3a05e69f6854 100644
--- a/sw/source/core/docnode/nodes.cxx
+++ b/sw/source/core/docnode/nodes.cxx
@@ -43,6 +43,7 @@
 #include <fmtftn.hxx>
 
 #include <docsh.hxx>
+#include <txtfrm.hxx>
 
 typedef std::vector<SwStartNode*> SwStartNodePointers;
 
@@ -227,8 +228,13 @@ void SwNodes::ChgNode( SwNodeIndex const & rDelPos, sal_uLong nSz,
                     }
                 }
                 else
+                {
                     // if movement into the UndoNodes-array, update numbering
-                    pTextNd->InvalidateNumRule();
+                    if (sw::HasNumberingWhichNeedsLayoutUpdate(*pTextNd))
+                    {
+                        pTextNd->InvalidateNumRule();
+                    }
+                }
 
                 pTextNd->RemoveFromList();
             }
@@ -1197,7 +1203,10 @@ void SwNodes::Delete(const SwNodeIndex &rIndex, sal_uLong nNodes)
                     m_pOutlineNodes->erase( pTextNd );
                     bUpdateOutline = true;
                 }
-                pTextNd->InvalidateNumRule();
+                if (sw::HasNumberingWhichNeedsLayoutUpdate(*pTextNd))
+                {
+                    pTextNd->InvalidateNumRule();
+                }
             }
             else if( pCurrentNode->IsContentNode() )
                 static_cast<SwContentNode*>(pCurrentNode)->InvalidateNumRule();
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index 389adb8c92ad..ff6086e1ac1f 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -144,6 +144,12 @@ bool IsMarkHintHidden(SwRootFrame const& rLayout,
 
 void RecreateStartTextFrames(SwTextNode & rNode);
 
+/**
+ * Decides if rTextNode has a numbering which has layout-level values (e.g. Arabic, but not
+ * none or bullets).
+ */
+bool HasNumberingWhichNeedsLayoutUpdate(const SwTextNode& rTextNode);
+
 } // namespace sw
 
 /// Represents the visualization of a paragraph. Typical upper is an
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index c615a8564289..fa29e80ad20e 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -910,15 +910,7 @@ void CheckResetRedlineMergeFlag(SwTextNode & rNode, Recreate const eRecreateMerg
     }
 }
 
-} // namespace
-
-namespace
-{
-/**
- * Decides if rTextNode has a numbering which has layout-level values (e.g. Arabic, but not
- * none or bullets).
- */
-bool NeedsRenumbering(const SwTextNode& rTextNode)
+bool HasNumberingWhichNeedsLayoutUpdate(const SwTextNode& rTextNode)
 {
     const SwNodeNum* pNodeNum = rTextNode.GetNum();
     if (!pNodeNum)
@@ -949,7 +941,7 @@ bool NeedsRenumbering(const SwTextNode& rTextNode)
             return true;
     }
 }
-}
+} // namespace
 
 SwContentNode *SwTextNode::JoinNext()
 {
@@ -1033,14 +1025,14 @@ SwContentNode *SwTextNode::JoinNext()
             rDoc.CorrAbs( aIdx, SwPosition( *this ), nOldLen, true );
         }
         SwNode::Merge const eOldMergeFlag(pTextNode->GetRedlineMergeFlag());
-        bool bOldNeedsRenumbering = NeedsRenumbering(*pTextNode);
+        bool bOldHasNumberingWhichNeedsLayoutUpdate = HasNumberingWhichNeedsLayoutUpdate(*pTextNode);
 
         rNds.Delete(aIdx);
         SetWrong( pList, false );
         SetGrammarCheck( pList3, false );
         SetSmartTags( pList2, false );
 
-        if (bOldNeedsRenumbering || NeedsRenumbering(*this))
+        if (bOldHasNumberingWhichNeedsLayoutUpdate || HasNumberingWhichNeedsLayoutUpdate(*this))
         {
             // Repaint all text frames that belong to this numbering to avoid outdated generated
             // numbers.
@@ -4884,7 +4876,7 @@ namespace {
                     });
             }
 
-            if (mbUpdateListCount && mrTextNode.IsInList() && NeedsRenumbering(mrTextNode))
+            if (mbUpdateListCount && mrTextNode.IsInList() && HasNumberingWhichNeedsLayoutUpdate(mrTextNode))
             {
                 // Repaint all text frames that belong to this numbering to avoid outdated generated
                 // numbers.
commit 33fdcc5ceae14a9225ca0a76577362986d5037cc
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Jan 29 09:44:04 2021 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Mar 30 11:08:04 2021 +0200

    sw: don't repaint all text frames on turning off a bullet for bullet numberings
    
    This is similar to the text node deletion case, but here no text is
    deleted, just a text node with bullet numbering is turned into one
    without a numbering.
    
    Again, it is not necessary to repaint all text frames of the numbering,
    since the bullet char is the same for all nodes (unlike e.g. Arabic
    numbering).
    
    (cherry picked from commit ccabb67d77e2bcece42434f51cf6d84d393d567c)
    
    Change-Id: Ieb071031ca5ce0421c4120c4c89089af6c811848

diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 9f9359480618..250d685d5faa 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -149,6 +149,7 @@ public:
     void testTablePaintInvalidate();
     void testExtTextInputReadOnly();
     void testBulletDeleteInvalidation();
+    void testBulletNoNumInvalidation();
 
     CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
     CPPUNIT_TEST(testRegisterCallback);
@@ -223,6 +224,7 @@ public:
     CPPUNIT_TEST(testTablePaintInvalidate);
     CPPUNIT_TEST(testExtTextInputReadOnly);
     CPPUNIT_TEST(testBulletDeleteInvalidation);
+    CPPUNIT_TEST(testBulletNoNumInvalidation);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -2953,6 +2955,38 @@ void SwTiledRenderingTest::testBulletDeleteInvalidation()
     CPPUNIT_ASSERT(!aFirstTextRect.IsOver(m_aInvalidations));
 }
 
+void SwTiledRenderingTest::testBulletNoNumInvalidation()
+{
+    // Given a document with 3 paragraphs: all are bulleted.
+    SwXTextDocument* pXTextDocument = createDoc();
+    SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell();
+    pWrtShell->StartAllAction();
+    pWrtShell->BulletOn();
+    pWrtShell->EndAllAction();
+    pWrtShell->Insert2("a");
+    pWrtShell->SplitNode();
+    pWrtShell->Insert2("b");
+    pWrtShell->SplitNode();
+    pWrtShell->GetLayout()->PaintSwFrame(*pWrtShell->GetOut(),
+                                         pWrtShell->GetLayout()->getFrameArea());
+    Scheduler::ProcessEventsToIdle();
+    pWrtShell->GetSfxViewShell()->registerLibreOfficeKitViewCallback(&SwTiledRenderingTest::callback, this);
+    m_aInvalidations = tools::Rectangle();
+
+    // When pressing backspace in the last paragraph to turn bullets off.
+    pWrtShell->StartAllAction();
+    pWrtShell->NumOrNoNum(/*bDelete=*/false);
+    pWrtShell->EndAllAction();
+
+    // Then the first paragraph should not be invalidated.
+    SwRootFrame* pRoot = pWrtShell->GetLayout();
+    SwFrame* pPage = pRoot->GetLower();
+    SwFrame* pBody = pPage->GetLower();
+    SwFrame* pFirstText = pBody->GetLower();
+    tools::Rectangle aFirstTextRect = pFirstText->getFrameArea().SVRect();
+    CPPUNIT_ASSERT(!aFirstTextRect.IsOver(m_aInvalidations));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 1279ca2d848f..c615a8564289 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -4884,8 +4884,10 @@ namespace {
                     });
             }
 
-            if ( mbUpdateListCount && mrTextNode.IsInList() )
+            if (mbUpdateListCount && mrTextNode.IsInList() && NeedsRenumbering(mrTextNode))
             {
+                // Repaint all text frames that belong to this numbering to avoid outdated generated
+                // numbers.
                 mrTextNode.DoNum(
                     [](SwNodeNum & rNum) { rNum.InvalidateAndNotifyTree(); });
             }
commit 599d0868d54cffe663d664143e94d4b450af8f4f
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Jan 28 17:28:54 2021 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Mar 30 11:08:04 2021 +0200

    sw: don't repaint all text frames on text node delete for bullet numberings
    
    The intention of the InvalidateNumRule() call is probably to make sure
    that generated number portions in e.g. Arabic numbering are up to date.
    But this is not necessary for bullets and causes not needed
    invalidations.
    
    (cherry picked from commit 6de46444027d03b617d02b66434f626c5723501f)
    
    Change-Id: Iad555727e5e2b069bbffae0e7650fb8c75a56770

diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index f8ee487ef788..9f9359480618 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -60,6 +60,7 @@
 #include <unotxdoc.hxx>
 #include <docsh.hxx>
 #include <txtfrm.hxx>
+#include <rootfrm.hxx>
 
 char const DATA_DIRECTORY[] = "/sw/qa/extras/tiledrendering/data/";
 
@@ -147,6 +148,7 @@ public:
     void testDropDownFormFieldButtonNoItem();
     void testTablePaintInvalidate();
     void testExtTextInputReadOnly();
+    void testBulletDeleteInvalidation();
 
     CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
     CPPUNIT_TEST(testRegisterCallback);
@@ -220,13 +222,17 @@ public:
     CPPUNIT_TEST(testDropDownFormFieldButtonNoItem);
     CPPUNIT_TEST(testTablePaintInvalidate);
     CPPUNIT_TEST(testExtTextInputReadOnly);
+    CPPUNIT_TEST(testBulletDeleteInvalidation);
     CPPUNIT_TEST_SUITE_END();
 
 private:
     SwXTextDocument* createDoc(const char* pName = nullptr);
     static void callback(int nType, const char* pPayload, void* pData);
     void callbackImpl(int nType, const char* pPayload);
+    // First invalidation.
     tools::Rectangle m_aInvalidation;
+    /// Union of all invalidations.
+    tools::Rectangle m_aInvalidations;
     Size m_aDocumentSize;
     OString m_aTextSelection;
     bool m_bFound;
@@ -307,17 +313,20 @@ void SwTiledRenderingTest::callbackImpl(int nType, const char* pPayload)
     {
     case LOK_CALLBACK_INVALIDATE_TILES:
     {
+        tools::Rectangle aInvalidation;
+        uno::Sequence<OUString> aSeq = comphelper::string::convertCommaSeparated(OUString::createFromAscii(pPayload));
+        if (OString("EMPTY") == pPayload)
+            return;
+        CPPUNIT_ASSERT(aSeq.getLength() == 4 || aSeq.getLength() == 5);
+        aInvalidation.setX(aSeq[0].toInt32());
+        aInvalidation.setY(aSeq[1].toInt32());
+        aInvalidation.setWidth(aSeq[2].toInt32());
+        aInvalidation.setHeight(aSeq[3].toInt32());
         if (m_aInvalidation.IsEmpty())
         {
-            uno::Sequence<OUString> aSeq = comphelper::string::convertCommaSeparated(OUString::createFromAscii(pPayload));
-            if (OString("EMPTY") == pPayload)
-                return;
-            CPPUNIT_ASSERT(aSeq.getLength() == 4 || aSeq.getLength() == 5);
-            m_aInvalidation.setX(aSeq[0].toInt32());
-            m_aInvalidation.setY(aSeq[1].toInt32());
-            m_aInvalidation.setWidth(aSeq[2].toInt32());
-            m_aInvalidation.setHeight(aSeq[3].toInt32());
+            m_aInvalidation = aInvalidation;
         }
+        m_aInvalidations.Union(aInvalidation);
         ++m_nInvalidations;
     }
     break;
@@ -2912,6 +2921,38 @@ void SwTiledRenderingTest::testExtTextInputReadOnly()
     CPPUNIT_ASSERT_EQUAL(OUString("x"), getParagraph(2)->getString());
 }
 
+void SwTiledRenderingTest::testBulletDeleteInvalidation()
+{
+    // Given a document with 3 paragraphs: first 2 is bulleted, the last is not.
+    SwXTextDocument* pXTextDocument = createDoc();
+    SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell();
+    pWrtShell->SplitNode();
+    pWrtShell->Up(/*bSelect=*/false);
+    pWrtShell->StartAllAction();
+    pWrtShell->BulletOn();
+    pWrtShell->EndAllAction();
+    pWrtShell->Insert2("a");
+    pWrtShell->SplitNode();
+    pWrtShell->Insert2("b");
+    pWrtShell->Down(/*bSelect=*/false);
+    pWrtShell->GetLayout()->PaintSwFrame(*pWrtShell->GetOut(),
+                                         pWrtShell->GetLayout()->getFrameArea());
+    Scheduler::ProcessEventsToIdle();
+    pWrtShell->GetSfxViewShell()->registerLibreOfficeKitViewCallback(&SwTiledRenderingTest::callback, this);
+    m_aInvalidations = tools::Rectangle();
+
+    // When pressing backspace in the last paragraph.
+    pWrtShell->DelLeft();
+
+    // Then the first paragraph should not be invalidated.
+    SwRootFrame* pRoot = pWrtShell->GetLayout();
+    SwFrame* pPage = pRoot->GetLower();
+    SwFrame* pBody = pPage->GetLower();
+    SwFrame* pFirstText = pBody->GetLower();
+    tools::Rectangle aFirstTextRect = pFirstText->getFrameArea().SVRect();
+    CPPUNIT_ASSERT(!aFirstTextRect.IsOver(m_aInvalidations));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 1c457429dd04..1279ca2d848f 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -912,6 +912,45 @@ void CheckResetRedlineMergeFlag(SwTextNode & rNode, Recreate const eRecreateMerg
 
 } // namespace
 
+namespace
+{
+/**
+ * Decides if rTextNode has a numbering which has layout-level values (e.g. Arabic, but not
+ * none or bullets).
+ */
+bool NeedsRenumbering(const SwTextNode& rTextNode)
+{
+    const SwNodeNum* pNodeNum = rTextNode.GetNum();
+    if (!pNodeNum)
+    {
+        return false;
+    }
+
+    const SwNumRule* pNumRule = pNodeNum->GetNumRule();
+    if (!pNumRule)
+    {
+        return false;
+    }
+
+    const SwNumFormat* pFormat
+        = pNumRule->GetNumFormat(static_cast<sal_uInt16>(rTextNode.GetAttrListLevel()));
+    if (!pFormat)
+    {
+        return false;
+    }
+
+    switch (pFormat->GetNumberingType())
+    {
+        case SVX_NUM_NUMBER_NONE:
+        case SVX_NUM_CHAR_SPECIAL:
+        case SVX_NUM_BITMAP:
+            return false;
+        default:
+            return true;
+    }
+}
+}
+
 SwContentNode *SwTextNode::JoinNext()
 {
     SwNodes& rNds = GetNodes();
@@ -994,11 +1033,20 @@ SwContentNode *SwTextNode::JoinNext()
             rDoc.CorrAbs( aIdx, SwPosition( *this ), nOldLen, true );
         }
         SwNode::Merge const eOldMergeFlag(pTextNode->GetRedlineMergeFlag());
+        bool bOldNeedsRenumbering = NeedsRenumbering(*pTextNode);
+
         rNds.Delete(aIdx);
         SetWrong( pList, false );
         SetGrammarCheck( pList3, false );
         SetSmartTags( pList2, false );
-        InvalidateNumRule();
+
+        if (bOldNeedsRenumbering || NeedsRenumbering(*this))
+        {
+            // Repaint all text frames that belong to this numbering to avoid outdated generated
+            // numbers.
+            InvalidateNumRule();
+        }
+
         CheckResetRedlineMergeFlag(*this, eOldMergeFlag == SwNode::Merge::First
                                             ? sw::Recreate::ThisNode
                                             : sw::Recreate::No);


More information about the Libreoffice-commits mailing list