diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2021-05-18 14:33:53 +0200 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2021-05-20 09:15:15 +0200 |
commit | 3a86bbd5e06d0fb7c057c761e924111e6499d20e (patch) | |
tree | 8dbb9e61a8ec40c25a8e29a330da0c1824edfa0f | |
parent | 5d992d36412cd41e8489e98ee1d251125219073f (diff) |
sw: fix not needed invalidation of title field on each keypressco-6.4-39
Type a character, SwDocShell::DoFlushDocInfo() is called because the
number of characters changed, and that rapaints all title fields.
This happens as SwFormatField::UpdateTextNode() calls
SwTextField::ExpandTextField() with bForceNotify=true, because that was
needed for conditional text in commit
cd94a84b89c476760ad74bf088a5d6f8ba4ce209 (125044: - use field's content
cache on <SwTxtFld> construction only, 2014-06-13).
Fix the problem by not forcing notifications for title fields in
SwFormatField::UpdateTextNode(): SwTextField::ExpandTextField() will
send a notification if the expend result differs without forcing as
well.
(cherry picked from commit 0a32630d11ebdb8b8218faa066c72582ef2f300d)
Conflicts:
sw/qa/core/txtnode/txtnode.cxx
sw/source/core/txtnode/atrfld.cxx
Change-Id: I5e46ab6aef33ff5e348d40b8644bcc9cf353c326
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115783
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r-- | sw/qa/core/txtnode/data/title-field-invalidate.fodt | 23 | ||||
-rw-r--r-- | sw/qa/core/txtnode/txtnode.cxx | 70 | ||||
-rw-r--r-- | sw/source/core/txtnode/atrfld.cxx | 18 |
3 files changed, 110 insertions, 1 deletions
diff --git a/sw/qa/core/txtnode/data/title-field-invalidate.fodt b/sw/qa/core/txtnode/data/title-field-invalidate.fodt new file mode 100644 index 000000000000..e47129538fa9 --- /dev/null +++ b/sw/qa/core/txtnode/data/title-field-invalidate.fodt @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<office:document xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:meta> + <dc:title>mytitle</dc:title> + </office:meta> + <office:automatic-styles> + <style:page-layout style:name="pm1"> + <style:page-layout-properties fo:page-width="14.8cm" fo:page-height="21.0cm" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm"/> + </style:page-layout> + </office:automatic-styles> + <office:master-styles> + <style:master-page style:name="Standard" style:display-name="Standard" style:page-layout-name="pm1" style:next-style-name="Standard"> + <style:footer> + <text:p><text:title>mytitle</text:title></text:p> + </style:footer> + </style:master-page> + </office:master-styles> + <office:body> + <office:text> + <text:p>body text</text:p> + </office:text> + </office:body> +</office:document> diff --git a/sw/qa/core/txtnode/txtnode.cxx b/sw/qa/core/txtnode/txtnode.cxx index eb675c6e77b8..56040043ed25 100644 --- a/sw/qa/core/txtnode/txtnode.cxx +++ b/sw/qa/core/txtnode/txtnode.cxx @@ -14,8 +14,13 @@ #include <svx/svdpage.hxx> #include <tools/globname.hxx> #include <unotest/bootstrapfixturebase.hxx> +#include <LibreOfficeKit/LibreOfficeKitEnums.h> +#include <comphelper/lok.hxx> +#include <sfx2/viewsh.hxx> #include <vcl/gdimtf.hxx> +#include <vcl/scheduler.hxx> +#include <IDocumentStatistics.hxx> #include <wrtsh.hxx> #include <fmtanchr.hxx> #include <IDocumentDrawModelAccess.hxx> @@ -89,6 +94,71 @@ CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testTextBoxNodeSplit) pWrtShell->SplitNode(); } +namespace +{ +struct ViewCallback +{ + int m_nInvalidations = 0; + + static void callback(int nType, const char* pPayload, void* pData); + void callbackImpl(int nType, const char* pPayload); +}; + +void ViewCallback::callback(int nType, const char* pPayload, void* pData) +{ + static_cast<ViewCallback*>(pData)->callbackImpl(nType, pPayload); +} + +void ViewCallback::callbackImpl(int nType, const char* /*pPayload*/) +{ + switch (nType) + { + case LOK_CALLBACK_INVALIDATE_TILES: + { + ++m_nInvalidations; + } + break; + } +} +} + +CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testTitleFieldInvalidate) +{ + // Set up LOK to track invalidations. + comphelper::LibreOfficeKit::setActive(true); + + // Given a document with a title field: + load(DATA_DIRECTORY, "title-field-invalidate.fodt"); + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + pTextDoc->initializeForTiledRendering({}); + SwDocShell* pShell = pTextDoc->GetDocShell(); + SwDoc* pDoc = pShell->GetDoc(); + SwWrtShell* pWrtShell = pShell->GetWrtShell(); + pWrtShell->SttEndDoc(/*bStt=*/false); + ViewCallback aCallback; + pWrtShell->GetSfxViewShell()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, + &aCallback); + Scheduler::ProcessEventsToIdle(); + aCallback.m_nInvalidations = 0; + + // When typing to the document: + pWrtShell->Insert("x"); + + // Then make sure that only the text frame at the cursor is invalidated: + pDoc->getIDocumentStatistics().GetUpdatedDocStat(/*bCompleteAsync=*/true, /*bFields=*/false); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 1 + // - Actual : 2 + // i.e. the footer was also invalidated on each keypress. + CPPUNIT_ASSERT_EQUAL(1, aCallback.m_nInvalidations); + + // Tear down LOK. + pWrtShell->GetSfxViewShell()->registerLibreOfficeKitViewCallback(nullptr, nullptr); + mxComponent->dispose(); + mxComponent.clear(); + comphelper::LibreOfficeKit::setActive(false); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/txtnode/atrfld.cxx b/sw/source/core/txtnode/atrfld.cxx index ebcdced03c52..d5f76f7ce4bd 100644 --- a/sw/source/core/txtnode/atrfld.cxx +++ b/sw/source/core/txtnode/atrfld.cxx @@ -314,7 +314,23 @@ void SwFormatField::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew ) } } - const bool bForceNotify = (pOld == nullptr) && (pNew == nullptr); + bool bForceNotify = (pOld == nullptr) && (pNew == nullptr); + if (bForceNotify) + { + // Force notify was added for conditional text fields, at least the title fields needs + // no forced notify. + const SwField* pField = mpTextField->GetFormatField().GetField(); + const SwFieldIds nWhich = pField->GetTyp()->Which(); + if (nWhich == SwFieldIds::DocInfo) + { + auto pDocInfoField = static_cast<const SwDocInfoField*>(pField); + if (pDocInfoField->GetSubType() == nsSwDocInfoSubType::DI_TITLE) + { + bForceNotify = false; + } + } + } + mpTextField->ExpandTextField( bForceNotify ); } |