sw/inc/unotextrange.hxx | 8 +++++--- sw/source/core/unocore/unobkm.cxx | 3 ++- sw/source/core/unocore/unoobj2.cxx | 25 ++++++++++++++++--------- 3 files changed, 23 insertions(+), 13 deletions(-)
New commits: commit 2273885b0785b91546962925e5ec44326eb302de Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Fri Jan 31 11:47:46 2025 +0100 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Tue Feb 11 22:27:40 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/+/180989 Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com> (cherry picked from commit fe5635c78557ef9f51e3bac1d782cf1c8555655d) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181105 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Michael Weghorn <m.wegh...@posteo.de> Reviewed-by: Christian Lohmaier <lohmaier+libreoff...@googlemail.com> Reviewed-by: Ilmari Lauhakangas <ilmari.lauhakan...@libreoffice.org> diff --git a/sw/inc/unotextrange.hxx b/sw/inc/unotextrange.hxx index 1d2265ddfec1..077bbf3e3e75 100644 --- a/sw/inc/unotextrange.hxx +++ b/sw/inc/unotextrange.hxx @@ -110,14 +110,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 @@ -130,7 +131,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; diff --git a/sw/source/core/unocore/unobkm.cxx b/sw/source/core/unocore/unobkm.cxx index cb9b3894a72e..6f0aa41fdf70 100644 --- a/sw/source/core/unocore/unobkm.cxx +++ b/sw/source/core/unocore/unobkm.cxx @@ -272,7 +272,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 f043515aefb4..5fa37d8b6b98 100644 --- a/sw/source/core/unocore/unoobj2.cxx +++ b/sw/source/core/unocore/unoobj2.cxx @@ -676,16 +676,18 @@ class SwXTextRange::Impl public: 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; uno::Reference<text::XText> m_xParentText; const SwFrameFormat* m_pTableOrSectionFormat; const ::sw::mark::IMark* m_pMark; - Impl(SwDoc& rDoc, const enum RangePosition eRange, + Impl(SwDoc& rDoc, const enum RangePosition eRange, bool const isInCell, SwFrameFormat* const pTableOrSectionFormat, uno::Reference<text::XText> xParent = nullptr) : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR)) , m_eRangePosition(eRange) + , m_isRangeInCell(isInCell) , m_rDoc(rDoc) , m_xParentText(std::move(xParent)) , m_pTableOrSectionFormat(pTableOrSectionFormat) @@ -744,15 +746,16 @@ void SwXTextRange::Impl::Notify(const SfxHint& rHint) SwXTextRange::SwXTextRange(SwPaM const & rPam, const uno::Reference< text::XText > & xParent, - const enum RangePosition eRange) - : m_pImpl( new SwXTextRange::Impl(rPam.GetDoc(), eRange, nullptr, xParent) ) + const enum RangePosition eRange, + bool const isInCell) + : m_pImpl( new SwXTextRange::Impl(rPam.GetDoc(), eRange, isInCell, nullptr, xParent) ) { SetPositions(rPam); } SwXTextRange::SwXTextRange(SwTableFormat& rTableFormat) : m_pImpl( - new SwXTextRange::Impl(*rTableFormat.GetDoc(), RANGE_IS_TABLE, &rTableFormat) ) + new SwXTextRange::Impl(*rTableFormat.GetDoc(), RANGE_IS_TABLE, false, &rTableFormat) ) { SwTable *const pTable = SwTable::FindTable( &rTableFormat ); SwTableNode *const pTableNode = pTable->GetTableNode(); @@ -763,7 +766,7 @@ SwXTextRange::SwXTextRange(SwTableFormat& rTableFormat) SwXTextRange::SwXTextRange(SwSectionFormat& rSectionFormat) : m_pImpl( - new SwXTextRange::Impl(*rSectionFormat.GetDoc(), RANGE_IS_SECTION, &rSectionFormat) ) + new SwXTextRange::Impl(*rSectionFormat.GetDoc(), RANGE_IS_SECTION, false, &rSectionFormat) ) { // no SetPositions here for now } @@ -1057,7 +1060,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_pImpl->m_eRangePosition + ? ::sw::DeleteAndInsertMode::ForceReplace + : ::sw::DeleteAndInsertMode::Default); } bool SwXTextRange::GetPositions(SwPaM& rToFill, ::sw::TextRangeMode const eMode) const @@ -1232,7 +1238,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)); @@ -1244,7 +1251,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 { @@ -1401,7 +1408,7 @@ SwXTextRange::createEnumeration() getText(); } - const CursorType eSetType = (RANGE_IN_CELL == m_pImpl->m_eRangePosition) + const CursorType eSetType = m_pImpl->m_isRangeInCell ? CursorType::SelectionInTable : CursorType::Selection; return SwXParagraphEnumeration::Create(m_pImpl->m_xParentText, pNewCursor, eSetType); }