sw/inc/contentindex.hxx           |   17 ++++++++++++++++-
 sw/inc/ndtxt.hxx                  |    3 +--
 sw/source/core/bastyp/index.cxx   |    5 ++---
 sw/source/core/txtnode/ndtxt.cxx  |   28 ++++++++++++++--------------
 sw/source/core/txtnode/thints.cxx |    4 ++--
 sw/source/core/txtnode/txtedt.cxx |    6 +++---
 6 files changed, 38 insertions(+), 25 deletions(-)

New commits:
commit 7974cea6c788e02d7c36573e2d10dcc51884f70e
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Wed Jul 20 17:54:16 2022 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Tue Jul 26 15:23:59 2022 +0200

    tdf#150017 sw: Replace should not shorten bookmarks
    
    If there is a bookmark on the text that is replaced, its end will be
    after the 1st character of the replacement text.
    
    This is very odd and it would be much better to put the end at the end
    of the replacement text, particularly if the end of the bookmark used to
    be at the end of the replaced text.
    
    Text attributes already work such that the attribute on the first
    character before the replace is expanded to the entire replacement text;
    this seems odd too but as it happens Word does the same thing, so
    this patch makes bookmarks consistent with attributes.
    
    Change-Id: I6a4b43c779c207a31edb02b416d50c30386c94c1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137272
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/inc/contentindex.hxx b/sw/inc/contentindex.hxx
index 00337570ecb5..c05845b378c7 100644
--- a/sw/inc/contentindex.hxx
+++ b/sw/inc/contentindex.hxx
@@ -21,6 +21,8 @@
 #include <sal/types.h>
 #include "swdllapi.h"
 
+#include <o3tl/typed_flags_set.hxx>
+
 #include <iostream>
 
 class SwContentNode;
@@ -112,9 +114,17 @@ class SAL_WARN_UNUSED SwContentIndexReg
     const SwContentIndex * m_pFirst;
     const SwContentIndex * m_pLast;
 
+public:
+    enum class UpdateMode {
+        Default = 0,
+        Negative = (1<<0),
+        Delete = (1<<1),
+        Replace = (1<<2),
+    };
+
 protected:
     virtual void Update( SwContentIndex const & rPos, const sal_Int32 
nChangeLen,
-                 const bool bNegative = false, const bool bDelete = false );
+            UpdateMode eMode);
 
     bool HasAnyIndex() const { return nullptr != m_pFirst; }
 
@@ -126,6 +136,11 @@ public:
     const SwContentIndex* GetFirstIndex() const { return m_pFirst; }
 };
 
+namespace o3tl
+{
+    template<> struct typed_flags<SwContentIndexReg::UpdateMode> : 
is_typed_flags<SwContentIndexReg::UpdateMode, 0x07> {};
+}
+
 #ifndef DBG_UTIL
 
 inline sal_Int32 SwContentIndex::operator++()
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 5b71bfd3d593..9a5aa068ade6 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -763,8 +763,7 @@ public:
     virtual void Update(
         SwContentIndex const & rPos,
         const sal_Int32 nChangeLen,
-        const bool bNegative = false,
-        const bool bDelete = false ) override;
+        UpdateMode eMode) override;
 
     /// change text to Upper/Lower/Hiragana/Katakana/...
     void TransliterateText( utl::TransliterationWrapper& rTrans,
diff --git a/sw/source/core/bastyp/index.cxx b/sw/source/core/bastyp/index.cxx
index cb18fbcced85..15507ab083d3 100644
--- a/sw/source/core/bastyp/index.cxx
+++ b/sw/source/core/bastyp/index.cxx
@@ -237,12 +237,11 @@ SwContentIndexReg::~SwContentIndexReg()
 void SwContentIndexReg::Update(
     SwContentIndex const & rIdx,
     const sal_Int32 nDiff,
-    const bool bNeg,
-    const bool /* argument is only used in derived class*/ )
+    UpdateMode const eMode)
 {
     SwContentIndex* pStt = const_cast<SwContentIndex*>(&rIdx);
     const sal_Int32 nNewVal = rIdx.m_nIndex;
-    if( bNeg )
+    if (eMode & UpdateMode::Negative)
     {
         const sal_Int32 nLast = rIdx.GetIndex() + nDiff;
         while (pStt && pStt->m_nIndex == nNewVal)
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 1be670c590a7..88465dbded6f 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -1227,8 +1227,7 @@ public:
 void SwTextNode::Update(
     SwContentIndex const & rPos,
     const sal_Int32 nChangeLen,
-    const bool bNegative,
-    const bool bDelete )
+    UpdateMode const eMode)
 {
     SetAutoCompleteWordDirty( true );
 
@@ -1237,7 +1236,7 @@ void SwTextNode::Update(
 
     if ( HasHints() )
     {
-        if ( bNegative )
+        if (eMode & UpdateMode::Negative)
         {
             std::vector<SwTextInputField*> aTextInputFields;
 
@@ -1409,7 +1408,7 @@ void SwTextNode::Update(
 
     bool bSortMarks = false;
     SwContentNodeTmp aTmpIdxReg;
-    if ( !bNegative && !bDelete )
+    if (!(eMode & UpdateMode::Negative) && !(eMode & UpdateMode::Delete))
     {
         const SwRedlineTable& rTable = 
GetDoc().getIDocumentRedlineAccess().GetRedlineTable();
         SwRedlineTable::size_type n = 
GetDoc().getIDocumentRedlineAccess().GetRedlinePos(*this, RedlineType::Any);
@@ -1446,6 +1445,7 @@ void SwTextNode::Update(
         // Bookmarks must never grow to either side, when editing (directly)
         // to the left or right (i#29942)! Exception: if the bookmark has
         // 2 positions and start == end, then expand it (tdf#96479)
+        if (!(eMode & UpdateMode::Replace)) // Exception: Replace
         {
             bool bAtLeastOneBookmarkMoved = false;
             bool bAtLeastOneExpandedBookmarkAtInsertionPosition = false;
@@ -1541,7 +1541,7 @@ void SwTextNode::Update(
     }
 
     // base class
-    SwContentIndexReg::Update( rPos, nChangeLen, bNegative, bDelete );
+    SwContentIndexReg::Update(rPos, nChangeLen, eMode);
 
     if (pCollector)
     {
@@ -2332,7 +2332,7 @@ OUString SwTextNode::InsertText( const OUString & rStr, 
const SwContentIndex & r
         SetIgnoreDontExpand( true );
     }
 
-    Update( rIdx, nLen ); // text content changed!
+    Update(rIdx, nLen, UpdateMode::Default); // text content changed!
 
     if (nMode & SwInsertFlags::FORCEHINTEXPAND)
     {
@@ -2468,7 +2468,7 @@ void SwTextNode::CutImpl( SwTextNode * const pDest, const 
SwContentIndex & rDest
     if (bUpdate)
     {
         // Update all SwContentIndex
-        pDest->Update( rDestStart, nLen, false, false/*??? why was it true*/);
+        pDest->Update(rDestStart, nLen, UpdateMode::Default);
     }
 
     CHECK_SWPHINTS(pDest);
@@ -2670,7 +2670,7 @@ void SwTextNode::CutImpl( SwTextNode * const pDest, const 
SwContentIndex & rDest
                 ++nAttrCnt;
             }
         }
-        Update( rStart, nLen, true, true );
+        Update(rStart, nLen, UpdateMode::Negative|UpdateMode::Delete);
 
         for (SwTextAttr* pHt : aArr)
         {
@@ -2681,7 +2681,7 @@ void SwTextNode::CutImpl( SwTextNode * const pDest, const 
SwContentIndex & rDest
     }
     else
     {
-        Update( rStart, nLen, true, true );
+        Update(rStart, nLen, UpdateMode::Negative|UpdateMode::Delete);
     }
 
     // set after moving hints
@@ -2774,7 +2774,7 @@ void SwTextNode::EraseText(const SwContentIndex &rIdx, 
const sal_Int32 nCount,
 
     TryDeleteSwpHints();
 
-    Update( rIdx, nCnt, true );
+    Update(rIdx, nCnt, UpdateMode::Negative);
 
     if( 1 == nCnt )
     {
@@ -3772,19 +3772,19 @@ void SwTextNode::ReplaceText( const SwContentIndex& 
rStart, const sal_Int32 nDel
 
         ++const_cast<SwContentIndex&>(rStart);
         m_Text = m_Text.replaceAt(rStart.GetIndex(), nLen - 1, u"");
-        Update( rStart, nLen - 1, true );
+        Update(rStart, nLen - 1, UpdateMode::Negative);
 
         std::u16string_view aTmpText( sInserted.subView(1) );
         m_Text = m_Text.replaceAt(rStart.GetIndex(), 0, aTmpText);
-        Update( rStart, aTmpText.size() );
+        Update(rStart, aTmpText.size(), UpdateMode::Replace);
     }
     else
     {
         m_Text = m_Text.replaceAt(nStartPos, nLen, u"");
-        Update( rStart, nLen, true );
+        Update(rStart, nLen, UpdateMode::Negative);
 
         m_Text = m_Text.replaceAt(nStartPos, 0, sInserted);
-        Update( rStart, sInserted.getLength() );
+        Update(rStart, sInserted.getLength(), UpdateMode::Replace);
     }
 
     SetIgnoreDontExpand( bOldExpFlg );
diff --git a/sw/source/core/txtnode/thints.cxx 
b/sw/source/core/txtnode/thints.cxx
index 9c9c4b047ca2..4312c08dff95 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -1423,7 +1423,7 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, 
const SetAttrMode nMode )
                             m_Text = m_Text.replaceAt(pAttr->GetStart(), 1, 
u"");
                             // Update SwIndexes
                             SwContentIndex aTmpIdx( this, pAttr->GetStart() );
-                            Update( aTmpIdx, 1, true );
+                            Update(aTmpIdx, 1, UpdateMode::Negative);
                         }
                         // do not record deletion of Format!
                         ::sw::UndoGuard const ug(pDoc->GetIDocumentUndoRedo());
@@ -1454,7 +1454,7 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, 
const SetAttrMode nMode )
                         m_Text = m_Text.replaceAt(pAttr->GetStart(), 1, u"");
                         // Update SwIndexes
                         SwContentIndex aTmpIdx( this, pAttr->GetStart() );
-                        Update( aTmpIdx, 1, true );
+                        Update(aTmpIdx, 1, UpdateMode::Negative);
                     }
                     DestroyAttr( pAttr );
                     return false;
diff --git a/sw/source/core/txtnode/txtedt.cxx 
b/sw/source/core/txtnode/txtedt.cxx
index 6d90143f59d4..7f0e0ea12edb 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -1999,7 +1999,7 @@ void SwTextNode::ReplaceTextOnly( sal_Int32 nPos, 
sal_Int32 nLen,
             while( nI + nCnt < nTLen && nOff == pOffsets[ nI + nCnt ] )
                 ++nCnt;
 
-            Update( SwContentIndex( this, nMyOff ), nCnt );
+            Update(SwContentIndex(this, nMyOff), nCnt, UpdateMode::Default);
             nMyOff = nOff;
             //nMyOff -= nCnt;
             nI += nCnt - 1;
@@ -2007,14 +2007,14 @@ void SwTextNode::ReplaceTextOnly( sal_Int32 nPos, 
sal_Int32 nLen,
         else if( nOff > nMyOff )
         {
             // something is deleted
-            Update( SwContentIndex( this, nMyOff+1 ), nOff - nMyOff, true );
+            Update(SwContentIndex(this, nMyOff + 1), nOff - nMyOff, 
UpdateMode::Negative);
             nMyOff = nOff;
         }
         ++nMyOff;
     }
     if( nMyOff < nLen )
         // something is deleted at the end
-        Update( SwContentIndex( this, nMyOff ), nLen - nMyOff, true );
+        Update(SwContentIndex(this, nMyOff), nLen - nMyOff, 
UpdateMode::Negative);
 
     // notify the layout!
     SwDelText aDelHint( nPos, nTLen );

Reply via email to