diff options
Diffstat (limited to 'sw/source/core/crsr/findtxt.cxx')
-rw-r--r-- | sw/source/core/crsr/findtxt.cxx | 624 |
1 files changed, 316 insertions, 308 deletions
diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx index f19f3ff908eb..07a19bde59b7 100644 --- a/sw/source/core/crsr/findtxt.cxx +++ b/sw/source/core/crsr/findtxt.cxx @@ -28,6 +28,7 @@ #include <svl/srchitem.hxx> #include <sfx2/sfxsids.hrc> #include <editeng/outliner.hxx> +#include <osl/diagnose.h> #include <wrtsh.hxx> #include <txatritr.hxx> @@ -152,11 +153,7 @@ public: { if (pFrame) { -#if BOOST_VERSION < 105600 - m_oMergedIter.reset(*pFrame); -#else m_oMergedIter.emplace(*pFrame); -#endif } } @@ -274,7 +271,6 @@ lcl_CleanStr(const SwTextNode& rNd, switch (pNextHint->Which()) { case RES_TXTATR_FLYCNT: - case RES_TXTATR_FTN: case RES_TXTATR_FIELD: case RES_TXTATR_REFMARK: case RES_TXTATR_TOXMARK: @@ -365,7 +361,7 @@ static bool DoSearch(SwPaM & rSearchPam, bool bSrchForward, bool bRegSearch, bool bChkEmptyPara, bool bChkParaEnd, AmbiguousIndex & nStart, AmbiguousIndex & nEnd, AmbiguousIndex nTextLen, SwTextNode const* pNode, SwTextFrame const* pTextFrame, - SwRootFrame const* pLayout, SwPaM* pPam); + SwRootFrame const* pLayout, SwPaM& rPam); namespace sw { @@ -380,10 +376,10 @@ bool FindTextImpl(SwPaM & rSearchPam, if( rSearchOpt.searchString.isEmpty() ) return false; - std::unique_ptr<SwPaM> pPam = sw::MakeRegion(fnMove, rRegion); + std::optional<SwPaM> oPam; + sw::MakeRegion(fnMove, rRegion, oPam); const bool bSrchForward = &fnMove == &fnMoveForward; - SwNodeIndex& rNdIdx = pPam->GetPoint()->nNode; - SwIndex& rContentIdx = pPam->GetPoint()->nContent; + SwPosition& rPtPos = *oPam->GetPoint(); // If bFound is true then the string was found and is between nStart and nEnd bool bFound = false; @@ -405,325 +401,317 @@ bool FindTextImpl(SwPaM & rSearchPam, } // LanguageType eLastLang = 0; - while (nullptr != (pNode = ::GetNode(*pPam, bFirst, fnMove, bInReadOnly, pLayout))) + while (nullptr != (pNode = ::GetNode(*oPam, bFirst, fnMove, bInReadOnly, pLayout))) { - if( pNode->IsTextNode() ) + if (!pNode->IsTextNode()) + continue; + + const SwTextNode& rTextNode = *pNode->GetTextNode(); + 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, oPam->GetMark()->GetNodeIndex()) + : rPtPos.GetNode() == oPam->GetMark()->GetNode()) { - SwTextNode& rTextNode = *pNode->GetTextNode(); - 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())); + nEnd.SetFrameIndex(pFrame->MapModelToViewPos(*oPam->GetMark())); } else { - nTextLen.SetModelIndex(rTextNode.GetText().getLength()); + nEnd.SetModelIndex(oPam->GetMark()->GetContentIndex()); + } + } + else + { + if (bSrchForward) + { + nEnd = nTextLen; } - AmbiguousIndex nEnd; - if (pLayout - ? FrameContainsNode(*pFrame, pPam->GetMark()->nNode.GetIndex()) - : rNdIdx == pPam->GetMark()->nNode) + else { if (pLayout) { - nEnd.SetFrameIndex(pFrame->MapModelToViewPos(*pPam->GetMark())); + nEnd.SetFrameIndex(TextFrameIndex(0)); } else { - nEnd.SetModelIndex(pPam->GetMark()->nContent.GetIndex()); + nEnd.SetModelIndex(0); } } - else + } + AmbiguousIndex nStart; + if (pLayout) + { + nStart.SetFrameIndex(pFrame->MapModelToViewPos(*oPam->GetPoint())); + } + else + { + nStart.SetModelIndex(rPtPos.GetContentIndex()); + } + + /* #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 + MaybeMergedIter iter(pLayout ? pFrame : nullptr, pLayout ? nullptr : &rTextNode); + + // count PostItFields by looping over all fields + std::vector<std::pair<SwTextAttr const*, AmbiguousIndex>> postits; + if (bSearchInNotes) + { + if (!bSrchForward) { - if (bSrchForward) - { - nEnd = nTextLen; - } - else + std::swap(nStart, nEnd); + } + + SwTextNode const* pTemp(nullptr); + while (SwTextAttr const* const pTextAttr = iter.NextAttr(pTemp)) + { + if (pTextAttr->Which() == RES_TXTATR_ANNOTATION) { + AmbiguousIndex aPos; + aPos.SetModelIndex(pTextAttr->GetStart()); if (pLayout) { - nEnd.SetFrameIndex(TextFrameIndex(0)); + aPos.SetFrameIndex(pFrame->MapModelToView(pTemp, aPos.GetModelIndex())); } - else + if ((nStart <= aPos) && (aPos <= nEnd)) { - nEnd.SetModelIndex(0); + postits.emplace_back(pTextAttr, aPos); } } } - AmbiguousIndex nStart; - if (pLayout) - { - nStart.SetFrameIndex(pFrame->MapModelToViewPos(*pPam->GetPoint())); - } - else + + if (!bSrchForward) { - nStart.SetModelIndex(rContentIdx.GetIndex()); + std::swap(nStart, nEnd); } + } - /* #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 - MaybeMergedIter iter(pLayout ? pFrame : nullptr, pLayout ? nullptr : &rTextNode); + SwDocShell* const pDocShell = pNode->GetDoc().GetDocShell(); + SwWrtShell* const pWrtShell = pDocShell ? pDocShell->GetWrtShell() : nullptr; + SwPostItMgr* const pPostItMgr = pWrtShell ? pWrtShell->GetPostItMgr() : nullptr; - // count PostItFields by looping over all fields - std::vector<std::pair<SwTextAttr const*, AmbiguousIndex>> postits; - if (bSearchInNotes) + // If there is an active text edit, then search there. + bool bEndedTextEdit = false; + SdrView* pSdrView = pWrtShell ? pWrtShell->GetDrawView() : nullptr; + if (pSdrView) + { + // If the edited object is not anchored to this node, then ignore it. + SdrObject* pObject = pSdrView->GetTextEditObject(); + if (pObject) { - if (!bSrchForward) + if (SwFrameFormat* pFrameFormat = FindFrameFormat(pObject)) { - std::swap(nStart, nEnd); + const SwNode* pAnchorNode = pFrameFormat->GetAnchor().GetAnchorNode(); + if (!pAnchorNode + || (pLayout ? !FrameContainsNode(*pFrame, pAnchorNode->GetIndex()) + : pAnchorNode->GetIndex() != pNode->GetIndex())) + pObject = nullptr; } + } - SwTextNode const* pTemp(nullptr); - while (SwTextAttr const*const pTextAttr = iter.NextAttr(pTemp)) + if (pObject) + { + sal_uInt16 nResult + = pSdrView->GetTextEditOutlinerView()->StartSearchAndReplace(*xSearchItem); + if (!nResult) { - if ( pTextAttr->Which()==RES_TXTATR_ANNOTATION ) - { - AmbiguousIndex aPos; - aPos.SetModelIndex(pTextAttr->GetStart()); - if (pLayout) - { - aPos.SetFrameIndex(pFrame->MapModelToView(pTemp, aPos.GetModelIndex())); - } - if ((nStart <= aPos) && (aPos <= nEnd)) - { - postits.emplace_back(pTextAttr, aPos); - } - } + // If not found, end the text edit. + pSdrView->SdrEndTextEdit(); + const Point aPoint(pSdrView->GetAllMarkedRect().TopLeft()); + pSdrView->UnmarkAll(); + pWrtShell->CallSetCursor(&aPoint, true); + pWrtShell->Edit(); + bEndedTextEdit = true; } - - if (!bSrchForward) + else { - std::swap(nStart, nEnd); + bFound = true; + break; } - } + } - SwDocShell *const pDocShell = pNode->GetDoc().GetDocShell(); - SwWrtShell *const pWrtShell = pDocShell ? pDocShell->GetWrtShell() : nullptr; - SwPostItMgr *const pPostItMgr = pWrtShell ? pWrtShell->GetPostItMgr() : nullptr; - - // If there is an active text edit, then search there. - bool bEndedTextEdit = false; - SdrView* pSdrView = pWrtShell ? pWrtShell->GetDrawView() : nullptr; - if (pSdrView) + if (comphelper::LibreOfficeKit::isActive()) + { + // Writer and editeng selections are not supported in parallel. + SvxSearchItem* pSearchItem = SwView::GetSearchItem(); + // If we just finished search in shape text, don't attempt to do that again. + if (!bEndedTextEdit + && !(pSearchItem && pSearchItem->GetCommand() == SvxSearchCmd::FIND_ALL)) { - // If the edited object is not anchored to this node, then ignore it. - SdrObject* pObject = pSdrView->GetTextEditObject(); - if (pObject) + // If there are any shapes anchored to this node, search there. + SwPaM aPaM(pNode->GetDoc().GetNodes().GetEndOfContent()); + if (pLayout) { - if (SwFrameFormat* pFrameFormat = FindFrameFormat(pObject)) - { - const SwPosition* pPosition = pFrameFormat->GetAnchor().GetContentAnchor(); - if (!pPosition || (pLayout - ? !FrameContainsNode(*pFrame, pPosition->nNode.GetIndex()) - : pPosition->nNode.GetIndex() != pNode->GetIndex())) - pObject = nullptr; - } + *aPaM.GetPoint() = pFrame->MapViewToModelPos(nStart.GetFrameIndex()); } - - if (pObject) + else { - sal_uInt16 nResult = pSdrView->GetTextEditOutlinerView()->StartSearchAndReplace(*xSearchItem); - if (!nResult) - { - // If not found, end the text edit. - pSdrView->SdrEndTextEdit(); - const Point aPoint(pSdrView->GetAllMarkedRect().TopLeft()); - pSdrView->UnmarkAll(); - pWrtShell->CallSetCursor(&aPoint, true); - pWrtShell->Edit(); - bEndedTextEdit = true; - } - else - { - bFound = true; - break; - } + aPaM.GetPoint()->Assign(rTextNode, nStart.GetModelIndex()); } - } - - if (comphelper::LibreOfficeKit::isActive()) - { - // Writer and editeng selections are not supported in parallel. - SvxSearchItem* pSearchItem = SwView::GetSearchItem(); - // If we just finished search in shape text, don't attempt to do that again. - if (!bEndedTextEdit && !(pSearchItem && pSearchItem->GetCommand() == SvxSearchCmd::FIND_ALL)) + aPaM.SetMark(); + if (pLayout) { - // If there are any shapes anchored to this node, search there. - SwPaM aPaM(pNode->GetDoc().GetNodes().GetEndOfContent()); - 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(); - 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, *xSearchItem) && pSdrView) + aPaM.GetMark()->Assign( + (pFrame->GetMergedPara() ? *pFrame->GetMergedPara()->pLastNode : rTextNode) + .GetIndex() + + 1); + } + else + { + aPaM.GetMark()->Assign(rTextNode.GetIndex() + 1); + } + if (pNode->GetDoc().getIDocumentDrawModelAccess().Search(aPaM, *xSearchItem) + && pSdrView) + { + if (SdrObject* pObject = pSdrView->GetTextEditObject()) { - if (SdrObject* pObject = pSdrView->GetTextEditObject()) + if (SwFrameFormat* pFrameFormat = FindFrameFormat(pObject)) { - if (SwFrameFormat* pFrameFormat = FindFrameFormat(pObject)) + const SwNode* pAnchorNode = pFrameFormat->GetAnchor().GetAnchorNode(); + if (pAnchorNode) { - const SwPosition* pPosition = pFrameFormat->GetAnchor().GetContentAnchor(); - if (pPosition) - { - // Set search position to the shape's anchor point. - *rSearchPam.GetPoint() = *pPosition; - rSearchPam.GetPoint()->nContent.Assign(pPosition->nNode.GetNode().GetContentNode(), 0); - rSearchPam.SetMark(); - bFound = true; - break; - } + // Set search position to the shape's anchor point. + rSearchPam.GetPoint()->Assign(*pAnchorNode); + rSearchPam.SetMark(); + bFound = true; + break; } } } } } + } - // do we need to finish a note? - if (pPostItMgr && pPostItMgr->HasActiveSidebarWin()) + // do we need to finish a note? + if (pPostItMgr && pPostItMgr->HasActiveSidebarWin()) + { + if (bSearchInNotes) { - if (bSearchInNotes) + if (!postits.empty()) { - if (!postits.empty()) + if (bSrchForward) { - if (bSrchForward) - { - postits.erase(postits.begin()); - } - else - { - postits.pop_back(); // hope that's the right one? - } + postits.erase(postits.begin()); } - //search inside, finish and put focus back into the doc - if (pPostItMgr->FinishSearchReplace(rSearchOpt,bSrchForward)) + else { - bFound = true ; - break; + postits.pop_back(); // hope that's the right one? } } - else + //search inside, finish and put focus back into the doc + if (pPostItMgr->FinishSearchReplace(rSearchOpt, bSrchForward)) { - pPostItMgr->SetActiveSidebarWin(nullptr); + bFound = true; + break; } } - - if (!postits.empty()) + else { - // now we have to split - AmbiguousIndex nStartInside; - AmbiguousIndex nEndInside; - sal_Int32 aLoop = bSrchForward ? 0 : postits.size(); + pPostItMgr->SetActiveSidebarWin(nullptr); + } + } - while ((0 <= aLoop) && (o3tl::make_unsigned(aLoop) <= postits.size())) + if (!postits.empty()) + { + // now we have to split + AmbiguousIndex nStartInside; + AmbiguousIndex nEndInside; + sal_Int32 aLoop = bSrchForward ? 0 : postits.size(); + + while ((0 <= aLoop) && (o3tl::make_unsigned(aLoop) <= postits.size())) + { + if (bSrchForward) { - if (bSrchForward) + if (aLoop == 0) { - 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; + nStartInside = nStart; + } + else if (pLayout) + { + nStartInside.SetFrameIndex(postits[aLoop - 1].second.GetFrameIndex() + + TextFrameIndex(1)); } else { - nStartInside = static_cast<size_t>(aLoop) == postits.size() - ? nStart - : 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; + 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 = static_cast<size_t>(aLoop) == postits.size() + ? nStart + : postits[aLoop].second; + if (aLoop == 0) + { + nEndInside = nEnd; + } + else if (pLayout) + { + nEndInside.SetFrameIndex(postits[aLoop - 1].second.GetFrameIndex() + + TextFrameIndex(1)); } - // search inside the text between a note - bFound = DoSearch( rSearchPam, - rSearchOpt, rSText, fnMove, bSrchForward, - bRegSearch, bChkEmptyPara, bChkParaEnd, - 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 - ? (static_cast<size_t>(aLoop) != postits.size()) - : (aLoop != 0)) + 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->GetTextNode(), pFrame, pLayout, *oPam); + if (bFound) + break; + else + { + // we should now be right in front of a note, search inside + if (bSrchForward ? (static_cast<size_t>(aLoop) != postits.size()) + : (aLoop != 0)) + { + 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)) { - 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)) - { - bFound = true ; - break; - } + bFound = true; + break; } } - aLoop = bSrchForward ? aLoop+1 : aLoop-1; } + aLoop = bSrchForward ? aLoop + 1 : aLoop - 1; } - else - { - // if there is no SwPostItField inside or searching inside notes - // is disabled, we search the whole length just like before - bFound = DoSearch( rSearchPam, - rSearchOpt, rSText, fnMove, bSrchForward, - bRegSearch, bChkEmptyPara, bChkParaEnd, - nStart, nEnd, nTextLen, - pNode->GetTextNode(), pFrame, pLayout, - pPam.get() ); - } - if (bFound) - break; } + else + { + // if there is no SwPostItField inside or searching inside notes + // is disabled, we search the whole length just like before + bFound = DoSearch(rSearchPam, rSearchOpt, rSText, fnMove, bSrchForward, bRegSearch, + bChkEmptyPara, bChkParaEnd, nStart, nEnd, nTextLen, + pNode->GetTextNode(), pFrame, pLayout, *oPam); + } + if (bFound) + break; } return bFound; } @@ -736,10 +724,28 @@ bool DoSearch(SwPaM & rSearchPam, bool bChkEmptyPara, bool bChkParaEnd, AmbiguousIndex & nStart, AmbiguousIndex & nEnd, AmbiguousIndex const nTextLen, SwTextNode const*const pNode, SwTextFrame const*const pFrame, - SwRootFrame const*const pLayout, SwPaM* pPam) + SwRootFrame const*const pLayout, SwPaM& rPam) { + if (bRegSearch && rSearchOpt.searchString.endsWith("$")) + { + bool bAlwaysSearchingForEndOfPara = true; + sal_Int32 nIndex = 0; + while ((nIndex = rSearchOpt.searchString.indexOf("|", nIndex)) != -1) + { + if (!nIndex || rSearchOpt.searchString[nIndex - 1] != '$') + { + bAlwaysSearchingForEndOfPara = false; + break; + } + ++nIndex; + } + // when searching for something at the end of the paragraph, the para end must be in range + const AmbiguousIndex& rParaEnd = bSrchForward ? nEnd : nStart; + if (bAlwaysSearchingForEndOfPara && nTextLen.GetAnyIndex() != rParaEnd.GetAnyIndex()) + return false; + } + bool bFound = false; - SwNodeIndex& rNdIdx = pPam->GetPoint()->nNode; OUString sCleanStr; std::vector<AmbiguousIndex> aFltArr; LanguageType eLastLang = LANGUAGE_SYSTEM; @@ -754,6 +760,7 @@ bool DoSearch(SwPaM & rSearchPam, if ( -1 != rSearchOpt.searchString.indexOf("\\xAD") || -1 != rSearchOpt.searchString.indexOf("\\x{00AD}") || -1 != rSearchOpt.searchString.indexOf("\\u00AD") + || -1 != rSearchOpt.searchString.indexOf("\\u00ad") || -1 != rSearchOpt.searchString.indexOf("\\U000000AD") || -1 != rSearchOpt.searchString.indexOf("\\N{SOFT HYPHEN}")) { @@ -811,7 +818,7 @@ bool DoSearch(SwPaM & rSearchPam, { const lang::Locale aLocale( g_pBreakIt->GetLocale( eCurrLang ) ); - rSText.SetLocale( utl::TextSearch::UpgradeToSearchOptions2( rSearchOpt), aLocale ); + rSText.SetLocale(rSearchOpt, aLocale); eLastLang = eCurrLang; } } @@ -826,7 +833,7 @@ bool DoSearch(SwPaM & rSearchPam, nStart = nProxyStart; nEnd = nProxyEnd; // set section correctly - *rSearchPam.GetPoint() = *pPam->GetPoint(); + *rSearchPam.GetPoint() = *rPam.GetPoint(); rSearchPam.SetMark(); // adjust start and end @@ -859,8 +866,8 @@ bool DoSearch(SwPaM & rSearchPam, } else { - rSearchPam.GetMark()->nContent = nStart.GetModelIndex(); - rSearchPam.GetPoint()->nContent = nEnd.GetModelIndex(); + rSearchPam.GetMark()->SetContent( nStart.GetModelIndex() ); + rSearchPam.GetPoint()->SetContent( nEnd.GetModelIndex() ); } // if backward search, switch point and mark @@ -880,39 +887,43 @@ bool DoSearch(SwPaM & rSearchPam, if ( bFound ) return true; - else if ((bChkEmptyPara && !nStart.GetAnyIndex() && !nTextLen.GetAnyIndex()) - || bChkParaEnd) + + if (!bChkEmptyPara && !bChkParaEnd) + return false; + + if (bChkEmptyPara && bSrchForward && nTextLen.GetAnyIndex()) + return false; // the length is not zero - there is content here + + // move to the end (or start) of the paragraph + *rSearchPam.GetPoint() = *rPam.GetPoint(); + if (pLayout) { - *rSearchPam.GetPoint() = *pPam->GetPoint(); - 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. */ - if( (bSrchForward || pSttNd != &rNdIdx.GetNode()) && - rSearchPam.Move(fnMoveForward, GoInContent) && - (!bSrchForward || pSttNd != &rSearchPam.GetPoint()->nNode.GetNode()) && - 1 == std::abs(static_cast<int>(rSearchPam.GetPoint()->nNode.GetIndex() - - rSearchPam.GetMark()->nNode.GetIndex()))) - { - // if backward search, switch point and mark - if( !bSrchForward ) - rSearchPam.Exchange(); - return true; - } + *rSearchPam.GetPoint() = pFrame->MapViewToModelPos( + bSrchForward ? nTextLen.GetFrameIndex() : TextFrameIndex(0)); } - return bFound; + else + { + rSearchPam.GetPoint()->SetContent(bSrchForward ? nTextLen.GetModelIndex() : 0); + } + rSearchPam.SetMark(); + + if (!rSearchPam.Move(fnMove, GoInContent)) + return false; // at start or end of the document + + // selection must not be outside of the search area + if (!rPam.ContainsPosition(*rSearchPam.GetPoint())) + return false; + + if (SwNodeOffset(1) == abs(rSearchPam.GetPoint()->GetNodeIndex() - + rSearchPam.GetMark()->GetNodeIndex())) + { + if (bChkEmptyPara && !bSrchForward && rSearchPam.GetPoint()->GetContentIndex()) + return false; // the length is not zero - there is content here + + return true; + } + + return false; } namespace { @@ -932,7 +943,7 @@ struct SwFindParaText : public SwFindParas : m_rSearchOpt( rOpt ) , m_rCursor( rCursor ) , m_pLayout(pLayout) - , m_aSText( utl::TextSearch::UpgradeToSearchOptions2(rOpt) ) + , m_aSText(rOpt) , m_bReplace( bRepl ) , m_bSearchInNotes( bSearchInNotes ) {} @@ -961,8 +972,7 @@ int SwFindParaText::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove, { // use replace method in SwDoc const bool bRegExp(SearchAlgorithms2::REGEXP == m_rSearchOpt.AlgorithmType2); - SwIndex& rSttCntIdx = rCursor.Start()->nContent; - const sal_Int32 nSttCnt = rSttCntIdx.GetIndex(); + const sal_Int32 nSttCnt = rCursor.Start()->GetContentIndex(); // add to shell-cursor-ring so that the regions will be moved eventually SwPaM* pPrev(nullptr); if( bRegExp ) @@ -999,7 +1009,7 @@ int SwFindParaText::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove, assert(bRet); // if join failed, next node must be SwTextNode } else - rCursor.Start()->nContent = nSttCnt; + rCursor.Start()->SetContent(nSttCnt); return FIND_NO_RING; } return bFnd ? FIND_FOUND : FIND_NOT_FOUND; @@ -1010,7 +1020,7 @@ bool SwFindParaText::IsReplaceMode() const return m_bReplace; } -sal_uLong SwCursor::Find_Text( const i18nutil::SearchOptions2& rSearchOpt, bool bSearchInNotes, +sal_Int32 SwCursor::Find_Text( const i18nutil::SearchOptions2& rSearchOpt, bool bSearchInNotes, SwDocPositions nStart, SwDocPositions nEnd, bool& bCancel, FindRanges eFndRngs, bool bReplace, SwRootFrame const*const pLayout) @@ -1030,7 +1040,7 @@ sal_uLong SwCursor::Find_Text( const i18nutil::SearchOptions2& rSearchOpt, bool if( bSearchSel ) eFndRngs = static_cast<FindRanges>(eFndRngs | FindRanges::InSel); SwFindParaText aSwFindParaText(rSearchOpt, bSearchInNotes, bReplace, *this, pLayout); - sal_uLong nRet = FindAll( aSwFindParaText, nStart, nEnd, eFndRngs, bCancel ); + sal_Int32 nRet = FindAll( aSwFindParaText, nStart, nEnd, eFndRngs, bCancel ); rDoc.SetOle2Link( aLnk ); if( nRet && bReplace ) rDoc.getIDocumentState().SetModified(); @@ -1068,7 +1078,7 @@ bool ReplaceImpl( else { assert(!ranges.empty()); - assert(ranges.front()->GetPoint()->nNode == ranges.front()->GetMark()->nNode); + assert(ranges.front()->GetPoint()->GetNode() == ranges.front()->GetMark()->GetNode()); bReplaced = rIDCO.ReplaceRange(*ranges.front(), rReplacement, bRegExp); for (auto it = ranges.begin() + 1; it != ranges.end(); ++it) { @@ -1121,8 +1131,8 @@ std::optional<OUString> ReplaceBackReferences(const i18nutil::SearchOptions2& rS if( pPam && pPam->HasMark() && SearchAlgorithms2::REGEXP == rSearchOpt.AlgorithmType2 ) { - SwContentNode const*const pTextNode = pPam->GetContentNode(); - SwContentNode const*const pMarkTextNode = pPam->GetContentNode(false); + SwContentNode const*const pTextNode = pPam->GetPointContentNode(); + SwContentNode const*const pMarkTextNode = pPam->GetMarkContentNode(); if (!pTextNode || !pTextNode->IsTextNode() || !pMarkTextNode || !pMarkTextNode->IsTextNode()) { @@ -1133,28 +1143,23 @@ std::optional<OUString> ReplaceBackReferences(const i18nutil::SearchOptions2& rS : nullptr); const bool bParaEnd = rSearchOpt.searchString == "$" || rSearchOpt.searchString == "^$" || rSearchOpt.searchString == "$^"; if (bParaEnd || (pLayout - ? sw::FrameContainsNode(*pFrame, pPam->GetMark()->nNode.GetIndex()) + ? sw::FrameContainsNode(*pFrame, pPam->GetMark()->GetNodeIndex()) : pTextNode == pMarkTextNode)) { - utl::TextSearch aSText( utl::TextSearch::UpgradeToSearchOptions2( rSearchOpt) ); + utl::TextSearch aSText(rSearchOpt); SearchResult aResult; OUString aReplaceStr( rSearchOpt.replaceString ); if (bParaEnd) { - OUString const aStr("\\n"); + static constexpr OUString aStr(u"\\n"_ustr); aResult.subRegExpressions = 1; - aResult.startOffset.realloc(1); - aResult.endOffset.realloc(1); - aResult.startOffset[0] = 0; - aResult.endOffset[0] = aStr.getLength(); - aSText.ReplaceBackReferences( aReplaceStr, aStr, aResult ); + aResult.startOffset = { 0 }; + aResult.endOffset = { aStr.getLength() }; + utl::TextSearch::ReplaceBackReferences( aReplaceStr, aStr, aResult ); xRet = aReplaceStr; } else { - OUString const aStr(pLayout - ? pFrame->GetText() - : pTextNode->GetTextNode()->GetText()); AmbiguousIndex nStart; AmbiguousIndex nEnd; if (pLayout) @@ -1164,12 +1169,15 @@ std::optional<OUString> ReplaceBackReferences(const i18nutil::SearchOptions2& rS } else { - nStart.SetModelIndex(pPam->Start()->nContent.GetIndex()); - nEnd.SetModelIndex(pPam->End()->nContent.GetIndex()); + nStart.SetModelIndex(pPam->Start()->GetContentIndex()); + nEnd.SetModelIndex(pPam->End()->GetContentIndex()); } + std::vector<AmbiguousIndex> aFltArr; + OUString const aStr = lcl_CleanStr(*pTextNode->GetTextNode(), pFrame, pLayout, + nStart, nEnd, aFltArr, false, false); if (aSText.SearchForward(aStr, &nStart.GetAnyIndex(), &nEnd.GetAnyIndex(), &aResult)) { - aSText.ReplaceBackReferences( aReplaceStr, aStr, aResult ); + utl::TextSearch::ReplaceBackReferences( aReplaceStr, aStr, aResult ); xRet = aReplaceStr; } } |