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