sw/CppunitTest_sw_core_txtnode.mk |    1 +
 sw/qa/core/txtnode/txtnode.cxx    |   26 ++++++++++++++++++++++++++
 sw/source/core/txtnode/ndtxt.cxx  |   31 +++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+)

New commits:
commit 46a9ca4b551b2d08b04e2b0cc28ea51579abf40f
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri May 6 15:21:45 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue May 10 10:38:37 2022 +0200

    sw: don't copy useless char escapement to next node on split
    
    Unless autocorrect notices such a just-typed content, pressing enter at
    the end of a paragraph which ends with superscript or subscript text
    will carry over that formatting to the next paragraph, which is hardly
    wanted by any user. Technically this is not copying: paragraph split
    works by creating a next text node, moving all content & formatting to
    this next node, then move part of the content back to the previous node,
    which is all content in case of an enter at the end of a paragraph.
    
    Copying character formatting over to the next text node makes sense:
    e.g. paragraph alignment or boldness is probably something a user wants
    to continue using in the next text node. But superscript is typically
    created by autocorrect in English text for "1st" and similar input, this
    is usually unwanted in the next paragraph.
    
    Fix the problem by special-casing the RES_CHRATR_ESCAPEMENT case and
    remove the matching SvxEscapementItem from the hints of the just created
    next paragraph in case it's there.
    
    A possible future improvement would be to support this when there are
    other active (direct formatting) hints, in which case going via
    SwDoc::ResetAttrs() is probably a better choice, but the effects of that
    for undo and redlining is not clear.
    
    (cherry picked from commit 71019ec15bd3fe15385443b68614fd2402e0040f)
    
    Conflicts:
            sw/qa/core/txtnode/txtnode.cxx
    
    Change-Id: I57feb99d9a31f16c277eba44f464ab49936b65aa
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134043
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/CppunitTest_sw_core_txtnode.mk 
b/sw/CppunitTest_sw_core_txtnode.mk
index 54aa0865cce3..441e415267b7 100644
--- a/sw/CppunitTest_sw_core_txtnode.mk
+++ b/sw/CppunitTest_sw_core_txtnode.mk
@@ -21,6 +21,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_core_txtnode, \
     comphelper \
     cppu \
     cppuhelper \
+    editeng \
     sal \
     sfx \
     svxcore \
diff --git a/sw/qa/core/txtnode/txtnode.cxx b/sw/qa/core/txtnode/txtnode.cxx
index 9d3c798dc0fa..fbbecc7cb6fa 100644
--- a/sw/qa/core/txtnode/txtnode.cxx
+++ b/sw/qa/core/txtnode/txtnode.cxx
@@ -16,6 +16,7 @@
 #include <vcl/scheduler.hxx>
 #include <sfx2/lokhelper.hxx>
 #include <test/lokcallback.hxx>
+#include <editeng/escapementitem.hxx>
 
 #include <IDocumentStatistics.hxx>
 #include <fmtanchr.hxx>
@@ -158,6 +159,31 @@ CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, 
testTitleFieldInvalidate)
     comphelper::LibreOfficeKit::setActive(false);
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testSplitNodeSuperscriptCopy)
+{
+    // Given a document with superscript text at the end of a paragraph:
+    SwDoc* pDoc = createSwDoc();
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    pWrtShell->Insert("1st");
+    pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/true, 2, 
/*bBasicCall=*/false);
+    SfxItemSet aSet(pWrtShell->GetAttrPool(),
+                    svl::Items<RES_CHRATR_ESCAPEMENT, 
RES_CHRATR_ESCAPEMENT>{});
+    SvxEscapementItem aItem(SvxEscapement::Superscript, RES_CHRATR_ESCAPEMENT);
+    aSet.Put(aItem);
+    pWrtShell->SetAttrSet(aSet);
+
+    // When hitting enter at the end of the paragraph:
+    pWrtShell->SttEndDoc(/*bStt=*/false);
+    pWrtShell->SplitNode(/*bAutoFormat=*/true);
+
+    // Then make sure that the superscript formatting doesn't appear on the 
next paragraph:
+    aSet.ClearItem(RES_CHRATR_ESCAPEMENT);
+    pWrtShell->GetCurAttr(aSet);
+    // Without the accompanying fix in place, this test would have failed, the 
unexpected
+    // superscript appeared in the next paragraph.
+    CPPUNIT_ASSERT(!aSet.HasItem(RES_CHRATR_ESCAPEMENT));
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index fa29e80ad20e..c4d8cd60bb3f 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -702,6 +702,37 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition 
& rPos,
         }
     }
 
+    // pNode is the previous node, 'this' is the next node from the split.
+    if (nSplitPos == nTextLen && m_pSwpHints)
+    {
+        // We just created an empty next node: avoid unwanted superscript in 
the new node if it's
+        // there.
+        for (size_t i = 0; i < m_pSwpHints->Count(); ++i)
+        {
+            SwTextAttr* pHt = m_pSwpHints->Get(i);
+            if (pHt->Which() != RES_TXTATR_AUTOFMT)
+            {
+                continue;
+            }
+
+            const sal_Int32* pEnd = pHt->GetEnd();
+            if (!pEnd || pHt->GetStart() != *pEnd)
+            {
+                continue;
+            }
+
+            const std::shared_ptr<SfxItemSet>& pSet = 
pHt->GetAutoFormat().GetStyleHandle();
+            if (!pSet || pSet->Count() != 1 || 
!pSet->GetItem(RES_CHRATR_ESCAPEMENT))
+            {
+                continue;
+            }
+
+            m_pSwpHints->DeleteAtPos(i);
+            SwTextAttr::Destroy(pHt, GetDoc().GetAttrPool());
+            --i;
+        }
+    }
+
 #ifndef NDEBUG
     if (isHide) // otherwise flags won't be set anyway
     {

Reply via email to