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