sw/inc/unotextrange.hxx            |    9 ++++++---
 sw/source/core/unocore/unobkm.cxx  |    3 ++-
 sw/source/core/unocore/unoobj2.cxx |   18 +++++++++++++-----
 3 files changed, 21 insertions(+), 9 deletions(-)

New commits:
commit aca6f30c6769ad5573724ffa3a42a595cb20b7fb
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Jan 31 11:47:46 2025 +0100
Commit:     Adolfo Jayme Barrientos <fit...@ubuntu.com>
CommitDate: Sat Feb 1 16:41:57 2025 +0100

    tdf#158198 sw: prevent xBookmark.getAnchor().setString("") from deleting
    
    ... the bookmark.
    
    Add a RANGE_IS_BOOKMARK to SwXTextRange and special case setString() so
    that it will do a replace, not a delete, to prevent the bookmark from
    being deleted.
    
    SwXBookmark::getAnchor() will create such a SwXTextRange.
    
    Bookmarks may be in table cells of course so we need RANGE_IN_CELL to be
    a flag now so it can be used with 2 different enum values.
    
    (regression from commit baf8d2c1c16cb3bdc4edad2560f95fea807a034f)
    
    Change-Id: I69169b9a5f6f7525715122b16de009c894246bef
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180985
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    Tested-by: Jenkins
    (cherry picked from commit b0d4b4664a295631ce4d8dee2ceb5cd94ae12edb)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180988
    Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com>

diff --git a/sw/inc/unotextrange.hxx b/sw/inc/unotextrange.hxx
index b9f2cd2d0d73..1b7eea967fe7 100644
--- a/sw/inc/unotextrange.hxx
+++ b/sw/inc/unotextrange.hxx
@@ -114,14 +114,15 @@ public:
     enum RangePosition
     {
         RANGE_IN_TEXT,  // "ordinary" css::text::TextRange
-        RANGE_IN_CELL,  // position created with a cell that has no uno object
         RANGE_IS_TABLE, // anchor of a table
         RANGE_IS_SECTION, // anchor of a section
+        RANGE_IS_BOOKMARK, ///< anchor of a bookmark
     };
 
     SwXTextRange(SwPaM const & rPam,
             const css::uno::Reference< css::text::XText > & xParent,
-            const enum RangePosition eRange = RANGE_IN_TEXT);
+            const enum RangePosition eRange = RANGE_IN_TEXT,
+            bool isInCell = false);
     // only for RANGE_IS_TABLE
     SwXTextRange(SwTableFormat& rTableFormat);
     // only for RANGE_IS_SECTION
@@ -136,7 +137,8 @@ public:
 
     static rtl::Reference< SwXTextRange > CreateXTextRange(
             SwDoc & rDoc,
-            const SwPosition& rPos, const SwPosition *const pMark);
+            const SwPosition& rPos, const SwPosition *const pMark,
+            RangePosition eRange = RANGE_IN_TEXT);
 
     // XServiceInfo
     virtual OUString SAL_CALL getImplementationName() override;
@@ -209,6 +211,7 @@ public:
 private:
     const SfxItemPropertySet& m_rPropSet;
     const enum RangePosition m_eRangePosition;
+    bool const m_isRangeInCell; //< position created with a cell that has no 
uno object
     SwDoc& m_rDoc;
     css::uno::Reference<css::text::XText> m_xParentText;
     const SwFrameFormat* m_pTableOrSectionFormat;
diff --git a/sw/source/core/unocore/unobkm.cxx 
b/sw/source/core/unocore/unobkm.cxx
index 6df22258bfa9..7d11ca555224 100644
--- a/sw/source/core/unocore/unobkm.cxx
+++ b/sw/source/core/unocore/unobkm.cxx
@@ -266,7 +266,8 @@ uno::Reference< text::XTextRange > SAL_CALL 
SwXBookmark::getAnchor()
             *m_pImpl->m_pDoc,
             m_pImpl->m_pRegisteredBookmark->GetMarkPos(),
             (m_pImpl->m_pRegisteredBookmark->IsExpanded())
-                ? &m_pImpl->m_pRegisteredBookmark->GetOtherMarkPos() : 
nullptr);
+                ? &m_pImpl->m_pRegisteredBookmark->GetOtherMarkPos() : nullptr,
+            SwXTextRange::RANGE_IS_BOOKMARK);
 }
 
 void SAL_CALL SwXBookmark::dispose()
diff --git a/sw/source/core/unocore/unoobj2.cxx 
b/sw/source/core/unocore/unoobj2.cxx
index d2910db91710..56de1e9911f0 100644
--- a/sw/source/core/unocore/unoobj2.cxx
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -702,9 +702,11 @@ void SwXTextRange::MySvtListener::Notify(const SfxHint& 
rHint)
 
 SwXTextRange::SwXTextRange(SwPaM const & rPam,
         const uno::Reference< text::XText > & xParent,
-        const enum RangePosition eRange)
+        const enum RangePosition eRange,
+        bool const isInCell)
     : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
     , m_eRangePosition(eRange)
+    , m_isRangeInCell(isInCell)
     , m_rDoc(rPam.GetDoc())
     , m_xParentText(xParent)
     , m_pTableOrSectionFormat(nullptr)
@@ -718,6 +720,7 @@ SwXTextRange::SwXTextRange(SwPaM const & rPam,
 SwXTextRange::SwXTextRange(SwTableFormat& rTableFormat)
     : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
     , m_eRangePosition(RANGE_IS_TABLE)
+    , m_isRangeInCell(false)
     , m_rDoc(*rTableFormat.GetDoc())
     , m_pTableOrSectionFormat(&rTableFormat)
     , m_pMark(nullptr)
@@ -734,6 +737,7 @@ SwXTextRange::SwXTextRange(SwTableFormat& rTableFormat)
 SwXTextRange::SwXTextRange(SwSectionFormat& rSectionFormat)
     : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
     , m_eRangePosition(RANGE_IS_SECTION)
+    , m_isRangeInCell(false)
     , m_rDoc(*rSectionFormat.GetDoc())
     , m_pTableOrSectionFormat(&rSectionFormat)
     , m_pMark(nullptr)
@@ -1025,7 +1029,10 @@ void SAL_CALL SwXTextRange::setString(const OUString& 
rString)
 {
     SolarMutexGuard aGuard;
 
-    DeleteAndInsert(rString, ::sw::DeleteAndInsertMode::Default);
+    // tdf#158198 avoid deleting bookmark via setString on its anchor
+    DeleteAndInsert(rString, RANGE_IS_BOOKMARK == m_eRangePosition
+                                ? ::sw::DeleteAndInsertMode::ForceReplace
+                                : ::sw::DeleteAndInsertMode::Default);
 }
 
 bool SwXTextRange::GetPositions(SwPaM& rToFill, ::sw::TextRangeMode const 
eMode) const
@@ -1265,7 +1272,8 @@ lcl_IsStartNodeInFormat(const bool bHeader, SwStartNode 
const *const pSttNode,
 
 rtl::Reference< SwXTextRange >
 SwXTextRange::CreateXTextRange(
-    SwDoc & rDoc, const SwPosition& rPos, const SwPosition *const pMark)
+    SwDoc & rDoc, const SwPosition& rPos, const SwPosition *const pMark,
+    RangePosition const eRange)
 {
     const uno::Reference<text::XText> xParentText(
             ::sw::CreateParentXText(rDoc, rPos));
@@ -1277,7 +1285,7 @@ SwXTextRange::CreateXTextRange(
     }
     const bool isCell( dynamic_cast<SwXCell*>(xParentText.get()) );
     return new SwXTextRange(*pNewCursor, xParentText,
-            isCell ? RANGE_IN_CELL : RANGE_IN_TEXT);
+            eRange, isCell);
 }
 
 namespace sw {
@@ -1432,7 +1440,7 @@ SwXTextRange::createEnumeration()
         getText();
     }
 
-    const CursorType eSetType = (RANGE_IN_CELL == m_eRangePosition)
+    const CursorType eSetType = m_isRangeInCell
             ? CursorType::SelectionInTable : CursorType::Selection;
     return SwXParagraphEnumeration::Create(m_xParentText, pNewCursor, 
eSetType);
 }

Reply via email to