summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-01-28 17:28:54 +0100
committerMiklos Vajna <vmiklos@collabora.com>2021-01-28 18:41:17 +0100
commit6de46444027d03b617d02b66434f626c5723501f (patch)
treef1495804b38b7b18a0b1fb48ef1bc7ead57805e2
parent4e84a42add9c8ac27feb5e49a96e00ffcc8f0bc8 (diff)
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. Change-Id: Iad555727e5e2b069bbffae0e7650fb8c75a56770 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110079 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
-rw-r--r--sw/qa/extras/tiledrendering/tiledrendering.cxx57
-rw-r--r--sw/source/core/txtnode/ndtxt.cxx50
2 files changed, 98 insertions, 9 deletions
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 28edd8c5fb55..eb453e9bbec8 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>
constexpr OUStringLiteral DATA_DIRECTORY = u"/sw/qa/extras/tiledrendering/data/";
@@ -148,6 +149,7 @@ public:
void testTablePaintInvalidate();
void testSpellOnlineRenderParameter();
void testExtTextInputReadOnly();
+ void testBulletDeleteInvalidation();
CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
CPPUNIT_TEST(testRegisterCallback);
@@ -222,13 +224,17 @@ public:
CPPUNIT_TEST(testTablePaintInvalidate);
CPPUNIT_TEST(testSpellOnlineRenderParameter);
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;
@@ -309,17 +315,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;
@@ -2929,6 +2938,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 9575652feec1..5516136db040 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);