LibreOffice Module sw (master)  1
findtxt.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <memory>
21 
22 #include <com/sun/star/util/SearchFlags.hpp>
23 #include <com/sun/star/util/SearchResult.hpp>
24 #include <comphelper/lok.hxx>
25 #include <vcl/svapp.hxx>
26 #include <svx/svdview.hxx>
27 #include <svl/srchitem.hxx>
28 #include <sfx2/sfxsids.hrc>
29 #include <editeng/outliner.hxx>
30 
31 #include <wrtsh.hxx>
32 #include <txatritr.hxx>
33 #include <fldbas.hxx>
34 #include <fmtfld.hxx>
35 #include <txtatr.hxx>
36 #include <txtfld.hxx>
37 #include <txtfrm.hxx>
38 #include <rootfrm.hxx>
39 #include <swcrsr.hxx>
40 #include <redline.hxx>
41 #include <doc.hxx>
42 #include <IDocumentUndoRedo.hxx>
43 #include <IDocumentState.hxx>
46 #include <dcontact.hxx>
47 #include <pamtyp.hxx>
48 #include <ndtxt.hxx>
49 #include <swundo.hxx>
50 #include <UndoInsert.hxx>
51 #include <breakit.hxx>
52 #include <docsh.hxx>
53 #include <PostItMgr.hxx>
54 #include <viewsh.hxx>
55 #include <view.hxx>
56 
57 using namespace ::com::sun::star;
58 using namespace util;
59 
63 {
64 private:
65  sal_Int32 m_value;
66 
67 #ifndef NDEBUG
68  enum class tags : char { Any, Frame, Model };
70 #endif
71 
72 public:
73  AmbiguousIndex() : m_value(-1)
74 #ifndef NDEBUG
75  , m_tag(tags::Any)
76 #endif
77  {}
78  explicit AmbiguousIndex(sal_Int32 const value
79 #ifndef NDEBUG
80  , tags const tag
81 #endif
82  ) : m_value(value)
83 #ifndef NDEBUG
84  , m_tag(tag)
85 #endif
86  {}
87 
88  sal_Int32 & GetAnyIndex() { return m_value; }
89  sal_Int32 const& GetAnyIndex() const { return m_value; }
91  {
92  assert(m_tag != tags::Model);
93  return TextFrameIndex(m_value);
94  }
95  sal_Int32 GetModelIndex() const
96  {
97  assert(m_tag != tags::Frame);
98  return m_value;
99  }
100  void SetFrameIndex(TextFrameIndex const value)
101  {
102 #ifndef NDEBUG
103  m_tag = tags::Frame;
104 #endif
105  m_value = sal_Int32(value);
106  }
107  void SetModelIndex(sal_Int32 const value)
108  {
109 #ifndef NDEBUG
110  m_tag = tags::Model;
111 #endif
112  m_value = value;
113  }
114 
115  bool operator ==(AmbiguousIndex const& rOther) const
116  {
117  assert(m_tag == tags::Any || rOther.m_tag == tags::Any || m_tag == rOther.m_tag);
118  return m_value == rOther.m_value;
119  }
120  bool operator <=(AmbiguousIndex const& rOther) const
121  {
122  assert(m_tag == tags::Any || rOther.m_tag == tags::Any || m_tag == rOther.m_tag);
123  return m_value <= rOther.m_value;
124  }
125  bool operator < (AmbiguousIndex const& rOther) const
126  {
127  assert(m_tag == tags::Any || rOther.m_tag == tags::Any || m_tag == rOther.m_tag);
128  return m_value < rOther.m_value;
129  }
130  AmbiguousIndex operator - (AmbiguousIndex const& rOther) const
131  {
132  assert(m_tag == tags::Any || rOther.m_tag == tags::Any || m_tag == rOther.m_tag);
133  return AmbiguousIndex(m_value - rOther.m_value
134 #ifndef NDEBUG
135  , std::max(m_tag, rOther.m_tag)
136 #endif
137  );
138  }
139 };
140 
142 {
144  SwTextNode const*const m_pNode;
145  size_t m_HintIndex;
146 
147 public:
148  MaybeMergedIter(SwTextFrame const*const pFrame, SwTextNode const*const pNode)
149  : m_pNode(pNode)
150  , m_HintIndex(0)
151  {
152  if (pFrame)
153  {
154 #if BOOST_VERSION < 105600
155  m_oMergedIter.reset(*pFrame);
156 #else
157  m_oMergedIter.emplace(*pFrame);
158 #endif
159  }
160  }
161 
162  SwTextAttr const* NextAttr(SwTextNode const*& rpNode)
163  {
164  if (m_oMergedIter)
165  {
166  return m_oMergedIter->NextAttr(&rpNode);
167  }
168  if (SwpHints const*const pHints = m_pNode->GetpSwpHints())
169  {
170  if (m_HintIndex < pHints->Count())
171  {
172  rpNode = m_pNode;
173  return pHints->Get(m_HintIndex++);
174  }
175  }
176  return nullptr;
177  }
178 };
179 
180 static OUString
182  SwTextFrame const*const pFrame,
183  SwRootFrame const*const pLayout,
184  AmbiguousIndex const nStart, AmbiguousIndex & rEnd,
185  std::vector<AmbiguousIndex> &rArr,
186  bool const bRemoveSoftHyphen, bool const bRemoveCommentAnchors)
187 {
188  OUStringBuffer buf(pLayout ? pFrame->GetText() : rNd.GetText());
189  rArr.clear();
190 
191  MaybeMergedIter iter(pLayout ? pFrame : nullptr, pLayout ? nullptr : &rNd);
192 
193  AmbiguousIndex nSoftHyphen = nStart;
194  AmbiguousIndex nHintStart;
195  bool bNewHint = true;
196  bool bNewSoftHyphen = true;
197  const AmbiguousIndex nEnd = rEnd;
198  std::vector<AmbiguousIndex> aReplaced;
199  SwTextNode const* pNextHintNode(nullptr);
200  SwTextAttr const* pNextHint(iter.NextAttr(pNextHintNode));
201 
202  do
203  {
204  if ( bNewHint )
205  {
206  if (pLayout)
207  {
208  nHintStart.SetFrameIndex(pNextHint
209  ? pFrame->MapModelToView(pNextHintNode, pNextHint->GetStart())
210  : TextFrameIndex(-1));
211  }
212  else
213  {
214  nHintStart.SetModelIndex(pNextHint ? pNextHint->GetStart() : -1);
215  }
216  }
217 
218  if ( bNewSoftHyphen )
219  {
220  if (pLayout)
221  {
222  nSoftHyphen.SetFrameIndex(TextFrameIndex(bRemoveSoftHyphen
223  ? pFrame->GetText().indexOf(CHAR_SOFTHYPHEN, nSoftHyphen.GetAnyIndex())
224  : -1));
225  }
226  else
227  {
228  nSoftHyphen.SetModelIndex(bRemoveSoftHyphen
229  ? rNd.GetText().indexOf(CHAR_SOFTHYPHEN, nSoftHyphen.GetAnyIndex())
230  : -1);
231  }
232  }
233 
234  bNewHint = false;
235  bNewSoftHyphen = false;
236  AmbiguousIndex nStt;
237 
238  // Check if next stop is a hint.
239  if (0 <= nHintStart.GetAnyIndex()
240  && (-1 == nSoftHyphen.GetAnyIndex() || nHintStart < nSoftHyphen)
241  && nHintStart < nEnd )
242  {
243  nStt = nHintStart;
244  bNewHint = true;
245  }
246  // Check if next stop is a soft hyphen.
247  else if ( -1 != nSoftHyphen.GetAnyIndex()
248  && (-1 == nHintStart.GetAnyIndex() || nSoftHyphen < nHintStart)
249  && nSoftHyphen < nEnd)
250  {
251  nStt = nSoftHyphen;
252  bNewSoftHyphen = true;
253  }
254  // If nSoftHyphen == nHintStart, the current hint *must* be a hint with an end.
255  else if (-1 != nSoftHyphen.GetAnyIndex() && nSoftHyphen == nHintStart)
256  {
257  nStt = nSoftHyphen;
258  bNewHint = true;
259  bNewSoftHyphen = true;
260  }
261  else
262  break;
263 
264  AmbiguousIndex nCurrent(nStt);
265  nCurrent.GetAnyIndex() -= rArr.size();
266 
267  if ( bNewHint )
268  {
269  if (pNextHint->HasDummyChar() && (nStart <= nStt))
270  {
271  switch (pNextHint->Which())
272  {
273  case RES_TXTATR_FLYCNT:
274  case RES_TXTATR_FTN:
275  case RES_TXTATR_FIELD:
276  case RES_TXTATR_REFMARK:
277  case RES_TXTATR_TOXMARK:
278  case RES_TXTATR_META:
280  {
281  // (1998) they are desired as separators and
282  // belong not any longer to a word.
283  // they should also be ignored at a
284  // beginning/end of a sentence if blank. Those are
285  // simply removed if first. If at the end, we keep the
286  // replacement and remove afterwards all at a string's
287  // end (might be normal 0x7f).
288  const bool bEmpty = pNextHint->Which() != RES_TXTATR_FIELD
289  || (static_txtattr_cast<SwTextField const*>(pNextHint)->GetFormatField().GetField()->ExpandField(true, pLayout).isEmpty());
290  if ( bEmpty && nStart == nCurrent )
291  {
292  rArr.push_back( nCurrent );
293  --rEnd.GetAnyIndex();
294  buf.remove(nCurrent.GetAnyIndex(), 1);
295  }
296  else
297  {
298  if ( bEmpty )
299  aReplaced.push_back( nCurrent );
300  buf[nCurrent.GetAnyIndex()] = '\x7f';
301  }
302  }
303  break;
305  {
306  if( bRemoveCommentAnchors )
307  {
308  rArr.push_back( nCurrent );
309  --rEnd.GetAnyIndex();
310  buf.remove( nCurrent.GetAnyIndex(), 1 );
311  }
312  }
313  break;
314  default:
315  OSL_FAIL( "unknown case in lcl_CleanStr" );
316  break;
317  }
318  }
319  pNextHint = iter.NextAttr(pNextHintNode);
320  }
321 
322  if ( bNewSoftHyphen )
323  {
324  rArr.push_back( nCurrent );
325  --rEnd.GetAnyIndex();
326  buf.remove(nCurrent.GetAnyIndex(), 1);
327  ++nSoftHyphen.GetAnyIndex();
328  }
329  }
330  while ( true );
331 
332  for (auto i = aReplaced.size(); i; )
333  {
334  const AmbiguousIndex nTmp = aReplaced[ --i ];
335  if (nTmp.GetAnyIndex() == buf.getLength() - 1)
336  {
337  buf.truncate(nTmp.GetAnyIndex());
338  rArr.push_back( nTmp );
339  --rEnd.GetAnyIndex();
340  }
341  }
342 
343  return buf.makeStringAndClear();
344 }
345 
346 static bool DoSearch(SwPaM & rSearchPam,
347  const i18nutil::SearchOptions2& rSearchOpt, utl::TextSearch& rSText,
348  SwMoveFnCollection const & fnMove,
349  bool bSrchForward, bool bRegSearch, bool bChkEmptyPara, bool bChkParaEnd,
350  AmbiguousIndex & nStart, AmbiguousIndex & nEnd, AmbiguousIndex nTextLen,
351  SwTextNode const* pNode, SwTextFrame const* pTextFrame,
352  SwRootFrame const* pLayout, SwPaM* pPam);
353 
354 namespace sw {
355 
356 bool FindTextImpl(SwPaM & rSearchPam,
357  const i18nutil::SearchOptions2& rSearchOpt, bool bSearchInNotes,
358  utl::TextSearch& rSText,
359  SwMoveFnCollection const & fnMove, const SwPaM & rRegion,
360  bool bInReadOnly, SwRootFrame const*const pLayout)
361 {
362  if( rSearchOpt.searchString.isEmpty() )
363  return false;
364 
365  std::unique_ptr<SwPaM> pPam = sw::MakeRegion(fnMove, rRegion);
366  const bool bSrchForward = &fnMove == &fnMoveForward;
367  SwNodeIndex& rNdIdx = pPam->GetPoint()->nNode;
368  SwIndex& rContentIdx = pPam->GetPoint()->nContent;
369 
370  // If bFound is true then the string was found and is between nStart and nEnd
371  bool bFound = false;
372  // start position in text or initial position
373  bool bFirst = true;
374  SwContentNode * pNode;
375 
376  const bool bRegSearch = SearchAlgorithms2::REGEXP == rSearchOpt.AlgorithmType2;
377  const bool bChkEmptyPara = bRegSearch && 2 == rSearchOpt.searchString.getLength() &&
378  ( rSearchOpt.searchString == "^$" ||
379  rSearchOpt.searchString == "$^" );
380  const bool bChkParaEnd = bRegSearch && rSearchOpt.searchString == "$";
381 
382  SvxSearchItem aSearchItem(SID_SEARCH_ITEM); // this is a very expensive operation (calling configmgr etc.)
383  aSearchItem.SetSearchOptions(rSearchOpt);
384  aSearchItem.SetBackward(!bSrchForward);
385 
386  // LanguageType eLastLang = 0;
387  while (nullptr != (pNode = ::GetNode(*pPam, bFirst, fnMove, bInReadOnly, pLayout)))
388  {
389  if( pNode->IsTextNode() )
390  {
391  SwTextNode& rTextNode = *pNode->GetTextNode();
392  SwTextFrame const*const pFrame(pLayout
393  ? static_cast<SwTextFrame const*>(rTextNode.getLayoutFrame(pLayout))
394  : nullptr);
395  assert(!pLayout || pFrame);
396  AmbiguousIndex nTextLen;
397  if (pLayout)
398  {
399  nTextLen.SetFrameIndex(TextFrameIndex(pFrame->GetText().getLength()));
400  }
401  else
402  {
403  nTextLen.SetModelIndex(rTextNode.GetText().getLength());
404  }
405  AmbiguousIndex nEnd;
406  if (pLayout
407  ? FrameContainsNode(*pFrame, pPam->GetMark()->nNode.GetIndex())
408  : rNdIdx == pPam->GetMark()->nNode)
409  {
410  if (pLayout)
411  {
412  nEnd.SetFrameIndex(pFrame->MapModelToViewPos(*pPam->GetMark()));
413  }
414  else
415  {
416  nEnd.SetModelIndex(pPam->GetMark()->nContent.GetIndex());
417  }
418  }
419  else
420  {
421  if (bSrchForward)
422  {
423  nEnd = nTextLen;
424  }
425  else
426  {
427  if (pLayout)
428  {
429  nEnd.SetFrameIndex(TextFrameIndex(0));
430  }
431  else
432  {
433  nEnd.SetModelIndex(0);
434  }
435  }
436  }
437  AmbiguousIndex nStart;
438  if (pLayout)
439  {
440  nStart.SetFrameIndex(pFrame->MapModelToViewPos(*pPam->GetPoint()));
441  }
442  else
443  {
444  nStart.SetModelIndex(rContentIdx.GetIndex());
445  }
446 
447  /* #i80135# */
448  // if there are SwPostItFields inside our current node text, we
449  // split the text into separate pieces and search for text inside
450  // the pieces as well as inside the fields
451  MaybeMergedIter iter(pLayout ? pFrame : nullptr, pLayout ? nullptr : &rTextNode);
452 
453  // count PostItFields by looping over all fields
454  std::vector<std::pair<SwTextAttr const*, AmbiguousIndex>> postits;
455  if (bSearchInNotes)
456  {
457  if (!bSrchForward)
458  {
459  std::swap(nStart, nEnd);
460  }
461 
462  SwTextNode const* pTemp(nullptr);
463  while (SwTextAttr const*const pTextAttr = iter.NextAttr(pTemp))
464  {
465  if ( pTextAttr->Which()==RES_TXTATR_ANNOTATION )
466  {
467  AmbiguousIndex aPos;
468  aPos.SetModelIndex(pTextAttr->GetStart());
469  if (pLayout)
470  {
471  aPos.SetFrameIndex(pFrame->MapModelToView(pTemp, aPos.GetModelIndex()));
472  }
473  if ((nStart <= aPos) && (aPos <= nEnd))
474  {
475  postits.emplace_back(pTextAttr, aPos);
476  }
477  }
478  }
479 
480  if (!bSrchForward)
481  {
482  std::swap(nStart, nEnd);
483  }
484 
485  }
486 
487  SwDocShell *const pDocShell = pNode->GetDoc()->GetDocShell();
488  SwWrtShell *const pWrtShell = pDocShell ? pDocShell->GetWrtShell() : nullptr;
489  SwPostItMgr *const pPostItMgr = pWrtShell ? pWrtShell->GetPostItMgr() : nullptr;
490 
491  // If there is an active text edit, then search there.
492  bool bEndedTextEdit = false;
493  SdrView* pSdrView = pWrtShell ? pWrtShell->GetDrawView() : nullptr;
494  if (pSdrView)
495  {
496  // If the edited object is not anchored to this node, then ignore it.
497  SdrObject* pObject = pSdrView->GetTextEditObject();
498  if (pObject)
499  {
500  if (SwFrameFormat* pFrameFormat = FindFrameFormat(pObject))
501  {
502  const SwPosition* pPosition = pFrameFormat->GetAnchor().GetContentAnchor();
503  if (!pPosition || (pLayout
504  ? !FrameContainsNode(*pFrame, pPosition->nNode.GetIndex())
505  : pPosition->nNode.GetIndex() != pNode->GetIndex()))
506  pObject = nullptr;
507  }
508  }
509 
510  if (pObject)
511  {
512  sal_uInt16 nResult = pSdrView->GetTextEditOutlinerView()->StartSearchAndReplace(aSearchItem);
513  if (!nResult)
514  {
515  // If not found, end the text edit.
516  pSdrView->SdrEndTextEdit();
517  const Point aPoint(pSdrView->GetAllMarkedRect().TopLeft());
518  pSdrView->UnmarkAll();
519  pWrtShell->CallSetCursor(&aPoint, true);
520  pWrtShell->Edit();
521  bEndedTextEdit = true;
522  }
523  else
524  {
525  bFound = true;
526  break;
527  }
528  }
529  }
530 
532  {
533  // Writer and editeng selections are not supported in parallel.
534  SvxSearchItem* pSearchItem = SwView::GetSearchItem();
535  // If we just finished search in shape text, don't attempt to do that again.
536  if (!bEndedTextEdit && !(pSearchItem && pSearchItem->GetCommand() == SvxSearchCmd::FIND_ALL))
537  {
538  // If there are any shapes anchored to this node, search there.
539  SwPaM aPaM(pNode->GetDoc()->GetNodes().GetEndOfContent());
540  if (pLayout)
541  {
542  *aPaM.GetPoint() = pFrame->MapViewToModelPos(nStart.GetFrameIndex());
543  }
544  else
545  {
546  aPaM.GetPoint()->nNode = rTextNode;
547  aPaM.GetPoint()->nContent.Assign(
548  aPaM.GetPoint()->nNode.GetNode().GetTextNode(),
549  nStart.GetModelIndex());
550  }
551  aPaM.SetMark();
552  if (pLayout)
553  {
554  aPaM.GetMark()->nNode = (pFrame->GetMergedPara()
555  ? *pFrame->GetMergedPara()->pLastNode
556  : rTextNode)
557  .GetIndex() + 1;
558  }
559  else
560  {
561  aPaM.GetMark()->nNode = rTextNode.GetIndex() + 1;
562  }
563  aPaM.GetMark()->nContent.Assign(aPaM.GetMark()->nNode.GetNode().GetTextNode(), 0);
564  if (pNode->GetDoc()->getIDocumentDrawModelAccess().Search(aPaM, aSearchItem) && pSdrView)
565  {
566  if (SdrObject* pObject = pSdrView->GetTextEditObject())
567  {
568  if (SwFrameFormat* pFrameFormat = FindFrameFormat(pObject))
569  {
570  const SwPosition* pPosition = pFrameFormat->GetAnchor().GetContentAnchor();
571  if (pPosition)
572  {
573  // Set search position to the shape's anchor point.
574  *rSearchPam.GetPoint() = *pPosition;
575  rSearchPam.GetPoint()->nContent.Assign(pPosition->nNode.GetNode().GetContentNode(), 0);
576  rSearchPam.SetMark();
577  bFound = true;
578  break;
579  }
580  }
581  }
582  }
583  }
584  }
585 
586  // do we need to finish a note?
587  if (pPostItMgr && pPostItMgr->HasActiveSidebarWin())
588  {
589  if (bSearchInNotes)
590  {
591  if (!postits.empty())
592  {
593  if (bSrchForward)
594  {
595  postits.erase(postits.begin());
596  }
597  else
598  {
599  postits.pop_back(); // hope that's the right one?
600  }
601  }
602  //search inside, finish and put focus back into the doc
603  if (pPostItMgr->FinishSearchReplace(rSearchOpt,bSrchForward))
604  {
605  bFound = true ;
606  break;
607  }
608  }
609  else
610  {
611  pPostItMgr->SetActiveSidebarWin(nullptr);
612  }
613  }
614 
615  if (!postits.empty())
616  {
617  // now we have to split
618  AmbiguousIndex nStartInside;
619  AmbiguousIndex nEndInside;
620  sal_Int32 aLoop = bSrchForward ? 0 : postits.size();
621 
622  while ((0 <= aLoop) && (static_cast<size_t>(aLoop) <= postits.size()))
623  {
624  if (bSrchForward)
625  {
626  if (aLoop == 0)
627  {
628  nStartInside = nStart;
629  }
630  else if (pLayout)
631  {
632  nStartInside.SetFrameIndex(postits[aLoop - 1].second.GetFrameIndex() + TextFrameIndex(1));
633  }
634  else
635  {
636  nStartInside.SetModelIndex(postits[aLoop - 1].second.GetModelIndex() + 1);
637  }
638  nEndInside = static_cast<size_t>(aLoop) == postits.size()
639  ? nEnd
640  : postits[aLoop].second;
641  nTextLen = nEndInside - nStartInside;
642  }
643  else
644  {
645  nStartInside = static_cast<size_t>(aLoop) == postits.size()
646  ? nStart
647  : postits[aLoop].second;
648  if (aLoop == 0)
649  {
650  nEndInside = nEnd;
651  }
652  else if (pLayout)
653  {
654  nEndInside.SetFrameIndex(postits[aLoop - 1].second.GetFrameIndex() + TextFrameIndex(1));
655  }
656  else
657  {
658  nEndInside.SetModelIndex(postits[aLoop - 1].second.GetModelIndex() + 1);
659  }
660  nTextLen = nStartInside - nEndInside;
661  }
662  // search inside the text between a note
663  bFound = DoSearch( rSearchPam,
664  rSearchOpt, rSText, fnMove, bSrchForward,
665  bRegSearch, bChkEmptyPara, bChkParaEnd,
666  nStartInside, nEndInside, nTextLen,
667  pNode->GetTextNode(), pFrame, pLayout,
668  pPam.get() );
669  if ( bFound )
670  break;
671  else
672  {
673  // we should now be right in front of a note, search inside
674  if (bSrchForward
675  ? (static_cast<size_t>(aLoop) != postits.size())
676  : (aLoop != 0))
677  {
678  const SwTextAttr *const pTextAttr = bSrchForward
679  ? postits[aLoop].first
680  : postits[aLoop - 1].first;
681  if (pPostItMgr && pPostItMgr->SearchReplace(
682  static_txtattr_cast<SwTextField const*>(pTextAttr)->GetFormatField(),rSearchOpt,bSrchForward))
683  {
684  bFound = true ;
685  break;
686  }
687  }
688  }
689  aLoop = bSrchForward ? aLoop+1 : aLoop-1;
690  }
691  }
692  else
693  {
694  // if there is no SwPostItField inside or searching inside notes
695  // is disabled, we search the whole length just like before
696  bFound = DoSearch( rSearchPam,
697  rSearchOpt, rSText, fnMove, bSrchForward,
698  bRegSearch, bChkEmptyPara, bChkParaEnd,
699  nStart, nEnd, nTextLen,
700  pNode->GetTextNode(), pFrame, pLayout,
701  pPam.get() );
702  }
703  if (bFound)
704  break;
705  }
706  }
707  return bFound;
708 }
709 
710 } // namespace sw
711 
712 bool DoSearch(SwPaM & rSearchPam,
713  const i18nutil::SearchOptions2& rSearchOpt, utl::TextSearch& rSText,
714  SwMoveFnCollection const & fnMove, bool bSrchForward, bool bRegSearch,
715  bool bChkEmptyPara, bool bChkParaEnd,
716  AmbiguousIndex & nStart, AmbiguousIndex & nEnd, AmbiguousIndex const nTextLen,
717  SwTextNode const*const pNode, SwTextFrame const*const pFrame,
718  SwRootFrame const*const pLayout, SwPaM* pPam)
719 {
720  bool bFound = false;
721  SwNodeIndex& rNdIdx = pPam->GetPoint()->nNode;
722  OUString sCleanStr;
723  std::vector<AmbiguousIndex> aFltArr;
724  LanguageType eLastLang = LANGUAGE_SYSTEM;
725  // if the search string contains a soft hyphen,
726  // we don't strip them from the text:
727  bool bRemoveSoftHyphens = true;
728  // if the search string contains a comment, we don't strip them from the text
729  const bool bRemoveCommentAnchors = rSearchOpt.searchString.indexOf( CH_TXTATR_INWORD ) == -1;
730 
731  if ( bRegSearch )
732  {
733  if ( -1 != rSearchOpt.searchString.indexOf("\\xAD")
734  || -1 != rSearchOpt.searchString.indexOf("\\x{00AD}")
735  || -1 != rSearchOpt.searchString.indexOf("\\u00AD")
736  || -1 != rSearchOpt.searchString.indexOf("\\U000000AD")
737  || -1 != rSearchOpt.searchString.indexOf("\\N{SOFT HYPHEN}"))
738  {
739  bRemoveSoftHyphens = false;
740  }
741  }
742  else
743  {
744  if ( 1 == rSearchOpt.searchString.getLength() &&
745  CHAR_SOFTHYPHEN == rSearchOpt.searchString.toChar() )
746  bRemoveSoftHyphens = false;
747  }
748 
749  if( bSrchForward )
750  sCleanStr = lcl_CleanStr(*pNode, pFrame, pLayout, nStart, nEnd,
751  aFltArr, bRemoveSoftHyphens, bRemoveCommentAnchors);
752  else
753  sCleanStr = lcl_CleanStr(*pNode, pFrame, pLayout, nEnd, nStart,
754  aFltArr, bRemoveSoftHyphens, bRemoveCommentAnchors);
755 
756  std::unique_ptr<SwScriptIterator> pScriptIter;
757  sal_uInt16 nSearchScript = 0;
758  sal_uInt16 nCurrScript = 0;
759 
760  if (SearchAlgorithms2::APPROXIMATE == rSearchOpt.AlgorithmType2)
761  {
762  pScriptIter.reset(new SwScriptIterator(sCleanStr, nStart.GetAnyIndex(), bSrchForward));
763  nSearchScript = g_pBreakIt->GetRealScriptOfText( rSearchOpt.searchString, 0 );
764  }
765 
766  const AmbiguousIndex nStringEnd = nEnd;
767  bool bZeroMatch = false; // zero-length match, i.e. only $ anchor as regex
768  while ( ((bSrchForward && nStart < nStringEnd) ||
769  (!bSrchForward && nStringEnd < nStart)) && !bZeroMatch )
770  {
771  // SearchAlgorithms_APPROXIMATE works on a per word base so we have to
772  // provide the text searcher with the correct locale, because it uses
773  // the break-iterator
774  if ( pScriptIter )
775  {
776  nEnd.GetAnyIndex() = pScriptIter->GetScriptChgPos();
777  nCurrScript = pScriptIter->GetCurrScript();
778  if ( nSearchScript == nCurrScript )
779  {
780  const LanguageType eCurrLang = pLayout
781  ? pFrame->GetLangOfChar(bSrchForward
782  ? nStart.GetFrameIndex()
783  : nEnd.GetFrameIndex(),
784  0, true)
785  : pNode->GetLang(bSrchForward
786  ? nStart.GetModelIndex()
787  : nEnd.GetModelIndex());
788 
789  if ( eCurrLang != eLastLang )
790  {
791  const lang::Locale aLocale(
792  g_pBreakIt->GetLocale( eCurrLang ) );
793  rSText.SetLocale( utl::TextSearch::UpgradeToSearchOptions2( rSearchOpt), aLocale );
794  eLastLang = eCurrLang;
795  }
796  }
797  pScriptIter->Next();
798  }
799  AmbiguousIndex nProxyStart = nStart;
800  AmbiguousIndex nProxyEnd = nEnd;
801  if( nSearchScript == nCurrScript &&
802  (rSText.*fnMove.fnSearch)( sCleanStr, &nProxyStart.GetAnyIndex(), &nProxyEnd.GetAnyIndex(), nullptr) &&
803  !(bZeroMatch = (nProxyStart == nProxyEnd)))
804  {
805  nStart = nProxyStart;
806  nEnd = nProxyEnd;
807  // set section correctly
808  *rSearchPam.GetPoint() = *pPam->GetPoint();
809  rSearchPam.SetMark();
810 
811  // adjust start and end
812  if( !aFltArr.empty() )
813  {
814  // if backward search, switch positions temporarily
815  if (!bSrchForward) { std::swap(nStart, nEnd); }
816 
817  AmbiguousIndex nNew = nStart;
818  for (size_t n = 0; n < aFltArr.size() && aFltArr[ n ] <= nStart; ++n )
819  {
820  ++nNew.GetAnyIndex();
821  }
822 
823  nStart = nNew;
824  nNew = nEnd;
825  for( size_t n = 0; n < aFltArr.size() && aFltArr[ n ] < nEnd; ++n )
826  {
827  ++nNew.GetAnyIndex();
828  }
829 
830  nEnd = nNew;
831  // if backward search, switch positions temporarily
832  if( !bSrchForward ) { std::swap(nStart, nEnd); }
833  }
834  if (pLayout)
835  {
836  *rSearchPam.GetMark() = pFrame->MapViewToModelPos(nStart.GetFrameIndex());
837  *rSearchPam.GetPoint() = pFrame->MapViewToModelPos(nEnd.GetFrameIndex());
838  }
839  else
840  {
841  rSearchPam.GetMark()->nContent = nStart.GetModelIndex();
842  rSearchPam.GetPoint()->nContent = nEnd.GetModelIndex();
843  }
844 
845  // if backward search, switch point and mark
846  if( !bSrchForward )
847  rSearchPam.Exchange();
848  bFound = true;
849  break;
850  }
851  else
852  {
853  nEnd = nProxyEnd;
854  }
855  nStart = nEnd;
856  }
857 
858  pScriptIter.reset();
859 
860  if ( bFound )
861  return true;
862  else if ((bChkEmptyPara && !nStart.GetAnyIndex() && !nTextLen.GetAnyIndex())
863  || bChkParaEnd)
864  {
865  *rSearchPam.GetPoint() = *pPam->GetPoint();
866  if (pLayout)
867  {
868  *rSearchPam.GetPoint() = pFrame->MapViewToModelPos(
869  bChkParaEnd ? nTextLen.GetFrameIndex() : TextFrameIndex(0));
870  }
871  else
872  {
873  rSearchPam.GetPoint()->nContent = bChkParaEnd ? nTextLen.GetModelIndex() : 0;
874  }
875  rSearchPam.SetMark();
876  const SwNode *const pSttNd = bSrchForward
877  ? &rSearchPam.GetPoint()->nNode.GetNode() // end of the frame
878  : &rNdIdx.GetNode(); // keep the bug as-is for now...
879  /* FIXME: this condition does not work for !bSrchForward backward
880  * search, it probably never did. (pSttNd != &rNdIdx.GetNode())
881  * is never true in this case. */
882  if( (bSrchForward || pSttNd != &rNdIdx.GetNode()) &&
883  rSearchPam.Move(fnMoveForward, GoInContent) &&
884  (!bSrchForward || pSttNd != &rSearchPam.GetPoint()->nNode.GetNode()) &&
885  1 == std::abs(static_cast<int>(rSearchPam.GetPoint()->nNode.GetIndex() -
886  rSearchPam.GetMark()->nNode.GetIndex())))
887  {
888  // if backward search, switch point and mark
889  if( !bSrchForward )
890  rSearchPam.Exchange();
891  return true;
892  }
893  }
894  return bFound;
895 }
896 
899 {
904  bool const m_bReplace;
905  bool const m_bSearchInNotes;
906 
907  SwFindParaText(const i18nutil::SearchOptions2& rOpt, bool bSearchInNotes,
908  bool bRepl, SwCursor& rCursor, SwRootFrame const*const pLayout)
909  : m_rSearchOpt( rOpt )
910  , m_rCursor( rCursor )
911  , m_pLayout(pLayout)
912  , m_aSText( utl::TextSearch::UpgradeToSearchOptions2(rOpt) )
913  , m_bReplace( bRepl )
914  , m_bSearchInNotes( bSearchInNotes )
915  {}
916  virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, bool bInReadOnly) override;
917  virtual bool IsReplaceMode() const override;
918  virtual ~SwFindParaText();
919 };
920 
922 {
923 }
924 
925 int SwFindParaText::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove,
926  const SwPaM & rRegion, bool bInReadOnly)
927 {
928  if( bInReadOnly && m_bReplace )
929  bInReadOnly = false;
930 
931  const bool bFnd = sw::FindTextImpl(rCursor, m_rSearchOpt, m_bSearchInNotes,
932  m_aSText, fnMove, rRegion, bInReadOnly, m_pLayout);
933 
934  if( bFnd && m_bReplace ) // replace string
935  {
936  // use replace method in SwDoc
937  const bool bRegExp(SearchAlgorithms2::REGEXP == m_rSearchOpt.AlgorithmType2);
938  SwIndex& rSttCntIdx = rCursor.Start()->nContent;
939  const sal_Int32 nSttCnt = rSttCntIdx.GetIndex();
940  // add to shell-cursor-ring so that the regions will be moved eventually
941  SwPaM* pPrev(nullptr);
942  if( bRegExp )
943  {
944  pPrev = const_cast<SwPaM&>(rRegion).GetPrev();
945  const_cast<SwPaM&>(rRegion).GetRingContainer().merge( m_rCursor.GetRingContainer() );
946  }
947 
949  if (bRegExp)
950  xRepl = sw::ReplaceBackReferences(m_rSearchOpt, &rCursor, m_pLayout);
951  bool const bReplaced = sw::ReplaceImpl(rCursor,
952  xRepl ? *xRepl : m_rSearchOpt.replaceString,
953  bRegExp, *m_rCursor.GetDoc(), m_pLayout);
954 
955  m_rCursor.SaveTableBoxContent( rCursor.GetPoint() );
956 
957  if( bRegExp )
958  {
959  // and remove region again
960  SwPaM* p;
961  SwPaM* pNext(const_cast<SwPaM*>(&rRegion));
962  do {
963  p = pNext;
964  pNext = p->GetNext();
965  p->MoveTo(const_cast<SwPaM*>(&rRegion));
966  } while( p != pPrev );
967  }
968  if (bRegExp && !bReplaced)
969  { // fdo#80715 avoid infinite loop if join failed
970  bool bRet = ((&fnMoveForward == &fnMove) ? &GoNextPara : &GoPrevPara)
971  (rCursor, fnMove);
972  (void) bRet;
973  assert(bRet); // if join failed, next node must be SwTextNode
974  }
975  else
976  rCursor.Start()->nContent = nSttCnt;
977  return FIND_NO_RING;
978  }
979  return bFnd ? FIND_FOUND : FIND_NOT_FOUND;
980 }
981 
983 {
984  return m_bReplace;
985 }
986 
987 sal_uLong SwCursor::Find_Text( const i18nutil::SearchOptions2& rSearchOpt, bool bSearchInNotes,
988  SwDocPositions nStart, SwDocPositions nEnd,
989  bool& bCancel, FindRanges eFndRngs, bool bReplace,
990  SwRootFrame const*const pLayout)
991 {
992  // switch off OLE-notifications
993  SwDoc* pDoc = GetDoc();
994  Link<bool,void> aLnk( pDoc->GetOle2Link() );
995  pDoc->SetOle2Link( Link<bool,void>() );
996 
997  bool const bStartUndo = pDoc->GetIDocumentUndoRedo().DoesUndo() && bReplace;
998  if (bStartUndo)
999  {
1000  pDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::REPLACE, nullptr );
1001  }
1002 
1003  bool bSearchSel = 0 != (rSearchOpt.searchFlag & SearchFlags::REG_NOT_BEGINOFLINE);
1004  if( bSearchSel )
1005  eFndRngs = static_cast<FindRanges>(eFndRngs | FindRanges::InSel);
1006  SwFindParaText aSwFindParaText(rSearchOpt, bSearchInNotes, bReplace, *this, pLayout);
1007  sal_uLong nRet = FindAll( aSwFindParaText, nStart, nEnd, eFndRngs, bCancel );
1008  pDoc->SetOle2Link( aLnk );
1009  if( nRet && bReplace )
1010  pDoc->getIDocumentState().SetModified();
1011 
1012  if (bStartUndo)
1013  {
1015  nRet, rSearchOpt.searchString, rSearchOpt.replaceString));
1016  pDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::REPLACE, & rewriter );
1017  }
1018  return nRet;
1019 }
1020 
1021 namespace sw {
1022 
1024  SwPaM & rCursor,
1025  OUString const& rReplacement,
1026  bool const bRegExp,
1027  SwDoc & rDoc,
1028  SwRootFrame const*const pLayout)
1029 {
1030  bool bReplaced(true);
1032 #if 0
1033  // FIXME there's some problem with multiple redlines here on Undo
1034  std::vector<std::shared_ptr<SwUnoCursor>> ranges;
1036  || !pLayout
1037  || !pLayout->IsHideRedlines()
1038  || sw::GetRanges(ranges, rDoc, rCursor))
1039  {
1040  bReplaced = rIDCO.ReplaceRange(rCursor, rReplacement, bRegExp);
1041  }
1042  else
1043  {
1044  assert(!ranges.empty());
1045  assert(ranges.front()->GetPoint()->nNode == ranges.front()->GetMark()->nNode);
1046  bReplaced = rIDCO.ReplaceRange(*ranges.front(), rReplacement, bRegExp);
1047  for (auto it = ranges.begin() + 1; it != ranges.end(); ++it)
1048  {
1049  bReplaced &= rIDCO.DeleteAndJoin(**it);
1050  }
1051  }
1052 #else
1054  if (pLayout && pLayout->IsHideRedlines()
1055  && !rIDRA.IsRedlineOn() // otherwise: ReplaceRange will handle it
1056  && (rIDRA.GetRedlineFlags() & RedlineFlags::ShowDelete)) // otherwise: ReplaceRange will DeleteRedline()
1057  {
1059  rIDRA.GetRedline(*rCursor.Start(), &tmp);
1060  while (tmp < rIDRA.GetRedlineTable().size())
1061  {
1062  SwRangeRedline const*const pRedline(rIDRA.GetRedlineTable()[tmp]);
1063  if (*rCursor.End() <= *pRedline->Start())
1064  {
1065  break;
1066  }
1067  if (*pRedline->End() <= *rCursor.Start())
1068  {
1069  ++tmp;
1070  continue;
1071  }
1072  if (pRedline->GetType() == nsRedlineType_t::REDLINE_DELETE)
1073  {
1074  assert(*pRedline->Start() != *pRedline->End());
1075  // search in hidden layout can't overlap redlines
1076  assert(*rCursor.Start() <= *pRedline->Start() && *pRedline->End() <= *rCursor.End());
1077  SwPaM pam(*pRedline, nullptr);
1078  bReplaced &= rIDCO.DeleteAndJoin(pam);
1079  }
1080  else
1081  {
1082  ++tmp;
1083  }
1084  }
1085  }
1086  bReplaced &= rIDCO.ReplaceRange(rCursor, rReplacement, bRegExp);
1087 #endif
1088  return bReplaced;
1089 }
1090 
1092  SwPaM *const pPam, SwRootFrame const*const pLayout)
1093 {
1095  if( pPam && pPam->HasMark() &&
1096  SearchAlgorithms2::REGEXP == rSearchOpt.AlgorithmType2 )
1097  {
1098  const SwContentNode* pTextNode = pPam->GetContentNode();
1099  if (!pTextNode || !pTextNode->IsTextNode())
1100  {
1101  return xRet;
1102  }
1103  SwTextFrame const*const pFrame(pLayout
1104  ? static_cast<SwTextFrame const*>(pTextNode->getLayoutFrame(pLayout))
1105  : nullptr);
1106  const bool bParaEnd = rSearchOpt.searchString == "$" || rSearchOpt.searchString == "^$" || rSearchOpt.searchString == "$^";
1107  if (bParaEnd || (pLayout
1108  ? sw::FrameContainsNode(*pFrame, pPam->GetMark()->nNode.GetIndex())
1109  : pTextNode == pPam->GetContentNode(false)))
1110  {
1112  OUString rStr = pLayout
1113  ? pFrame->GetText()
1114  : pTextNode->GetTextNode()->GetText();
1115  AmbiguousIndex nStart;
1116  AmbiguousIndex nEnd;
1117  if (pLayout)
1118  {
1119  nStart.SetFrameIndex(pFrame->MapModelToViewPos(*pPam->Start()));
1120  nEnd.SetFrameIndex(pFrame->MapModelToViewPos(*pPam->End()));
1121  }
1122  else
1123  {
1124  nStart.SetModelIndex(pPam->Start()->nContent.GetIndex());
1125  nEnd.SetModelIndex(pPam->End()->nContent.GetIndex());
1126  }
1127  SearchResult aResult;
1128  if (bParaEnd ||
1129  aSText.SearchForward(rStr, &nStart.GetAnyIndex(), &nEnd.GetAnyIndex(), &aResult))
1130  {
1131  if ( bParaEnd )
1132  {
1133  rStr = "\\n";
1134  aResult.subRegExpressions = 1;
1135  aResult.startOffset.realloc(1);
1136  aResult.endOffset.realloc(1);
1137  aResult.startOffset[0] = 0;
1138  aResult.endOffset[0] = rStr.getLength();
1139  }
1140  OUString aReplaceStr( rSearchOpt.replaceString );
1141  aSText.ReplaceBackReferences( aReplaceStr, rStr, aResult );
1142  xRet = aReplaceStr;
1143  }
1144  }
1145  }
1146  return xRet;
1147 }
1148 
1149 } // namespace sw
1150 
1151 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwCursor & m_rCursor
Definition: findtxt.cxx:901
Point TopLeft() const
size_t m_HintIndex
Definition: findtxt.cxx:145
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:149
sal_uLong GetIndex() const
Definition: node.hxx:282
bool operator<(const SwTextGlyphsKey &l, const SwTextGlyphsKey &r)
Definition: fntcache.cxx:132
bool GoInContent(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:903
SwRewriter MakeUndoReplaceRewriter(sal_uLong const occurrences, OUString const &sOld, OUString const &sNew)
Definition: unins.cxx:534
bool GetRanges(std::vector< std::shared_ptr< SwUnoCursor >> &rRanges, SwDoc &rDoc, SwPaM const &rDelPam)
Definition: autofmt.cxx:1127
Marks a position in the document model.
Definition: pam.hxx:35
IJScriptValueObject VARIANT value
sal_Int32 const & GetAnyIndex() const
for arithmetic
Definition: findtxt.cxx:89
virtual SdrEndTextEditKind SdrEndTextEdit(bool bDontDeleteReally=false)
SwContentNode * GetNode(SwPaM &rPam, bool &rbFirst, SwMoveFnCollection const &fnMove, bool const bInReadOnly, SwRootFrame const *const i_pLayout)
This function returns the next node in direction of search.
Definition: pam.cxx:756
SdrView * GetDrawView()
Definition: vnew.cxx:376
LanguageType GetLangOfChar(TextFrameIndex nIndex, sal_uInt16 nScript, bool bNoChar=false) const
Definition: txtfrm.cxx:1328
void SetModelIndex(sal_Int32 const value)
Definition: findtxt.cxx:107
const OUString & GetText() const
Definition: ndtxt.hxx:211
std::unique_ptr< SwPaM > MakeRegion(SwMoveFnCollection const &fnMove, const SwPaM &rOrigRg)
make a new region
Definition: pam.cxx:503
#define RES_TXTATR_METAFIELD
Definition: hintids.hxx:139
SwDocShell * GetDocShell()
Definition: doc.hxx:1340
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:219
Frame
void SetFrameIndex(TextFrameIndex const value)
Definition: findtxt.cxx:100
SwNodeIndex nNode
Definition: pam.hxx:37
static bool DoSearch(SwPaM &rSearchPam, const i18nutil::SearchOptions2 &rSearchOpt, utl::TextSearch &rSText, SwMoveFnCollection const &fnMove, 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)
Definition: findtxt.cxx:712
sal_Int32 StartSearchAndReplace(const SvxSearchItem &rSearchItem)
SdrTextObj * GetTextEditObject() const
void SetSearchOptions(const i18nutil::SearchOptions2 &rOpt)
boost::optional< OUString > ReplaceBackReferences(const i18nutil::SearchOptions2 &rSearchOpt, SwPaM *const pPam, SwRootFrame const *const pLayout)
Helperfunction to resolve backward references in regular expressions.
Definition: findtxt.cxx:1091
virtual void SetModified()=0
Must be called manually at changes of format.
sal_uIntPtr sal_uLong
const SwPosition * GetMark() const
Definition: pam.hxx:209
MaybeMergedIter(SwTextFrame const *const pFrame, SwTextNode const *const pNode)
Definition: findtxt.cxx:148
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1150
virtual SwUndoId EndUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Closes undo block.
Definition: doc.hxx:185
void SetOle2Link(const Link< bool, void > &rLink)
Definition: doc.hxx:1316
SwFindParaText(const i18nutil::SearchOptions2 &rOpt, bool bSearchInNotes, bool bRepl, SwCursor &rCursor, SwRootFrame const *const pLayout)
Definition: findtxt.cxx:907
sal_Int32 m_value
Definition: findtxt.cxx:65
SwTextAttr const * NextAttr(SwTextNode const *&rpNode)
Definition: findtxt.cxx:162
virtual bool Search(const SwPaM &rPaM, const SvxSearchItem &rSearchItem)=0
Searches text in shapes anchored inside rPaM.
SwNode & GetNode() const
Definition: ndindex.hxx:118
void SetActiveSidebarWin(sw::annotation::SwAnnotationWin *p)
Definition: PostItMgr.cxx:2113
parameters for search and replace in text
Definition: findtxt.cxx:898
because the Find may be called on the View or the Model, we need an index afflicted by multiple perso...
Definition: findtxt.cxx:62
Dialog to specify the properties of drop-down form field.
Definition: accframe.hxx:34
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:176
virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, bool bInReadOnly) override
Definition: findtxt.cxx:925
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1278
const i18nutil::SearchOptions2 & m_rSearchOpt
Definition: findtxt.cxx:900
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:347
The root element of a Writer document layout.
Definition: rootfrm.hxx:79
void MoveTo(value_type *pDestRing)
Removes this item from its current ring container and adds it to another ring container.
Definition: ring.hxx:135
Find in selections.
sal_uInt16 GetRealScriptOfText(const OUString &rText, sal_Int32 nPos) const
Definition: breakit.cxx:84
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:187
#define CHAR_SOFTHYPHEN
Definition: swtypes.hxx:174
SwRootFrame const * m_pLayout
Definition: findtxt.cxx:902
SwDocPositions
Definition: cshtyp.hxx:103
SwContentNode * GetContentNode(bool bPoint=true) const
Definition: pam.hxx:229
Used by the UI to modify the document model.
Definition: wrtsh.hxx:86
sal_Int32 GetModelIndex() const
Definition: findtxt.cxx:95
#define RES_TXTATR_META
Definition: hintids.hxx:138
bool FindTextImpl(SwPaM &rSearchPam, const i18nutil::SearchOptions2 &rSearchOpt, bool bSearchInNotes, utl::TextSearch &rSText, SwMoveFnCollection const &fnMove, const SwPaM &rRegion, bool bInReadOnly, SwRootFrame const *const pLayout)
Search.
Definition: findtxt.cxx:356
#define CH_TXTATR_INWORD
Definition: hintids.hxx:44
boost::optional< sw::MergedAttrIter > m_oMergedIter
Definition: findtxt.cxx:143
static i18nutil::SearchOptions2 UpgradeToSearchOptions2(const i18nutil::SearchOptions &rOptions)
SwIndex nContent
Definition: pam.hxx:38
const Link< bool, void > & GetOle2Link() const
Definition: doc.hxx:1317
static bool IsRedlineOn(const RedlineFlags eM)
void Edit()
Definition: wrtsh1.cxx:143
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:34
sal_uLong GetIndex() const
Definition: ndindex.hxx:151
FindRanges
Definition: cshtyp.hxx:90
sal_uLong Find_Text(const i18nutil::SearchOptions2 &rSearchOpt, bool bSearchInNotes, SwDocPositions nStart, SwDocPositions nEnde, bool &bCancel, FindRanges, bool bReplace=false, SwRootFrame const *const pLayout=nullptr)
Definition: findtxt.cxx:987
SwFrameFormat * FindFrameFormat(SdrObject *pObj)
The Get reverse way: seeks the format to the specified object.
Definition: dcontact.cxx:125
const RedlineType_t REDLINE_DELETE
void UnmarkAll()
void ReplaceBackReferences(OUString &rReplaceStr, const OUString &rStr, const css::util::SearchResult &rResult) const
virtual bool DoesUndo() const =0
Is Undo enabled?
bool const m_bSearchInNotes
Definition: findtxt.cxx:905
SwPaM * GetNext()
Definition: pam.hxx:264
void SetBackward(bool bNewBackward)
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:164
bool SearchForward(const OUString &rStr, sal_Int32 *pStart, sal_Int32 *pEnd, css::util::SearchResult *pRes=nullptr)
bool GoPrevPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:935
sal_uInt32 tag
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
bool FrameContainsNode(SwContentFrame const &rFrame, sal_uLong nNodeIndex)
Definition: txtfrm.cxx:289
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:483
Style of a layout element.
Definition: frmfmt.hxx:57
virtual SwUndoId StartUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Opens undo block.
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1254
bool const m_bReplace
Definition: findtxt.cxx:904
SvxSearchCmd GetCommand() const
const SwPosition * GetPoint() const
Definition: pam.hxx:207
sal_uInt16 SearchReplace(const SwFormatField &pField, const i18nutil::SearchOptions2 &rSearchOptions, bool bSrchForward)
Definition: PostItMgr.cxx:2234
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:198
#define RES_TXTATR_FTN
Definition: hintids.hxx:152
#define LANGUAGE_SYSTEM
Count
void Exchange()
Definition: pam.cxx:471
int i
SwContentNode * GetContentNode()
Definition: node.hxx:615
vector_type::size_type size_type
Definition: docary.hxx:331
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
SwDoc * GetDoc()
Definition: node.hxx:702
void SetLocale(const i18nutil::SearchOptions2 &rOpt, const css::lang::Locale &rLocale)
Marks a character position inside a document model node.
Definition: index.hxx:37
static SvxSearchItem * GetSearchItem()
Definition: view.hxx:634
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:426
SwWrtShell * GetWrtShell()
Access to the SwWrtShell belonging to SwView.
Definition: docsh.hxx:223
const OutlinerView * GetTextEditOutlinerView() const
#define RES_TXTATR_TOXMARK
Definition: hintids.hxx:137
Marks a node in the document model.
Definition: ndindex.hxx:31
virtual bool ReplaceRange(SwPaM &rPam, const OUString &rNewStr, const bool bRegExReplace)=0
Replace selected range in a TextNode with string.
T static_txtattr_cast(S *s)
Definition: txatbase.hxx:231
utl::TextSearch m_aSText
Definition: findtxt.cxx:903
Text operation/manipulation interface.
bool ReplaceImpl(SwPaM &rCursor, OUString const &rReplacement, bool const bRegExp, SwDoc &rDoc, SwRootFrame const *const pLayout)
Definition: findtxt.cxx:1023
const tools::Rectangle & GetAllMarkedRect() const
show all deletes
const int FIND_NO_RING
Definition: swcrsr.hxx:36
const SwPosition * Start() const
Definition: pam.hxx:212
SW_DLLPUBLIC bool HasActiveSidebarWin() const
Definition: PostItMgr.cxx:2285
virtual const SwRangeRedline * GetRedline(const SwPosition &rPos, SwRedlineTable::size_type *pFndPos) const =0
const css::lang::Locale & GetLocale(const LanguageType aLang)
Definition: breakit.hxx:67
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:367
#define RES_TXTATR_FIELD
Definition: hintids.hxx:150
An SwTextAttr container, stores all directly formatted text portions for a text node.
Definition: ndhints.hxx:76
TextFrameIndex GetFrameIndex() const
Definition: findtxt.cxx:90
virtual ~SwFindParaText()
Definition: findtxt.cxx:921
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:59
#define RES_TXTATR_ANNOTATION
Definition: hintids.hxx:153
const int FIND_FOUND
Definition: swcrsr.hxx:35
sal_Int32 GetIndex() const
Definition: index.hxx:95
SwNodes & GetNodes()
Definition: doc.hxx:403
const SwPosition * End() const
Definition: pam.hxx:217
LanguageType GetLang(const sal_Int32 nBegin, const sal_Int32 nLen=0, sal_uInt16 nScript=0) const
Definition: thints.cxx:3361
bool GoNextPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:977
virtual bool IsReplaceMode() const override
Definition: findtxt.cxx:982
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding)...
Definition: rootfrm.hxx:416
#define RES_TXTATR_FLYCNT
Definition: hintids.hxx:151
#define RES_TXTATR_REFMARK
Definition: hintids.hxx:136
const SwPostItMgr * GetPostItMgr() const
Definition: viewsh.hxx:559
long CallSetCursor(const Point *pPt, bool bProp)
Definition: wrtsh.hxx:113
const int FIND_NOT_FOUND
Definition: swcrsr.hxx:34
sal_Int32 & GetAnyIndex()
for arithmetic
Definition: findtxt.cxx:88
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:457
AmbiguousIndex(sal_Int32 const value, tags const tag)
Definition: findtxt.cxx:78
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
bool IsTextNode() const
Definition: node.hxx:636
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1233
static OUString 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)
Definition: findtxt.cxx:181
SwTextNode const *const m_pNode
Definition: findtxt.cxx:144
sal_uInt16 FinishSearchReplace(const i18nutil::SearchOptions2 &rSearchOptions, bool bSrchForward)
Definition: PostItMgr.cxx:2222
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:842
SwNodeIndex & Assign(SwNodes const &rNds, sal_uLong)
Definition: ndindex.hxx:271
SearchText fnSearch
Definition: pamtyp.hxx:77
Base class of the Writer document model elements.
Definition: node.hxx:79
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo