[Libreoffice-commits] core.git: Branch 'private/mst/sw_redlinehide_4b' - 11 commits - sw/inc sw/qa sw/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Tue Dec 11 17:59:50 UTC 2018


Rebased ref, commits from common ancestor:
commit cead5932707f6eb0124f553086456eb7d8cf2c21
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Dec 11 18:43:35 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Dec 11 18:57:15 2018 +0100

    sw_redlinehide_4b: bookmark
    
    SwCursorShell::GotoMark(), GoNextBookmark(), GoPrevBookmark() check
    visibility of mark.
    
    SwWrtShell::GotoMark() returns whether it was successful.
    
    EnhancedPDFExport skips marks that are not visible.
    
    Change-Id: I36c0706c18a5f861b15eaf451a97daec04104056

diff --git a/sw/source/core/crsr/crbm.cxx b/sw/source/core/crsr/crbm.cxx
index 2387c128a33b..1b09e36409d9 100644
--- a/sw/source/core/crsr/crbm.cxx
+++ b/sw/source/core/crsr/crbm.cxx
@@ -19,6 +19,8 @@
 
 #include <crsrsh.hxx>
 #include <ndtxt.hxx>
+#include <rootfrm.hxx>
+#include <txtfrm.hxx>
 #include <docary.hxx>
 #include <IMark.hxx>
 #include "callnk.hxx"
@@ -121,10 +123,50 @@ namespace
     EndAction();
     return pMark;
 }
-// set CurrentCursor.SPoint
 
+static bool
+IsMarkHidden(SwRootFrame const& rLayout, ::sw::mark::IMark const& rMark)
+{
+    if (!rLayout.IsHideRedlines())
+    {
+        return false;
+    }
+    SwTextNode const& rNode(*rMark.GetMarkPos().nNode.GetNode().GetTextNode());
+    SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(
+        rNode.getLayoutFrame(&rLayout)));
+    if (!pFrame)
+    {
+        return true;
+    }
+    if (rMark.IsExpanded())
+    {
+        SwTextFrame const*const pOtherFrame(static_cast<SwTextFrame const*>(
+            rMark.GetOtherMarkPos().nNode.GetNode().GetTextNode()->getLayoutFrame(&rLayout)));
+        return pFrame == pOtherFrame
+            && pFrame->MapModelToViewPos(rMark.GetMarkPos())
+                == pFrame->MapModelToViewPos(rMark.GetOtherMarkPos());
+    }
+    else
+    {
+        if (rMark.GetMarkPos().nContent.GetIndex() == rNode.Len())
+        {   // at end of node: never deleted (except if node deleted)
+            return rNode.GetRedlineMergeFlag() == SwNode::Merge::Hidden;
+        }
+        else
+        {   // check character following mark pos
+            return pFrame->MapModelToViewPos(rMark.GetMarkPos())
+                == pFrame->MapModelToView(&rNode, rMark.GetMarkPos().nContent.GetIndex() + 1);
+        }
+    }
+}
+
+// set CurrentCursor.SPoint
 bool SwCursorShell::GotoMark(const ::sw::mark::IMark* const pMark, bool bAtStart)
 {
+    if (IsMarkHidden(*GetLayout(), *pMark))
+    {
+        return false;
+    }
     // watch Cursor-Moves
     CursorStateHelper aCursorSt(*this);
     if ( bAtStart )
@@ -140,6 +182,10 @@ bool SwCursorShell::GotoMark(const ::sw::mark::IMark* const pMark, bool bAtStart
 
 bool SwCursorShell::GotoMark(const ::sw::mark::IMark* const pMark)
 {
+    if (IsMarkHidden(*GetLayout(), *pMark))
+    {
+        return false;
+    }
     // watch Cursor-Moves
     CursorStateHelper aCursorSt(*this);
     aCursorSt.SetCursorToMark(pMark);
@@ -169,6 +215,10 @@ bool SwCursorShell::GoNextBookmark()
     IDocumentMarkAccess::const_iterator_t ppMark = vCandidates.begin();
     for(; ppMark!=vCandidates.end(); ++ppMark)
     {
+        if (IsMarkHidden(*GetLayout(), **ppMark))
+        {
+            continue;
+        }
         aCursorSt.SetCursorToMark(ppMark->get());
         if(!aCursorSt.RollbackIfIllegal())
             break; // found legal move
@@ -214,6 +264,10 @@ bool SwCursorShell::GoPrevBookmark()
         // above)
         if(!(**ppMark).EndsBefore(*GetCursor()->GetPoint()))
             continue;
+        if (IsMarkHidden(*GetLayout(), **ppMark))
+        {
+            continue;
+        }
         aCursorSt.SetCursorToMark(ppMark->get());
         if(!aCursorSt.RollbackIfIllegal())
             break; // found legal move
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index bc4aa9830f83..31c01837298a 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -2095,7 +2095,10 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
                 const OUString& sBkName = pBkmk->GetName();
 
                 //jump to it
-                JumpToSwMark( &mrSh, sBkName );
+                if (! JumpToSwMark( &mrSh, sBkName ))
+                {
+                    continue;
+                }
 
                 // Destination Rectangle
                 const SwRect& rDestRect = mrSh.GetCharRect();
diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx
index 6697fd01bd03..8dd284c41cda 100644
--- a/sw/source/uibase/inc/wrtsh.hxx
+++ b/sw/source/uibase/inc/wrtsh.hxx
@@ -404,7 +404,7 @@ typedef bool (SwWrtShell:: *FNSimpleMove)();
 
     // jump to bookmark and set the "selections-flags" correctly again
     void GotoMark( const ::sw::mark::IMark* const pMark );
-    void GotoMark( const ::sw::mark::IMark* const pMark, bool bSelect );
+    bool GotoMark( const ::sw::mark::IMark* const pMark, bool bSelect );
     void GotoMark( const OUString& rName );
     bool GoNextBookmark(); // true when there still was one
     bool GoPrevBookmark();
diff --git a/sw/source/uibase/uiview/view2.cxx b/sw/source/uibase/uiview/view2.cxx
index dfd9cceeeddc..4de245a22243 100644
--- a/sw/source/uibase/uiview/view2.cxx
+++ b/sw/source/uibase/uiview/view2.cxx
@@ -2001,8 +2001,7 @@ bool SwView::JumpToSwMark( const OUString& rMark )
             }
             else if( pMarkAccess->getAllMarksEnd() != (ppMark = pMarkAccess->findMark(sMark)) )
             {
-                m_pWrtShell->GotoMark( ppMark->get(), false );
-                bRet = true;
+                bRet = m_pWrtShell->GotoMark( ppMark->get(), false );
             }
             else if( nullptr != ( pINet = m_pWrtShell->FindINetAttr( sMark ) )) {
                 m_pWrtShell->addCurrentPosition();
@@ -2028,8 +2027,7 @@ bool SwView::JumpToSwMark( const OUString& rMark )
         }
         else if( pMarkAccess->getAllMarksEnd() != (ppMark = pMarkAccess->findMark(sMark)))
         {
-            m_pWrtShell->GotoMark( ppMark->get(), false );
-            bRet = true;
+            bRet = m_pWrtShell->GotoMark( ppMark->get(), false );
         }
         else if( nullptr != ( pINet = m_pWrtShell->FindINetAttr( sMark ) ))
             bRet = m_pWrtShell->GotoINetAttr( *pINet->GetTextINetFormat() );
diff --git a/sw/source/uibase/wrtsh/move.cxx b/sw/source/uibase/wrtsh/move.cxx
index d9cf0a00b73f..ef35f0922ec2 100644
--- a/sw/source/uibase/wrtsh/move.cxx
+++ b/sw/source/uibase/wrtsh/move.cxx
@@ -576,13 +576,14 @@ bool SwWrtShell::GotoPage(sal_uInt16 nPage, bool bRecord)
     return false;
 }
 
-void SwWrtShell::GotoMark( const ::sw::mark::IMark* const pMark, bool bSelect )
+bool SwWrtShell::GotoMark( const ::sw::mark::IMark* const pMark, bool bSelect )
 {
     ShellMoveCursor aTmp( this, bSelect );
     SwPosition aPos = *GetCursor()->GetPoint();
     bool bRet = SwCursorShell::GotoMark( pMark, true/*bStart*/ );
     if (bRet)
         m_aNavigationMgr.addEntry(aPos);
+    return bRet;
 }
 
 bool SwWrtShell::GotoFly( const OUString& rName, FlyCntType eType, bool bSelFrame )
commit 473d6cd6925a3add0c466140957a78c03c9e4bc2
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Dec 11 17:29:44 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Dec 11 17:29:44 2018 +0100

    sw_redlinehide_4b: visibility checks for EnhancedPDFExport links
    
    EnhancedPDFExportHelper should not create links to things that are
    hidden by the layout:
    
    * SwCursorShell::GotoFormatField() skips deleted fields
      (this triggers an assert in GetCharRect() with ooo69593-1.odt)
    
    * SwEditShell::GetINetAttrs() skips deleted INet attributes
      (which, as an additional bonus, hides then in the Navigator too)
    
    * SwFlyFrameFormats are skipped by EnhancedPDFExportHelper itself
    
    * footnotes dito
    
    Change-Id: Ife77dc7724688631d20cbaf8531b3c826a8ece94

diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx
index a4c774aa30df..e7e8373d0549 100644
--- a/sw/source/core/crsr/crstrvl.cxx
+++ b/sw/source/core/crsr/crstrvl.cxx
@@ -854,7 +854,11 @@ bool SwCursorShell::MoveFieldType(
 bool SwCursorShell::GotoFormatField( const SwFormatField& rField )
 {
     bool bRet = false;
-    if( rField.GetTextField() )
+    SwTextField const*const pTextField(rField.GetTextField());
+    if (pTextField
+        && (!GetLayout()->IsHideRedlines()
+             || !sw::IsFieldDeletedInModel(
+                 GetDoc()->getIDocumentRedlineAccess(), *pTextField)))
     {
         SET_CURR_SHELL( this );
         SwCallLink aLk( *this ); // watch Cursor-Moves
@@ -862,9 +866,9 @@ bool SwCursorShell::GotoFormatField( const SwFormatField& rField )
         SwCursor* pCursor = getShellCursor( true );
         SwCursorSaveState aSaveState( *pCursor );
 
-        SwTextNode* pTNd = rField.GetTextField()->GetpTextNode();
+        SwTextNode* pTNd = pTextField->GetpTextNode();
         pCursor->GetPoint()->nNode = *pTNd;
-        pCursor->GetPoint()->nContent.Assign( pTNd, rField.GetTextField()->GetStart() );
+        pCursor->GetPoint()->nContent.Assign( pTNd, pTextField->GetStart() );
 
         bRet = !pCursor->IsSelOvr();
         if( bRet )
diff --git a/sw/source/core/edit/editsh.cxx b/sw/source/core/edit/editsh.cxx
index 27bc3125e79e..7dd875749d8f 100644
--- a/sw/source/core/edit/editsh.cxx
+++ b/sw/source/core/edit/editsh.cxx
@@ -694,15 +694,21 @@ void SwEditShell::GetINetAttrs( SwGetINetAttrs& rArr )
 {
     rArr.clear();
 
-    const SwTextNode* pTextNd;
     const SwCharFormats* pFormats = GetDoc()->GetCharFormats();
     for( auto n = pFormats->size(); 1 < n; )
     {
         SwIterator<SwTextINetFormat,SwCharFormat> aIter(*(*pFormats)[--n]);
         for( SwTextINetFormat* pFnd = aIter.First(); pFnd; pFnd = aIter.Next() )
         {
-            if( nullptr != ( pTextNd = pFnd->GetpTextNode()) &&
-                pTextNd->GetNodes().IsDocNodes() )
+            SwTextNode const*const pTextNd(pFnd->GetpTextNode());
+            SwTextFrame const*const pFrame(pTextNd
+                ? static_cast<SwTextFrame const*>(pTextNd->getLayoutFrame(GetLayout()))
+                : nullptr);
+            if (nullptr != pTextNd && nullptr != pFrame
+                && pTextNd->GetNodes().IsDocNodes()
+                // check it's not fully deleted
+                && pFrame->MapModelToView(pTextNd, pFnd->GetStart())
+                    != pFrame->MapModelToView(pTextNd, *pFnd->GetEnd()))
             {
                 SwTextINetFormat& rAttr = *pFnd;
                 OUString sText( pTextNd->GetExpandText(GetLayout(),
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index a3e97f716409..bc4aa9830f83 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -1734,6 +1734,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
             SwFrameFormat* pFrameFormat = (*pTable)[n];
             const SfxPoolItem* pItem;
             if ( RES_DRAWFRMFMT != pFrameFormat->Which() &&
+                GetFrameOfModify(mrSh.GetLayout(), *pFrameFormat, SwFrameType::Fly) &&
                  SfxItemState::SET == pFrameFormat->GetAttrSet().GetItemState( RES_URL, true, &pItem ) )
             {
                 const SwPageFrame* pCurrPage =
@@ -1947,8 +1948,12 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
 
             // 1. Check if the whole paragraph is hidden
             // 2. Check for hidden text attribute
-            if ( rTNd.GetTextNode()->IsHidden() || mrSh.SelectHiddenRange() )
+            if (rTNd.GetTextNode()->IsHidden() || mrSh.SelectHiddenRange()
+                || (mrSh.GetLayout()->IsHideRedlines()
+                    && sw::IsFootnoteDeleted(pDoc->getIDocumentRedlineAccess(), *pTextFootnote)))
+            {
                 continue;
+            }
 
             SwCursorSaveState aSaveState( *mrSh.GetCursor_() );
 
commit 18592d8872719a62f99a0de9c6e5396755dcd0ab
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Nov 30 18:00:19 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Dec 11 14:59:43 2018 +0100

    HACK: ODF import: always hide redlines
    
    Change-Id: I275c6738943ee0d74ccacea69af1c1f4c9ede1df

diff --git a/sw/source/filter/xml/swxml.cxx b/sw/source/filter/xml/swxml.cxx
index f36ffb47a147..60cc3a5f46a9 100644
--- a/sw/source/filter/xml/swxml.cxx
+++ b/sw/source/filter/xml/swxml.cxx
@@ -856,8 +856,11 @@ ErrCode XMLReader::Read( SwDoc &rDoc, const OUString& rBaseURL, SwPaM &rPaM, con
     if( !(IsOrganizerMode() || IsBlockMode() || m_bInsertMode ||
           m_aOption.IsFormatsOnly() ||
             // sw_redlinehide: disable layout cache for now
-          (officecfg::Office::Common::Misc::ExperimentalMode::get(xContext) &&
-            !*o3tl::doAccess<bool>(xInfoSet->getPropertyValue(sShowChanges)))))
+#if 0
+          !*o3tl::doAccess<bool>(xInfoSet->getPropertyValue(sShowChanges))))
+#else
+          true))
+#endif
     {
         try
         {
@@ -890,8 +893,10 @@ ErrCode XMLReader::Read( SwDoc &rDoc, const OUString& rBaseURL, SwPaM &rPaM, con
     // restore redline mode from import info property set
     RedlineFlags nRedlineFlags = RedlineFlags::ShowInsert;
     aAny = xInfoSet->getPropertyValue( sShowChanges );
+#if 0
     if ( *o3tl::doAccess<bool>(aAny) )
         nRedlineFlags |= RedlineFlags::ShowDelete;
+#endif
     aAny = xInfoSet->getPropertyValue( sRecordChanges );
     if ( *o3tl::doAccess<bool>(aAny) || (aKey.getLength() > 0) )
         nRedlineFlags |= RedlineFlags::On;
commit f9f7f37674e0860373b583ead7baa395af36a004
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Dec 5 16:37:18 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Dec 11 14:59:42 2018 +0100

    temp?
    
    Change-Id: Ide2abf0c2ce054b75c917063a5d5aa8d13430426

diff --git a/sw/source/core/text/frmcrsr.cxx b/sw/source/core/text/frmcrsr.cxx
index 7b6411163cb3..c756aedf4cd2 100644
--- a/sw/source/core/text/frmcrsr.cxx
+++ b/sw/source/core/text/frmcrsr.cxx
@@ -267,6 +267,7 @@ bool SwTextFrame::GetCharRect( SwRect& rOrig, const SwPosition &rPos,
 
         bool bGoOn = true;
         TextFrameIndex const nOffset = MapModelToViewPos(rPos);
+        assert(nOffset != TextFrameIndex(COMPLETE_STRING)); // not going to end well
         TextFrameIndex nNextOfst;
 
         do
commit 93bd6768aba4253a9cdab285ca4e740ea80ccc4e
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Mon Dec 10 15:25:37 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Dec 11 14:59:42 2018 +0100

    sw_redlinehide_4b: FindText() adapt the replace part as well
    
    When redlining is enabled, the result will be a delete redline for the
    existing text, and an insert redline for the new text; that much is
    obious (and ReplaceRange can deal with a selection larger than one
    SwTextNode easily, since it mostly adds redlines).
    
    For the case when redlining is disabled, there are 2 options,
    and i don't really know which is preferrable from UX point of view:
    
    One approach is to reuse GetRanges() to ignore delete redlines in
    the replace range; move its declaration to different header.
    
    Another approach is to DeleteAndJoin() the existing delete redlines,
    which is the same as the previous model based Hide mode,
    which calls DeleteRedline() to remove the hidden redlines.
    
    Also change ChgAutoCorrWord() to call DeleteSelImpl() directly.
    
    Change-Id: I5974409d09eb39e04cc0b5dfc20d4db510e1cf58

diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index 84c83dd232a1..6f96643cfaf5 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -43,6 +43,7 @@
 class SfxItemSet;
 class SfxPoolItem;
 class SwContentFrame;
+class SwUnoCursor;
 class SwFormatField;
 class SwTextFormatColl;
 class SwTextINetFormat;
@@ -125,8 +126,19 @@ struct SwContentAtPos
 const int CRSR_POSOLD = 0x01,   // cursor stays at old position
           CRSR_POSCHG = 0x02;   // position changed by the layout
 
+namespace sw {
+
+bool ReplaceImpl(SwPaM & rCursor, OUString const& rReplacement,
+        bool const bRegExp, SwDoc & rDoc, SwRootFrame const*const pLayout);
+
 /// Helperfunction to resolve backward references in regular expressions
-OUString *ReplaceBackReferences( const i18nutil::SearchOptions2& rSearchOpt, SwPaM* pPam );
+OUString *ReplaceBackReferences(const i18nutil::SearchOptions2& rSearchOpt,
+        SwPaM* pPam, SwRootFrame const* pLayout );
+
+bool GetRanges(std::vector<std::shared_ptr<SwUnoCursor>> & rRanges,
+        SwDoc & rDoc, SwPaM const& rDelPam);
+
+} // namespace sw
 
 class SW_DLLPUBLIC SwCursorShell
     : public SwViewShell
diff --git a/sw/source/core/crsr/findattr.cxx b/sw/source/core/crsr/findattr.cxx
index 9da44ada4dfe..500d4628ad27 100644
--- a/sw/source/core/crsr/findattr.cxx
+++ b/sw/source/core/crsr/findattr.cxx
@@ -1164,8 +1164,9 @@ int SwFindParaAttr::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove,
             const_cast<SwPaM &>(rRegion).GetRingContainer().merge( m_rCursor.GetRingContainer() );
         }
 
-        std::unique_ptr<OUString> pRepl( bRegExp ?
-                ReplaceBackReferences(*pSearchOpt, &rCursor) : nullptr );
+        std::unique_ptr<OUString> pRepl(bRegExp
+                ? sw::ReplaceBackReferences(*pSearchOpt, &rCursor, nullptr/*FIXME*/)
+                : nullptr);
         m_rCursor.GetDoc()->getIDocumentContentOperations().ReplaceRange(
             rCursor, pRepl ? *pRepl : pSearchOpt->replaceString, bRegExp);
         m_rCursor.SaveTableBoxContent( rCursor.GetPoint() );
diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx
index c99ac4f34c9a..7f126085c884 100644
--- a/sw/source/core/crsr/findtxt.cxx
+++ b/sw/source/core/crsr/findtxt.cxx
@@ -35,11 +35,14 @@
 #include <txtatr.hxx>
 #include <txtfld.hxx>
 #include <txtfrm.hxx>
+#include <rootfrm.hxx>
 #include <swcrsr.hxx>
+#include <redline.hxx>
 #include <doc.hxx>
 #include <IDocumentUndoRedo.hxx>
 #include <IDocumentState.hxx>
 #include <IDocumentDrawModelAccess.hxx>
+#include <IDocumentRedlineAccess.hxx>
 #include <dcontact.hxx>
 #include <pamtyp.hxx>
 #include <ndtxt.hxx>
@@ -925,9 +928,12 @@ int SwFindParaText::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove,
         }
 
         std::unique_ptr<OUString> pRepl( bRegExp
-                ? ReplaceBackReferences(m_rSearchOpt, &rCursor) : nullptr );
-        bool const bReplaced = m_rCursor.GetDoc()->getIDocumentContentOperations().ReplaceRange(
-            rCursor, pRepl ? *pRepl : m_rSearchOpt.replaceString, bRegExp);
+                ? sw::ReplaceBackReferences(m_rSearchOpt, &rCursor, m_pLayout)
+                : nullptr );
+        bool const bReplaced = sw::ReplaceImpl(rCursor,
+                pRepl ? *pRepl : m_rSearchOpt.replaceString,
+                bRegExp, *m_rCursor.GetDoc(), m_pLayout);
+
         m_rCursor.SaveTableBoxContent( rCursor.GetPoint() );
 
         if( bRegExp )
@@ -994,22 +1000,115 @@ sal_uLong SwCursor::FindText( const i18nutil::SearchOptions2& rSearchOpt, bool b
     return nRet;
 }
 
-OUString *ReplaceBackReferences( const i18nutil::SearchOptions2& rSearchOpt, SwPaM* pPam )
+namespace sw {
+
+bool ReplaceImpl(
+        SwPaM & rCursor,
+        OUString const& rReplacement,
+        bool const bRegExp,
+        SwDoc & rDoc,
+        SwRootFrame const*const pLayout)
+{
+    bool bReplaced(true);
+    IDocumentContentOperations & rIDCO(rDoc.getIDocumentContentOperations());
+#if 0
+    // FIXME there's some problem with multiple redlines here on Undo
+    std::vector<std::shared_ptr<SwUnoCursor>> ranges;
+    if (rDoc.getIDocumentRedlineAccess().IsRedlineOn()
+        || !pLayout
+        || !pLayout->IsHideRedlines()
+        || sw::GetRanges(ranges, rDoc, rCursor))
+    {
+        bReplaced = rIDCO.ReplaceRange(rCursor, rReplacement, bRegExp);
+    }
+    else
+    {
+        assert(!ranges.empty());
+        assert(ranges.front()->GetPoint()->nNode == ranges.front()->GetMark()->nNode);
+        bReplaced = rIDCO.ReplaceRange(*ranges.front(), rReplacement, bRegExp);
+        for (auto it = ranges.begin() + 1; it != ranges.end(); ++it)
+        {
+            bReplaced &= rIDCO.DeleteAndJoin(**it);
+        }
+    }
+#else
+    IDocumentRedlineAccess const& rIDRA(rDoc.getIDocumentRedlineAccess());
+    if (pLayout && pLayout->IsHideRedlines()
+        && !rIDRA.IsRedlineOn() // otherwise: ReplaceRange will handle it
+        && (rIDRA.GetRedlineFlags() & RedlineFlags::ShowDelete)) // otherwise: ReplaceRange will DeleteRedline()
+    {
+        SwRedlineTable::size_type tmp;
+        rIDRA.GetRedline(*rCursor.Start(), &tmp);
+        while (tmp < rIDRA.GetRedlineTable().size())
+        {
+            SwRangeRedline const*const pRedline(rIDRA.GetRedlineTable()[tmp]);
+            if (*rCursor.End() <= *pRedline->Start())
+            {
+                break;
+            }
+            if (*pRedline->End() <= *rCursor.Start())
+            {
+                ++tmp;
+                continue;
+            }
+            if (pRedline->GetType() == nsRedlineType_t::REDLINE_DELETE)
+            {
+                assert(*pRedline->Start() != *pRedline->End());
+                // search in hidden layout can't overlap redlines
+                assert(*rCursor.Start() <= *pRedline->Start() && *pRedline->End() <= *rCursor.End());
+                SwPaM pam(*pRedline, nullptr);
+                bReplaced &= rIDCO.DeleteAndJoin(pam);
+            }
+            else
+            {
+                ++tmp;
+            }
+        }
+    }
+    bReplaced &= rIDCO.ReplaceRange(rCursor, rReplacement, bRegExp);
+#endif
+    return bReplaced;
+}
+
+OUString *ReplaceBackReferences(const i18nutil::SearchOptions2& rSearchOpt,
+        SwPaM *const pPam, SwRootFrame const*const pLayout)
 {
     OUString *pRet = nullptr;
     if( pPam && pPam->HasMark() &&
         SearchAlgorithms2::REGEXP == rSearchOpt.AlgorithmType2 )
     {
         const SwContentNode* pTextNode = pPam->GetContentNode();
+        if (!pTextNode || !pTextNode->IsTextNode())
+        {
+            return pRet;
+        }
+        SwTextFrame const*const pFrame(pLayout
+            ? static_cast<SwTextFrame const*>(pTextNode->getLayoutFrame(pLayout))
+            : nullptr);
         const bool bParaEnd = rSearchOpt.searchString == "$" || rSearchOpt.searchString == "^$" || rSearchOpt.searchString == "$^";
-        if ( pTextNode && pTextNode->IsTextNode() && (bParaEnd || pTextNode == pPam->GetContentNode( false )) )
+        if (bParaEnd || (pLayout
+                ? sw::FrameContainsNode(*pFrame, pPam->GetMark()->nNode.GetIndex())
+                : pTextNode == pPam->GetContentNode(false)))
         {
             utl::TextSearch aSText( utl::TextSearch::UpgradeToSearchOptions2( rSearchOpt) );
-            OUString rStr = pTextNode->GetTextNode()->GetText();
-            sal_Int32 nStart = pPam->Start()->nContent.GetIndex();
-            sal_Int32 nEnd = pPam->End()->nContent.GetIndex();
+            OUString rStr = pLayout
+                ? pFrame->GetText()
+                : pTextNode->GetTextNode()->GetText();
+            AmbiguousIndex nStart;
+            AmbiguousIndex nEnd;
+            if (pLayout)
+            {
+                nStart.SetFrameIndex(pFrame->MapModelToViewPos(*pPam->Start()));
+                nEnd.SetFrameIndex(pFrame->MapModelToViewPos(*pPam->End()));
+            }
+            else
+            {
+                nStart.SetModelIndex(pPam->Start()->nContent.GetIndex());
+                nEnd.SetModelIndex(pPam->End()->nContent.GetIndex());
+            }
             SearchResult aResult;
-            if ( bParaEnd || aSText.SearchForward( rStr, &nStart, &nEnd, &aResult ) )
+            if (bParaEnd ||
+                aSText.SearchForward(rStr, &nStart.GetAnyIndex(), &nEnd.GetAnyIndex(), &aResult))
             {
                 if ( bParaEnd )
                 {
@@ -1029,4 +1128,6 @@ OUString *ReplaceBackReferences( const i18nutil::SearchOptions2& rSearchOpt, SwP
     return pRet;
 }
 
+} // namespace sw
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index ad467c57580d..6e34a5d33ddc 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -4062,10 +4062,6 @@ bool DocumentContentOperationsManager::ReplaceRangeImpl( SwPaM& rPam, const OUSt
 
         SwPosition *pStt = aDelPam.Start(),
                    *pEnd = aDelPam.End();
-        OSL_ENSURE( pStt->nNode == pEnd->nNode ||
-                ( pStt->nNode.GetIndex() + 1 == pEnd->nNode.GetIndex() &&
-                    !pEnd->nContent.GetIndex() ),
-                "invalid range: Point and Mark on different nodes" );
         bool bOneNode = pStt->nNode == pEnd->nNode;
 
         // Own Undo?
@@ -4201,6 +4197,11 @@ bool DocumentContentOperationsManager::ReplaceRangeImpl( SwPaM& rPam, const OUSt
         }
         else
         {
+            assert((pStt->nNode == pEnd->nNode ||
+                    ( pStt->nNode.GetIndex() + 1 == pEnd->nNode.GetIndex() &&
+                        !pEnd->nContent.GetIndex() )) &&
+                    "invalid range: Point and Mark on different nodes" );
+
             if( !m_rDoc.getIDocumentRedlineAccess().IsIgnoreRedline() && !m_rDoc.getIDocumentRedlineAccess().GetRedlineTable().empty() )
                 m_rDoc.getIDocumentRedlineAccess().DeleteRedline( aDelPam, true, USHRT_MAX );
 
diff --git a/sw/source/core/edit/acorrect.cxx b/sw/source/core/edit/acorrect.cxx
index e5ca4d63c69b..eaf61bec0451 100644
--- a/sw/source/core/edit/acorrect.cxx
+++ b/sw/source/core/edit/acorrect.cxx
@@ -416,7 +416,7 @@ bool SwAutoCorrDoc::ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos,
                             *ranges.front(), pFnd->GetLong(), false);
                     for (auto it = ranges.begin() + 1; it != ranges.end(); ++it)
                     {
-                        DeleteSel(**it);
+                        DeleteSelImpl(**it);
                     }
                 }
 
diff --git a/sw/source/core/edit/eddel.cxx b/sw/source/core/edit/eddel.cxx
index 126b5000a923..1a37235190a9 100644
--- a/sw/source/core/edit/eddel.cxx
+++ b/sw/source/core/edit/eddel.cxx
@@ -22,9 +22,11 @@
 #include <doc.hxx>
 #include <IDocumentUndoRedo.hxx>
 #include <IDocumentContentOperations.hxx>
+#include <IDocumentRedlineAccess.hxx>
 #include <editsh.hxx>
 #include <cntfrm.hxx>
 #include <pam.hxx>
+#include <unocrsr.hxx>
 #include <swundo.hxx>
 #include <edimp.hxx>
 #include <IMark.hxx>
@@ -318,7 +320,7 @@ bool SwEditShell::Replace( const OUString& rNewStr, bool bRegExpRplc )
         {
             if( rPaM.HasMark() && *rPaM.GetMark() != *rPaM.GetPoint() )
             {
-                bRet = GetDoc()->getIDocumentContentOperations().ReplaceRange( rPaM, rNewStr, bRegExpRplc )
+                bRet = sw::ReplaceImpl(rPaM, rNewStr, bRegExpRplc, *GetDoc(), GetLayout())
                     || bRet;
                 SaveTableBoxContent( rPaM.GetPoint() );
             }
diff --git a/sw/source/core/inc/acorrect.hxx b/sw/source/core/inc/acorrect.hxx
index 73f63c1ebac8..39bd19e91584 100644
--- a/sw/source/core/inc/acorrect.hxx
+++ b/sw/source/core/inc/acorrect.hxx
@@ -21,14 +21,11 @@
 #define INCLUDED_SW_SOURCE_CORE_INC_ACORRECT_HXX
 
 #include <memory>
-#include <vector>
 
 #include <tools/solar.h>
 #include <editeng/svxacorr.hxx>
 #include <swundo.hxx>
 
-class SwDoc;
-class SwUnoCursor;
 class SwEditShell;
 class SwPaM;
 class SwNodeIndex;
@@ -116,13 +113,6 @@ public:
     bool CheckDelChar(const SwPosition& rPos);
 };
 
-namespace sw {
-
-bool GetRanges(std::vector<std::shared_ptr<SwUnoCursor>> & rRanges,
-        SwDoc & rDoc, SwPaM const& rDelPam);
-
-} // namespace sw
-
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uiview/viewsrch.cxx b/sw/source/uibase/uiview/viewsrch.cxx
index 09fd18015ae6..96b1708eb4be 100644
--- a/sw/source/uibase/uiview/viewsrch.cxx
+++ b/sw/source/uibase/uiview/viewsrch.cxx
@@ -309,7 +309,8 @@ void SwView::ExecSearch(SfxRequest& rReq)
                             m_pWrtShell->Push();
                         OUString aReplace( m_pSrchItem->GetReplaceString() );
                         i18nutil::SearchOptions2 aTmp( m_pSrchItem->GetSearchOptions() );
-                        OUString *pBackRef = ReplaceBackReferences( aTmp, m_pWrtShell->GetCursor() );
+                        OUString *pBackRef = sw::ReplaceBackReferences(aTmp,
+                            m_pWrtShell->GetCursor(), m_pWrtShell->GetLayout());
                         if( pBackRef )
                             m_pSrchItem->SetReplaceString( *pBackRef );
                         Replace();
commit a3d09c2dd27a2ae5019b72aa84c0eaaf9171a38a
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Dec 7 18:52:54 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Dec 11 14:59:42 2018 +0100

    sw_redlinehide_4b: adapt FindText()
    
    Generally speaking, the find functions should find the strings that are
    visible in the document view.  However, they may also be called from
    SwXTextDocument functions, where they ought to find the strings that are
    actually in the document model.
    
    So concoct some funny helper types and adapt this so it can handle both
    cases; it's not pretty but maybe it even works.
    
    Change-Id: I1917398ff928e922673353e75e8fb724dc042031

diff --git a/sw/source/core/crsr/findattr.cxx b/sw/source/core/crsr/findattr.cxx
index 4999c07d734b..9da44ada4dfe 100644
--- a/sw/source/core/crsr/findattr.cxx
+++ b/sw/source/core/crsr/findattr.cxx
@@ -1135,7 +1135,7 @@ int SwFindParaAttr::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove,
             // TODO: searching for attributes in Outliner text?!
 
             // continue search in correct section (pTextRegion)
-            if (sw::FindTextImpl(aSrchPam, *pSearchOpt, false/*bSearchInNotes*/, *pSText, fnMove, *pTextRegion, bInReadOnly) &&
+            if (sw::FindTextImpl(aSrchPam, *pSearchOpt, false/*bSearchInNotes*/, *pSText, fnMove, *pTextRegion, bInReadOnly, nullptr/*FIXME*/) &&
                 *aSrchPam.GetMark() != *aSrchPam.GetPoint() )
                 break; // found
             else if( !pSet->Count() )
diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx
index 5fe3a757e890..c99ac4f34c9a 100644
--- a/sw/source/core/crsr/findtxt.cxx
+++ b/sw/source/core/crsr/findtxt.cxx
@@ -34,6 +34,7 @@
 #include <fmtfld.hxx>
 #include <txtatr.hxx>
 #include <txtfld.hxx>
+#include <txtfrm.hxx>
 #include <swcrsr.hxx>
 #include <doc.hxx>
 #include <IDocumentUndoRedo.hxx>
@@ -53,59 +54,184 @@
 using namespace ::com::sun::star;
 using namespace util;
 
+/// because the Find may be called on the View or the Model, we need an index
+/// afflicted by multiple personality disorder
+struct AmbiguousIndex
+{
+private:
+    sal_Int32 m_value;
+
+#ifndef NDEBUG
+    enum class tags : char { Any, Frame, Model };
+    tags m_tag;
+#endif
+
+public:
+    AmbiguousIndex() : m_value(-1), m_tag(tags::Any) {}
+    explicit AmbiguousIndex(TextFrameIndex const value) : m_value(value), m_tag(tags::Frame)  {}
+    explicit AmbiguousIndex(sal_Int32 const value) : m_value(value), m_tag(tags::Model) {}
+    explicit AmbiguousIndex(sal_Int32 const value, tags const tag) : m_value(value), m_tag(tag) {}
+
+    sal_Int32 & GetAnyIndex() { return m_value; } ///< for arithmetic
+    sal_Int32 const& GetAnyIndex() const { return m_value; } ///< for arithmetic
+    TextFrameIndex GetFrameIndex() const
+    {
+        assert(m_tag != tags::Model);
+        return TextFrameIndex(m_value);
+    }
+    sal_Int32 GetModelIndex() const
+    {
+        assert(m_tag != tags::Frame);
+        return m_value;
+    }
+    void SetFrameIndex(TextFrameIndex const value)
+    {
+#ifndef NDEBUG
+        m_tag = tags::Frame;
+#endif
+        m_value = sal_Int32(value);
+    }
+    void SetModelIndex(sal_Int32 const value)
+    {
+#ifndef NDEBUG
+        m_tag = tags::Model;
+#endif
+        m_value = value;
+    }
+
+    bool operator ==(AmbiguousIndex const& rOther) const
+    {
+        assert(m_tag == tags::Any || rOther.m_tag == tags::Any || m_tag == rOther.m_tag);
+        return m_value == rOther.m_value;
+    }
+    bool operator <=(AmbiguousIndex const& rOther) const
+    {
+        assert(m_tag == tags::Any || rOther.m_tag == tags::Any || m_tag == rOther.m_tag);
+        return m_value <= rOther.m_value;
+    }
+    bool operator < (AmbiguousIndex const& rOther) const
+    {
+        assert(m_tag == tags::Any || rOther.m_tag == tags::Any || m_tag == rOther.m_tag);
+        return m_value <  rOther.m_value;
+    }
+    AmbiguousIndex operator - (AmbiguousIndex const& rOther) const
+    {
+        assert(m_tag == tags::Any || rOther.m_tag == tags::Any || m_tag == rOther.m_tag);
+        return AmbiguousIndex(m_value - rOther.m_value, std::max(m_tag, rOther.m_tag));
+    }
+};
+
+class MaybeMergedIter
+{
+    boost::optional<sw::MergedAttrIter> m_oMergedIter;
+    SwTextNode const*const m_pNode;
+    size_t m_HintIndex;
+
+public:
+    MaybeMergedIter(SwTextFrame const*const pFrame, SwTextNode const*const pNode)
+        : m_pNode(pNode)
+        , m_HintIndex(0)
+    {
+        if (pFrame)
+        {
+            m_oMergedIter.emplace(*pFrame);
+        }
+    }
+
+    SwTextAttr const* NextAttr(SwTextNode const*& rpNode)
+    {
+        if (m_oMergedIter)
+        {
+            return m_oMergedIter->NextAttr(&rpNode);
+        }
+        if (SwpHints const*const pHints = m_pNode->GetpSwpHints())
+        {
+            if (m_HintIndex < pHints->Count())
+            {
+                rpNode = m_pNode;
+                return pHints->Get(m_HintIndex++);
+            }
+        }
+        return nullptr;
+    }
+};
+
 static OUString
-lcl_CleanStr(const SwTextNode& rNd, sal_Int32 const nStart, sal_Int32& rEnd,
-             std::vector<sal_Int32> &rArr, bool const bRemoveSoftHyphen, bool const bRemoveCommentAnchors)
+lcl_CleanStr(const SwTextNode& rNd,
+             SwTextFrame const*const pFrame,
+             SwRootFrame const*const pLayout,
+             AmbiguousIndex const nStart, AmbiguousIndex & rEnd,
+             std::vector<AmbiguousIndex> &rArr,
+             bool const bRemoveSoftHyphen, bool const bRemoveCommentAnchors)
 {
-    OUStringBuffer buf(rNd.GetText());
+    OUStringBuffer buf(pLayout ? pFrame->GetText() : rNd.GetText());
     rArr.clear();
 
-    const SwpHints *pHts = rNd.GetpSwpHints();
+    MaybeMergedIter iter(pLayout ? pFrame : nullptr, pLayout ? nullptr : &rNd);
 
-    size_t n = 0;
-    sal_Int32 nSoftHyphen = nStart;
-    sal_Int32 nHintStart = -1;
+    AmbiguousIndex nSoftHyphen = nStart;
+    AmbiguousIndex nHintStart;
     bool bNewHint       = true;
     bool bNewSoftHyphen = true;
-    const sal_Int32 nEnd = rEnd;
-    std::vector<sal_Int32> aReplaced;
+    const AmbiguousIndex nEnd = rEnd;
+    std::vector<AmbiguousIndex> aReplaced;
+    SwTextNode const* pNextHintNode(nullptr);
+    SwTextAttr const* pNextHint(iter.NextAttr(pNextHintNode));
 
     do
     {
         if ( bNewHint )
-            nHintStart = pHts && n < pHts->Count() ?
-                         pHts->Get(n)->GetStart() :
-                         -1;
+        {
+            if (pLayout)
+            {
+                nHintStart.SetFrameIndex(pNextHint
+                        ? pFrame->MapModelToView(pNextHintNode, pNextHint->GetStart())
+                        : TextFrameIndex(-1));
+            }
+            else
+            {
+                nHintStart.SetModelIndex(pNextHint ? pNextHint->GetStart() : -1);
+            }
+        }
 
         if ( bNewSoftHyphen )
         {
-            nSoftHyphen = bRemoveSoftHyphen
-                    ?  rNd.GetText().indexOf(CHAR_SOFTHYPHEN, nSoftHyphen)
-                    : -1;
+            if (pLayout)
+            {
+                nSoftHyphen.SetFrameIndex(TextFrameIndex(bRemoveSoftHyphen
+                    ? pFrame->GetText().indexOf(CHAR_SOFTHYPHEN, nSoftHyphen.GetAnyIndex())
+                    : -1));
+            }
+            else
+            {
+                nSoftHyphen.SetModelIndex(bRemoveSoftHyphen
+                    ? rNd.GetText().indexOf(CHAR_SOFTHYPHEN, nSoftHyphen.GetAnyIndex())
+                    : -1);
+            }
         }
 
         bNewHint       = false;
         bNewSoftHyphen = false;
-        sal_Int32 nStt = 0;
+        AmbiguousIndex nStt;
 
         // Check if next stop is a hint.
-        if ( nHintStart>=0
-            && (-1 == nSoftHyphen || nHintStart < nSoftHyphen)
+        if (0 <= nHintStart.GetAnyIndex()
+            && (-1 == nSoftHyphen.GetAnyIndex() || nHintStart < nSoftHyphen)
             && nHintStart < nEnd )
         {
             nStt = nHintStart;
             bNewHint = true;
         }
         // Check if next stop is a soft hyphen.
-        else if (   -1 != nSoftHyphen
-                 && (-1 == nHintStart || nSoftHyphen < nHintStart)
+        else if (   -1 != nSoftHyphen.GetAnyIndex()
+                 && (-1 == nHintStart.GetAnyIndex() || nSoftHyphen < nHintStart)
                  && nSoftHyphen < nEnd)
         {
             nStt = nSoftHyphen;
             bNewSoftHyphen = true;
         }
         // If nSoftHyphen == nHintStart, the current hint *must* be a hint with an end.
-        else if (-1 != nSoftHyphen && nSoftHyphen == nHintStart)
+        else if (-1 != nSoftHyphen.GetAnyIndex() && nSoftHyphen == nHintStart)
         {
             nStt = nSoftHyphen;
             bNewHint = true;
@@ -114,14 +240,14 @@ lcl_CleanStr(const SwTextNode& rNd, sal_Int32 const nStart, sal_Int32& rEnd,
         else
             break;
 
-        const sal_Int32 nCurrent = nStt - rArr.size();
+        AmbiguousIndex nCurrent(nStt);
+        nCurrent.GetAnyIndex() -= rArr.size();
 
         if ( bNewHint )
         {
-            const SwTextAttr* pHt = pHts->Get(n);
-            if ( pHt->HasDummyChar() && (nStt >= nStart) )
+            if (pNextHint->HasDummyChar() && (nStart <= nStt))
             {
-                switch( pHt->Which() )
+                switch (pNextHint->Which())
                 {
                 case RES_TXTATR_FLYCNT:
                 case RES_TXTATR_FTN:
@@ -138,19 +264,19 @@ lcl_CleanStr(const SwTextNode& rNd, sal_Int32 const nStart, sal_Int32& rEnd,
                         // simply removed if first. If at the end, we keep the
                         // replacement and remove afterwards all at a string's
                         // end (might be normal 0x7f).
-                        const bool bEmpty = pHt->Which() != RES_TXTATR_FIELD
-                            || (static_txtattr_cast<SwTextField const*>(pHt)->GetFormatField().GetField()->ExpandField(true, nullptr).isEmpty());
+                        const bool bEmpty = pNextHint->Which() != RES_TXTATR_FIELD
+                            || (static_txtattr_cast<SwTextField const*>(pNextHint)->GetFormatField().GetField()->ExpandField(true, pLayout).isEmpty());
                         if ( bEmpty && nStart == nCurrent )
                         {
                             rArr.push_back( nCurrent );
-                            --rEnd;
-                            buf.remove(nCurrent, 1);
+                            --rEnd.GetAnyIndex();
+                            buf.remove(nCurrent.GetAnyIndex(), 1);
                         }
                         else
                         {
                             if ( bEmpty )
                                 aReplaced.push_back( nCurrent );
-                            buf[nCurrent] = '\x7f';
+                            buf[nCurrent.GetAnyIndex()] = '\x7f';
                         }
                     }
                     break;
@@ -159,8 +285,8 @@ lcl_CleanStr(const SwTextNode& rNd, sal_Int32 const nStart, sal_Int32& rEnd,
                         if( bRemoveCommentAnchors )
                         {
                             rArr.push_back( nCurrent );
-                            --rEnd;
-                            buf.remove( nCurrent, 1 );
+                            --rEnd.GetAnyIndex();
+                            buf.remove( nCurrent.GetAnyIndex(), 1 );
                         }
                     }
                     break;
@@ -169,69 +295,40 @@ lcl_CleanStr(const SwTextNode& rNd, sal_Int32 const nStart, sal_Int32& rEnd,
                     break;
                 }
             }
-            ++n;
+            pNextHint = iter.NextAttr(pNextHintNode);
         }
 
         if ( bNewSoftHyphen )
         {
             rArr.push_back( nCurrent );
-            --rEnd;
-            buf.remove(nCurrent, 1);
-            ++nSoftHyphen;
+            --rEnd.GetAnyIndex();
+            buf.remove(nCurrent.GetAnyIndex(), 1);
+            ++nSoftHyphen.GetAnyIndex();
         }
     }
     while ( true );
 
-    for( std::vector<sal_Int32>::size_type i = aReplaced.size(); i; )
+    for (auto i = aReplaced.size(); i; )
     {
-        const sal_Int32 nTmp = aReplaced[ --i ];
-        if (nTmp == buf.getLength() - 1)
+        const AmbiguousIndex nTmp = aReplaced[ --i ];
+        if (nTmp.GetAnyIndex() == buf.getLength() - 1)
         {
-            buf.truncate(nTmp);
+            buf.truncate(nTmp.GetAnyIndex());
             rArr.push_back( nTmp );
-            --rEnd;
+            --rEnd.GetAnyIndex();
         }
     }
 
     return buf.makeStringAndClear();
 }
 
-// skip all non SwPostIts inside the array
-static size_t GetPostIt(sal_Int32 aCount,const SwpHints *pHts)
-{
-    size_t aIndex = 0;
-    while (aCount)
-    {
-        for (size_t i = 0; i < pHts->Count(); ++i )
-        {
-            aIndex++;
-            const SwTextAttr* pTextAttr = pHts->Get(i);
-            if ( pTextAttr->Which() == RES_TXTATR_ANNOTATION )
-            {
-                aCount--;
-                if (!aCount)
-                    break;
-            }
-        }
-    }
-    // throw away all following non postits
-    for( size_t i = aIndex; i < pHts->Count(); ++i )
-    {
-        const SwTextAttr* pTextAttr = pHts->Get(i);
-        if ( pTextAttr->Which() == RES_TXTATR_ANNOTATION )
-            break;
-        else
-            aIndex++;
-    }
-    return aIndex;
-}
-
 static bool DoSearch(SwPaM & rSearchPam,
     const i18nutil::SearchOptions2& rSearchOpt, utl::TextSearch& rSText,
     SwMoveFnCollection const & fnMove,
     bool bSrchForward, bool bRegSearch, bool bChkEmptyPara, bool bChkParaEnd,
-    sal_Int32 &nStart, sal_Int32 &nEnd, sal_Int32 nTextLen, SwNode* pNode,
-    SwPaM* pPam);
+    AmbiguousIndex & nStart, AmbiguousIndex & nEnd, AmbiguousIndex nTextLen,
+    SwTextNode const* pNode, SwTextFrame const* pTextFrame,
+    SwRootFrame const* pLayout, SwPaM* pPam);
 
 namespace sw {
 
@@ -239,7 +336,7 @@ bool FindTextImpl(SwPaM & rSearchPam,
         const i18nutil::SearchOptions2& rSearchOpt, bool bSearchInNotes,
         utl::TextSearch& rSText,
         SwMoveFnCollection const & fnMove, const SwPaM & rRegion,
-        bool bInReadOnly)
+        bool bInReadOnly, SwRootFrame const*const pLayout)
 {
     if( rSearchOpt.searchString.isEmpty() )
         return false;
@@ -266,47 +363,95 @@ bool FindTextImpl(SwPaM & rSearchPam,
     aSearchItem.SetBackward(!bSrchForward);
 
     // LanguageType eLastLang = 0;
-    while( nullptr != ( pNode = ::GetNode( *pPam, bFirst, fnMove, bInReadOnly ) ))
+    while (nullptr != (pNode = ::GetNode(*pPam, bFirst, fnMove, bInReadOnly, pLayout)))
     {
         if( pNode->IsTextNode() )
         {
             SwTextNode& rTextNode = *pNode->GetTextNode();
-            sal_Int32 nTextLen = rTextNode.GetText().getLength();
-            sal_Int32 nEnd;
-            if( rNdIdx == pPam->GetMark()->nNode )
-                nEnd = pPam->GetMark()->nContent.GetIndex();
+            SwTextFrame const*const pFrame(pLayout
+                ? static_cast<SwTextFrame const*>(rTextNode.getLayoutFrame(pLayout))
+                : nullptr);
+            assert(!pLayout || pFrame);
+            AmbiguousIndex nTextLen;
+            if (pLayout)
+            {
+                nTextLen.SetFrameIndex(TextFrameIndex(pFrame->GetText().getLength()));
+            }
+            else
+            {
+                nTextLen.SetModelIndex(rTextNode.GetText().getLength());
+            }
+            AmbiguousIndex nEnd;
+            if (pLayout
+                    ? FrameContainsNode(*pFrame, pPam->GetMark()->nNode.GetIndex())
+                    : rNdIdx == pPam->GetMark()->nNode)
+            {
+                if (pLayout)
+                {
+                    nEnd.SetFrameIndex(pFrame->MapModelToViewPos(*pPam->GetMark()));
+                }
+                else
+                {
+                    nEnd.SetModelIndex(pPam->GetMark()->nContent.GetIndex());
+                }
+            }
+            else
+            {
+                if (bSrchForward)
+                {
+                    nEnd = nTextLen;
+                }
+                else
+                {
+                    if (pLayout)
+                    {
+                        nEnd.SetFrameIndex(TextFrameIndex(0));
+                    }
+                    else
+                    {
+                        nEnd.SetModelIndex(0);
+                    }
+                }
+            }
+            AmbiguousIndex nStart;
+            if (pLayout)
+            {
+                nStart.SetFrameIndex(pFrame->MapModelToViewPos(*pPam->GetPoint()));
+            }
             else
-                nEnd = bSrchForward ? nTextLen : 0;
-            sal_Int32 nStart = rContentIdx.GetIndex();
+            {
+                nStart.SetModelIndex(rContentIdx.GetIndex());
+            }
 
             /* #i80135# */
             // if there are SwPostItFields inside our current node text, we
             // split the text into separate pieces and search for text inside
             // the pieces as well as inside the fields
-            const SwpHints *pHts = rTextNode.GetpSwpHints();
+            MaybeMergedIter iter(pLayout ? pFrame : nullptr, pLayout ? nullptr : &rTextNode);
 
             // count PostItFields by looping over all fields
-            sal_Int32 aNumberPostits = 0;
-            sal_Int32 aIgnore = 0;
-            if (pHts && bSearchInNotes)
+            std::vector<std::pair<SwTextAttr const*, AmbiguousIndex>> postits;
+            if (bSearchInNotes)
             {
                 if (!bSrchForward)
                 {
                     std::swap(nStart, nEnd);
                 }
 
-                for( size_t i = 0; i < pHts->Count(); ++i )
+                SwTextNode const* pTemp(nullptr);
+                while (SwTextAttr const*const pTextAttr = iter.NextAttr(pTemp))
                 {
-                    const SwTextAttr* pTextAttr = pHts->Get(i);
                     if ( pTextAttr->Which()==RES_TXTATR_ANNOTATION )
                     {
-                        const sal_Int32 aPos = pTextAttr->GetStart();
-                        if ( (aPos >= nStart) && (aPos <= nEnd) )
-                            aNumberPostits++;
-                        else
+                        AmbiguousIndex aPos;
+                        aPos.SetModelIndex(pTextAttr->GetStart());
+                        if (pLayout)
+                        {
+                            aPos.SetFrameIndex(pFrame->MapModelToView(pTemp, aPos.GetModelIndex()));
+                        }
+                        if ((nStart <= aPos) && (aPos <= nEnd))
                         {
-                            if (bSrchForward)
-                                aIgnore++;
+                            postits.emplace_back(pTextAttr, aPos);
                         }
                     }
                 }
@@ -334,7 +479,9 @@ bool FindTextImpl(SwPaM & rSearchPam,
                     if (SwFrameFormat* pFrameFormat = FindFrameFormat(pObject))
                     {
                         const SwPosition* pPosition = pFrameFormat->GetAnchor().GetContentAnchor();
-                        if (!pPosition || pPosition->nNode.GetIndex() != pNode->GetIndex())
+                        if (!pPosition || (pLayout
+                                ? !FrameContainsNode(*pFrame, pPosition->nNode.GetIndex())
+                                : pPosition->nNode.GetIndex() != pNode->GetIndex()))
                             pObject = nullptr;
                     }
                 }
@@ -369,10 +516,29 @@ bool FindTextImpl(SwPaM & rSearchPam,
                 {
                     // If there are any shapes anchored to this node, search there.
                     SwPaM aPaM(pNode->GetDoc()->GetNodes().GetEndOfContent());
-                    aPaM.GetPoint()->nNode = rTextNode;
-                    aPaM.GetPoint()->nContent.Assign(aPaM.GetPoint()->nNode.GetNode().GetTextNode(), nStart);
+                    if (pLayout)
+                    {
+                        *aPaM.GetPoint() = pFrame->MapViewToModelPos(nStart.GetFrameIndex());
+                    }
+                    else
+                    {
+                        aPaM.GetPoint()->nNode = rTextNode;
+                        aPaM.GetPoint()->nContent.Assign(
+                            aPaM.GetPoint()->nNode.GetNode().GetTextNode(),
+                            nStart.GetModelIndex());
+                    }
                     aPaM.SetMark();
-                    aPaM.GetMark()->nNode = rTextNode.GetIndex() + 1;
+                    if (pLayout)
+                    {
+                        aPaM.GetMark()->nNode = (pFrame->GetMergedPara()
+                                ? *pFrame->GetMergedPara()->pLastNode
+                                : rTextNode)
+                            .GetIndex() + 1;
+                    }
+                    else
+                    {
+                        aPaM.GetMark()->nNode = rTextNode.GetIndex() + 1;
+                    }
                     aPaM.GetMark()->nContent.Assign(aPaM.GetMark()->nNode.GetNode().GetTextNode(), 0);
                     if (pNode->GetDoc()->getIDocumentDrawModelAccess().Search(aPaM, aSearchItem) && pSdrView)
                     {
@@ -396,18 +562,21 @@ bool FindTextImpl(SwPaM & rSearchPam,
                 }
             }
 
-            sal_Int32 aStart = 0;
             // do we need to finish a note?
             if (pPostItMgr && pPostItMgr->HasActiveSidebarWin())
             {
                 if (bSearchInNotes)
                 {
-                    if (bSrchForward)
-                        aStart++;
-                    else
+                    if (!postits.empty())
                     {
-                        if (aNumberPostits)
-                            --aNumberPostits;
+                        if (bSrchForward)
+                        {
+                            postits.erase(postits.begin());
+                        }
+                        else
+                        {
+                            postits.pop_back(); // hope that's the right one?
+                        }
                     }
                     //search inside, finish and put focus back into the doc
                     if (pPostItMgr->FinishSearchReplace(rSearchOpt,bSrchForward))
@@ -422,43 +591,72 @@ bool FindTextImpl(SwPaM & rSearchPam,
                 }
             }
 
-            if (aNumberPostits)
+            if (!postits.empty())
             {
                 // now we have to split
-                sal_Int32 nStartInside = 0;
-                sal_Int32 nEndInside = 0;
-                sal_Int32 aLoop= bSrchForward ? aStart : aNumberPostits;
+                AmbiguousIndex nStartInside;
+                AmbiguousIndex nEndInside;
+                sal_Int32 aLoop = bSrchForward ? 0 : postits.size();
 
-                while ( (aLoop>=0) && (aLoop<=aNumberPostits))
+                while ((0 <= aLoop) && (static_cast<size_t>(aLoop) <= postits.size()))
                 {
                     if (bSrchForward)
                     {
-                        nStartInside = aLoop==0 ? nStart : pHts->Get(GetPostIt(aLoop+aIgnore-1,pHts))->GetStart()+1;
-                        nEndInside = aLoop==aNumberPostits ? nEnd : pHts->Get(GetPostIt(aLoop+aIgnore,pHts))->GetStart();
+                        if (aLoop == 0)
+                        {
+                            nStartInside = nStart;
+                        }
+                        else if (pLayout)
+                        {
+                            nStartInside.SetFrameIndex(postits[aLoop - 1].second.GetFrameIndex() + TextFrameIndex(1));
+                        }
+                        else
+                        {
+                            nStartInside.SetModelIndex(postits[aLoop - 1].second.GetModelIndex() + 1);
+                        }
+                        nEndInside = static_cast<size_t>(aLoop) == postits.size()
+                            ? nEnd
+                            : postits[aLoop].second;
                         nTextLen = nEndInside - nStartInside;
                     }
                     else
                     {
-                        nStartInside =  aLoop==aNumberPostits ? nStart : pHts->Get(GetPostIt(aLoop+aIgnore,pHts))->GetStart();
-                        nEndInside = aLoop==0 ? nEnd : pHts->Get(GetPostIt(aLoop+aIgnore-1,pHts))->GetStart()+1;
+                        nStartInside = static_cast<size_t>(aLoop) == postits.size()
+                            ? nStart
+                            : nStartInside = postits[aLoop].second;
+                        if (aLoop == 0)
+                        {
+                            nEndInside = nEnd;
+                        }
+                        else if (pLayout)
+                        {
+                            nEndInside.SetFrameIndex(postits[aLoop - 1].second.GetFrameIndex() + TextFrameIndex(1));
+                        }
+                        else
+                        {
+                            nEndInside.SetModelIndex(postits[aLoop - 1].second.GetModelIndex() + 1);
+                        }
                         nTextLen = nStartInside - nEndInside;
                     }
                     // search inside the text between a note
                     bFound = DoSearch( rSearchPam,
                                        rSearchOpt, rSText, fnMove, bSrchForward,
                                        bRegSearch, bChkEmptyPara, bChkParaEnd,
-                                       nStartInside, nEndInside, nTextLen, pNode,
+                                       nStartInside, nEndInside, nTextLen,
+                                       pNode->GetTextNode(), pFrame, pLayout,
                                        pPam.get() );
                     if ( bFound )
                         break;
                     else
                     {
                         // we should now be right in front of a note, search inside
-                        if ( (bSrchForward && (GetPostIt(aLoop + aIgnore,pHts) < pHts->Count()) ) || ( !bSrchForward && (aLoop!=0) ))
+                        if (bSrchForward
+                            ? (static_cast<size_t>(aLoop) != postits.size())
+                            : (aLoop != 0))
                         {
-                            const SwTextAttr* pTextAttr = bSrchForward
-                                    ? pHts->Get(GetPostIt(aLoop+aIgnore,pHts))
-                                    : pHts->Get(GetPostIt(aLoop+aIgnore-1,pHts));
+                            const SwTextAttr *const pTextAttr = bSrchForward
+                                ? postits[aLoop].first
+                                : postits[aLoop - 1].first;
                             if (pPostItMgr && pPostItMgr->SearchReplace(
                                     static_txtattr_cast<SwTextField const*>(pTextAttr)->GetFormatField(),rSearchOpt,bSrchForward))
                             {
@@ -477,7 +675,9 @@ bool FindTextImpl(SwPaM & rSearchPam,
                 bFound = DoSearch( rSearchPam,
                                    rSearchOpt, rSText, fnMove, bSrchForward,
                                    bRegSearch, bChkEmptyPara, bChkParaEnd,
-                                   nStart, nEnd, nTextLen, pNode, pPam.get() );
+                                   nStart, nEnd, nTextLen,
+                                   pNode->GetTextNode(), pFrame, pLayout,
+                                   pPam.get() );
             }
             if (bFound)
                 break;
@@ -492,14 +692,14 @@ bool DoSearch(SwPaM & rSearchPam,
         const i18nutil::SearchOptions2& rSearchOpt, utl::TextSearch& rSText,
                       SwMoveFnCollection const & fnMove, bool bSrchForward, bool bRegSearch,
                       bool bChkEmptyPara, bool bChkParaEnd,
-                      sal_Int32 &nStart, sal_Int32 &nEnd, sal_Int32 nTextLen,
-                      SwNode* pNode, SwPaM* pPam)
+        AmbiguousIndex & nStart, AmbiguousIndex & nEnd, AmbiguousIndex const nTextLen,
+        SwTextNode const*const pNode, SwTextFrame const*const pFrame,
+        SwRootFrame const*const pLayout, SwPaM* pPam)
 {
     bool bFound = false;
     SwNodeIndex& rNdIdx = pPam->GetPoint()->nNode;
-    const SwNode* pSttNd = &rNdIdx.GetNode();
     OUString sCleanStr;
-    std::vector<sal_Int32> aFltArr;
+    std::vector<AmbiguousIndex> aFltArr;
     LanguageType eLastLang = LANGUAGE_SYSTEM;
     // if the search string contains a soft hyphen,
     // we don't strip them from the text:
@@ -526,10 +726,10 @@ bool DoSearch(SwPaM & rSearchPam,
     }
 
     if( bSrchForward )
-        sCleanStr = lcl_CleanStr(*pNode->GetTextNode(), nStart, nEnd,
+        sCleanStr = lcl_CleanStr(*pNode, pFrame, pLayout, nStart, nEnd,
                         aFltArr, bRemoveSoftHyphens, bRemoveCommentAnchors);
     else
-        sCleanStr = lcl_CleanStr(*pNode->GetTextNode(), nEnd, nStart,
+        sCleanStr = lcl_CleanStr(*pNode, pFrame, pLayout, nEnd, nStart,
                         aFltArr, bRemoveSoftHyphens, bRemoveCommentAnchors);
 
     std::unique_ptr<SwScriptIterator> pScriptIter;
@@ -538,28 +738,32 @@ bool DoSearch(SwPaM & rSearchPam,
 
     if (SearchAlgorithms2::APPROXIMATE == rSearchOpt.AlgorithmType2)
     {
-        pScriptIter.reset(new SwScriptIterator( sCleanStr, nStart, bSrchForward ));
+        pScriptIter.reset(new SwScriptIterator(sCleanStr, nStart.GetAnyIndex(), bSrchForward));
         nSearchScript = g_pBreakIt->GetRealScriptOfText( rSearchOpt.searchString, 0 );
     }
 
-    const sal_Int32 nStringEnd = nEnd;
+    const AmbiguousIndex nStringEnd = nEnd;
     bool bZeroMatch = false;    // zero-length match, i.e. only $ anchor as regex
     while ( ((bSrchForward && nStart < nStringEnd) ||
-            (! bSrchForward && nStart > nStringEnd)) && !bZeroMatch )
+            (!bSrchForward && nStringEnd < nStart)) && !bZeroMatch )
     {
         // SearchAlgorithms_APPROXIMATE works on a per word base so we have to
         // provide the text searcher with the correct locale, because it uses
         // the break-iterator
         if ( pScriptIter )
         {
-            nEnd = pScriptIter->GetScriptChgPos();
+            nEnd.GetAnyIndex() = pScriptIter->GetScriptChgPos();
             nCurrScript = pScriptIter->GetCurrScript();
             if ( nSearchScript == nCurrScript )
             {
-                const LanguageType eCurrLang =
-                        pNode->GetTextNode()->GetLang( bSrchForward ?
-                                                      nStart :
-                                                      nEnd );
+                const LanguageType eCurrLang = pLayout
+                        ? pFrame->GetLangOfChar(bSrchForward
+                                ? nStart.GetFrameIndex()
+                                : nEnd.GetFrameIndex(),
+                            0, true)
+                        : pNode->GetLang(bSrchForward
+                                ? nStart.GetModelIndex()
+                                : nEnd.GetModelIndex());
 
                 if ( eCurrLang != eLastLang )
                 {
@@ -571,10 +775,10 @@ bool DoSearch(SwPaM & rSearchPam,
             }
             pScriptIter->Next();
         }
-        sal_Int32 nProxyStart = nStart;
-        sal_Int32 nProxyEnd = nEnd;
+        AmbiguousIndex nProxyStart = nStart;
+        AmbiguousIndex nProxyEnd = nEnd;
         if( nSearchScript == nCurrScript &&
-                (rSText.*fnMove.fnSearch)( sCleanStr, &nProxyStart, &nProxyEnd, nullptr ) &&
+                (rSText.*fnMove.fnSearch)( sCleanStr, &nProxyStart.GetAnyIndex(), &nProxyEnd.GetAnyIndex(), nullptr) &&
                 !(bZeroMatch = (nProxyStart == nProxyEnd)))
         {
             nStart = nProxyStart;
@@ -587,27 +791,35 @@ bool DoSearch(SwPaM & rSearchPam,
             if( !aFltArr.empty() )
             {
                 // if backward search, switch positions temporarily
-                if( !bSrchForward ) { std::swap(nStart, nEnd); }
+                if (!bSrchForward) { std::swap(nStart, nEnd); }
 
-                sal_Int32 nNew = nStart;
+                AmbiguousIndex nNew = nStart;
                 for (size_t n = 0; n < aFltArr.size() && aFltArr[ n ] <= nStart; ++n )
                 {
-                    ++nNew;
+                    ++nNew.GetAnyIndex();
                 }
 
                 nStart = nNew;
                 nNew = nEnd;
                 for( size_t n = 0; n < aFltArr.size() && aFltArr[ n ] < nEnd; ++n )
                 {
-                    ++nNew;
+                    ++nNew.GetAnyIndex();
                 }
 
                 nEnd = nNew;
                 // if backward search, switch positions temporarily
                 if( !bSrchForward ) { std::swap(nStart, nEnd); }
             }
-            rSearchPam.GetMark()->nContent = nStart;
-            rSearchPam.GetPoint()->nContent = nEnd;
+            if (pLayout)
+            {
+                *rSearchPam.GetMark() = pFrame->MapViewToModelPos(nStart.GetFrameIndex());
+                *rSearchPam.GetPoint() = pFrame->MapViewToModelPos(nEnd.GetFrameIndex());
+            }
+            else
+            {
+                rSearchPam.GetMark()->nContent = nStart.GetModelIndex();
+                rSearchPam.GetPoint()->nContent = nEnd.GetModelIndex();
+            }
 
             // if backward search, switch point and mark
             if( !bSrchForward )
@@ -626,11 +838,23 @@ bool DoSearch(SwPaM & rSearchPam,
 
     if ( bFound )
         return true;
-    else if( ( bChkEmptyPara && !nStart && !nTextLen ) || bChkParaEnd)
+    else if ((bChkEmptyPara && !nStart.GetAnyIndex() && !nTextLen.GetAnyIndex())
+             || bChkParaEnd)
     {
         *rSearchPam.GetPoint() = *pPam->GetPoint();
-        rSearchPam.GetPoint()->nContent = bChkParaEnd ? nTextLen : 0;
+        if (pLayout)
+        {
+            *rSearchPam.GetPoint() = pFrame->MapViewToModelPos(
+                bChkParaEnd ? nTextLen.GetFrameIndex() : TextFrameIndex(0));
+        }
+        else
+        {
+            rSearchPam.GetPoint()->nContent = bChkParaEnd ? nTextLen.GetModelIndex() : 0;
+        }
         rSearchPam.SetMark();
+        const SwNode *const pSttNd = bSrchForward
+            ? &rSearchPam.GetPoint()->nNode.GetNode() // end of the frame
+            : &rNdIdx.GetNode(); // keep the bug as-is for now...
         /* FIXME: this condition does not work for !bSrchForward backward
          * search, it probably never did. (pSttNd != &rNdIdx.GetNode())
          * is never true in this case. */
@@ -683,7 +907,8 @@ int SwFindParaText::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove,
     if( bInReadOnly && m_bReplace )
         bInReadOnly = false;
 
-    const bool bFnd = sw::FindTextImpl(rCursor, m_rSearchOpt, m_bSearchInNotes, m_aSText, fnMove, rRegion, bInReadOnly);
+    const bool bFnd = sw::FindTextImpl(rCursor, m_rSearchOpt, m_bSearchInNotes,
+            m_aSText, fnMove, rRegion, bInReadOnly, m_pLayout);
 
     if( bFnd && m_bReplace ) // replace string
     {
diff --git a/sw/source/core/crsr/pam.cxx b/sw/source/core/crsr/pam.cxx
index 354adfbbfe37..5e395024ef5d 100644
--- a/sw/source/core/crsr/pam.cxx
+++ b/sw/source/core/crsr/pam.cxx
@@ -735,24 +735,26 @@ bool SwPaM::HasReadonlySel( bool bFormView ) const
 /// @param rbFirst If <true> then first time request. If so than the position of
 ///        the PaM must not be changed!
 SwContentNode* GetNode( SwPaM & rPam, bool& rbFirst, SwMoveFnCollection const & fnMove,
-                      bool bInReadOnly )
+        bool const bInReadOnly, SwRootFrame const*const i_pLayout)
 {
+    SwRootFrame const*const pLayout(i_pLayout ? i_pLayout :
+        rPam.GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout());
     SwContentNode * pNd = nullptr;
     if( ((*rPam.GetPoint()).*fnMove.fnCmpOp)( *rPam.GetMark() ) ||
         ( *rPam.GetPoint() == *rPam.GetMark() && rbFirst ) )
     {
-        SwContentFrame* pFrame;
         if( rbFirst )
         {
             rbFirst = false;
             pNd = rPam.GetContentNode();
             if( pNd )
             {
+                SwContentFrame const*const pFrame(pNd->getLayoutFrame(pLayout));
                 if(
                     (
-                        nullptr == ( pFrame = pNd->getLayoutFrame( pNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout() ) ) ||
+                        nullptr == pFrame ||
                         ( !bInReadOnly && pFrame->IsProtected() ) ||
-                        (pFrame->IsTextFrame() && static_cast<SwTextFrame*>(pFrame)->IsHiddenNow())
+                        (pFrame->IsTextFrame() && static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow())
                     ) ||
                     ( !bInReadOnly && pNd->FindSectionNode() &&
                         pNd->FindSectionNode()->GetSection().IsProtect()
@@ -773,6 +775,12 @@ SwContentNode* GetNode( SwPaM & rPam, bool& rbFirst, SwMoveFnCollection const &
             // go to next/previous ContentNode
             while( true )
             {
+                if (i_pLayout && aPos.nNode.GetNode().IsTextNode())
+                {
+                    auto const fal(sw::GetFirstAndLastNode(*pLayout, aPos.nNode));
+                    aPos.nNode = (bSrchForward) ? *fal.second : *fal.first;
+                }
+
                 pNd = bSrchForward
                         ? rNodes.GoNextSection( &aPos.nNode, true, !bInReadOnly )
                         : SwNodes::GoPrevSection( &aPos.nNode, true, !bInReadOnly );
@@ -783,10 +791,11 @@ SwContentNode* GetNode( SwPaM & rPam, bool& rbFirst, SwMoveFnCollection const &
                     if( (aPos.*fnMove.fnCmpOp)( *rPam.GetMark() ) )
                     {
                         // only in AutoTextSection can be nodes that are hidden
-                        if( nullptr == ( pFrame = pNd->getLayoutFrame( pNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout() ) ) ||
+                        SwContentFrame const*const pFrame(pNd->getLayoutFrame(pLayout));
+                        if (nullptr == pFrame ||
                             ( !bInReadOnly && pFrame->IsProtected() ) ||
                             ( pFrame->IsTextFrame() &&
-                                static_cast<SwTextFrame*>(pFrame)->IsHiddenNow() ) )
+                                static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow()))
                         {
                             pNd = nullptr;
                             continue;
diff --git a/sw/source/core/inc/pamtyp.hxx b/sw/source/core/inc/pamtyp.hxx
index b8a81a090387..a0ebf2bea708 100644
--- a/sw/source/core/inc/pamtyp.hxx
+++ b/sw/source/core/inc/pamtyp.hxx
@@ -29,6 +29,7 @@ class SwPaM;
 class SwTextAttr;
 class SwFormat;
 class SfxPoolItem;
+class SwRootFrame;
 
 namespace i18nutil {
     struct SearchOptions2;
@@ -75,7 +76,8 @@ struct SwMoveFnCollection
 };
 
 // function prototype for searching
-SwContentNode* GetNode( SwPaM&, bool&, SwMoveFnCollection const &, bool bInReadOnly = false );
+SwContentNode* GetNode(SwPaM&, bool&, SwMoveFnCollection const &,
+        bool bInReadOnly = false, SwRootFrame const* pLayout = nullptr);
 
 namespace sw {
 
@@ -88,7 +90,8 @@ namespace sw {
                 bool bSearchInNotes,
                 utl::TextSearch& rSText,
                 SwMoveFnCollection const & fnMove,
-                const SwPaM & rRegion, bool bInReadOnly = false);
+                const SwPaM & rRegion, bool bInReadOnly,
+                SwRootFrame const* pLayout);
     bool FindFormatImpl(SwPaM & rSearchPam,
                 const SwFormat& rFormat,
                 SwMoveFnCollection const & fnMove,
commit bf0afa3c78fc6d7b3e181dacf0b4506916880ef5
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Dec 4 15:57:47 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Dec 11 14:59:42 2018 +0100

    sw_redlinehide_4b: FindText layout parameter
    
    Change-Id: I22c0adb40219bc53b5685e2e20bd55bfd65fd4a3

diff --git a/sw/inc/swcrsr.hxx b/sw/inc/swcrsr.hxx
index dd3b2720abf0..2a89054e02eb 100644
--- a/sw/inc/swcrsr.hxx
+++ b/sw/inc/swcrsr.hxx
@@ -116,7 +116,8 @@ public:
                 SwDocPositions nStart, SwDocPositions nEnde,
                 bool& bCancel,
                 FindRanges,
-                bool bReplace = false );
+                bool bReplace = false,
+                SwRootFrame const*const pLayout = nullptr);
     sal_uLong FindFormat( const SwTextFormatColl& rFormatColl,
                 SwDocPositions nStart, SwDocPositions nEnde,
                 bool& bCancel,
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 903902c50351..8c2f062611ab 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -3330,7 +3330,7 @@ sal_uLong SwCursorShell::FindText( const i18nutil::SearchOptions2& rSearchOpt,
     m_pTableCursor = nullptr;
     SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
     sal_uLong nRet = m_pCurrentCursor->FindText(rSearchOpt, bSearchInNotes, eStart, eEnd,
-                                     bCancel, eRng, bReplace );
+                                     bCancel, eRng, bReplace, GetLayout());
     if( nRet || bCancel )
         UpdateCursor();
     return nRet;
diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx
index 62e42184fcae..5fe3a757e890 100644
--- a/sw/source/core/crsr/findtxt.cxx
+++ b/sw/source/core/crsr/findtxt.cxx
@@ -654,13 +654,19 @@ struct SwFindParaText : public SwFindParas
 {
     const i18nutil::SearchOptions2& m_rSearchOpt;
     SwCursor& m_rCursor;
+    SwRootFrame const* m_pLayout;
     utl::TextSearch m_aSText;
     bool const m_bReplace;
     bool const m_bSearchInNotes;
 
-    SwFindParaText( const i18nutil::SearchOptions2& rOpt, bool bSearchInNotes, bool bRepl, SwCursor& rCursor )
-        : m_rSearchOpt( rOpt ), m_rCursor( rCursor ), m_aSText( utl::TextSearch::UpgradeToSearchOptions2( rOpt) ),
-        m_bReplace( bRepl ), m_bSearchInNotes( bSearchInNotes )
+    SwFindParaText(const i18nutil::SearchOptions2& rOpt, bool bSearchInNotes,
+            bool bRepl, SwCursor& rCursor, SwRootFrame const*const pLayout)
+        : m_rSearchOpt( rOpt )
+        , m_rCursor( rCursor )
+        , m_pLayout(pLayout)
+        , m_aSText( utl::TextSearch::UpgradeToSearchOptions2(rOpt) )
+        , m_bReplace( bRepl )
+        , m_bSearchInNotes( bSearchInNotes )
     {}
     virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, bool bInReadOnly) override;
     virtual bool IsReplaceMode() const override;
@@ -731,7 +737,8 @@ bool SwFindParaText::IsReplaceMode() const
 
 sal_uLong SwCursor::FindText( const i18nutil::SearchOptions2& rSearchOpt, bool bSearchInNotes,
                           SwDocPositions nStart, SwDocPositions nEnd,
-                          bool& bCancel, FindRanges eFndRngs, bool bReplace )
+                          bool& bCancel, FindRanges eFndRngs, bool bReplace,
+                          SwRootFrame const*const pLayout)
 {
     // switch off OLE-notifications
     SwDoc* pDoc = GetDoc();
@@ -747,7 +754,7 @@ sal_uLong SwCursor::FindText( const i18nutil::SearchOptions2& rSearchOpt, bool b
     bool bSearchSel = 0 != (rSearchOpt.searchFlag & SearchFlags::REG_NOT_BEGINOFLINE);
     if( bSearchSel )
         eFndRngs = static_cast<FindRanges>(eFndRngs | FindRanges::InSel);
-    SwFindParaText aSwFindParaText( rSearchOpt, bSearchInNotes, bReplace, *this );
+    SwFindParaText aSwFindParaText(rSearchOpt, bSearchInNotes, bReplace, *this, pLayout);
     sal_uLong nRet = FindAll( aSwFindParaText, nStart, nEnd, eFndRngs, bCancel );
     pDoc->SetOle2Link( aLnk );
     if( nRet && bReplace )
commit 7606c35c8e4b5b6a2176f8c182cb45ec5073a54c
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Dec 4 14:20:02 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Dec 11 14:59:41 2018 +0100

    sw: refactor a confusing thicket of overloads, all named Find()
    
    Also, some of these don't really make much sense as member functions of
    SwPaM, so make them plain functions instead.
    
    Also, some pointer parameters are never null, but there is code to
    handle that case in MakeRegion(); simplify that.
    
    Change-Id: I822e814b0cab14f7f31cfa33478ed15774405a61

diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index 327674e3c547..84c83dd232a1 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -358,18 +358,18 @@ public:
     void MoveColumn( SwWhichColumn, SwPosColumn );
     bool MoveRegion( SwWhichRegion, SwMoveFnCollection const & );
 
-    sal_uLong Find( const i18nutil::SearchOptions2& rSearchOpt,
+    sal_uLong FindText( const i18nutil::SearchOptions2& rSearchOpt,
                 bool bSearchInNotes,
                 SwDocPositions eStart, SwDocPositions eEnd,
                 bool& bCancel,
                 FindRanges eRng, bool bReplace = false );
 
-    sal_uLong Find( const SwTextFormatColl& rFormatColl,
+    sal_uLong FindFormat( const SwTextFormatColl& rFormatColl,
                 SwDocPositions eStart, SwDocPositions eEnd,
                 bool& bCancel,
                 FindRanges eRng, const SwTextFormatColl* pReplFormat );
 
-    sal_uLong Find( const SfxItemSet& rSet, bool bNoCollections,
+    sal_uLong FindAttrs( const SfxItemSet& rSet, bool bNoCollections,
                 SwDocPositions eStart, SwDocPositions eEnd,
                 bool& bCancel,
                 FindRanges eRng,
diff --git a/sw/inc/pam.hxx b/sw/inc/pam.hxx
index c71667e30f50..c7bc752ff347 100644
--- a/sw/inc/pam.hxx
+++ b/sw/inc/pam.hxx
@@ -27,18 +27,9 @@
 
 #include <iostream>
 
-class SwFormat;
-class SfxPoolItem;
-class SfxItemSet;
 class SwDoc;
 class SwPaM;
 class Point;
-namespace i18nutil {
-    struct SearchOptions2;
-}
-namespace utl {
-    class TextSearch;
-}
 
 /// Marks a position in the document model.
 struct SAL_WARN_UNUSED SW_DLLPUBLIC SwPosition
@@ -150,8 +141,6 @@ class SAL_WARN_UNUSED SW_DLLPUBLIC SwPaM : public sw::Ring<SwPaM>
     SwPosition * m_pMark;  ///< points at either m_Bound1 or m_Bound2
     bool m_bIsInFrontOfLabel;
 
-    std::unique_ptr<SwPaM> MakeRegion( SwMoveFnCollection const & fnMove, const SwPaM * pOrigRg );
-
     SwPaM(SwPaM const& rPaM) = delete;
 
 public:
@@ -179,26 +168,6 @@ public:
     bool Move( SwMoveFnCollection const & fnMove = fnMoveForward,
                 SwGoInDoc fnGo = GoInContent );
 
-    /// Search.
-    bool Find(  const i18nutil::SearchOptions2& rSearchOpt,
-                bool bSearchInNotes,
-                utl::TextSearch& rSText,
-                SwMoveFnCollection const & fnMove,
-                const SwPaM *pPam, bool bInReadOnly = false);
-    bool Find(  const SwFormat& rFormat,
-                SwMoveFnCollection const & fnMove,
-                const SwPaM *pPam, bool bInReadOnly = false);
-    bool Find(  const SfxPoolItem& rAttr, bool bValue,
-                SwMoveFnCollection const & fnMove,
-                const SwPaM *pPam, bool bInReadOnly = false );
-    bool Find(  const SfxItemSet& rAttr, bool bNoColls,
-                SwMoveFnCollection const & fnMove,
-                const SwPaM *pPam, bool bInReadOnly, bool bMoveFirst );
-
-    bool DoSearch( const i18nutil::SearchOptions2& rSearchOpt, utl::TextSearch& rSText,
-                   SwMoveFnCollection const & fnMove, bool bSrchForward, bool bRegSearch, bool bChkEmptyPara, bool bChkParaEnd,
-                   sal_Int32 &nStart, sal_Int32 &nEnd, sal_Int32 nTextLen, SwNode* pNode, SwPaM* pPam);
-
     bool IsInFrontOfLabel() const        { return m_bIsInFrontOfLabel; }
     void SetInFrontOfLabel_( bool bNew ) { m_bIsInFrontOfLabel = bNew; }
 
diff --git a/sw/inc/swcrsr.hxx b/sw/inc/swcrsr.hxx
index 5c9214dc2d00..dd3b2720abf0 100644
--- a/sw/inc/swcrsr.hxx
+++ b/sw/inc/swcrsr.hxx
@@ -23,6 +23,7 @@
 #include "tblsel.hxx"
 #include "cshtyp.hxx"
 
+class SfxItemSet;
 struct SwCursor_SavePos;
 namespace i18nutil {
     struct SearchOptions2;
@@ -36,7 +37,7 @@ const int FIND_NO_RING      = 2;
 
 struct SwFindParas
 {
-    virtual int Find( SwPaM*, SwMoveFnCollection const &, const SwPaM*, bool ) = 0;
+    virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM&, bool) = 0;
     virtual bool IsReplaceMode() const = 0;
 
 protected:
@@ -75,8 +76,6 @@ class SW_DLLPUBLIC SwCursor : public SwPaM
 
     sal_uLong FindAll( SwFindParas& , SwDocPositions, SwDocPositions, FindRanges, bool& bCancel );
 
-    using SwPaM::Find;
-
     SwCursor(SwCursor const& rPaM) = delete;
 
 protected:
@@ -112,18 +111,18 @@ public:
     SwMoveFnCollection const & MakeFindRange( SwDocPositions, SwDocPositions,
                                         SwPaM* ) const;
 
-    sal_uLong Find( const i18nutil::SearchOptions2& rSearchOpt,
+    sal_uLong FindText( const i18nutil::SearchOptions2& rSearchOpt,
                 bool bSearchInNotes,
                 SwDocPositions nStart, SwDocPositions nEnde,
                 bool& bCancel,
                 FindRanges,
                 bool bReplace = false );
-    sal_uLong Find( const SwTextFormatColl& rFormatColl,
+    sal_uLong FindFormat( const SwTextFormatColl& rFormatColl,
                 SwDocPositions nStart, SwDocPositions nEnde,
                 bool& bCancel,
                 FindRanges,
                 const SwTextFormatColl* pReplFormat );
-    sal_uLong Find( const SfxItemSet& rSet, bool bNoCollections,
+    sal_uLong FindAttrs( const SfxItemSet& rSet, bool bNoCollections,
                 SwDocPositions nStart, SwDocPositions nEnde,
                 bool& bCancel,
                 FindRanges,
diff --git a/sw/qa/core/macros-test.cxx b/sw/qa/core/macros-test.cxx
index 068001c7551b..82bdea2b4ca5 100644
--- a/sw/qa/core/macros-test.cxx
+++ b/sw/qa/core/macros-test.cxx
@@ -554,7 +554,7 @@ void SwMacrosTest::testFindReplace()
             '\\');
 
     // find newline on 1st paragraph
-    bool bFound = pPaM->Find(
+    bool bFound = pPaM->FindText(
             opts, false, SwDocPositions::Curr, SwDocPositions::End, bCancel, FindRanges::InBody);
     CPPUNIT_ASSERT(bFound);
     CPPUNIT_ASSERT(pPaM->HasMark());
@@ -562,7 +562,7 @@ void SwMacrosTest::testFindReplace()
 
     // now do another Find, inside the selection from the first Find
 //    opts.searchFlags = 71680;
-    bFound = pPaM->Find(
+    bFound = pPaM->FindText(
             opts, false, SwDocPositions::Curr, SwDocPositions::End, bCancel, FindRanges::InSel);
     CPPUNIT_ASSERT(bFound);
     CPPUNIT_ASSERT(pPaM->HasMark());
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 7c59d0d70751..903902c50351 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -3317,7 +3317,7 @@ bool SwCursorShell::SelectHiddenRange()
     return bRet;
 }
 
-sal_uLong SwCursorShell::Find( const i18nutil::SearchOptions2& rSearchOpt,
+sal_uLong SwCursorShell::FindText( const i18nutil::SearchOptions2& rSearchOpt,
                              bool bSearchInNotes,
                              SwDocPositions eStart, SwDocPositions eEnd,
                              bool& bCancel,
@@ -3329,14 +3329,14 @@ sal_uLong SwCursorShell::Find( const i18nutil::SearchOptions2& rSearchOpt,
     delete m_pTableCursor;
     m_pTableCursor = nullptr;
     SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
-    sal_uLong nRet = m_pCurrentCursor->Find( rSearchOpt, bSearchInNotes, eStart, eEnd,
+    sal_uLong nRet = m_pCurrentCursor->FindText(rSearchOpt, bSearchInNotes, eStart, eEnd,
                                      bCancel, eRng, bReplace );
     if( nRet || bCancel )
         UpdateCursor();
     return nRet;
 }
 
-sal_uLong SwCursorShell::Find( const SwTextFormatColl& rFormatColl,
+sal_uLong SwCursorShell::FindFormat( const SwTextFormatColl& rFormatColl,
                              SwDocPositions eStart, SwDocPositions eEnd,
                              bool& bCancel,
                              FindRanges eRng,
@@ -3347,14 +3347,14 @@ sal_uLong SwCursorShell::Find( const SwTextFormatColl& rFormatColl,
     delete m_pTableCursor;
     m_pTableCursor = nullptr;
     SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
-    sal_uLong nRet = m_pCurrentCursor->Find( rFormatColl, eStart, eEnd, bCancel, eRng,
+    sal_uLong nRet = m_pCurrentCursor->FindFormat(rFormatColl, eStart, eEnd, bCancel, eRng,
                                      pReplFormat );
     if( nRet )
         UpdateCursor();
     return nRet;
 }
 
-sal_uLong SwCursorShell::Find( const SfxItemSet& rSet,
+sal_uLong SwCursorShell::FindAttrs( const SfxItemSet& rSet,
                              bool bNoCollections,
                              SwDocPositions eStart, SwDocPositions eEnd,
                              bool& bCancel,
@@ -3367,7 +3367,7 @@ sal_uLong SwCursorShell::Find( const SfxItemSet& rSet,
     delete m_pTableCursor;
     m_pTableCursor = nullptr;
     SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
-    sal_uLong nRet = m_pCurrentCursor->Find( rSet, bNoCollections, eStart, eEnd,
+    sal_uLong nRet = m_pCurrentCursor->FindAttrs(rSet, bNoCollections, eStart, eEnd,
                                      bCancel, eRng, pSearchOpt, rReplSet );
     if( nRet )
         UpdateCursor();
diff --git a/sw/source/core/crsr/findattr.cxx b/sw/source/core/crsr/findattr.cxx
index fa258e82ae53..4999c07d734b 100644
--- a/sw/source/core/crsr/findattr.cxx
+++ b/sw/source/core/crsr/findattr.cxx
@@ -887,14 +887,17 @@ static bool lcl_Search( const SwContentNode& rCNd, const SfxItemSet& rCmpSet, bo
     return true; // found
 }
 
-bool SwPaM::Find( const SfxPoolItem& rAttr, bool bValue, SwMoveFnCollection const & fnMove,
-                  const SwPaM *pRegion, bool bInReadOnly )
+namespace sw {
+
+bool FindAttrImpl(SwPaM & rSearchPam,
+        const SfxPoolItem& rAttr, bool bValue, SwMoveFnCollection const & fnMove,
+        const SwPaM & rRegion, bool bInReadOnly)
 {
     // determine which attribute is searched:
     const sal_uInt16 nWhich = rAttr.Which();
     bool bCharAttr = isCHRATR(nWhich) || isTXTATR(nWhich);
 
-    std::unique_ptr<SwPaM> pPam(MakeRegion( fnMove, pRegion ));
+    std::unique_ptr<SwPaM> pPam(sw::MakeRegion(fnMove, rRegion));
 
     bool bFound = false;
     bool bFirst = true;
@@ -927,9 +930,9 @@ bool SwPaM::Find( const SfxPoolItem& rAttr, bool bValue, SwMoveFnCollection cons
                 lcl_Search( *pNode->GetTextNode(), *pPam, rAttr, fnMove,  bValue ))
             {
                 // set to the values of the attribute
-                SetMark();
-                *GetPoint() = *pPam->GetPoint();
-                *GetMark() = *pPam->GetMark();
+                rSearchPam.SetMark();
+                *rSearchPam.GetPoint() = *pPam->GetPoint();
+                *rSearchPam.GetMark() = *pPam->GetMark();
                 bFound = true;
                 break;
             }
@@ -952,9 +955,9 @@ bool SwPaM::Find( const SfxPoolItem& rAttr, bool bValue, SwMoveFnCollection cons
             // FORWARD:  SPoint at the end, GetMark at the beginning of the node
             // BACKWARD: SPoint at the beginning, GetMark at the end of the node
             // always: incl. start and incl. end
-            *GetPoint() = *pPam->GetPoint();
-            SetMark();
-            pNode->MakeEndIndex( &GetPoint()->nContent );
+            *rSearchPam.GetPoint() = *pPam->GetPoint();
+            rSearchPam.SetMark();
+            pNode->MakeEndIndex( &rSearchPam.GetPoint()->nContent );
             bFound = true;
             break;
         }
@@ -962,17 +965,20 @@ bool SwPaM::Find( const SfxPoolItem& rAttr, bool bValue, SwMoveFnCollection cons
 
     // if backward search, switch point and mark
     if( bFound && !bSrchForward )
-        Exchange();
+        rSearchPam.Exchange();
 
     return bFound;
 }
 
+} // namespace sw
+
 typedef bool (*FnSearchAttr)( const SwTextNode&, SwAttrCheckArr&, SwPaM& );
 
-bool SwPaM::Find( const SfxItemSet& rSet, bool bNoColls, SwMoveFnCollection const & fnMove,
-                  const SwPaM *pRegion, bool bInReadOnly, bool bMoveFirst )
+static bool FindAttrsImpl(SwPaM & rSearchPam,
+        const SfxItemSet& rSet, bool bNoColls, SwMoveFnCollection const & fnMove,
+        const SwPaM & rRegion, bool bInReadOnly, bool bMoveFirst)
 {
-    std::unique_ptr<SwPaM> pPam(MakeRegion( fnMove, pRegion ));
+    std::unique_ptr<SwPaM> pPam(sw::MakeRegion(fnMove, rRegion));
 
     bool bFound = false;
     bool bFirst = true;
@@ -982,7 +988,7 @@ bool SwPaM::Find( const SfxItemSet& rSet, bool bNoColls, SwMoveFnCollection cons
 
     // check which text/char attributes are searched
     SwAttrCheckArr aCmpArr( rSet, bSrchForward, bNoColls );
-    SfxItemSet aOtherSet( GetDoc()->GetAttrPool(),
+    SfxItemSet aOtherSet( rSearchPam.GetDoc()->GetAttrPool(),
                             svl::Items<RES_PARATR_BEGIN, RES_GRFATR_END-1>{} );
     aOtherSet.Put( rSet, false );   // got all invalid items
 
@@ -1016,9 +1022,9 @@ bool SwPaM::Find( const SfxItemSet& rSet, bool bNoColls, SwMoveFnCollection cons
                 (*fnSearch)( *pNode->GetTextNode(), aCmpArr, *pPam ))
             {
                 // set to the values of the attribute
-                SetMark();
-                *GetPoint() = *pPam->GetPoint();
-                *GetMark() = *pPam->GetMark();
+                rSearchPam.SetMark();
+                *rSearchPam.GetPoint() = *pPam->GetPoint();
+                *rSearchPam.GetMark() = *pPam->GetMark();
                 bFound = true;
                 break;
             }
@@ -1042,9 +1048,9 @@ bool SwPaM::Find( const SfxItemSet& rSet, bool bNoColls, SwMoveFnCollection cons
             // FORWARD:  SPoint at the end, GetMark at the beginning of the node
             // BACKWARD: SPoint at the beginning, GetMark at the end of the node
             // always: incl. start and incl. end
-            *GetPoint() = *pPam->GetPoint();
-            SetMark();
-            pNode->MakeEndIndex( &GetPoint()->nContent );
+            *rSearchPam.GetPoint() = *pPam->GetPoint();
+            rSearchPam.SetMark();
+            pNode->MakeEndIndex( &rSearchPam.GetPoint()->nContent );
             bFound = true;
             break;
         }
@@ -1052,7 +1058,7 @@ bool SwPaM::Find( const SfxItemSet& rSet, bool bNoColls, SwMoveFnCollection cons
 
     // if backward search, switch point and mark
     if( bFound && !bSrchForward )
-        Exchange();
+        rSearchPam.Exchange();
 
     return bFound;
 }
@@ -1074,12 +1080,12 @@ struct SwFindParaAttr : public SwFindParas
 
     virtual ~SwFindParaAttr()   {}
 
-    virtual int Find( SwPaM* , SwMoveFnCollection const & , const SwPaM*, bool bInReadOnly ) override;
+    virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, bool bInReadOnly) override;
     virtual bool IsReplaceMode() const override;
 };
 
-int SwFindParaAttr::Find( SwPaM* pCursor, SwMoveFnCollection const & fnMove, const SwPaM* pRegion,
-                          bool bInReadOnly )
+int SwFindParaAttr::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove,
+        const SwPaM & rRegion, bool bInReadOnly)
 {
     // replace string (only if text given and search is not parameterized)?
     bool bReplaceText = pSearchOpt && ( !pSearchOpt->replaceString.isEmpty() ||
@@ -1091,16 +1097,16 @@ int SwFindParaAttr::Find( SwPaM* pCursor, SwMoveFnCollection const & fnMove, con
 
     // We search for attributes, should we search for text as well?
     {
-        SwPaM aRegion( *pRegion->GetMark(), *pRegion->GetPoint() );
+        SwPaM aRegion( *rRegion.GetMark(), *rRegion.GetPoint() );
         SwPaM* pTextRegion = &aRegion;
-        SwPaM aSrchPam( *pCursor->GetPoint() );
+        SwPaM aSrchPam( *rCursor.GetPoint() );
 
         while( true )
         {
             if( pSet->Count() ) // any attributes?
             {
                 // first attributes
-                if( !aSrchPam.Find( *pSet, bValue, fnMove, &aRegion, bInReadOnly, bMoveFirst ) )
+                if (!FindAttrsImpl(aSrchPam, *pSet, bValue, fnMove, aRegion, bInReadOnly, bMoveFirst))
                     return FIND_NOT_FOUND;
                 bMoveFirst = true;
 
@@ -1129,7 +1135,7 @@ int SwFindParaAttr::Find( SwPaM* pCursor, SwMoveFnCollection const & fnMove, con
             // TODO: searching for attributes in Outliner text?!
 
             // continue search in correct section (pTextRegion)
-            if( aSrchPam.Find( *pSearchOpt, false/*bSearchInNotes*/, *pSText, fnMove, pTextRegion, bInReadOnly ) &&
+            if (sw::FindTextImpl(aSrchPam, *pSearchOpt, false/*bSearchInNotes*/, *pSText, fnMove, *pTextRegion, bInReadOnly) &&
                 *aSrchPam.GetMark() != *aSrchPam.GetPoint() )
                 break; // found
             else if( !pSet->Count() )
@@ -1138,41 +1144,41 @@ int SwFindParaAttr::Find( SwPaM* pCursor, SwMoveFnCollection const & fnMove, con
             *aRegion.GetMark() = *aSrchPam.GetPoint();
         }
 
-        *pCursor->GetPoint() = *aSrchPam.GetPoint();
-        pCursor->SetMark();
-        *pCursor->GetMark() = *aSrchPam.GetMark();
+        *rCursor.GetPoint() = *aSrchPam.GetPoint();
+        rCursor.SetMark();
+        *rCursor.GetMark() = *aSrchPam.GetMark();
     }
 
     if( bReplaceText )
     {
         const bool bRegExp(
                 SearchAlgorithms2::REGEXP == pSearchOpt->AlgorithmType2);
-        SwIndex& rSttCntIdx = pCursor->Start()->nContent;
+        SwIndex& rSttCntIdx = rCursor.Start()->nContent;
         const sal_Int32 nSttCnt = rSttCntIdx.GetIndex();
 
         // add to shell-cursor-ring so that the regions will be moved eventually
         SwPaM* pPrevRing(nullptr);
         if( bRegExp )
         {
-            pPrevRing = const_cast< SwPaM* >(pRegion)->GetPrev();
-            const_cast< SwPaM* >(pRegion)->GetRingContainer().merge( m_rCursor.GetRingContainer() );
+            pPrevRing = const_cast<SwPaM &>(rRegion).GetPrev();
+            const_cast<SwPaM &>(rRegion).GetRingContainer().merge( m_rCursor.GetRingContainer() );
         }
 
         std::unique_ptr<OUString> pRepl( bRegExp ?
-                ReplaceBackReferences( *pSearchOpt, pCursor ) : nullptr );
+                ReplaceBackReferences(*pSearchOpt, &rCursor) : nullptr );
         m_rCursor.GetDoc()->getIDocumentContentOperations().ReplaceRange(
-            *pCursor, pRepl ? *pRepl : pSearchOpt->replaceString, bRegExp);
-        m_rCursor.SaveTableBoxContent( pCursor->GetPoint() );
+            rCursor, pRepl ? *pRepl : pSearchOpt->replaceString, bRegExp);
+        m_rCursor.SaveTableBoxContent( rCursor.GetPoint() );
 
         if( bRegExp )
         {
             // and remove region again
             SwPaM* p;
-            SwPaM* pNext = const_cast<SwPaM*>(pRegion);
+            SwPaM* pNext = const_cast<SwPaM*>(&rRegion);
             do {
                 p = pNext;
                 pNext = p->GetNext();
-                p->MoveTo( const_cast<SwPaM*>(pRegion) );
+                p->MoveTo(const_cast<SwPaM*>(&rRegion));
             } while( p != pPrevRing );
         }
         rSttCntIdx = nSttCnt;
@@ -1185,7 +1191,7 @@ int SwFindParaAttr::Find( SwPaM* pCursor, SwMoveFnCollection const & fnMove, con
         // they are not in ReplaceSet
         if( !pSet->Count() )
         {
-            pCursor->GetDoc()->getIDocumentContentOperations().InsertItemSet( *pCursor, *pReplSet );
+            rCursor.GetDoc()->getIDocumentContentOperations().InsertItemSet(rCursor, *pReplSet);
         }
         else
         {
@@ -1206,7 +1212,7 @@ int SwFindParaAttr::Find( SwPaM* pCursor, SwMoveFnCollection const & fnMove, con
                 pItem = aIter.NextItem();
             }
             aSet.Put( *pReplSet );
-            pCursor->GetDoc()->getIDocumentContentOperations().InsertItemSet( *pCursor, aSet );
+            rCursor.GetDoc()->getIDocumentContentOperations().InsertItemSet(rCursor, aSet);
         }
 
         return FIND_NO_RING;
@@ -1222,7 +1228,7 @@ bool SwFindParaAttr::IsReplaceMode() const
 }
 
 /// search for attributes
-sal_uLong SwCursor::Find( const SfxItemSet& rSet, bool bNoCollections,
+sal_uLong SwCursor::FindAttrs( const SfxItemSet& rSet, bool bNoCollections,
                           SwDocPositions nStart, SwDocPositions nEnd,
                           bool& bCancel, FindRanges eFndRngs,
                           const i18nutil::SearchOptions2* pSearchOpt,
diff --git a/sw/source/core/crsr/findcoll.cxx b/sw/source/core/crsr/findcoll.cxx
index 6f59f3148750..b05fe2c5f742 100644
--- a/sw/source/core/crsr/findcoll.cxx
+++ b/sw/source/core/crsr/findcoll.cxx
@@ -34,22 +34,22 @@ struct SwFindParaFormatColl : public SwFindParas
         : pFormatColl( &rFormatColl ), pReplColl( pRpColl )
     {}
     virtual ~SwFindParaFormatColl() {}
-    virtual int Find( SwPaM* , SwMoveFnCollection const & , const SwPaM*, bool bInReadOnly ) override;
+    virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, bool bInReadOnly) override;
     virtual bool IsReplaceMode() const override;
 };
 
-int SwFindParaFormatColl::Find( SwPaM* pCursor, SwMoveFnCollection const & fnMove, const SwPaM* pRegion,
-                             bool bInReadOnly )
+int SwFindParaFormatColl::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove,
+        const SwPaM & rRegion, bool bInReadOnly)
 {
     int nRet = FIND_FOUND;
     if( bInReadOnly && pReplColl )
         bInReadOnly = false;
 
-    if( !pCursor->Find( *pFormatColl, fnMove, pRegion, bInReadOnly ) )
+    if (!sw::FindFormatImpl(rCursor, *pFormatColl, fnMove, rRegion, bInReadOnly))
         nRet = FIND_NOT_FOUND;
     else if( pReplColl )
     {
-        pCursor->GetDoc()->SetTextFormatColl( *pCursor, const_cast<SwTextFormatColl*>(pReplColl) );
+        rCursor.GetDoc()->SetTextFormatColl(rCursor, const_cast<SwTextFormatColl*>(pReplColl));
         nRet = FIND_NO_RING;
     }
     return nRet;
@@ -61,7 +61,7 @@ bool SwFindParaFormatColl::IsReplaceMode() const
 }
 
 /// search for Format-Collections
-sal_uLong SwCursor::Find( const SwTextFormatColl& rFormatColl, SwDocPositions nStart,
+sal_uLong SwCursor::FindFormat( const SwTextFormatColl& rFormatColl, SwDocPositions nStart,
                           SwDocPositions nEnd, bool& bCancel,
                           FindRanges eFndRngs, const SwTextFormatColl* pReplFormatColl )
 {
diff --git a/sw/source/core/crsr/findfmt.cxx b/sw/source/core/crsr/findfmt.cxx
index 2b16d0481ddd..f45759e5a0d6 100644
--- a/sw/source/core/crsr/findfmt.cxx
+++ b/sw/source/core/crsr/findfmt.cxx
@@ -22,12 +22,15 @@
 #include <pam.hxx>
 #include <memory>
 
-bool SwPaM::Find( const SwFormat& rFormat, SwMoveFnCollection const & fnMove,
-                  const SwPaM *pRegion, bool bInReadOnly  )
+namespace sw {
+
+bool FindFormatImpl(SwPaM & rSearchPam,
+        const SwFormat& rFormat, SwMoveFnCollection const & fnMove,
+        const SwPaM &rRegion, bool bInReadOnly)
 {
     bool bFound = false;
     const bool bSrchForward = &fnMove == &fnMoveForward;
-    std::unique_ptr<SwPaM> pPam(MakeRegion( fnMove, pRegion ));
+    std::unique_ptr<SwPaM> pPam(MakeRegion( fnMove, rRegion ));
 
     // if at beginning/end then move it out of the node
     if( bSrchForward
@@ -53,14 +56,14 @@ bool SwPaM::Find( const SwFormat& rFormat, SwMoveFnCollection const & fnMove,
             // FORWARD:  SPoint at the end, GetMark at the beginning of the node
             // BACKWARD: SPoint at the beginning, GetMark at the end of the node
             // always: incl. start and incl. end
-            *GetPoint() = *pPam->GetPoint();
-            SetMark();
-            pNode->MakeEndIndex( &GetPoint()->nContent );
-            GetMark()->nContent = 0;
+            *rSearchPam.GetPoint() = *pPam->GetPoint();
+            rSearchPam.SetMark();
+            pNode->MakeEndIndex( &rSearchPam.GetPoint()->nContent );
+            rSearchPam.GetMark()->nContent = 0;
 
             // if backward search, switch point and mark
             if( !bSrchForward )
-                Exchange();
+                rSearchPam.Exchange();
 
             bFound = true;
             break;
@@ -69,4 +72,6 @@ bool SwPaM::Find( const SwFormat& rFormat, SwMoveFnCollection const & fnMove,
     return bFound;
 }
 
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx
index ad7ec024ef4a..62e42184fcae 100644
--- a/sw/source/core/crsr/findtxt.cxx
+++ b/sw/source/core/crsr/findtxt.cxx
@@ -226,14 +226,25 @@ static size_t GetPostIt(sal_Int32 aCount,const SwpHints *pHts)
     return aIndex;
 }
 
-bool SwPaM::Find( const i18nutil::SearchOptions2& rSearchOpt, bool bSearchInNotes , utl::TextSearch& rSText,
-                  SwMoveFnCollection const & fnMove, const SwPaM * pRegion,
-                  bool bInReadOnly )
+static bool DoSearch(SwPaM & rSearchPam,
+    const i18nutil::SearchOptions2& rSearchOpt, utl::TextSearch& rSText,
+    SwMoveFnCollection const & fnMove,
+    bool bSrchForward, bool bRegSearch, bool bChkEmptyPara, bool bChkParaEnd,
+    sal_Int32 &nStart, sal_Int32 &nEnd, sal_Int32 nTextLen, SwNode* pNode,
+    SwPaM* pPam);
+
+namespace sw {
+
+bool FindTextImpl(SwPaM & rSearchPam,
+        const i18nutil::SearchOptions2& rSearchOpt, bool bSearchInNotes,
+        utl::TextSearch& rSText,
+        SwMoveFnCollection const & fnMove, const SwPaM & rRegion,
+        bool bInReadOnly)
 {
     if( rSearchOpt.searchString.isEmpty() )
         return false;
 
-    std::unique_ptr<SwPaM> pPam = MakeRegion( fnMove, pRegion );
+    std::unique_ptr<SwPaM> pPam = sw::MakeRegion(fnMove, rRegion);
     const bool bSrchForward = &fnMove == &fnMoveForward;
     SwNodeIndex& rNdIdx = pPam->GetPoint()->nNode;
     SwIndex& rContentIdx = pPam->GetPoint()->nContent;
@@ -373,9 +384,9 @@ bool SwPaM::Find( const i18nutil::SearchOptions2& rSearchOpt, bool bSearchInNote
                                 if (pPosition)
                                 {
                                     // Set search position to the shape's anchor point.
-                                    *GetPoint() = *pPosition;
-                                    GetPoint()->nContent.Assign(pPosition->nNode.GetNode().GetContentNode(), 0);
-                                    SetMark();

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list