editeng/qa/unit/core-test.cxx          |   47 +++++++++++++++++++++++++++++++++
 editeng/source/editeng/ContentNode.cxx |    3 +-
 2 files changed, 49 insertions(+), 1 deletion(-)

New commits:
commit 03ed94560aaa20070708b265d3a551c862718bc3
Author:     Michael Meeks <[email protected]>
AuthorDate: Tue Feb 10 21:22:31 2026 +0000
Commit:     Miklos Vajna <[email protected]>
CommitDate: Thu Feb 12 09:48:35 2026 +0100

    editeng: don't preserve escapement attribute on paragraph break.
    
    This fixes a particuarly annoying habit of a trailing superscript
    ordinal suffix getting dragged into the next bullet and causing
    the unwary user weird small fonts, and non-aligned bullets.
    
    Nail only the most obvious case, leaving multi-line superscript
    in-place, and ignoring other attributes.
    
    Include unit test.
    
    Change-Id: I9ba5009ed17377e5c2f24c9edb74c3a1c1393cd4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199203
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Miklos Vajna <[email protected]>

diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx
index 5484593ad9c5..fe6773e4f842 100644
--- a/editeng/qa/unit/core-test.cxx
+++ b/editeng/qa/unit/core-test.cxx
@@ -30,6 +30,7 @@
 #include <editeng/editobj.hxx>
 #include <editeng/flditem.hxx>
 #include <editeng/udlnitem.hxx>
+#include <editeng/escapementitem.hxx>
 #include <svl/srchitem.hxx>
 #include <svl/voiditem.hxx>
 #include <editeng/fontitem.hxx>
@@ -130,6 +131,7 @@ public:
     void testTdf154248MultilineFieldWrapping();
     void testTdf151748StaleKashidaArray();
     void testTdf162803StaleKashidaArray();
+    void testEscapementNotPreservedOnParaBreak();
 
     DECL_STATIC_LINK(Test, CalcFieldValueHdl, EditFieldInfo*, void);
 
@@ -164,6 +166,7 @@ public:
     CPPUNIT_TEST(testTdf154248MultilineFieldWrapping);
     CPPUNIT_TEST(testTdf151748StaleKashidaArray);
     CPPUNIT_TEST(testTdf162803StaleKashidaArray);
+    CPPUNIT_TEST(testEscapementNotPreservedOnParaBreak);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -2368,6 +2371,50 @@ void Test::testTdf162803StaleKashidaArray()
     }
 }
 
+void Test::testEscapementNotPreservedOnParaBreak()
+{
+    EditEngine aEditEngine(mpItemPool.get());
+    EditDoc& rDoc = aEditEngine.GetEditDoc();
+
+    OUString aParaText = u"item 1st"_ustr;
+    aEditEngine.SetText(aParaText);
+    CPPUNIT_ASSERT_EQUAL(aParaText, rDoc.GetParaAsString(0));
+
+    {
+        std::unique_ptr<SfxItemSet> pSet(new 
SfxItemSet(aEditEngine.GetEmptyItemSet()));
+        SvxEscapementItem aSuperscript(SvxEscapement::Superscript, 
EE_CHAR_ESCAPEMENT);
+        pSet->Put(aSuperscript);
+        aEditEngine.QuickSetAttribs(*pSet, ESelection(0, 6, 0, 8));
+    }
+
+    {
+        std::unique_ptr<SfxItemSet> pSet(new 
SfxItemSet(aEditEngine.GetEmptyItemSet()));
+        SvxWeightItem aBold(WEIGHT_BOLD, EE_CHAR_WEIGHT);
+        pSet->Put(aBold);
+        aEditEngine.QuickSetAttribs(*pSet, ESelection(0, 6, 0, 8));
+    }
+
+    // new para break at the end of the text (cf. pressing enter)
+    ContentNode* pNode = rDoc.GetObject(0);
+    CPPUNIT_ASSERT(pNode);
+    EditPaM aEndPaM(pNode, pNode->Len());
+    rDoc.InsertParaBreak(aEndPaM, true /* bKeepEndingAttribs */);
+
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), rDoc.Count());
+    CPPUNIT_ASSERT_EQUAL(aParaText, rDoc.GetParaAsString(0));
+    CPPUNIT_ASSERT_EQUAL(OUString(), rDoc.GetParaAsString(1));
+
+    // Check new para's character attributes
+    pNode = rDoc.GetObject(1);
+    CPPUNIT_ASSERT(pNode);
+
+    const EditCharAttrib* pBoldAttr = 
pNode->GetCharAttribs().FindEmptyAttrib(EE_CHAR_WEIGHT, 0);
+    CPPUNIT_ASSERT_MESSAGE("Bold attribute should be carried over.", pBoldAttr 
!= nullptr);
+
+    const EditCharAttrib* pEscAttr = 
pNode->GetCharAttribs().FindEmptyAttrib(EE_CHAR_ESCAPEMENT, 0);
+    CPPUNIT_ASSERT_MESSAGE("Escapement attribute should NOT be included.", 
!pEscAttr);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 }
 
diff --git a/editeng/source/editeng/ContentNode.cxx 
b/editeng/source/editeng/ContentNode.cxx
index b7e7f4b0e8ee..1683c8fc6bdb 100644
--- a/editeng/source/editeng/ContentNode.cxx
+++ b/editeng/source/editeng/ContentNode.cxx
@@ -300,7 +300,8 @@ void ContentNode::CopyAndCutAttribs( ContentNode* 
pPrevNode, SfxItemPool& rPool,
         else if ( pAttrib->GetEnd() == nCut )
         {
             // must be copied as an empty attributes.
-            if ( bKeepEndingAttribs && !pAttrib->IsFeature() && 
!maCharAttribList.FindAttrib( pAttrib->GetItem()->Which(), 0 ) )
+            if ( bKeepEndingAttribs && !pAttrib->IsFeature() && 
!maCharAttribList.FindAttrib( pAttrib->GetItem()->Which(), 0 )
+                && pAttrib->GetItem()->Which() != EE_CHAR_ESCAPEMENT )
             {
                 EditCharAttrib* pNewAttrib = MakeCharAttrib( rPool, 
*(pAttrib->GetItem()), 0, 0 );
                 assert(pNewAttrib);

Reply via email to