editeng/qa/unit/core-test.cxx          |   47 +++++++++++++++++++++++++++++++++
 editeng/source/editeng/ContentNode.cxx |    3 +-
 editeng/source/items/flditem.cxx       |   27 +++++++++++++++---
 sc/inc/editutil.hxx                    |    5 +++
 sc/source/core/tool/editutil.cxx       |   19 ++++++++++++-
 sc/source/ui/view/prevwsh.cxx          |    7 ----
 sc/source/ui/view/printfun.cxx         |    7 ----
 sc/source/ui/view/tabvwsh4.cxx         |    8 +----
 sw/source/core/fields/docufld.cxx      |   23 ++++++++++++----
 9 files changed, 116 insertions(+), 30 deletions(-)

New commits:
commit 52d8e57447f93a47cfeaea35ee1346ba95699904
Author:     Michael Meeks <[email protected]>
AuthorDate: Tue Feb 10 21:22:31 2026 +0000
Commit:     Caolán McNamara <[email protected]>
CommitDate: Sat Feb 28 17:03:42 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]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200676
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx
index c68727f575af..7ce9de7c1f2a 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>
@@ -134,6 +135,7 @@ public:
     void testTdf154248MultilineFieldWrapping();
     void testTdf151748StaleKashidaArray();
     void testTdf162803StaleKashidaArray();
+    void testEscapementNotPreservedOnParaBreak();
 
     DECL_STATIC_LINK(Test, CalcFieldValueHdl, EditFieldInfo*, void);
 
@@ -168,6 +170,7 @@ public:
     CPPUNIT_TEST(testTdf154248MultilineFieldWrapping);
     CPPUNIT_TEST(testTdf151748StaleKashidaArray);
     CPPUNIT_TEST(testTdf162803StaleKashidaArray);
+    CPPUNIT_TEST(testEscapementNotPreservedOnParaBreak);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -2372,6 +2375,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 56c2659c7025..1904e55cb1aa 100644
--- a/editeng/source/editeng/ContentNode.cxx
+++ b/editeng/source/editeng/ContentNode.cxx
@@ -302,7 +302,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);
commit eef50420cbed14c979ff4d35bc07c94dfb6149f6
Author:     Caolán McNamara <[email protected]>
AuthorDate: Fri Jan 30 10:43:23 2026 +0000
Commit:     Caolán McNamara <[email protected]>
CommitDate: Sat Feb 28 17:03:35 2026 +0100

    Use Documents/filename in jailed mode as file path field results
    
    The path is useless in jailed kit mode, so present a field result that
    the document is in some (translated) "Documents" toplevel directory when
    LibreOfficeKit::isActive() so it's stable between runs and retains some
    structural hint to distinguish between the various field modes.
    
    Change-Id: Ia8040924396207583e1a12b989d8862962371fc9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198420
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Miklos Vajna <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200675
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/editeng/source/items/flditem.cxx b/editeng/source/items/flditem.cxx
index 70a54653b090..96f1952bd8da 100644
--- a/editeng/source/items/flditem.cxx
+++ b/editeng/source/items/flditem.cxx
@@ -24,11 +24,15 @@
 #include <svl/zforlist.hxx>
 #include <tools/urlobj.hxx>
 
+#include <comphelper/lok.hxx>
 #include <editeng/flditem.hxx>
 #include <editeng/CustomPropertyField.hxx>
 #include <editeng/measfld.hxx>
 #include <editeng/unonames.hxx>
 
+#include <sfx2/sfxresid.hxx>
+#include <sfx2/strings.hrc>
+
 #include <tools/debug.hxx>
 #include <libxml/xmlwriter.h>
 
@@ -735,17 +739,30 @@ OUString SvxExtFileField::GetFormatted() const
     }
     else if( INetProtocol::File == aURLObj.GetProtocol() )
     {
+        // Note: The path is useless in jailed kit mode, so present a view that
+        // the document is in a Documents toplevel directory for 
LibreOfficeKit::isActive()
         switch( eFormat )
         {
             case SvxFileFormat::PathFull:
-                aString = aURLObj.getFSysPath(FSysStyle::Detect);
+                if (comphelper::LibreOfficeKit::isActive())
+                {
+                    aString = "/" + SfxResId(STR_GID_DOCUMENT) + "/" +
+                        aURLObj.getName(INetURLObject::LAST_SEGMENT, true, 
INetURLObject::DecodeMechanism::Unambiguous);
+                }
+                else
+                    aString = aURLObj.getFSysPath(FSysStyle::Detect);
             break;
 
             case SvxFileFormat::PathOnly:
-                aURLObj.removeSegment(INetURLObject::LAST_SEGMENT, false);
-                // #101742# Leave trailing slash at the pathname
-                aURLObj.setFinalSlash();
-                aString = aURLObj.getFSysPath(FSysStyle::Detect);
+                if (comphelper::LibreOfficeKit::isActive())
+                    aString = "/" + SfxResId(STR_GID_DOCUMENT);
+                else
+                {
+                    aURLObj.removeSegment(INetURLObject::LAST_SEGMENT, false);
+                    // #101742# Leave trailing slash at the pathname
+                    aURLObj.setFinalSlash();
+                    aString = aURLObj.getFSysPath(FSysStyle::Detect);
+                }
             break;
 
             case SvxFileFormat::NameOnly:
diff --git a/sc/inc/editutil.hxx b/sc/inc/editutil.hxx
index b580a811d4da..ae105b72e599 100644
--- a/sc/inc/editutil.hxx
+++ b/sc/inc/editutil.hxx
@@ -29,6 +29,7 @@
 #include <tools/fract.hxx>
 #include <vcl/outdev.hxx>
 
+class INetURLObject;
 class ScDocument;
 class ScPatternAttr;
 class ScEditEngineDefaulter;
@@ -209,6 +210,10 @@ struct ScHeaderFieldData
     SvxNumType  eNumType;
 
     ScHeaderFieldData();
+
+    // Set aLongDocName and aShortDocName from rURLObj,
+    // falling back back to aTitle,
+    void SetDocNames(const INetURLObject& rURLObj);
 };
 
 // for headers/footers with fields
diff --git a/sc/source/core/tool/editutil.cxx b/sc/source/core/tool/editutil.cxx
index 89a4622f8f41..6176ed8765cc 100644
--- a/sc/source/core/tool/editutil.cxx
+++ b/sc/source/core/tool/editutil.cxx
@@ -18,6 +18,7 @@
  */
 
 #include <scitems.hxx>
+#include <comphelper/lok.hxx>
 #include <comphelper/processfactory.hxx>
 #include <editeng/eeitem.hxx>
 
@@ -32,7 +33,8 @@
 #include <svl/numformat.hxx>
 #include <svl/inethist.hxx>
 #include <sfx2/objsh.hxx>
-#include <comphelper/lok.hxx>
+#include <sfx2/sfxresid.hxx>
+#include <sfx2/strings.hrc>
 #include <osl/diagnose.h>
 
 #include <com/sun/star/text/textfield/Type.hpp>
@@ -880,6 +882,21 @@ OUString ScHeaderEditEngine::CalcFieldValue( const 
SvxFieldItem& rField,
     return aRet;
 }
 
+void ScHeaderFieldData::SetDocNames(const INetURLObject& rURLObj)
+{
+    aLongDocName = 
rURLObj.GetMainURL(INetURLObject::DecodeMechanism::Unambiguous);
+    if (!aLongDocName.isEmpty())
+    {
+        aShortDocName = 
rURLObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
+        // The path is useless in jailed kit mode, so present a view that the
+        // document is in a Documents toplevel directory for 
LibreOfficeKit::isActive()
+        if (comphelper::LibreOfficeKit::isActive())
+            aLongDocName = "/" + SfxResId(STR_GID_DOCUMENT) + "/" + 
aShortDocName;
+    }
+    else
+        aShortDocName = aLongDocName = aTitle;
+}
+
 //                          field data
 
 ScFieldEditEngine::ScFieldEditEngine(
diff --git a/sc/source/ui/view/prevwsh.cxx b/sc/source/ui/view/prevwsh.cxx
index f633c5ebb364..715c17be7c0d 100644
--- a/sc/source/ui/view/prevwsh.cxx
+++ b/sc/source/ui/view/prevwsh.cxx
@@ -876,12 +876,7 @@ void ScPreviewShell::FillFieldData( ScHeaderFieldData& 
rData )
     else
         rData.aTitle = pDocShell->GetTitle();
 
-    const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
-    rData.aLongDocName  = rURLObj.GetMainURL( 
INetURLObject::DecodeMechanism::Unambiguous );
-    if ( !rData.aLongDocName.isEmpty() )
-        rData.aShortDocName = 
rURLObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
-    else
-        rData.aShortDocName = rData.aLongDocName = rData.aTitle;
+    rData.SetDocNames(pDocShell->GetMedium()->GetURLObject());
     rData.nPageNo       = pPreview->GetPageNo() + 1;
 
     bool bAllTested = pPreview->AllTested();
diff --git a/sc/source/ui/view/printfun.cxx b/sc/source/ui/view/printfun.cxx
index a390c0be38c2..26ffd086531b 100644
--- a/sc/source/ui/view/printfun.cxx
+++ b/sc/source/ui/view/printfun.cxx
@@ -1100,12 +1100,7 @@ void ScPrintFunc::InitParam( const ScPrintOptions* 
pOptions )
     else
         aFieldData.aTitle = rDocShell.GetTitle();
 
-    const INetURLObject& rURLObj = rDocShell.GetMedium()->GetURLObject();
-    aFieldData.aLongDocName = rURLObj.GetMainURL( 
INetURLObject::DecodeMechanism::Unambiguous );
-    if ( !aFieldData.aLongDocName.isEmpty() )
-        aFieldData.aShortDocName = 
rURLObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
-    else
-        aFieldData.aShortDocName = aFieldData.aLongDocName = aFieldData.aTitle;
+    aFieldData.SetDocNames(rDocShell.GetMedium()->GetURLObject());
 
     //  Printer settings (Orientation, Paper) at DoPrint
 }
diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx
index d2a3d04e7133..aa3e3406cf8f 100644
--- a/sc/source/ui/view/tabvwsh4.cxx
+++ b/sc/source/ui/view/tabvwsh4.cxx
@@ -2330,12 +2330,8 @@ void ScTabViewShell::FillFieldData( ScHeaderFieldData& 
rData )
     else
         rData.aTitle = pDocShell->GetTitle();
 
-    const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
-    rData.aLongDocName  = rURLObj.GetMainURL( 
INetURLObject::DecodeMechanism::Unambiguous );
-    if ( !rData.aLongDocName.isEmpty() )
-        rData.aShortDocName = 
rURLObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
-    else
-        rData.aShortDocName = rData.aLongDocName = rData.aTitle;
+    rData.SetDocNames(pDocShell->GetMedium()->GetURLObject());
+
     rData.nPageNo       = 1;
     rData.nTotalPages   = 99;
 
diff --git a/sw/source/core/fields/docufld.cxx 
b/sw/source/core/fields/docufld.cxx
index c2639ce82234..1b5b7c068033 100644
--- a/sw/source/core/fields/docufld.cxx
+++ b/sw/source/core/fields/docufld.cxx
@@ -37,6 +37,7 @@
 #include <o3tl/any.hxx>
 #include <o3tl/string_view.hxx>
 #include <unotools/localedatawrapper.hxx>
+#include <comphelper/lok.hxx>
 #include <comphelper/processfactory.hxx>
 #include <comphelper/string.hxx>
 #include <tools/urlobj.hxx>
@@ -55,6 +56,8 @@
 #include <swmodule.hxx>
 #include <sfx2/docfile.hxx>
 #include <sfx2/doctempl.hxx>
+#include <sfx2/sfxresid.hxx>
+#include <sfx2/strings.hrc>
 #include <fmtfld.hxx>
 #include <txtfld.hxx>
 #include <charfmt.hxx>
@@ -436,9 +439,14 @@ OUString SwFileNameFieldType::Expand(SwFileNameFormat 
nFormat) const
     if( pDShell && pDShell->HasName() )
     {
         const INetURLObject& rURLObj = pDShell->GetMedium()->GetURLObject();
+        // Note: The path is useless in jailed kit mode, so present a view that
+        // the document is in a Documents toplevel directory for 
LibreOfficeKit::isActive()
         switch( nFormat & ~SwFileNameFormat::Fixed )
         {
             case SwFileNameFormat::Path:
+                if (comphelper::LibreOfficeKit::isActive())
+                    aRet = "/" + SfxResId(STR_GID_DOCUMENT);
+                else
                 {
                     if( INetProtocol::File == rURLObj.GetProtocol() )
                     {
@@ -470,12 +478,17 @@ OUString SwFileNameFieldType::Expand(SwFileNameFormat 
nFormat) const
                 break;
 
             default:
-                if( INetProtocol::File == rURLObj.GetProtocol() )
-                    aRet = rURLObj.GetFull();
+                if (comphelper::LibreOfficeKit::isActive())
+                    aRet = "/" + SfxResId(STR_GID_DOCUMENT) + "/" + 
rURLObj.GetLastName(INetURLObject::DecodeMechanism::WithCharset);
                 else
-                    aRet = URIHelper::removePassword(
-                                    rURLObj.GetMainURL( 
INetURLObject::DecodeMechanism::NONE ),
-                                    
INetURLObject::EncodeMechanism::WasEncoded, URL_DECODE );
+                {
+                    if( INetProtocol::File == rURLObj.GetProtocol() )
+                        aRet = rURLObj.GetFull();
+                    else
+                        aRet = URIHelper::removePassword(
+                                        rURLObj.GetMainURL( 
INetURLObject::DecodeMechanism::NONE ),
+                                        
INetURLObject::EncodeMechanism::WasEncoded, URL_DECODE );
+                }
         }
     }
     return aRet;

Reply via email to