LibreOffice Module sw (master)  1
redlnitr.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 <sal/config.h>
21 
22 #include <string_view>
23 
24 #include <hintids.hxx>
25 #include <o3tl/safeint.hxx>
26 #include <svl/whiter.hxx>
27 #include <com/sun/star/i18n/ScriptType.hpp>
28 #include <scriptinfo.hxx>
29 #include <swmodule.hxx>
30 #include <redline.hxx>
31 #include <txatbase.hxx>
32 #include <docary.hxx>
33 #include "itratr.hxx"
34 #include <ndtxt.hxx>
35 #include <doc.hxx>
38 #include <IDocumentMarkAccess.hxx>
39 #include <IMark.hxx>
40 #include <bookmrk.hxx>
41 #include <rootfrm.hxx>
42 #include <breakit.hxx>
43 #include <vcl/commandevent.hxx>
44 #include <vcl/settings.hxx>
45 #include <txtfrm.hxx>
46 #include <ftnfrm.hxx>
47 #include <vcl/svapp.hxx>
48 #include "redlnitr.hxx"
49 #include <extinput.hxx>
50 
51 using namespace ::com::sun::star;
52 
53 namespace {
54 
55 class HideIterator
56 {
57 private:
58  IDocumentRedlineAccess const& m_rIDRA;
59  IDocumentMarkAccess const& m_rIDMA;
60  bool const m_isHideRedlines;
61  sw::FieldmarkMode const m_eFieldmarkMode;
62  SwPosition const m_Start;
64  SwRedlineTable::size_type m_RedlineIndex;
66  std::pair<sw::mark::IFieldmark const*, std::unique_ptr<SwPosition>> m_Fieldmark;
67  std::optional<SwPosition> m_oNextFieldmarkHide;
69  SwPosition const* m_pStartPos;
70  SwPosition const* m_pEndPos;
71 
72 public:
73  SwPosition const* GetStartPos() const { return m_pStartPos; }
74  SwPosition const* GetEndPos() const { return m_pEndPos; }
75 
76  HideIterator(SwTextNode & rTextNode,
77  bool const isHideRedlines, sw::FieldmarkMode const eMode)
78  : m_rIDRA(rTextNode.getIDocumentRedlineAccess())
79  , m_rIDMA(*rTextNode.getIDocumentMarkAccess())
80  , m_isHideRedlines(isHideRedlines)
81  , m_eFieldmarkMode(eMode)
82  , m_Start(rTextNode, 0)
83  , m_RedlineIndex(m_rIDRA.GetRedlinePos(rTextNode, RedlineType::Any))
84  , m_pStartPos(nullptr)
85  , m_pEndPos(&m_Start)
86  {
87  }
88 
89  // delete redlines and fieldmarks can't overlap, due to sw::CalcBreaks()
90  // and no combining of adjacent redlines
91  // -> dummy chars are delete-redlined *iff* entire fieldmark is
92  // Note: caller is responsible for checking for immediately adjacent hides
93  bool Next()
94  {
95  SwPosition const* pNextRedlineHide(nullptr);
96  assert(m_pEndPos);
97  if (m_isHideRedlines)
98  {
99  // position on current or next redline
100  for (; m_RedlineIndex < m_rIDRA.GetRedlineTable().size(); ++m_RedlineIndex)
101  {
102  SwRangeRedline const*const pRed = m_rIDRA.GetRedlineTable()[m_RedlineIndex];
103 
104  if (m_pEndPos->nNode.GetIndex() < pRed->Start()->nNode.GetIndex())
105  break;
106 
107  if (pRed->GetType() != RedlineType::Delete)
108  continue;
109 
110  SwPosition const*const pStart(pRed->Start());
111  SwPosition const*const pEnd(pRed->End());
112  if (*pStart == *pEnd)
113  { // only allowed while moving (either way?)
114 // assert(IDocumentRedlineAccess::IsHideChanges(rIDRA.GetRedlineFlags()));
115  continue;
116  }
117  if (pStart->nNode.GetNode().IsTableNode())
118  {
119  assert(pEnd->nNode == m_Start.nNode && pEnd->nContent.GetIndex() == 0);
120  continue; // known pathology, ignore it
121  }
122  if (*m_pEndPos <= *pStart)
123  {
124  pNextRedlineHide = pStart;
125  break; // the next one
126  }
127  }
128  }
129 
130  // position on current or next fieldmark
131  m_oNextFieldmarkHide.reset();
132  if (m_eFieldmarkMode != sw::FieldmarkMode::ShowBoth)
133  {
134  sal_Unicode const magic(m_eFieldmarkMode == sw::FieldmarkMode::ShowResult
137  SwTextNode* pTextNode = m_pEndPos->nNode.GetNode().GetTextNode();
138  sal_Int32 const nPos = pTextNode ? pTextNode->GetText().indexOf(
139  magic, m_pEndPos->nContent.GetIndex()) : -1;
140  if (nPos != -1)
141  {
142  m_oNextFieldmarkHide.emplace(*pTextNode, nPos);
143  sw::mark::IFieldmark const*const pFieldmark(
144  m_eFieldmarkMode == sw::FieldmarkMode::ShowResult
145  ? m_rIDMA.getFieldmarkAt(*m_oNextFieldmarkHide)
146  : m_rIDMA.getFieldmarkFor(*m_oNextFieldmarkHide));
147  assert(pFieldmark);
148  m_Fieldmark.first = pFieldmark;
149  // for cursor travelling, there should be 2 visible chars;
150  // whichever char is hidden, the cursor travelling needs to
151  // be adapted in any case to skip in some situation or other;
152  // always hide the CH_TXT_ATR_FIELDSEP for now
153  if (m_eFieldmarkMode == sw::FieldmarkMode::ShowResult)
154  {
155  m_Fieldmark.second.reset(
156  new SwPosition(sw::mark::FindFieldSep(*m_Fieldmark.first)));
157  ++m_Fieldmark.second->nContent;
158  ++m_oNextFieldmarkHide->nContent; // skip start
159  }
160  else
161  {
162  m_Fieldmark.second.reset(
163  new SwPosition(pFieldmark->GetMarkEnd()));
164  --m_Fieldmark.second->nContent;
165  }
166  }
167  }
168 
169  // == can happen only if redline starts inside field command, and in
170  // that case redline will end before field separator
171  assert(!pNextRedlineHide || !m_oNextFieldmarkHide
172  || *pNextRedlineHide != *m_oNextFieldmarkHide
173  || *m_rIDRA.GetRedlineTable()[m_RedlineIndex]->End() < *m_Fieldmark.second);
174  if (pNextRedlineHide
175  && (!m_oNextFieldmarkHide || *pNextRedlineHide < *m_oNextFieldmarkHide))
176  {
177  SwRangeRedline const*const pRed(m_rIDRA.GetRedlineTable()[m_RedlineIndex]);
178  m_pStartPos = pRed->Start();
179  m_pEndPos = pRed->End();
180  ++m_RedlineIndex;
181  return true;
182  }
183  else if (m_oNextFieldmarkHide)
184  {
185  assert(!pNextRedlineHide || *m_oNextFieldmarkHide <= *pNextRedlineHide);
186  m_pStartPos = &*m_oNextFieldmarkHide;
187  m_pEndPos = m_Fieldmark.second.get();
188  return true;
189  }
190  else // nothing
191  {
192  assert(!pNextRedlineHide && !m_oNextFieldmarkHide);
193  m_pStartPos = nullptr;
194  m_pEndPos = nullptr;
195  return false;
196  }
197  }
198 };
199 
200 }
201 
202 namespace sw {
203 
204 std::unique_ptr<sw::MergedPara>
206  FrameMode const eMode)
207 {
208  if (!rFrame.getRootFrame()->HasMergedParas())
209  {
210  return nullptr;
211  }
212  bool bHaveRedlines(false);
213  std::vector<SwTextNode *> nodes{ &rTextNode };
214  std::vector<SwTableNode *> tables;
215  std::vector<SwSectionNode *> sections;
216  std::vector<sw::Extent> extents;
217  OUStringBuffer mergedText;
218  SwTextNode * pParaPropsNode(nullptr);
219  SwTextNode * pNode(&rTextNode);
220  sal_Int32 nLastEnd(0);
221  for (auto iter = HideIterator(rTextNode,
222  rFrame.getRootFrame()->IsHideRedlines(),
223  rFrame.getRootFrame()->GetFieldmarkMode()); iter.Next(); )
224  {
225  SwPosition const*const pStart(iter.GetStartPos());
226  SwPosition const*const pEnd(iter.GetEndPos());
227  bHaveRedlines = true;
228  assert(pNode != &rTextNode || &pStart->nNode.GetNode() == &rTextNode); // detect calls with wrong start node
229  if (pStart->nContent != nLastEnd) // not 0 so we eliminate adjacent deletes
230  {
231  extents.emplace_back(pNode, nLastEnd, pStart->nContent.GetIndex());
232  mergedText.append(pNode->GetText().subView(nLastEnd, pStart->nContent.GetIndex() - nLastEnd));
233  }
234  if (&pEnd->nNode.GetNode() != pNode)
235  {
236  if (pNode == &rTextNode)
237  {
239  } // else: was already set before
240  int nLevel(0);
241  for (sal_uLong j = pNode->GetIndex() + 1; j < pEnd->nNode.GetIndex(); ++j)
242  {
243  SwNode *const pTmp(pNode->GetNodes()[j]);
244  if (nLevel == 0)
245  {
246  if (pTmp->IsTextNode())
247  {
248  nodes.push_back(pTmp->GetTextNode());
249  }
250  else if (pTmp->IsTableNode())
251  {
252  tables.push_back(pTmp->GetTableNode());
253  }
254  else if (pTmp->IsSectionNode())
255  {
256  sections.push_back(pTmp->GetSectionNode());
257  }
258  }
259  if (pTmp->IsStartNode())
260  {
261  ++nLevel;
262  }
263  else if (pTmp->IsEndNode())
264  {
265  --nLevel;
266  }
268  }
269  // note: in DelLastPara() case, the end node is not actually merged
270  // and is likely a SwTableNode!
271  if (!pEnd->nNode.GetNode().IsTextNode())
272  {
273  assert(pEnd->nNode != pStart->nNode);
274  // must set pNode too because it will mark the last node
275  pNode = nodes.back();
276  assert(pNode == pNode->GetNodes()[pEnd->nNode.GetIndex() - 1]);
277  if (pNode != &rTextNode)
278  { // something might depend on last merged one being NonFirst?
280  }
281  nLastEnd = pNode->Len();
282  }
283  else
284  {
285  pNode = pEnd->nNode.GetNode().GetTextNode();
286  nodes.push_back(pNode);
288  nLastEnd = pEnd->nContent.GetIndex();
289  }
290  }
291  else
292  {
293  nLastEnd = pEnd->nContent.GetIndex();
294  }
295  }
296  if (pNode == &rTextNode)
297  {
298  if (rTextNode.GetRedlineMergeFlag() != SwNode::Merge::None)
299  {
301  }
302  }
303  // Reset flag of the following text node since we know it's not merged;
304  // also any table/sections in between.
305  // * the following SwTextNode is in same nodes section as pNode (nLevel=0)
306  // * the start nodes that don't have a SwTextNode before them
307  // on their level, and their corresponding end nodes
308  // * the first SwTextNode inside each start node of the previous point
309  // Other (non-first) SwTextNodes in nested sections shouldn't be reset!
310  int nLevel(0);
311  for (sal_uLong j = pNode->GetIndex() + 1; j < pNode->GetNodes().Count(); ++j)
312  {
313  SwNode *const pTmp(pNode->GetNodes()[j]);
314  if (!pTmp->IsCreateFrameWhenHidingRedlines())
315  { // clear stale flag caused by editing with redlines shown
317  }
318  if (pTmp->IsStartNode())
319  {
320  ++nLevel;
321  }
322  else if (pTmp->IsEndNode())
323  {
324  if (nLevel == 0)
325  {
326  break; // there is no following text node; avoid leaving section
327  }
328  --nLevel;
329  }
330  else if (pTmp->IsTextNode())
331  {
332  if (nLevel == 0)
333  {
334  break; // done
335  }
336  else
337  { // skip everything other than 1st text node in section!
338  j = pTmp->EndOfSectionIndex() - 1; // will be incremented again
339  }
340  }
341  }
342  if (!bHaveRedlines)
343  {
344  if (rTextNode.IsInList() && !rTextNode.GetNum(rFrame.getRootFrame()))
345  {
346  rTextNode.AddToListRLHidden(); // try to add it...
347  }
348  return nullptr;
349  }
350  if (nLastEnd != pNode->Len())
351  {
352  extents.emplace_back(pNode, nLastEnd, pNode->Len());
353  mergedText.append(pNode->GetText().subView(nLastEnd, pNode->Len() - nLastEnd));
354  }
355  if (extents.empty()) // there was no text anywhere
356  {
357  assert(mergedText.isEmpty());
358  pParaPropsNode = pNode; // if every node is empty, the last one wins
359  }
360  else
361  {
362  assert(!mergedText.isEmpty());
363  pParaPropsNode = extents.begin()->pNode; // para props from first node that isn't empty
364  }
365 // pParaPropsNode = &rTextNode; // well, actually...
366  // keep lists up to date with visible nodes
367  if (pParaPropsNode->IsInList() && !pParaPropsNode->GetNum(rFrame.getRootFrame()))
368  {
369  pParaPropsNode->AddToListRLHidden(); // try to add it...
370  }
371  for (auto const pTextNode : nodes)
372  {
373  if (pTextNode != pParaPropsNode)
374  {
375  pTextNode->RemoveFromListRLHidden();
376  }
377  }
378  if (eMode == FrameMode::Existing)
379  {
380  // remove existing footnote frames for first node;
381  // for non-first nodes with own frames, DelFrames will remove all
382  // (could possibly call lcl_ChangeFootnoteRef, not sure if worth it)
383  // note: must be done *before* changing listeners!
384  // for non-first nodes that are already merged with this frame,
385  // need to remove here too, otherwise footnotes can be removed only
386  // by lucky accident, e.g. TruncLines().
387  auto itExtent(extents.begin());
388  for (auto const pTextNode : nodes)
389  {
390  sal_Int32 nLast(0);
391  std::vector<std::pair<sal_Int32, sal_Int32>> hidden;
392  for ( ; itExtent != extents.end(); ++itExtent)
393  {
394  if (itExtent->pNode != pTextNode)
395  {
396  break;
397  }
398  if (itExtent->nStart != 0)
399  {
400  assert(itExtent->nStart != nLast);
401  hidden.emplace_back(nLast, itExtent->nStart);
402  }
403  nLast = itExtent->nEnd;
404  }
405  if (nLast != pTextNode->Len())
406  {
407  hidden.emplace_back(nLast, pTextNode->Len());
408  }
409  sw::RemoveFootnotesForNode(*rFrame.getRootFrame(), *pTextNode, &hidden);
410  }
411  // unfortunately DelFrames() must be done before StartListening too,
412  // otherwise footnotes cannot be deleted by SwTextFootnote::DelFrames!
413  auto const end(--nodes.rend());
414  for (auto iter = nodes.rbegin(); iter != end; ++iter)
415  {
416  (**iter).DelFrames(rFrame.getRootFrame());
417  }
418  // also delete tables & sections here; not necessary, but convenient
419  for (auto const pTableNode : tables)
420  {
421  pTableNode->DelFrames(rFrame.getRootFrame());
422  }
423  for (auto const pSectionNode : sections)
424  {
425  pSectionNode->DelFrames(rFrame.getRootFrame());
426  }
427  }
428  auto pRet(std::make_unique<sw::MergedPara>(rFrame, std::move(extents),
429  mergedText.makeStringAndClear(), pParaPropsNode, &rTextNode,
430  nodes.back()));
431  for (SwTextNode * pTmp : nodes)
432  {
433  pRet->listener.StartListening(pTmp);
434  }
435  rFrame.EndListeningAll();
436  return pRet;
437 }
438 
439 } // namespace sw
440 
442  SwTextNode const& rPropsNode,
443  SwTextNode const& rTextNode,
444  OUString const& rText,
445  bool const*const pbVertLayout,
446  bool const*const pbVertLayoutLRBT)
447 {
448  // Build a font matching the default paragraph style:
449  SwFontAccess aFontAccess( &rPropsNode.GetAnyFormatColl(), m_pViewShell );
450  // It is possible that Init is called more than once, e.g., in a
451  // SwTextFrame::FormatOnceMore situation or (since sw_redlinehide)
452  // from SwAttrIter::Seek(); in the latter case SwTextSizeInfo::m_pFnt
453  // is an alias of m_pFont so it must not be deleted!
454  if (m_pFont)
455  {
456  *m_pFont = aFontAccess.Get()->GetFont();
457  }
458  else
459  {
460  m_pFont = new SwFont( aFontAccess.Get()->GetFont() );
461  }
462 
463  // set font to vertical if frame layout is vertical
464  // if it's a re-init, the vert flag never changes
465  bool bVertLayoutLRBT = false;
466  if (pbVertLayoutLRBT)
467  bVertLayoutLRBT = *pbVertLayoutLRBT;
468  if (pbVertLayout ? *pbVertLayout : m_aAttrHandler.IsVertLayout())
469  {
470  m_pFont->SetVertical(m_pFont->GetOrientation(), true, bVertLayoutLRBT);
471  }
472 
473  // Initialize the default attribute of the attribute handler
474  // based on the attribute array cached together with the font.
475  // If any further attributes for the paragraph are given in pAttrSet
476  // consider them during construction of the default array, and apply
477  // them to the font
478  m_aAttrHandler.Init(aFontAccess.Get()->GetDefault(), rTextNode.GetpSwAttrSet(),
480  pbVertLayout ? *pbVertLayout : m_aAttrHandler.IsVertLayout(),
481  bVertLayoutLRBT );
482 
484 
486 
487  m_pFont->SetActual( m_pScriptInfo->WhichFont(TextFrameIndex(0)) );
488 
489  TextFrameIndex nChg(0);
490  size_t nCnt = 0;
491 
492  do
493  {
494  if ( nCnt >= m_pScriptInfo->CountScriptChg() )
495  break;
496  nChg = m_pScriptInfo->GetScriptChg( nCnt );
497  SwFontScript nTmp = SW_SCRIPTS;
498  switch ( m_pScriptInfo->GetScriptType( nCnt++ ) ) {
499  case i18n::ScriptType::ASIAN :
501  break;
502  case i18n::ScriptType::COMPLEX :
504  break;
505  default:
507  }
508  if( nTmp < SW_SCRIPTS )
509  {
510  m_pFont->CheckFontCacheId( m_pViewShell, nTmp );
511  m_pFont->GetFontCacheId( m_aFontCacheIds[ nTmp ], m_aFontIdx[ nTmp ], nTmp );
512  }
513  }
514  while (nChg < TextFrameIndex(rText.getLength()));
515 }
516 
518  SwScriptInfo & rScriptInfo, SwTextFrame const*const pFrame)
519 {
520  // during HTML-Import it can happen, that no layout exists
521  SwRootFrame* pRootFrame = rTextNode.getIDocumentLayoutAccess().GetCurrentLayout();
522  m_pViewShell = pRootFrame ? pRootFrame->GetCurrShell() : nullptr;
523 
524  m_pScriptInfo = &rScriptInfo;
525 
526  // set font to vertical if frame layout is vertical
527  bool bVertLayout = false;
528  bool bVertLayoutLRBT = false;
529  bool bRTL = false;
530  if ( pFrame )
531  {
532  if ( pFrame->IsVertical() )
533  {
534  bVertLayout = true;
535  }
536  if (pFrame->IsVertLRBT())
537  {
538  bVertLayoutLRBT = true;
539  }
540  bRTL = pFrame->IsRightToLeft();
541  m_pMergedPara = pFrame->GetMergedPara();
542  }
543 
544  // determine script changes if not already done for current paragraph
547  m_pScriptInfo->InitScriptInfo(rTextNode, m_pMergedPara, bRTL);
548 
551  rTextNode,
552  m_pMergedPara ? m_pMergedPara->mergedText : rTextNode.GetText(),
553  & bVertLayout,
554  & bVertLayoutLRBT);
555 
557  m_nPropFont = 0;
558  SwDoc& rDoc = rTextNode.GetDoc();
559  const IDocumentRedlineAccess& rIDRA = rTextNode.getIDocumentRedlineAccess();
560 
561  // sw_redlinehide: this is a Ring - pExtInp is the first PaM that's inside
562  // the node. It's not clear whether there can be more than 1 PaM in the
563  // Ring, and this code doesn't handle that case; neither did the old code.
564  const SwExtTextInput* pExtInp = rDoc.GetExtTextInput( rTextNode );
565  if (!pExtInp && m_pMergedPara)
566  {
567  SwTextNode const* pNode(&rTextNode);
568  for (auto const& rExtent : m_pMergedPara->extents)
569  {
570  if (rExtent.pNode != pNode)
571  {
572  pNode = rExtent.pNode;
573  pExtInp = rDoc.GetExtTextInput(*pNode);
574  if (pExtInp)
575  break;
576  }
577  }
578  }
579  const bool bShow = IDocumentRedlineAccess::IsShowChanges(rIDRA.GetRedlineFlags())
580  && pRootFrame && !pRootFrame->IsHideRedlines();
581  if (!(pExtInp || m_pMergedPara || bShow))
582  return;
583 
584  SwRedlineTable::size_type nRedlPos = rIDRA.GetRedlinePos( rTextNode, RedlineType::Any );
585  if (SwRedlineTable::npos == nRedlPos && m_pMergedPara)
586  {
587  SwTextNode const* pNode(&rTextNode);
588  for (auto const& rExtent : m_pMergedPara->extents)
589  { // note: have to search because extents based only on Delete
590  if (rExtent.pNode != pNode)
591  {
592  pNode = rExtent.pNode;
593  nRedlPos = rIDRA.GetRedlinePos(*pNode, RedlineType::Any);
594  if (SwRedlineTable::npos != nRedlPos)
595  break;
596  }
597  }
598  // TODO this is true initially but after delete ops it may be false... need to delete m_pMerged somewhere?
599  // assert(SwRedlineTable::npos != nRedlPos);
600  // false now with fieldmarks
601  assert(!pRootFrame
603  || SwRedlineTable::npos != nRedlPos || m_pMergedPara->extents.size() <= 1);
604  }
605  if (!(pExtInp || m_pMergedPara || SwRedlineTable::npos != nRedlPos))
606  return;
607 
608  const std::vector<ExtTextInputAttr> *pArr = nullptr;
609  if( pExtInp )
610  {
611  pArr = &pExtInp->GetAttrs();
612  Seek( TextFrameIndex(0) );
613  }
614 
615  m_pRedline.reset(new SwRedlineItr( rTextNode, *m_pFont, m_aAttrHandler, nRedlPos,
616  (pRootFrame && pRootFrame->IsHideRedlines())
618  : bShow
621  pArr, pExtInp ? pExtInp->Start() : nullptr));
622 
623  if( m_pRedline->IsOn() )
624  ++m_nChgCnt;
625 }
626 
627 // The Redline-Iterator
628 // The following information/states exist in RedlineIterator:
629 //
630 // m_nFirst is the first index of RedlineTable, which overlaps with the paragraph.
631 //
632 // m_nAct is the currently active (if m_bOn is set) or the next possible index.
633 // m_nStart and m_nEnd give you the borders of the object within the paragraph.
634 //
635 // If m_bOn is set, the font has been manipulated according to it.
636 //
637 // If m_nAct is set to SwRedlineTable::npos (via Reset()), then currently no
638 // Redline is active, m_nStart and m_nEnd are invalid.
640  SwAttrHandler& rAH, sal_Int32 nRed,
641  Mode const mode,
642  const std::vector<ExtTextInputAttr> *pArr,
643  SwPosition const*const pExtInputStart)
644  : m_rDoc( rTextNd.GetDoc() )
645  , m_rAttrHandler( rAH )
646  , m_nNdIdx( rTextNd.GetIndex() )
647  , m_nFirst( nRed )
648  , m_nAct( SwRedlineTable::npos )
649  , m_bOn( false )
650  , m_eMode( mode )
651 {
652  if( pArr )
653  {
654  assert(pExtInputStart);
655  m_pExt.reset( new SwExtend(*pArr, pExtInputStart->nNode.GetIndex(),
656  pExtInputStart->nContent.GetIndex()) );
657  }
658  else
659  m_pExt = nullptr;
660  assert(m_pExt || m_eMode != Mode::Ignore); // only create if necessary
661  Seek(rFnt, m_nNdIdx, 0, COMPLETE_STRING);
662 }
663 
664 SwRedlineItr::~SwRedlineItr() COVERITY_NOEXCEPT_FALSE
665 {
666  Clear( nullptr );
667  m_pExt.reset();
668 }
669 
670 // The return value of SwRedlineItr::Seek tells you if the current font
671 // has been manipulated by leaving (-1) or accessing (+1) of a section
673  sal_uLong const nNode, sal_Int32 const nNew, sal_Int32 const nOld)
674 {
675  short nRet = 0;
676  if( ExtOn() )
677  return 0; // Abbreviation: if we're within an ExtendTextInputs
678  // there can't be other changes of attributes (not even by redlining)
679  if (m_eMode == Mode::Show)
680  {
681  if (m_bOn)
682  {
683  if (nNew >= m_nEnd)
684  {
685  --nRet;
686  Clear_( &rFnt ); // We go behind the current section
687  ++m_nAct; // and check the next one
688  }
689  else if (nNew < m_nStart)
690  {
691  --nRet;
692  Clear_( &rFnt ); // We go in front of the current section
693  if (m_nAct > m_nFirst)
694  m_nAct = m_nFirst; // the test has to run from the beginning
695  else
696  return nRet + EnterExtend(rFnt, nNode, nNew); // There's none prior to us
697  }
698  else
699  return nRet + EnterExtend(rFnt, nNode, nNew); // We stayed in the same section
700  }
701  if (SwRedlineTable::npos == m_nAct || nOld > nNew)
702  m_nAct = m_nFirst;
703 
706 
708  {
710 
711  if (nNew < m_nEnd)
712  {
713  if (nNew >= m_nStart) // only possible candidate
714  {
715  m_bOn = true;
717 
718  if (m_pSet)
719  m_pSet->ClearItem();
720  else
721  {
722  SwAttrPool& rPool =
723  const_cast<SwDoc&>(m_rDoc).GetAttrPool();
724  m_pSet = std::make_unique<SfxItemSet>(rPool, svl::Items<RES_CHRATR_BEGIN, RES_CHRATR_END-1>{});
725  }
726 
727  if( 1 < pRed->GetStackCount() )
728  FillHints( pRed->GetAuthor( 1 ), pRed->GetType( 1 ) );
729  FillHints( pRed->GetAuthor(), pRed->GetType() );
730 
731  SfxWhichIter aIter( *m_pSet );
732  sal_uInt16 nWhich = aIter.FirstWhich();
733  while( nWhich )
734  {
735  const SfxPoolItem* pItem;
736  if( ( nWhich < RES_CHRATR_END ) &&
737  ( SfxItemState::SET == m_pSet->GetItemState( nWhich, true, &pItem ) ) )
738  {
740  const_cast<SwDoc&>(m_rDoc),
741  *const_cast<SfxPoolItem*>(pItem) );
742  pAttr->SetPriorityAttr( true );
743  m_Hints.push_back(pAttr);
744  m_rAttrHandler.PushAndChg( *pAttr, rFnt );
745  }
746  nWhich = aIter.NextWhich();
747  }
748 
749  ++nRet;
750  }
751  break;
752  }
755  }
756  }
757  else if (m_eMode == Mode::Hide)
758  { // ... just iterate to update m_nAct for GetNextRedln();
759  // there is no need to care about formatting in this mode
760  if (m_nAct == SwRedlineTable::npos || nOld == COMPLETE_STRING)
761  { // reset, or move backward
762  m_nAct = m_nFirst;
763  }
765  { // only Start matters in this mode
766  // Seeks until it finds a RL that starts at or behind the seek pos.
767  // - then update m_nStart/m_nEnd to the intersection of it with the
768  // current node (if any).
769  // The only way to skip to a different node is if there is a Delete
770  // RL, so if there is no intersection we'll never skip again.
771  // Note: here, assume that delete can't nest inside delete!
772  SwRangeRedline const*const pRedline(
774  SwPosition const*const pStart(pRedline->Start());
775  if (pRedline->GetType() == RedlineType::Delete
776  && (nNode < pStart->nNode.GetIndex()
777  || (nNode == pStart->nNode.GetIndex()
778  && nNew <= pStart->nContent.GetIndex())))
779  {
780  pRedline->CalcStartEnd(nNode, m_nStart, m_nEnd);
781  break;
782  }
785  }
786  }
787  return nRet + EnterExtend(rFnt, nNode, nNew);
788 }
789 
790 void SwRedlineItr::FillHints( std::size_t nAuthor, RedlineType eType )
791 {
792  switch ( eType )
793  {
794  case RedlineType::Insert:
795  SW_MOD()->GetInsertAuthorAttr(nAuthor, *m_pSet);
796  break;
797  case RedlineType::Delete:
798  SW_MOD()->GetDeletedAuthorAttr(nAuthor, *m_pSet);
799  break;
800  case RedlineType::Format:
801  case RedlineType::FmtColl:
802  SW_MOD()->GetFormatAuthorAttr(nAuthor, *m_pSet);
803  break;
804  default:
805  break;
806  }
807 }
808 
809 void SwRedlineItr::ChangeTextAttr( SwFont* pFnt, SwTextAttr const &rHt, bool bChg )
810 {
811  OSL_ENSURE( IsOn(), "SwRedlineItr::ChangeTextAttr: Off?" );
812 
813  if (m_eMode != Mode::Show && !m_pExt)
814  return;
815 
816  if( bChg )
817  {
818  if (m_pExt && m_pExt->IsOn())
819  m_rAttrHandler.PushAndChg( rHt, *m_pExt->GetFont() );
820  else
821  m_rAttrHandler.PushAndChg( rHt, *pFnt );
822  }
823  else
824  {
825  OSL_ENSURE( ! m_pExt || ! m_pExt->IsOn(), "Pop of attribute during opened extension" );
826  m_rAttrHandler.PopAndChg( rHt, *pFnt );
827  }
828 }
829 
831 {
832  OSL_ENSURE( m_bOn, "SwRedlineItr::Clear: Off?" );
833  m_bOn = false;
834  for (auto const& hint : m_Hints)
835  {
836  if( pFnt )
837  m_rAttrHandler.PopAndChg( *hint, *pFnt );
838  else
839  m_rAttrHandler.Pop( *hint );
840  SwTextAttr::Destroy(hint, const_cast<SwDoc&>(m_rDoc).GetAttrPool() );
841  }
842  m_Hints.clear();
843 }
844 
849 std::pair<sal_Int32, std::pair<SwRangeRedline const*, size_t>>
850 SwRedlineItr::GetNextRedln(sal_Int32 nNext, SwTextNode const*const pNode,
852 {
853  sal_Int32 nStart(m_nStart);
854  sal_Int32 nEnd(m_nEnd);
855  nNext = NextExtend(pNode->GetIndex(), nNext);
857  return std::make_pair(nNext, std::make_pair(nullptr, 0));
858  if (SwRedlineTable::npos == rAct)
859  {
860  rAct = m_nFirst;
861  }
862  if (rAct != m_nAct)
863  {
865  {
866  SwRangeRedline const*const pRedline(
868  pRedline->CalcStartEnd(pNode->GetIndex(), nStart, nEnd);
869  if (m_eMode != Mode::Hide
870  || pRedline->GetType() == RedlineType::Delete)
871  {
872  break;
873  }
874  ++rAct; // Hide mode: search a Delete RL
875  }
876  }
878  {
879  return std::make_pair(nNext, std::make_pair(nullptr, 0)); // no Delete here
880  }
881  if (m_bOn || (m_eMode == Mode::Show && nStart == 0))
882  { // in Ignore mode, the end of redlines isn't relevant, except as returned in the second in the pair!
883  if (nEnd < nNext)
884  nNext = nEnd;
885  }
886  else if (nStart <= nNext)
887  {
888  if (m_eMode == Mode::Show)
889  {
890  nNext = nStart;
891  }
892  else
893  {
895  SwRangeRedline const* pRedline(
897  assert(pRedline->GetType() == RedlineType::Delete); //?
898  if (pRedline->GetType() == RedlineType::Delete)
899  {
900  nNext = nStart;
901  size_t nSkipped(1); // (consecutive) candidates to be skipped
902  while (rAct + nSkipped <
904  {
905  SwRangeRedline const*const pNext =
906  m_rDoc.getIDocumentRedlineAccess().GetRedlineTable()[rAct + nSkipped];
907  if (*pRedline->End() < *pNext->Start())
908  {
909  break; // done for now
910  }
911  else if (*pNext->Start() == *pRedline->End() &&
912  pNext->GetType() == RedlineType::Delete)
913  {
914  // consecutive delete - continue
915  pRedline = pNext;
916  }
917  ++nSkipped;
918  }
919  return std::make_pair(nNext, std::make_pair(pRedline, nSkipped));
920  }
921  }
922  }
923  return std::make_pair(nNext, std::make_pair(nullptr, 0));
924 }
925 
927 {
928  // If the underlining or the escapement is caused by redlining,
929  // we always apply the SpecialUnderlining, i.e. the underlining
930  // below the base line
931  for (SwTextAttr* pHint : m_Hints)
932  {
933  const sal_uInt16 nWhich = pHint->Which();
934  if( RES_CHRATR_UNDERLINE == nWhich ||
935  RES_CHRATR_ESCAPEMENT == nWhich )
936  return true;
937  }
938  return false;
939 }
940 
942  sal_uLong const nStartNode, sal_Int32 const nChkStart,
943  sal_uLong const nEndNode, sal_Int32 nChkEnd, OUString& rRedlineText,
944  bool& bRedlineEnd, RedlineType& eRedlineEnd)
945 {
946  // note: previously this would return true in the (!m_bShow && m_pExt)
947  // case, but surely that was a bug?
949  return false;
950  if( nChkEnd == nChkStart ) // empty lines look one char further
951  ++nChkEnd;
952  sal_Int32 nOldStart = m_nStart;
953  sal_Int32 nOldEnd = m_nEnd;
954  SwRedlineTable::size_type const nOldAct = m_nAct;
955  bool bRet = bRedlineEnd = false;
956  eRedlineEnd = RedlineType::None;
957 
958  SwPosition const start(*m_rDoc.GetNodes()[nStartNode]->GetContentNode(), nChkStart);
959  SwPosition const end(*m_rDoc.GetNodes()[nEndNode]->GetContentNode(), nChkEnd);
960  SwRangeRedline const* pPrevRedline = nullptr;
961  bool isBreak(false);
963  {
964  SwRangeRedline const*const pRedline(
966  // collect text of the hidden redlines at the end of the line
967  bool isExtendText(false);
968  switch (ComparePosition(*pRedline->Start(), *pRedline->End(), start, end))
969  {
971  isBreak = true;
972  break;
977  // store redlining at line end (for line break formatting)
978  eRedlineEnd = pRedline->GetType();
979  bRedlineEnd = true;
980  isBreak = true;
981  [[fallthrough]];
985  {
986  bRet = true;
987  // start to collect text of invisible redlines for ChangesInMargin layout
988  if (rRedlineText.isEmpty() && !pRedline->IsVisible())
989  {
990  rRedlineText = const_cast<SwRangeRedline*>(pRedline)->GetDescr(/*bSimplified=*/true);
991  pPrevRedline = pRedline;
992  isExtendText = true;
993  }
994  // join the text of the next invisible redlines in the same position
995  // i.e. characters deleted by pressing backspace or delete
996  else if (pPrevRedline && !pRedline->IsVisible() &&
997  *pRedline->Start() == *pPrevRedline->Start() && *pRedline->End() == *pPrevRedline->End() )
998  {
999  OUString sExtendText(const_cast<SwRangeRedline*>(pRedline)->GetDescr(/*bSimplified=*/true));
1000  if (!sExtendText.isEmpty())
1001  {
1002  if (rRedlineText.getLength() < 12)
1003  {
1004  // TODO: remove extra space from GetDescr(true),
1005  // but show deletion of paragraph or line break
1006  rRedlineText = rRedlineText +
1007  const_cast<SwRangeRedline*>(pRedline)->GetDescr(/*bSimplified=*/true).subView(1);
1008  }
1009  else
1010  rRedlineText = OUString::Concat(rRedlineText.subView(0, rRedlineText.getLength() - 3)) + "...";
1011  }
1012  isExtendText = true;
1013  }
1014  break;
1015  }
1017  break; // -Werror=switch
1018  }
1019  if (isBreak && !isExtendText)
1020  {
1021  break;
1022  }
1023  }
1024 
1025  m_nStart = nOldStart;
1026  m_nEnd = nOldEnd;
1027  m_nAct = nOldAct;
1028  return bRet;
1029 }
1030 
1032 {
1033  if ( nAttr & ExtTextInputAttr::Underline )
1035  else if ( nAttr & ExtTextInputAttr::BoldUnderline )
1036  rFnt.SetUnderline( LINESTYLE_BOLD );
1037  else if ( nAttr & ExtTextInputAttr::DottedUnderline )
1039  else if ( nAttr & ExtTextInputAttr::DashDotUnderline )
1041 
1042  if ( nAttr & ExtTextInputAttr::RedText )
1043  rFnt.SetColor( COL_RED );
1044 
1045  if ( nAttr & ExtTextInputAttr::Highlight )
1046  {
1047  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1048  rFnt.SetColor( rStyleSettings.GetHighlightTextColor() );
1049  rFnt.SetBackColor( rStyleSettings.GetHighlightColor() );
1050  }
1051  if ( nAttr & ExtTextInputAttr::GrayWaveline )
1052  rFnt.SetGreyWave( true );
1053 }
1054 
1055 short SwExtend::Enter(SwFont& rFnt, sal_uLong const nNode, sal_Int32 const nNew)
1056 {
1057  OSL_ENSURE( !m_pFont, "SwExtend: Enter with Font" );
1058  if (nNode != m_nNode)
1059  return 0;
1060  OSL_ENSURE( !Inside(), "SwExtend: Enter without Leave" );
1061  m_nPos = nNew;
1062  if( Inside() )
1063  {
1064  m_pFont.reset( new SwFont(rFnt) );
1065  ActualizeFont( rFnt, m_rArr[m_nPos - m_nStart] );
1066  return 1;
1067  }
1068  return 0;
1069 }
1070 
1071 bool SwExtend::Leave_(SwFont& rFnt, sal_uLong const nNode, sal_Int32 const nNew)
1072 {
1073  OSL_ENSURE(nNode == m_nNode && Inside(), "SwExtend: Leave without Enter");
1074  if (nNode != m_nNode)
1075  return true;
1076  const ExtTextInputAttr nOldAttr = m_rArr[m_nPos - m_nStart];
1077  m_nPos = nNew;
1078  if( Inside() )
1079  { // We stayed within the ExtendText-section
1080  const ExtTextInputAttr nAttr = m_rArr[m_nPos - m_nStart];
1081  if( nOldAttr != nAttr ) // Is there an (inner) change of attributes?
1082  {
1083  rFnt = *m_pFont;
1084  ActualizeFont( rFnt, nAttr );
1085  }
1086  }
1087  else
1088  {
1089  rFnt = *m_pFont;
1090  m_pFont.reset();
1091  return true;
1092  }
1093  return false;
1094 }
1095 
1096 sal_Int32 SwExtend::Next(sal_uLong const nNode, sal_Int32 nNext)
1097 {
1098  if (nNode != m_nNode)
1099  return nNext;
1100  if (m_nPos < m_nStart)
1101  {
1102  if (nNext > m_nStart)
1103  nNext = m_nStart;
1104  }
1105  else if (m_nPos < m_nEnd)
1106  {
1107  sal_Int32 nIdx = m_nPos - m_nStart;
1108  const ExtTextInputAttr nAttr = m_rArr[ nIdx ];
1109  while (o3tl::make_unsigned(++nIdx) < m_rArr.size() && nAttr == m_rArr[nIdx])
1110  ; //nothing
1111  nIdx = nIdx + m_nStart;
1112  if( nNext > nIdx )
1113  nNext = nIdx;
1114  }
1115  return nNext;
1116 }
1117 
1118 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 m_nEnd
Definition: redlnitr.hxx:82
SwScriptInfo * m_pScriptInfo
Definition: itratr.hxx:40
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:157
std::deque< SwTextAttr * > m_Hints
Definition: redlnitr.hxx:72
SwFontScript WhichFont(TextFrameIndex nIdx) const
Definition: porlay.cxx:750
sal_uLong GetIndex() const
Definition: node.hxx:291
TextFrameIndex GetInvalidityA() const
Definition: scriptinfo.hxx:118
sal_uLong Count() const
Definition: ndarr.hxx:142
virtual ::sw::mark::IFieldmark * getFieldmarkAt(const SwPosition &rPos) const =0
get Fieldmark for CH_TXT_ATR_FIELDSTART/CH_TXT_ATR_FIELDEND at rPos
Marks a position in the document model.
Definition: pam.hxx:35
constexpr TypedWhichId< SvxEscapementItem > RES_CHRATR_ESCAPEMENT(6)
void Pop(const SwTextAttr &rAttr)
Only used during redlining.
Definition: atrstck.cxx:466
const SwNodeNum * GetNum(SwRootFrame const *pLayout=nullptr) const
Definition: ndtxt.cxx:3956
SwComparePosition ComparePosition(const T &rStt1, const T &rEnd1, const T &rStt2, const T &rEnd2)
Definition: pam.hxx:77
const OUString & GetText() const
Definition: ndtxt.hxx:210
virtual const SwRootFrame * GetCurrentLayout() const =0
void PopAndChg(const SwTextAttr &rAttr, SwFont &rFnt)
Definition: atrstck.cxx:426
std::unique_ptr< SwFont > m_pFont
Definition: redlnitr.hxx:39
const Color & GetHighlightTextColor() const
SwNodeIndex nNode
Definition: pam.hxx:37
constexpr::Color COL_RED(0x80, 0x00, 0x00)
void SetPriorityAttr(bool bFlag)
Definition: txatbase.hxx:102
LINESTYLE_BOLD
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:275
sal_uIntPtr sal_uLong
#define SW_SCRIPTS
Definition: swfont.hxx:128
Pos1 is as large as Pos2.
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
size_t m_nEndIndex
current iteration index in HintEnds
Definition: itratr.hxx:50
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:447
const sal_uInt32 magic
void SetGreyWave(const bool bNew)
Definition: swfont.hxx:815
Pos1 completely contained in Pos2.
Provides access to the marks of a document.
Definition: doc.hxx:187
short Seek(SwFont &rFnt, sal_uLong nNode, sal_Int32 nNew, sal_Int32 nOld)
Definition: redlnitr.cxx:672
sal_Int32 const m_nStart
Definition: redlnitr.hxx:43
SwPosition FindFieldSep(IFieldmark const &rMark)
return position of the CH_TXT_ATR_FIELDSEP for rMark
Definition: bookmrk.cxx:56
constexpr TypedWhichId< SvxUnderlineItem > RES_CHRATR_UNDERLINE(14)
SwNode & GetNode() const
Definition: ndindex.hxx:119
SwFont * m_pFont
Definition: itratr.hxx:39
Dialog to specify the properties of date form field.
void CalcStartEnd(sal_uLong nNdIdx, sal_Int32 &rStart, sal_Int32 &rEnd) const
Calculates the intersection with text node number nNdIdx.
Definition: docredln.cxx:1302
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
Degree10 GetOrientation(const bool bVertLayout=false, const bool bVertFormatLRBT=false) const
Definition: swfont.cxx:412
bool Seek(TextFrameIndex nPos)
Enables the attributes used at char pos nPos in the logical font.
Definition: itratr.cxx:301
const Color & GetHighlightColor() const
static bool IsShowChanges(const RedlineFlags eM)
bool IsVertLRBT() const
Definition: frame.hxx:964
FieldmarkMode
Definition: rootfrm.hxx:50
void SetColor(const Color &rColor)
Definition: swfont.hxx:411
size_type size() const
Definition: docary.hxx:266
sal_Int32 m_nStart
Definition: redlnitr.hxx:81
Pos1 end touches at Pos2 start.
SwDoc & m_rDoc
Definition: docbm.cxx:1208
sal_Int32 m_nPosition
current iteration index in text node
Definition: itratr.hxx:52
sal_uInt16 sal_Unicode
void RemoveFromListRLHidden()
Definition: ndtxt.cxx:4335
void CtorInitAttrIter(SwTextNode &rTextNode, SwScriptInfo &rScrInf, SwTextFrame const *pFrame=nullptr)
Definition: redlnitr.cxx:517
SwIndex nContent
Definition: pam.hxx:38
o3tl::enumarray< SwFontScript, sal_uInt16 > m_aFontIdx
Definition: itratr.hxx:55
SwRedlineTable::size_type m_nAct
Definition: redlnitr.hxx:80
void FillHints(std::size_t nAuthor, RedlineType eType)
Definition: redlnitr.cxx:790
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
A wrapper around SfxPoolItem to store the start position of (usually) a text portion, with an optional end.
Definition: txatbase.hxx:41
virtual ::sw::mark::IFieldmark * getFieldmarkFor(const SwPosition &pos) const =0
bool ExtOn()
Definition: redlnitr.hxx:124
bool Leave_(SwFont &rFnt, sal_uLong nNode, sal_Int32 nNew)
Definition: redlnitr.cxx:1071
std::unique_ptr< sw::MergedPara > CheckParaRedlineMerge(SwTextFrame &rFrame, SwTextNode &rTextNode, FrameMode eMode)
Definition: redlnitr.cxx:205
bool IsOn() const
Definition: redlnitr.hxx:108
Used by Attribute Iterators to organize attributes on stacks to find the valid attribute in each cate...
Definition: atrhndl.hxx:38
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:33
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
void InitScriptInfo(const SwTextNode &rNode, sw::MergedPara const *pMerged, bool bRTL)
Definition: porlay.cxx:936
Pos2 completely contained in Pos1.
void SetUnderline(const FontLineStyle eUnderline)
Definition: swfont.hxx:542
sal_Int32 Next(sal_uLong nNode, sal_Int32 nNext)
Definition: redlnitr.cxx:1096
Pos1 before Pos2.
std::unique_ptr< SwRedlineItr, o3tl::default_delete< SwRedlineItr > > m_pRedline
Definition: itratr.hxx:46
sal_uInt16 GetStackCount() const
Definition: docredln.cxx:1786
sal_Int32 m_nPos
current position (inside)
Definition: redlnitr.hxx:45
SwFormatColl & GetAnyFormatColl() const
Definition: node.hxx:711
void EndListeningAll()
Definition: calbck.cxx:135
FrameMode
Definition: txtfrm.hxx:102
std::vector< Extent > extents
Definition: txtfrm.hxx:956
void InitFontAndAttrHandler(SwTextNode const &rPropsNode, SwTextNode const &rTextNode, OUString const &rText, bool const *pbVertLayout, bool const *pbVertLayoutLRBT)
Definition: redlnitr.cxx:441
bool Inside() const
Definition: redlnitr.hxx:49
std::unique_ptr< SfxItemSet > m_pSet
Definition: redlnitr.hxx:75
sw::MergedPara const * m_pMergedPara
Definition: itratr.hxx:58
const SwAttrSet * GetpSwAttrSet() const
Definition: node.hxx:452
virtual SwRedlineTable::size_type GetRedlinePos(const SwNode &rNode, RedlineType nType) const =0
#define SW_MOD()
Definition: swmodule.hxx:255
void Init(const SwAttrSet &rAttrSet, const IDocumentSettingAccess &rIDocumentSettingAccess)
Definition: atrstck.cxx:277
Pos1 start touches at Pos2 end.
sal_uLong const m_nNdIdx
Definition: redlnitr.hxx:78
sw::FieldmarkMode GetFieldmarkMode() const
Definition: rootfrm.hxx:422
bool IsVertLayout() const
Definition: atrhndl.hxx:80
void SetVertical(Degree10 nDir, const bool bVertLayout=false, const bool bVertLayoutLRBT=false)
Definition: swfont.cxx:417
vector_type::size_type size_type
Definition: docary.hxx:228
std::unique_ptr< SwExtend > m_pExt
Definition: redlnitr.hxx:76
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
LINESTYLE_SINGLE
#define CH_TXT_ATR_FIELDSTART
Definition: hintids.hxx:178
sal_Int32 const m_nEnd
position of end of SwExtTextInput (in same node as start)
Definition: redlnitr.hxx:47
SwTextNode * pParaPropsNode
most paragraph properties are taken from the first non-empty node
Definition: txtfrm.hxx:961
~SwRedlineItr() COVERITY_NOEXCEPT_FALSE
Definition: redlnitr.cxx:664
void RemoveFootnotesForNode(SwRootFrame const &rLayout, SwTextNode const &rTextNode, std::vector< std::pair< sal_Int32, sal_Int32 >> const *const pExtents)
Definition: txtfrm.cxx:802
const IDocumentSettingAccess * getIDocumentSettingAccess() const
Provides access to the document setting interface.
Definition: node.cxx:2092
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:697
sal_uLong const m_nNode
position of start of SwExtTextInput
Definition: redlnitr.hxx:42
OUString mergedText
note: cannot be const currently to avoid UB because SwTextGuess::Guess const_casts it and modifies it...
Definition: txtfrm.hxx:959
enumrange< T >::Iterator end(enumrange< T >)
const SwPosition * Start() const
Definition: pam.hxx:212
size_t m_nStartIndex
current iteration index in HintStarts
Definition: itratr.hxx:48
sal_uInt8 m_nPropFont
Definition: itratr.hxx:53
const IDocumentLayoutAccess & getIDocumentLayoutAccess() const
Provides access to the document layout interface.
Definition: node.cxx:2097
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter() const
Definition: breakit.hxx:62
const SwDoc & m_rDoc
Definition: redlnitr.hxx:73
SwRedlineTable::size_type const m_nFirst
Definition: redlnitr.hxx:79
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
Mode const m_eMode
Definition: redlnitr.hxx:87
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:335
void Clear_(SwFont *pFnt)
Definition: redlnitr.cxx:830
o3tl::enumarray< SwFontScript, const void * > m_aFontCacheIds
Definition: itratr.hxx:54
constexpr sal_uInt16 RES_CHRATR_BEGIN(HINT_BEGIN)
std::size_t GetAuthor(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1794
void SetBackColor(std::optional< Color > xNewColor)
Definition: swfont.cxx:64
std::pair< sal_Int32, std::pair< SwRangeRedline const *, size_t > > GetNextRedln(sal_Int32 nNext, SwTextNode const *pNode, SwRedlineTable::size_type &rAct)
Ignore mode: does nothing.
Definition: redlnitr.cxx:850
Pos1 overlaps Pos2 at the end.
LINESTYLE_DOTTED
SwAttrHandler m_aAttrHandler
Definition: itratr.hxx:37
sal_uInt8 GetScriptType(const size_t nCnt) const
Definition: scriptinfo.hxx:133
sal_Int32 GetIndex() const
Definition: index.hxx:91
SwNodes & GetNodes()
Definition: doc.hxx:408
const SwPosition * End() const
Definition: pam.hxx:217
bool IsRightToLeft() const
Definition: frame.hxx:968
static void Destroy(SwTextAttr *pToDestroy, SfxItemPool &rPool)
destroy instance
Definition: txatbase.cxx:58
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1809
bool ChkSpecialUnderline_() const
Definition: redlnitr.cxx:926
SwFontScript
Definition: swfont.hxx:122
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding)...
Definition: rootfrm.hxx:420
constexpr sal_uInt16 RES_CHRATR_END(46)
void ChangeTextAttr(SwFont *pFnt, SwTextAttr const &rHt, bool bChg)
Definition: redlnitr.cxx:809
void PushAndChg(const SwTextAttr &rAttr, SwFont &rFnt)
Definition: atrstck.cxx:341
const std::vector< ExtTextInputAttr > & m_rArr
Definition: redlnitr.hxx:40
bool IsVertical() const
Definition: frame.hxx:954
TextFrameIndex GetScriptChg(const size_t nCnt) const
Definition: scriptinfo.hxx:128
virtual RedlineFlags GetRedlineFlags() const =0
Query the currently set redline mode.
size_t CountScriptChg() const
Definition: scriptinfo.hxx:127
void AddToListRLHidden()
Definition: ndtxt.cxx:4304
bool CheckLine(sal_uLong nStartNode, sal_Int32 nChkStart, sal_uLong nEndNode, sal_Int32 nChkEnd, OUString &rRedlineText, bool &bRedlineEnd, RedlineType &eRedlineEnd)
Definition: redlnitr.cxx:941
SwRedlineItr(const SwTextNode &rTextNd, SwFont &rFnt, SwAttrHandler &rAH, sal_Int32 nRedlPos, Mode mode, const std::vector< ExtTextInputAttr > *pArr=nullptr, SwPosition const *pExtInputStart=nullptr)
Definition: redlnitr.cxx:639
ExtTextInputAttr
bool IsInList() const
Definition: ndtxt.cxx:4347
bool HasMergedParas() const
Definition: rootfrm.hxx:424
RedlineType
short Enter(SwFont &rFnt, sal_uLong nNode, sal_Int32 nNew)
Definition: redlnitr.cxx:1055
Pos1 behind Pos2.
SwAttrHandler & m_rAttrHandler
Definition: redlnitr.hxx:74
SwViewShell * m_pViewShell
Definition: itratr.hxx:38
virtual const SwRedlineTable & GetRedlineTable() const =0
short m_nChgCnt
count currently open hints, redlines, ext-input
Definition: itratr.hxx:45
short EnterExtend(SwFont &rFnt, sal_uLong const nNode, sal_Int32 const nNew)
Definition: redlnitr.hxx:92
#define CH_TXT_ATR_FIELDSEP
Definition: hintids.hxx:179
void SetRedlineMergeFlag(Merge const eMerge)
Definition: node.hxx:97
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:208
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...
static constexpr size_type npos
Definition: docary.hxx:229
static void ActualizeFont(SwFont &rFnt, ExtTextInputAttr nAttr)
Definition: redlnitr.cxx:1031
Merge GetRedlineMergeFlag() const
Definition: node.hxx:98
void Clear(SwFont *pFnt)
Definition: redlnitr.hxx:109
const sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:61
SwRootFrame * getRootFrame()
Definition: frame.hxx:662
Pos1 overlaps Pos2 at the beginning.
sal_uInt16 nPos
SwExtTextInput * GetExtTextInput(const SwNode &rNd, sal_Int32 nContentPos=-1) const
Definition: extinput.cxx:263
const std::vector< ExtTextInputAttr > & GetAttrs() const
Definition: extinput.hxx:39
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:845
Base class of the Writer document model elements.
Definition: node.hxx:80
sal_Int32 NextExtend(sal_uLong const nNode, sal_Int32 const nNext)
Definition: redlnitr.hxx:97
SwTextAttr * MakeRedlineTextAttr(SwDoc &rDoc, SfxPoolItem const &rAttr)
create redline dummy text hint that must not be inserted into hints array
Definition: thints.cxx:986