LibreOffice Module sw (master) 1
docredln.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 <libxml/xmlwriter.h>
21#include <boost/property_tree/json_parser.hpp>
22
23#include <osl/diagnose.h>
24#include <sal/log.hxx>
26#include <hintids.hxx>
27#include <svl/itemiter.hxx>
28#include <comphelper/lok.hxx>
29#include <comphelper/string.hxx>
30#include <LibreOfficeKit/LibreOfficeKitEnums.h>
31#include <unotools/datetime.hxx>
32#include <sfx2/viewsh.hxx>
33#include <o3tl/string_view.hxx>
34#include <swmodule.hxx>
35#include <doc.hxx>
36#include <docredln.hxx>
37#include <IDocumentUndoRedo.hxx>
40#include <IDocumentState.hxx>
43#include <docary.hxx>
44#include <ndtxt.hxx>
45#include <redline.hxx>
46#include <UndoCore.hxx>
47#include <hints.hxx>
48#include <pamtyp.hxx>
49#include <poolfmt.hxx>
50#include <algorithm>
51#include <limits>
52#include <utility>
53#include <view.hxx>
54#include <viewopt.hxx>
55#include <usrpref.hxx>
56#include <viewsh.hxx>
57#include <viscrs.hxx>
58#include <rootfrm.hxx>
59#include <strings.hrc>
60#include <swtypes.hxx>
61#include <wrtsh.hxx>
62#include <txtfld.hxx>
63
64#include <flowfrm.hxx>
65#include <txtfrm.hxx>
66
67using namespace com::sun::star;
68
69#ifdef DBG_UTIL
70
71 void sw_DebugRedline( const SwDoc* pDoc )
72 {
73 static SwRedlineTable::size_type nWatch = 0; // loplugin:constvars:ignore
75 for( SwRedlineTable::size_type n = 0; n < rTable.size(); ++n )
76 {
77 volatile SwRedlineTable::size_type nDummy = 0;
78 const SwRangeRedline* pCurrent = rTable[ n ];
79 const SwRangeRedline* pNext = n+1 < rTable.size() ? rTable[ n+1 ] : nullptr;
80 if( pCurrent == pNext )
81 (void) nDummy;
82 if( n == nWatch )
83 (void) nDummy; // Possible debugger breakpoint
84 }
85 }
86
87#endif
88
89
91{
93}
94
96{
97 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwExtraRedlineTable"));
98 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
99
100 for (sal_uInt16 nCurExtraRedlinePos = 0; nCurExtraRedlinePos < GetSize(); ++nCurExtraRedlinePos)
101 {
102 const SwExtraRedline* pExtraRedline = GetRedline(nCurExtraRedlinePos);
103 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwExtraRedline"));
104 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
105 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("symbol"), "%s", BAD_CAST(typeid(*pExtraRedline).name()));
106 (void)xmlTextWriterEndElement(pWriter);
107 }
108 (void)xmlTextWriterEndElement(pWriter);
109}
110
111#if OSL_DEBUG_LEVEL > 0
112static bool CheckPosition( const SwPosition* pStt, const SwPosition* pEnd )
113{
114 int nError = 0;
115 SwNode* pSttNode = &pStt->GetNode();
116 SwNode* pEndNode = &pEnd->GetNode();
117 SwNode* pSttTab = pSttNode->StartOfSectionNode()->FindTableNode();
118 SwNode* pEndTab = pEndNode->StartOfSectionNode()->FindTableNode();
119 SwNode* pSttStart = pSttNode;
120 while( pSttStart && (!pSttStart->IsStartNode() || pSttStart->IsSectionNode() ||
121 pSttStart->IsTableNode() ) )
122 pSttStart = pSttStart->StartOfSectionNode();
123 SwNode* pEndStart = pEndNode;
124 while( pEndStart && (!pEndStart->IsStartNode() || pEndStart->IsSectionNode() ||
125 pEndStart->IsTableNode() ) )
126 pEndStart = pEndStart->StartOfSectionNode();
127 assert(pSttTab == pEndTab);
128 if( pSttTab != pEndTab )
129 nError = 1;
130 assert(pSttTab || pSttStart == pEndStart);
131 if( !pSttTab && pSttStart != pEndStart )
132 nError |= 2;
133 if( nError )
134 nError += 10;
135 return nError != 0;
136}
137#endif
138
139bool SwExtraRedlineTable::DeleteAllTableRedlines( SwDoc& rDoc, const SwTable& rTable, bool bSaveInUndo, RedlineType nRedlineTypeToDelete )
140{
141 bool bChg = false;
142
143 if (bSaveInUndo && rDoc.GetIDocumentUndoRedo().DoesUndo())
144 {
145 // #TODO - Add 'Undo' support for deleting 'Table Cell' redlines
146 /*
147 SwUndoRedline* pUndo = new SwUndoRedline( SwUndoId::REDLINE, rRange );
148 if( pUndo->GetRedlSaveCount() )
149 {
150 GetIDocumentUndoRedo().AppendUndo(pUndo);
151 }
152 else
153 delete pUndo;
154 */
155 }
156
157 for (sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < GetSize(); )
158 {
159 SwExtraRedline* pExtraRedline = GetRedline(nCurRedlinePos);
160 const SwTableCellRedline* pTableCellRedline = dynamic_cast<const SwTableCellRedline*>(pExtraRedline);
161 if (pTableCellRedline)
162 {
163 const SwTableBox *pRedTabBox = &pTableCellRedline->GetTableBox();
164 const SwTable& rRedTable = pRedTabBox->GetSttNd()->FindTableNode()->GetTable();
165 if ( &rRedTable == &rTable )
166 {
167 // Redline for this table
168 const SwRedlineData& aRedlineData = pTableCellRedline->GetRedlineData();
169 const RedlineType nRedlineType = aRedlineData.GetType();
170
171 // Check if this redline object type should be deleted
172 if (RedlineType::Any == nRedlineTypeToDelete || nRedlineTypeToDelete == nRedlineType)
173 {
174
175 DeleteAndDestroy( nCurRedlinePos );
176 bChg = true;
177 continue; // don't increment position after delete
178 }
179 }
180 }
181 ++nCurRedlinePos;
182 }
183
184 if( bChg )
186
187 return bChg;
188}
189
190bool SwExtraRedlineTable::DeleteTableRowRedline( SwDoc* pDoc, const SwTableLine& rTableLine, bool bSaveInUndo, RedlineType nRedlineTypeToDelete )
191{
192 bool bChg = false;
193
194 if (bSaveInUndo && pDoc->GetIDocumentUndoRedo().DoesUndo())
195 {
196 // #TODO - Add 'Undo' support for deleting 'Table Cell' redlines
197 /*
198 SwUndoRedline* pUndo = new SwUndoRedline( SwUndoId::REDLINE, rRange );
199 if( pUndo->GetRedlSaveCount() )
200 {
201 GetIDocumentUndoRedo().AppendUndo(pUndo);
202 }
203 else
204 delete pUndo;
205 */
206 }
207
208 for(sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < GetSize(); ++nCurRedlinePos )
209 {
210 SwExtraRedline* pExtraRedline = GetRedline(nCurRedlinePos);
211 const SwTableRowRedline* pTableRowRedline = dynamic_cast<const SwTableRowRedline*>(pExtraRedline);
212 const SwTableLine *pRedTabLine = pTableRowRedline ? &pTableRowRedline->GetTableLine() : nullptr;
213 if ( pRedTabLine == &rTableLine )
214 {
215 // Redline for this table row
216 const SwRedlineData& aRedlineData = pTableRowRedline->GetRedlineData();
217 const RedlineType nRedlineType = aRedlineData.GetType();
218
219 // Check if this redline object type should be deleted
220 if( RedlineType::Any != nRedlineTypeToDelete && nRedlineTypeToDelete != nRedlineType )
221 continue;
222
223 DeleteAndDestroy( nCurRedlinePos );
224 bChg = true;
225 }
226 }
227
228 if( bChg )
230
231 return bChg;
232}
233
234bool SwExtraRedlineTable::DeleteTableCellRedline( SwDoc* pDoc, const SwTableBox& rTableBox, bool bSaveInUndo, RedlineType nRedlineTypeToDelete )
235{
236 bool bChg = false;
237
238 if (bSaveInUndo && pDoc->GetIDocumentUndoRedo().DoesUndo())
239 {
240 // #TODO - Add 'Undo' support for deleting 'Table Cell' redlines
241 /*
242 SwUndoRedline* pUndo = new SwUndoRedline( SwUndoId::REDLINE, rRange );
243 if( pUndo->GetRedlSaveCount() )
244 {
245 GetIDocumentUndoRedo().AppendUndo(pUndo);
246 }
247 else
248 delete pUndo;
249 */
250 }
251
252 for(sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < GetSize(); ++nCurRedlinePos )
253 {
254 SwExtraRedline* pExtraRedline = GetRedline(nCurRedlinePos);
255 const SwTableCellRedline* pTableCellRedline = dynamic_cast<const SwTableCellRedline*>(pExtraRedline);
256 const SwTableBox *pRedTabBox = pTableCellRedline ? &pTableCellRedline->GetTableBox() : nullptr;
257 if ( pRedTabBox == &rTableBox )
258 {
259 // Redline for this table cell
260 const SwRedlineData& aRedlineData = pTableCellRedline->GetRedlineData();
261 const RedlineType nRedlineType = aRedlineData.GetType();
262
263 // Check if this redline object type should be deleted
264 if( RedlineType::Any != nRedlineTypeToDelete && nRedlineTypeToDelete != nRedlineType )
265 continue;
266
267 DeleteAndDestroy( nCurRedlinePos );
268 bChg = true;
269 }
270 }
271
272 if( bChg )
274
275 return bChg;
276}
277
278namespace
279{
280
281void lcl_LOKInvalidateFrames(const sw::BroadcastingModify& rMod, const SwRootFrame* pLayout,
282 SwFrameType const nFrameType, const Point* pPoint)
283{
285
286 for (SwFrame* pTmpFrame = aIter.First(); pTmpFrame; pTmpFrame = aIter.Next() )
287 {
288 if ((pTmpFrame->GetType() & nFrameType) &&
289 (!pLayout || pLayout == pTmpFrame->getRootFrame()) &&
290 (!pTmpFrame->IsFlowFrame() || !SwFlowFrame::CastFlowFrame( pTmpFrame )->IsFollow()))
291 {
292 if (pPoint)
293 {
294 pTmpFrame->InvalidateSize();
295
296 // Also empty the text portion cache, so it gets rebuilt, taking the new redlines
297 // into account.
298 if (pTmpFrame->IsTextFrame())
299 {
300 auto pTextFrame = static_cast<SwTextFrame*>(pTmpFrame);
301 pTextFrame->ClearPara();
302 }
303 }
304 }
305 }
306}
307
308void lcl_LOKInvalidateStartEndFrames(SwShellCursor& rCursor)
309{
310 if (!(rCursor.HasMark() &&
311 rCursor.GetPoint()->GetNode().IsContentNode() &&
312 rCursor.GetPoint()->GetNode().GetContentNode()->getLayoutFrame(rCursor.GetShell()->GetLayout()) &&
313 (rCursor.GetMark()->GetNode() == rCursor.GetPoint()->GetNode() ||
314 (rCursor.GetMark()->GetNode().IsContentNode() &&
315 rCursor.GetMark()->GetNode().GetContentNode()->getLayoutFrame(rCursor.GetShell()->GetLayout())))))
316 {
317 return;
318 }
319
320 auto [pStartPos, pEndPos] = rCursor.StartEnd(); // SwPosition*
321
322 lcl_LOKInvalidateFrames(*(pStartPos->GetNode().GetContentNode()),
323 rCursor.GetShell()->GetLayout(),
324 FRM_CNTNT, &rCursor.GetSttPos());
325
326 lcl_LOKInvalidateFrames(*(pEndPos->GetNode().GetContentNode()),
327 rCursor.GetShell()->GetLayout(),
328 FRM_CNTNT, &rCursor.GetEndPos());
329}
330
331bool lcl_LOKRedlineNotificationEnabled()
332{
333 static bool bDisableRedlineComments = getenv("DISABLE_REDLINE") != nullptr;
334 if (comphelper::LibreOfficeKit::isActive() && !bDisableRedlineComments)
335 return true;
336
337 return false;
338}
339
340} // anonymous namespace
341
344{
345 // Disable since usability is very low beyond some small number of changes.
346 if (!lcl_LOKRedlineNotificationEnabled())
347 return;
348
349 boost::property_tree::ptree aRedline;
350 aRedline.put("action", (nType == RedlineNotification::Add ? "Add" :
351 (nType == RedlineNotification::Remove ? "Remove" :
352 (nType == RedlineNotification::Modify ? "Modify" : "???"))));
353 aRedline.put("index", pRedline->GetId());
354 aRedline.put("author", pRedline->GetAuthorString(1).toUtf8().getStr());
355 aRedline.put("type", SwRedlineTypeToOUString(pRedline->GetRedlineData().GetType()).toUtf8().getStr());
356 aRedline.put("comment", pRedline->GetRedlineData().GetComment().toUtf8().getStr());
357 aRedline.put("description", pRedline->GetDescr().toUtf8().getStr());
358 OUString sDateTime = utl::toISO8601(pRedline->GetRedlineData().GetTimeStamp().GetUNODateTime());
359 aRedline.put("dateTime", sDateTime.toUtf8().getStr());
360
361 auto [pStartPos, pEndPos] = pRedline->StartEnd(); // SwPosition*
362 SwContentNode* pContentNd = pRedline->GetPointContentNode();
363 SwView* pView = dynamic_cast<SwView*>(SfxViewShell::Current());
364 if (pView && pContentNd)
365 {
366 SwShellCursor aCursor(pView->GetWrtShell(), *pStartPos);
367 aCursor.SetMark();
368 *aCursor.GetMark() = *pEndPos;
369
370 aCursor.FillRects();
371
372 SwRects* pRects(&aCursor);
373 std::vector<OString> aRects;
374 for(const SwRect& rNextRect : *pRects)
375 aRects.push_back(rNextRect.SVRect().toString());
376
377 const OString sRects = comphelper::string::join("; ", aRects);
378 aRedline.put("textRange", sRects.getStr());
379
380 lcl_LOKInvalidateStartEndFrames(aCursor);
381
382 // When this notify method is called text invalidation is not done yet
383 // Calling FillRects updates the text area so invalidation will not run on the correct rects
384 // So we need to do an own invalidation here. It invalidates text frames containing the redlining
385 SwDoc& rDoc = pRedline->GetDoc();
386 SwViewShell* pSh;
387 if( !rDoc.IsInDtor() )
388 {
390 if( pSh )
391 for(SwNodeIndex nIdx(pStartPos->GetNode()); nIdx <= pEndPos->GetNode(); ++nIdx)
392 {
393 SwContentNode* pContentNode = nIdx.GetNode().GetContentNode();
394 if (pContentNode)
395 pSh->InvalidateWindows(pContentNode->FindLayoutRect());
396 }
397 }
398 }
399
400 boost::property_tree::ptree aTree;
401 aTree.add_child("redline", aRedline);
402 std::stringstream aStream;
403 boost::property_tree::write_json(aStream, aTree);
404 std::string aPayload = aStream.str();
405
406 SfxViewShell* pViewShell = SfxViewShell::GetFirst();
407 while (pViewShell)
408 {
409 if (pView && pView->GetDocId() == pViewShell->GetDocId())
410 pViewShell->libreOfficeKitViewCallback(nType == RedlineNotification::Modify ? LOK_CALLBACK_REDLINE_TABLE_ENTRY_MODIFIED : LOK_CALLBACK_REDLINE_TABLE_SIZE_CHANGED, aPayload.c_str());
411 pViewShell = SfxViewShell::GetNext(*pViewShell);
412 }
413}
414
416{
417 if( p->HasValidRange() )
418 {
419 std::pair<vector_type::const_iterator, bool> rv = maVector.insert( p );
420 size_type nP = rv.first - begin();
422
423 // detect text moving by checking nearby redlines, except during Undo
424 // (apply isMoved() during OpenDocument and DOCX import, too, to fix
425 // missing text moving handling in ODF and e.g. web version of MSO)
426 if ( p->GetDoc().GetIDocumentUndoRedo().DoesUndo() ||
427 p->GetDoc().IsInWriterfilterImport() ||
428 p->GetDoc().IsInXMLImport() )
429 {
430 isMoved(nP);
431 }
432
433 p->CallDisplayFunc(nP);
434 if (rv.second)
435 CheckOverlapping(rv.first);
436 return rv.second;
437 }
438 return InsertWithValidRanges( p );
439}
440
441void SwRedlineTable::CheckOverlapping(vector_type::const_iterator it)
442{
444 return;
445 if (maVector.size() <= 1) // a single element cannot be overlapping
446 return;
447 auto pCurr = *it;
448 auto itNext = it + 1;
449 if (itNext != maVector.end())
450 {
451 auto pNext = *itNext;
452 if (pCurr->End()->GetNodeIndex() >= pNext->Start()->GetNodeIndex())
453 {
455 return;
456 }
457 }
458 if (it != maVector.begin())
459 {
460 auto pPrev = *(it - 1);
461 if (pPrev->End()->GetNodeIndex() >= pCurr->Start()->GetNodeIndex())
463 }
464}
465
467{
468 if( p->HasValidRange() )
469 {
470 std::pair<vector_type::const_iterator, bool> rv = maVector.insert( p );
471 rP = rv.first - begin();
472 p->CallDisplayFunc(rP);
473 if (rv.second)
474 CheckOverlapping(rv.first);
475 return rv.second;
476 }
477 return InsertWithValidRanges( p, &rP );
478}
479
480namespace sw {
481
482std::vector<std::unique_ptr<SwRangeRedline>> GetAllValidRanges(std::unique_ptr<SwRangeRedline> p)
483{
484 std::vector<std::unique_ptr<SwRangeRedline>> ret;
485 // Create valid "sub-ranges" from the Selection
486 auto [pStt, pEnd] = p->StartEnd(); // SwPosition*
487 SwPosition aNewStt( *pStt );
488 SwNodes& rNds = aNewStt.GetNodes();
489 SwContentNode* pC;
490
491 if( !aNewStt.GetNode().IsContentNode() )
492 {
493 pC = rNds.GoNext( &aNewStt );
494 if( !pC )
495 aNewStt.Assign(rNds.GetEndOfContent());
496 }
497
498
499 if( aNewStt >= *pEnd )
500 return ret;
501
502 std::unique_ptr<SwRangeRedline> pNew;
503 do {
504 if( !pNew )
505 pNew.reset(new SwRangeRedline( p->GetRedlineData(), aNewStt ));
506 else
507 {
508 pNew->DeleteMark();
509 *pNew->GetPoint() = aNewStt;
510 }
511
512 pNew->SetMark();
513 GoEndSection( pNew->GetPoint() );
514 // i60396: If the redlines starts before a table but the table is the last member
515 // of the section, the GoEndSection will end inside the table.
516 // This will result in an incorrect redline, so we've to go back
517 SwNode* pTab = pNew->GetPoint()->GetNode().StartOfSectionNode()->FindTableNode();
518 // We end in a table when pTab != 0
519 if( pTab && !pNew->GetMark()->GetNode().StartOfSectionNode()->FindTableNode() )
520 { // but our Mark was outside the table => Correction
521 do
522 {
523 // We want to be before the table
524 pNew->GetPoint()->Assign(*pTab);
525 pC = GoPreviousPos( pNew->GetPoint(), false ); // here we are.
526 if( pC )
527 pNew->GetPoint()->SetContent( 0 );
528 pTab = pNew->GetPoint()->GetNode().StartOfSectionNode()->FindTableNode();
529 } while( pTab ); // If there is another table we have to repeat our step backwards
530 }
531
532 if( *pNew->GetPoint() > *pEnd )
533 {
534 pC = nullptr;
535 if( aNewStt.GetNode() != pEnd->GetNode() )
536 do {
537 SwNode& rCurNd = aNewStt.GetNode();
538 if( rCurNd.IsStartNode() )
539 {
540 if( rCurNd.EndOfSectionIndex() < pEnd->GetNodeIndex() )
541 aNewStt.Assign( *rCurNd.EndOfSectionNode() );
542 else
543 break;
544 }
545 else if( rCurNd.IsContentNode() )
546 pC = rCurNd.GetContentNode();
547 aNewStt.Adjust(SwNodeOffset(1));
548 } while( aNewStt.GetNodeIndex() < pEnd->GetNodeIndex() );
549
550 if( aNewStt.GetNode() == pEnd->GetNode() )
551 aNewStt.SetContent(pEnd->GetContentIndex());
552 else if( pC )
553 {
554 aNewStt.Assign(*pC, pC->Len() );
555 }
556
557 if( aNewStt <= *pEnd )
558 *pNew->GetPoint() = aNewStt;
559 }
560 else
561 aNewStt = *pNew->GetPoint();
562#if OSL_DEBUG_LEVEL > 0
563 CheckPosition( pNew->GetPoint(), pNew->GetMark() );
564#endif
565
566 if( *pNew->GetPoint() != *pNew->GetMark() &&
567 pNew->HasValidRange())
568 {
569 ret.push_back(std::move(pNew));
570 }
571
572 if( aNewStt >= *pEnd )
573 break;
574 pC = rNds.GoNext( &aNewStt );
575 if( !pC )
576 break;
577 } while( aNewStt < *pEnd );
578
579 return ret;
580}
581
582} // namespace sw
583
585{
586 bool bAnyIns = false;
587 std::vector<std::unique_ptr<SwRangeRedline>> redlines(
588 GetAllValidRanges(std::unique_ptr<SwRangeRedline>(p)));
589 for (std::unique_ptr<SwRangeRedline> & pRedline : redlines)
590 {
591 assert(pRedline->HasValidRange());
592 size_type nInsPos;
593 auto pTmpRedline = pRedline.release();
594 if (Insert(pTmpRedline, nInsPos))
595 {
596 pTmpRedline->CallDisplayFunc(nInsPos);
597 bAnyIns = true;
598 if (pInsPos && *pInsPos < nInsPos)
599 {
600 *pInsPos = nInsPos;
601 }
602 }
603 }
604 p = nullptr;
605 return bAnyIns;
606}
607
609{
610 return *lhs < *rhs;
611}
612
614{
616}
617
619{
621 if( it == maVector.end() )
622 return npos;
623 return it - maVector.begin();
624}
625
627{
628 const size_type nPos = GetPos(p);
629 if (nPos == npos)
630 return;
631 Remove(nPos);
632}
633
635{
637 SwDoc* pDoc = nullptr;
638 if( !nP && 1 == size() )
639 pDoc = &maVector.front()->GetDoc();
640
641 maVector.erase( maVector.begin() + nP );
642
643 if( pDoc && !pDoc->IsInDtor() )
644 {
646 if( pSh )
648 }
649}
650
652{
653 while (!maVector.empty())
654 {
655 auto const pRedline = maVector.back();
658 delete pRedline;
659 }
661}
662
664{
665 auto const pRedline = maVector[nP];
668 delete pRedline;
669}
670
672{
673 return nSttPos + 1 < size()
674 ? FindNextSeqNo( operator[]( nSttPos )->GetSeqNo(), nSttPos+1 )
675 : npos;
676}
677
679{
680 return nSttPos ? FindPrevSeqNo( operator[]( nSttPos )->GetSeqNo(), nSttPos-1 )
681 : npos;
682}
683
687{
688 auto constexpr nLookahead = 20;
689 size_type nRet = npos;
690 if( nSeqNo && nSttPos < size() )
691 {
692 size_type nEnd = size();
693 const size_type nTmp = nSttPos + nLookahead;
694 if (nTmp < nEnd)
695 {
696 nEnd = nTmp;
697 }
698
699 for( ; nSttPos < nEnd; ++nSttPos )
700 if( nSeqNo == operator[]( nSttPos )->GetSeqNo() )
701 {
702 nRet = nSttPos;
703 break;
704 }
705 }
706 return nRet;
707}
708
710{
711 auto constexpr nLookahead = 20;
712 size_type nRet = npos;
713 if( nSeqNo && nSttPos < size() )
714 {
715 size_type nEnd = 0;
716 if( nSttPos > nLookahead )
717 nEnd = nSttPos - nLookahead;
718
719 ++nSttPos;
720 while( nSttPos > nEnd )
721 if( nSeqNo == operator[]( --nSttPos )->GetSeqNo() )
722 {
723 nRet = nSttPos;
724 break;
725 }
726 }
727 return nRet;
728}
729
731 size_type& rPos,
732 bool bNext ) const
733{
734 const SwRangeRedline* pFnd = nullptr;
735 for( ; rPos < maVector.size() ; ++rPos )
736 {
737 const SwRangeRedline* pTmp = (*this)[ rPos ];
738 if( pTmp->HasMark() && pTmp->IsVisible() )
739 {
740 auto [pRStt, pREnd] = pTmp->StartEnd(); // SwPosition*
741 if( bNext ? *pRStt <= rSttPos : *pRStt < rSttPos )
742 {
743 if( bNext ? *pREnd > rSttPos : *pREnd >= rSttPos )
744 {
745 pFnd = pTmp;
746 break;
747 }
748 }
749 else
750 break;
751 }
752 }
753 return pFnd;
754}
755
757{
758 bool bRet = false;
759 auto constexpr nLookahead = 20;
760 SwRangeRedline* pRedline = (*this)[ rPos ];
761
762 // set redline type of the searched pair
763 RedlineType nPairType = pRedline->GetType();
764 if ( RedlineType::Delete == nPairType )
765 nPairType = RedlineType::Insert;
766 else if ( RedlineType::Insert == nPairType )
767 nPairType = RedlineType::Delete;
768 else
769 // only deleted or inserted text can be moved
770 return false;
771
772 bool bDeletePaM = false;
773 SwPaM* pPaM;
774
775 // if this redline is visible the content is in this PaM
776 if ( nullptr == pRedline->GetContentIdx() )
777 {
778 pPaM = pRedline;
779 }
780 else // otherwise it is saved in pContentSect, e.g. during ODT import
781 {
782 pPaM = new SwPaM(pRedline->GetContentIdx()->GetNode(), *pRedline->GetContentIdx()->GetNode().EndOfSectionNode() );
783 bDeletePaM = true;
784 }
785
786 const OUString sTrimmed = pPaM->GetText().trim();
787 // detection of move needs at least 6 characters with an inner
788 // space after stripping white spaces of the redline to skip
789 // frequent deleted and inserted articles or other common
790 // word parts, e.g. 'the' and 'of a' to detect as text moving
791 if ( sTrimmed.getLength() < 6 || sTrimmed.indexOf(' ') == -1 )
792 {
793 if ( bDeletePaM )
794 delete pPaM;
795 return false;
796 }
797
798 // search pair around the actual redline
799 size_type nEnd = rPos + nLookahead < size()
800 ? rPos + nLookahead
801 : size();
802 rPos = rPos > nLookahead ? rPos - nLookahead : 0;
803 for ( ; rPos < nEnd && !bRet ; ++rPos )
804 {
805 SwRangeRedline* pPair = (*this)[ rPos ];
806
807 // redline must be the requested type and from the same author
808 if ( nPairType != pPair->GetType() ||
809 pRedline->GetAuthor() != pPair->GetAuthor() )
810 {
811 continue;
812 }
813
814 bool bDeletePairPaM = false;
815 SwPaM* pPairPaM;
816
817 // if this redline is visible the content is in this PaM
818 if ( nullptr == pPair->GetContentIdx() )
819 {
820 pPairPaM = pPair;
821 }
822 else // otherwise it is saved in pContentSect, e.g. during ODT import
823 {
824 // saved in pContentSect, e.g. during ODT import
825 pPairPaM = new SwPaM(pPair->GetContentIdx()->GetNode(), *pPair->GetContentIdx()->GetNode().EndOfSectionNode() );
826 bDeletePairPaM = true;
827 }
828
829 // pair at tracked moving: same text by trimming trailing white spaces
830 if ( abs(pPaM->GetText().getLength() - pPairPaM->GetText().getLength()) <= 2 &&
831 sTrimmed == o3tl::trim(pPairPaM->GetText()) )
832 {
833 pRedline->SetMoved();
834 pPair->SetMoved();
836 bRet = true;
837 }
838
839 if ( bDeletePairPaM )
840 delete pPairPaM;
841 }
842
843 if ( bDeletePaM )
844 delete pPaM;
845
846 return bRet;
847}
848
850{
851 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwRedlineTable"));
852 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
853
854 for (SwRedlineTable::size_type nCurRedlinePos = 0; nCurRedlinePos < size(); ++nCurRedlinePos)
855 operator[](nCurRedlinePos)->dumpAsXml(pWriter);
856
857 (void)xmlTextWriterEndElement(pWriter);
858}
859
861{
862}
863
865{
866}
867
869{
870 return false;
871}
872
874 sal_uInt16 nPoolFormatId,
875 const SfxItemSet* pItemSet,
876 bool bFormatAll )
877 : m_sFormatNm(std::move(aColl)), m_nPoolId(nPoolFormatId), m_bFormatAll(bFormatAll)
878{
879 if( pItemSet && pItemSet->Count() )
880 m_pSet.reset( new SfxItemSet( *pItemSet ) );
881}
882
884{
885}
886
888{
890}
891
893{
894 SwDoc& rDoc = rPam.GetDoc();
895
896 // What about Undo? Is it turned off?
897 SwTextFormatColl* pColl = USHRT_MAX == m_nPoolId
900
903
904 SwPaM aPam( *rPam.GetMark(), *rPam.GetPoint() );
905
906 const SwPosition* pEnd = rPam.End();
907
908 if ( !m_bFormatAll || pEnd->GetContentIndex() == 0 )
909 {
910 // don't reject the format of the next paragraph (that is handled by the next redline)
911 if (aPam.GetPoint()->GetNode() > aPam.GetMark()->GetNode())
912 {
913 aPam.GetPoint()->Adjust(SwNodeOffset(-1));
914 SwContentNode* pNode = aPam.GetPoint()->GetNode().GetContentNode();
915 if ( pNode )
916 aPam.GetPoint()->SetContent( pNode->Len() );
917 else
918 // tdf#147507 set it back to a content node to avoid of crashing
919 aPam.GetPoint()->Adjust(SwNodeOffset(+1));
920 }
921 else if (aPam.GetPoint()->GetNode() < aPam.GetMark()->GetNode())
922 {
923 aPam.GetMark()->Adjust(SwNodeOffset(-1));
924 SwContentNode* pNode = aPam.GetMark()->GetNode().GetContentNode();
925 aPam.GetMark()->SetContent( pNode->Len() );
926 }
927 }
928
929 if( pColl )
930 rDoc.SetTextFormatColl( aPam, pColl, false );
931
932 if( m_pSet )
934
936}
937
939{
940 const SwRedlineExtraData_FormatColl& rCmp = static_cast<const SwRedlineExtraData_FormatColl&>(r);
941 return m_sFormatNm == rCmp.m_sFormatNm && m_nPoolId == rCmp.m_nPoolId &&
942 m_bFormatAll == rCmp.m_bFormatAll &&
943 ( ( !m_pSet && !rCmp.m_pSet ) ||
944 ( m_pSet && rCmp.m_pSet && *m_pSet == *rCmp.m_pSet ) );
945}
946
948{
949 if( rSet.Count() )
950 m_pSet.reset( new SfxItemSet( rSet ) );
951 else
952 m_pSet.reset();
953}
954
956{
957 SfxItemIter aIter( rSet );
958 for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
959 {
960 m_aWhichIds.push_back( pItem->Which() );
961 }
962}
963
965 const SwRedlineExtraData_Format& rCpy )
967{
968 m_aWhichIds.insert( m_aWhichIds.begin(), rCpy.m_aWhichIds.begin(), rCpy.m_aWhichIds.end() );
969}
970
972{
973}
974
976{
977 return new SwRedlineExtraData_Format( *this );
978}
979
981{
982 SwDoc& rDoc = rPam.GetDoc();
983
986
987 // Actually we need to reset the Attribute here!
988 for( const auto& rWhichId : m_aWhichIds )
989 {
992 }
993
995}
996
998{
999 const size_t nEnd = m_aWhichIds.size();
1000 if( nEnd != static_cast<const SwRedlineExtraData_Format&>(rCmp).m_aWhichIds.size() )
1001 return false;
1002
1003 for( size_t n = 0; n < nEnd; ++n )
1004 {
1005 if( static_cast<const SwRedlineExtraData_Format&>(rCmp).m_aWhichIds[n] != m_aWhichIds[n])
1006 {
1007 return false;
1008 }
1009 }
1010 return true;
1011}
1012
1014 : m_pNext( nullptr ), m_pExtraData( nullptr ),
1015 m_aStamp( DateTime::SYSTEM ),
1016 m_nAuthor( nAut ), m_eType( eT ), m_nSeqNo( 0 ), m_bAutoFormat(false), m_bMoved(false)
1017{
1018 m_aStamp.SetNanoSec( 0 );
1019}
1020
1022 const SwRedlineData& rCpy,
1023 bool bCpyNext )
1024 : m_pNext( ( bCpyNext && rCpy.m_pNext ) ? new SwRedlineData( *rCpy.m_pNext ) : nullptr )
1025 , m_pExtraData( rCpy.m_pExtraData ? rCpy.m_pExtraData->CreateNew() : nullptr )
1026 , m_sComment( rCpy.m_sComment )
1027 , m_aStamp( rCpy.m_aStamp )
1028 , m_nAuthor( rCpy.m_nAuthor )
1029 , m_eType( rCpy.m_eType )
1030 , m_nSeqNo( rCpy.m_nSeqNo )
1031 , m_bAutoFormat(false)
1032 , m_bMoved( rCpy.m_bMoved )
1033{
1034}
1035
1036// For sw3io: We now own pNext!
1037SwRedlineData::SwRedlineData(RedlineType eT, std::size_t nAut, const DateTime& rDT,
1038 OUString aCmnt, SwRedlineData *pNxt)
1039 : m_pNext(pNxt), m_pExtraData(nullptr), m_sComment(std::move(aCmnt)), m_aStamp(rDT),
1040 m_nAuthor(nAut), m_eType(eT), m_nSeqNo(0), m_bAutoFormat(false), m_bMoved(false)
1041{
1042}
1043
1045{
1046 delete m_pExtraData;
1047 delete m_pNext;
1048}
1049
1050// Check whether the absolute difference between the two dates is no larger than one minute (can
1051// give inaccurate results if at least one of the dates is not valid/normalized):
1052static bool deltaOneMinute(DateTime const & t1, DateTime const & t2) {
1053 auto const & [min, max] = std::minmax(t1, t2);
1054 // Avoid overflow of `min + tools::Time(0, 1)` below when min is close to the maximum valid
1055 // DateTime:
1056 if (min >= DateTime({31, 12, std::numeric_limits<sal_Int16>::max()}, {23, 59})) {
1057 return true;
1058 }
1059 return max <= min + tools::Time(0, 1);
1060}
1061
1063{
1064 return m_nAuthor == rCmp.m_nAuthor &&
1065 m_eType == rCmp.m_eType &&
1066 m_sComment == rCmp.m_sComment &&
1068 m_bMoved == rCmp.m_bMoved &&
1069 (( !m_pNext && !rCmp.m_pNext ) ||
1070 ( m_pNext && rCmp.m_pNext &&
1071 m_pNext->CanCombine( *rCmp.m_pNext ))) &&
1072 (( !m_pExtraData && !rCmp.m_pExtraData ) ||
1073 ( m_pExtraData && rCmp.m_pExtraData &&
1074 *m_pExtraData == *rCmp.m_pExtraData ));
1075}
1076
1080{
1081 delete m_pExtraData;
1082
1083 // Check if there is data - and if so - delete it
1084 if( pData )
1085 m_pExtraData = pData->CreateNew();
1086 else
1087 m_pExtraData = nullptr;
1088}
1089
1091{
1092 STR_UNDO_REDLINE_INSERT,
1093 STR_UNDO_REDLINE_DELETE,
1094 STR_UNDO_REDLINE_FORMAT,
1095 STR_UNDO_REDLINE_TABLE,
1096 STR_UNDO_REDLINE_FMTCOLL,
1097 STR_UNDO_REDLINE_PARAGRAPH_FORMAT,
1098 STR_UNDO_REDLINE_TABLE_ROW_INSERT,
1099 STR_UNDO_REDLINE_TABLE_ROW_DELETE,
1100 STR_UNDO_REDLINE_TABLE_CELL_INSERT,
1101 STR_UNDO_REDLINE_TABLE_CELL_DELETE
1102};
1103
1105{
1106 return SwResId(STR_REDLINE_ARY[static_cast<int>(GetType())]);
1107}
1108
1109sal_uInt32 SwRangeRedline::s_nLastId = 1;
1110
1112 : SwPaM( *rPam.GetMark(), *rPam.GetPoint() ),
1113 m_pRedlineData( new SwRedlineData( eTyp, GetDoc().getIDocumentRedlineAccess().GetRedlineAuthor() ) ),
1114 m_nId( s_nLastId++ )
1115{
1116 GetBound().SetRedline(this);
1117 GetBound(false).SetRedline(this);
1118
1119 m_bDelLastPara = false;
1120 m_bIsVisible = true;
1121 if( !rPam.HasMark() )
1122 DeleteMark();
1123
1124 // set default comment for single annotations added or deleted
1125 if ( IsAnnotation() )
1126 {
1127 SetComment( RedlineType::Delete == eTyp
1128 ? SwResId(STR_REDLINE_COMMENT_DELETED)
1129 : SwResId(STR_REDLINE_COMMENT_ADDED) );
1130 }
1131}
1132
1134 : SwPaM( *rPam.GetMark(), *rPam.GetPoint() ),
1135 m_pRedlineData( new SwRedlineData( rData )),
1136 m_nId( s_nLastId++ )
1137{
1138 GetBound().SetRedline(this);
1139 GetBound(false).SetRedline(this);
1140
1141 m_bDelLastPara = false;
1142 m_bIsVisible = true;
1143 if( !rPam.HasMark() )
1144 DeleteMark();
1145}
1146
1148 : SwPaM( rPos ),
1149 m_pRedlineData( new SwRedlineData( rData )),
1150 m_nId( s_nLastId++ )
1151{
1152 GetBound().SetRedline(this);
1153 GetBound(false).SetRedline(this);
1154
1155 m_bDelLastPara = false;
1156 m_bIsVisible = true;
1157}
1158
1160 : SwPaM( *rCpy.GetMark(), *rCpy.GetPoint() ),
1161 m_pRedlineData( new SwRedlineData( *rCpy.m_pRedlineData )),
1162 m_nId( s_nLastId++ )
1163{
1164 GetBound().SetRedline(this);
1165 GetBound(false).SetRedline(this);
1166
1167 m_bDelLastPara = false;
1168 m_bIsVisible = true;
1169 if( !rCpy.HasMark() )
1170 DeleteMark();
1171}
1172
1174{
1175 if( m_oContentSect )
1176 {
1177 // delete the ContentSection
1178 if( !GetDoc().IsInDtor() )
1180 m_oContentSect.reset();
1181 }
1182 delete m_pRedlineData;
1183}
1184
1186{
1187 if (!lcl_LOKRedlineNotificationEnabled())
1188 return;
1189
1190 const SwRedlineTable& rRedTable = rDoc.getIDocumentRedlineAccess().GetRedlineTable();
1191 for (SwRedlineTable::size_type i = 0; i < rRedTable.size(); ++i)
1192 {
1193 if (rRedTable[i] == &rRedline)
1194 {
1196 break;
1197 }
1198 }
1199}
1200
1202{
1203 if (!lcl_LOKRedlineNotificationEnabled())
1204 return;
1205
1206 if(!m_oLOKLastNodeTop || *m_oLOKLastNodeTop != nTop)
1207 {
1208 m_oLOKLastNodeTop = nTop;
1210 }
1211}
1212
1214{
1215 if( !pSttPtr ) pSttPtr = Start();
1216 *pSttPtr = rPos;
1217
1219}
1220
1221void SwRangeRedline::SetEnd( const SwPosition& rPos, SwPosition* pEndPtr )
1222{
1223 if( !pEndPtr ) pEndPtr = End();
1224 *pEndPtr = rPos;
1225
1227}
1228
1231{
1232 const SwNode* pPtNd = &GetPoint()->GetNode(),
1233 * pMkNd = &GetMark()->GetNode();
1234 if( pPtNd->StartOfSectionNode() == pMkNd->StartOfSectionNode() &&
1235 !pPtNd->StartOfSectionNode()->IsTableNode() &&
1236 // invalid if points on the end of content
1237 // end-of-content only invalid if no content index exists
1238 ( pPtNd != pMkNd || GetContentIdx() != nullptr ||
1239 pPtNd != &pPtNd->GetNodes().GetEndOfContent() )
1240 )
1241 return true;
1242 return false;
1243}
1244
1246{
1249 Show(0, nMyPos);
1250 else if (eShow == RedlineFlags::ShowInsert)
1251 Hide(0, nMyPos);
1252 else if (eShow == RedlineFlags::ShowDelete)
1253 ShowOriginal(0, nMyPos);
1254}
1255
1256void SwRangeRedline::Show(sal_uInt16 nLoop, size_t nMyPos, bool bForced)
1257{
1258 SwDoc& rDoc = GetDoc();
1259
1260 bool bIsShowChangesInMargin = false;
1261 if ( !bForced )
1262 {
1264 if (pSh)
1265 bIsShowChangesInMargin = pSh->GetViewOptions()->IsShowChangesInMargin();
1266 else
1267 bIsShowChangesInMargin = SW_MOD()->GetUsrPref(false)->IsShowChangesInMargin();
1268 }
1269
1270 if( 1 > nLoop && !bIsShowChangesInMargin )
1271 return;
1272
1275 ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
1276
1277 switch( GetType() )
1278 {
1279 case RedlineType::Insert: // Content has been inserted
1280 m_bIsVisible = true;
1281 MoveFromSection(nMyPos);
1282 break;
1283
1284 case RedlineType::Delete: // Content has been deleted
1285 m_bIsVisible = !bIsShowChangesInMargin;
1286
1287 if (m_bIsVisible)
1288 MoveFromSection(nMyPos);
1289 else
1290 {
1291 switch( nLoop )
1292 {
1293 case 0: MoveToSection(); break;
1294 case 1: CopyToSection(); break;
1295 case 2: DelCopyOfSection(nMyPos); break;
1296 }
1297 }
1298 break;
1299
1300 case RedlineType::Format: // Attributes have been applied
1301 case RedlineType::Table: // Table structure has been modified
1303 break;
1304 default:
1305 break;
1306 }
1308}
1309
1310void SwRangeRedline::Hide(sal_uInt16 nLoop, size_t nMyPos, bool /*bForced*/)
1311{
1312 SwDoc& rDoc = GetDoc();
1315 ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
1316
1317 switch( GetType() )
1318 {
1319 case RedlineType::Insert: // Content has been inserted
1320 m_bIsVisible = true;
1321 if( 1 <= nLoop )
1322 MoveFromSection(nMyPos);
1323 break;
1324
1325 case RedlineType::Delete: // Content has been deleted
1326 m_bIsVisible = false;
1327 switch( nLoop )
1328 {
1329 case 0: MoveToSection(); break;
1330 case 1: CopyToSection(); break;
1331 case 2: DelCopyOfSection(nMyPos); break;
1332 }
1333 break;
1334
1335 case RedlineType::Format: // Attributes have been applied
1336 case RedlineType::Table: // Table structure has been modified
1337 if( 1 <= nLoop )
1339 break;
1340 default:
1341 break;
1342 }
1344}
1345
1346void SwRangeRedline::ShowOriginal(sal_uInt16 nLoop, size_t nMyPos, bool /*bForced*/)
1347{
1348 SwDoc& rDoc = GetDoc();
1350 SwRedlineData* pCur;
1351
1353 ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
1354
1355 // Determine the Type, it's the first on Stack
1356 for( pCur = m_pRedlineData; pCur->m_pNext; )
1357 pCur = pCur->m_pNext;
1358
1359 switch( pCur->m_eType )
1360 {
1361 case RedlineType::Insert: // Content has been inserted
1362 m_bIsVisible = false;
1363 switch( nLoop )
1364 {
1365 case 0: MoveToSection(); break;
1366 case 1: CopyToSection(); break;
1367 case 2: DelCopyOfSection(nMyPos); break;
1368 }
1369 break;
1370
1371 case RedlineType::Delete: // Content has been deleted
1372 m_bIsVisible = true;
1373 if( 1 <= nLoop )
1374 MoveFromSection(nMyPos);
1375 break;
1376
1377 case RedlineType::Format: // Attributes have been applied
1378 case RedlineType::Table: // Table structure has been modified
1379 if( 1 <= nLoop )
1381 break;
1382 default:
1383 break;
1384 }
1386}
1387
1388// trigger the Layout
1390{
1391 auto [pRStt, pREnd] = StartEnd(); // SwPosition*
1392 SwNodeOffset nSttNd = pRStt->GetNodeIndex(),
1393 nEndNd = pREnd->GetNodeIndex();
1394 sal_Int32 nSttCnt = pRStt->GetContentIndex();
1395 sal_Int32 nEndCnt = pREnd->GetContentIndex();
1396
1397 SwNodes& rNds = GetDoc().GetNodes();
1398 for (SwNodeOffset n(nSttNd); n <= nEndNd; ++n)
1399 {
1400 SwNode* pNode = rNds[n];
1401
1402 if (pNode && pNode->IsTextNode())
1403 {
1404 SwTextNode* pNd = pNode->GetTextNode();
1405
1406 SwUpdateAttr aHt(
1407 n == nSttNd ? nSttCnt : 0,
1408 n == nEndNd ? nEndCnt : pNd->GetText().getLength(),
1409 RES_FMT_CHG);
1410
1411 pNd->TriggerNodeUpdate(sw::LegacyModifyHint(&aHt, &aHt));
1412
1413 // SwUpdateAttr must be handled first, otherwise indexes are off
1414 if (GetType() == RedlineType::Delete)
1415 {
1416 sal_Int32 const nStart(n == nSttNd ? nSttCnt : 0);
1417 sal_Int32 const nLen((n == nEndNd ? nEndCnt : pNd->GetText().getLength()) - nStart);
1418 if (eWhy == Invalidation::Add)
1419 {
1420 sw::RedlineDelText const hint(nStart, nLen);
1421 pNd->CallSwClientNotify(hint);
1422 }
1423 else
1424 {
1425 sw::RedlineUnDelText const hint(nStart, nLen);
1426 pNd->CallSwClientNotify(hint);
1427 }
1428 }
1429 }
1430 }
1431}
1432
1435void SwRangeRedline::CalcStartEnd( SwNodeOffset nNdIdx, sal_Int32& rStart, sal_Int32& rEnd ) const
1436{
1437 auto [pRStt, pREnd] = StartEnd(); // SwPosition*
1438 if( pRStt->GetNodeIndex() < nNdIdx )
1439 {
1440 if( pREnd->GetNodeIndex() > nNdIdx )
1441 {
1442 rStart = 0; // Paragraph is completely enclosed
1443 rEnd = COMPLETE_STRING;
1444 }
1445 else if (pREnd->GetNodeIndex() == nNdIdx)
1446 {
1447 rStart = 0; // Paragraph is overlapped in the beginning
1448 rEnd = pREnd->GetContentIndex();
1449 }
1450 else // redline ends before paragraph
1451 {
1452 rStart = COMPLETE_STRING;
1453 rEnd = COMPLETE_STRING;
1454 }
1455 }
1456 else if( pRStt->GetNodeIndex() == nNdIdx )
1457 {
1458 rStart = pRStt->GetContentIndex();
1459 if( pREnd->GetNodeIndex() == nNdIdx )
1460 rEnd = pREnd->GetContentIndex(); // Within the Paragraph
1461 else
1462 rEnd = COMPLETE_STRING; // Paragraph is overlapped in the end
1463 }
1464 else
1465 {
1466 rStart = COMPLETE_STRING;
1467 rEnd = COMPLETE_STRING;
1468 }
1469}
1470
1471static void lcl_storeAnnotationMarks(SwDoc& rDoc, const SwPosition* pStt, const SwPosition* pEnd)
1472{
1473 // tdf#115815 keep original start position of collapsed annotation ranges
1474 // as temporary bookmarks (removed after file saving and file loading)
1476 for (auto iter = rDMA.getAnnotationMarksBegin();
1477 iter != rDMA.getAnnotationMarksEnd(); )
1478 {
1479 SwPosition const& rStartPos((**iter).GetMarkStart());
1480 if ( *pStt <= rStartPos && rStartPos < *pEnd )
1481 {
1483 rDMA.findAnnotationBookmark((**iter).GetName());
1484 if ( pOldMark == rDMA.getBookmarksEnd() )
1485 {
1486 // at start of redlines use a 1-character length bookmark range
1487 // instead of a 0-character length bookmark position to avoid its losing
1488 sal_Int32 nLen = (*pStt == rStartPos) ? 1 : 0;
1489 SwPaM aPam( rStartPos.GetNode(), rStartPos.GetContentIndex(),
1490 rStartPos.GetNode(), rStartPos.GetContentIndex() + nLen);
1492 aPam,
1493 (**iter).GetName(),
1495 ::sw::mark::IBookmark* pBookmark = dynamic_cast< ::sw::mark::IBookmark* >(pMark);
1496 if (pBookmark)
1497 {
1498 pBookmark->SetKeyCode(vcl::KeyCode());
1499 pBookmark->SetShortName(OUString());
1500 }
1501 }
1502 }
1503 ++iter;
1504 }
1505}
1506
1508{
1509 if( !m_oContentSect )
1510 {
1511 auto [pStt, pEnd] = StartEnd(); // SwPosition*
1512
1513 SwDoc& rDoc = GetDoc();
1514 SwPaM aPam( *pStt, *pEnd );
1515 SwContentNode* pCSttNd = pStt->GetNode().GetContentNode();
1516 SwContentNode* pCEndNd = pEnd->GetNode().GetContentNode();
1517
1518 if( !pCSttNd )
1519 {
1520 // In order to not move other Redlines' indices, we set them
1521 // to the end (is exclusive)
1523 for(SwRangeRedline* pRedl : rTable)
1524 {
1525 if( pRedl->GetBound() == *pStt )
1526 pRedl->GetBound() = *pEnd;
1527 if( pRedl->GetBound(false) == *pStt )
1528 pRedl->GetBound(false) = *pEnd;
1529 }
1530 }
1531
1532 SwStartNode* pSttNd;
1533 SwNodes& rNds = rDoc.GetNodes();
1534 if( pCSttNd || pCEndNd )
1535 {
1536 SwTextFormatColl* pColl = (pCSttNd && pCSttNd->IsTextNode() )
1537 ? pCSttNd->GetTextNode()->GetTextColl()
1538 : (pCEndNd && pCEndNd->IsTextNode() )
1539 ? pCEndNd->GetTextNode()->GetTextColl()
1541
1542 pSttNd = rNds.MakeTextSection( rNds.GetEndOfRedlines(),
1543 SwNormalStartNode, pColl );
1544 SwTextNode* pTextNd = rNds[ pSttNd->GetIndex() + 1 ]->GetTextNode();
1545
1546 SwPosition aPos( *pTextNd );
1547 if( pCSttNd && pCEndNd )
1548 {
1549 // tdf#140982 keep annotation ranges in deletions in margin mode
1550 lcl_storeAnnotationMarks( rDoc, pStt, pEnd );
1551 rDoc.getIDocumentContentOperations().MoveAndJoin( aPam, aPos );
1552 }
1553 else
1554 {
1555 if( pCSttNd && !pCEndNd )
1556 m_bDelLastPara = true;
1557 rDoc.getIDocumentContentOperations().MoveRange( aPam, aPos,
1559 }
1560 }
1561 else
1562 {
1564
1565 SwPosition aPos( *pSttNd->EndOfSectionNode() );
1566 rDoc.getIDocumentContentOperations().MoveRange( aPam, aPos,
1568 }
1569 m_oContentSect.emplace( *pSttNd );
1570
1571 if( pStt == GetPoint() )
1572 Exchange();
1573
1574 DeleteMark();
1575 }
1576 else
1578}
1579
1581{
1582 if( m_oContentSect )
1583 return;
1584
1585 auto [pStt, pEnd] = StartEnd(); // SwPosition*
1586
1587 SwContentNode* pCSttNd = pStt->GetNode().GetContentNode();
1588 SwContentNode* pCEndNd = pEnd->GetNode().GetContentNode();
1589
1590 SwStartNode* pSttNd;
1591 SwDoc& rDoc = GetDoc();
1592 SwNodes& rNds = rDoc.GetNodes();
1593
1594 bool bSaveCopyFlag = rDoc.IsCopyIsMove(),
1595 bSaveRdlMoveFlg = rDoc.getIDocumentRedlineAccess().IsRedlineMove();
1596 rDoc.SetCopyIsMove( true );
1597
1598 // The IsRedlineMove() flag causes the behaviour of the
1599 // DocumentContentOperationsManager::CopyFlyInFlyImpl() method to change,
1600 // which will eventually be called by the CopyRange() below.
1602
1603 if( pCSttNd )
1604 {
1605 SwTextFormatColl* pColl = pCSttNd->IsTextNode()
1606 ? pCSttNd->GetTextNode()->GetTextColl()
1608
1609 pSttNd = rNds.MakeTextSection( rNds.GetEndOfRedlines(),
1610 SwNormalStartNode, pColl );
1611
1612 SwPosition aPos( *pSttNd, SwNodeOffset(1) );
1613
1614 // tdf#115815 keep original start position of collapsed annotation ranges
1615 // as temporary bookmarks (removed after file saving and file loading)
1616 lcl_storeAnnotationMarks( rDoc, pStt, pEnd );
1618
1619 // Take over the style from the EndNode if needed
1620 // We don't want this in Doc::Copy
1621 if( pCEndNd && pCEndNd != pCSttNd )
1622 {
1623 SwContentNode* pDestNd = aPos.GetNode().GetContentNode();
1624 if( pDestNd )
1625 {
1626 if( pDestNd->IsTextNode() && pCEndNd->IsTextNode() )
1627 pCEndNd->GetTextNode()->CopyCollFormat(*pDestNd->GetTextNode());
1628 else
1629 pDestNd->ChgFormatColl( pCEndNd->GetFormatColl() );
1630 }
1631 }
1632 }
1633 else
1634 {
1636
1637 if( pCEndNd )
1638 {
1639 SwPosition aPos( *pSttNd->EndOfSectionNode() );
1641 }
1642 else
1643 {
1644 SwNodeRange aRg( pStt->GetNode(), SwNodeOffset(0), pEnd->GetNode(), SwNodeOffset(1) );
1646 }
1647 }
1648 m_oContentSect.emplace( *pSttNd );
1649
1650 rDoc.SetCopyIsMove( bSaveCopyFlag );
1651 rDoc.getIDocumentRedlineAccess().SetRedlineMove( bSaveRdlMoveFlg );
1652}
1653
1655{
1656 if( !m_oContentSect )
1657 return;
1658
1659 auto [pStt, pEnd] = StartEnd(); // SwPosition*
1660
1661 SwDoc& rDoc = GetDoc();
1662 SwPaM aPam( *pStt, *pEnd );
1663 SwContentNode* pCSttNd = pStt->GetNode().GetContentNode();
1664 SwContentNode* pCEndNd = pEnd->GetNode().GetContentNode();
1665
1666 if( !pCSttNd )
1667 {
1668 // In order to not move other Redlines' indices, we set them
1669 // to the end (is exclusive)
1671 for(SwRangeRedline* pRedl : rTable)
1672 {
1673 if( pRedl->GetBound() == *pStt )
1674 pRedl->GetBound() = *pEnd;
1675 if( pRedl->GetBound(false) == *pStt )
1676 pRedl->GetBound(false) = *pEnd;
1677 }
1678 }
1679
1680 if( pCSttNd && pCEndNd )
1681 {
1682 // #i100466# - force a <join next> on <delete and join> operation
1683 // tdf#125319 - rather not?
1684 rDoc.getIDocumentContentOperations().DeleteAndJoin(aPam/*, true*/);
1685 }
1686 else if( pCSttNd || pCEndNd )
1687 {
1688 if( pCSttNd && !pCEndNd )
1689 m_bDelLastPara = true;
1691
1692 if( m_bDelLastPara )
1693 {
1694 // To prevent dangling references to the paragraph to
1695 // be deleted, redline that point into this paragraph should be
1696 // moved to the new end position. Since redlines in the redline
1697 // table are sorted and the pEnd position is an endnode (see
1698 // bDelLastPara condition above), only redlines before the
1699 // current ones can be affected.
1701 size_t n = nMyPos;
1702 for( bool bBreak = false; !bBreak && n > 0; )
1703 {
1704 --n;
1705 bBreak = true;
1706 if( rTable[ n ]->GetBound() == *aPam.GetPoint() )
1707 {
1708 rTable[ n ]->GetBound() = *pEnd;
1709 bBreak = false;
1710 }
1711 if( rTable[ n ]->GetBound(false) == *aPam.GetPoint() )
1712 {
1713 rTable[ n ]->GetBound(false) = *pEnd;
1714 bBreak = false;
1715 }
1716 }
1717
1718 *GetPoint() = *pEnd;
1719 *GetMark() = *pEnd;
1720 DeleteMark();
1721
1722 aPam.DeleteMark();
1723 aPam.GetPoint()->SetContent(0);;
1725 }
1726 }
1727 else
1728 {
1730 }
1731
1732 if( pStt == GetPoint() )
1733 Exchange();
1734
1735 DeleteMark();
1736}
1737
1739{
1740 if( m_oContentSect )
1741 {
1742 SwDoc& rDoc = GetDoc();
1744 std::vector<SwPosition*> aBeforeArr, aBehindArr;
1745 bool bBreak = false;
1747
1748 for( n = nMyPos+1; !bBreak && n < rTable.size(); ++n )
1749 {
1750 bBreak = true;
1751 if( rTable[ n ]->GetBound() == *GetPoint() )
1752 {
1753 SwRangeRedline* pRedl = rTable[n];
1754 aBehindArr.push_back(&pRedl->GetBound());
1755 bBreak = false;
1756 }
1757 if( rTable[ n ]->GetBound(false) == *GetPoint() )
1758 {
1759 SwRangeRedline* pRedl = rTable[n];
1760 aBehindArr.push_back(&pRedl->GetBound(false));
1761 bBreak = false;
1762 }
1763 }
1764 for( bBreak = false, n = nMyPos; !bBreak && n ; )
1765 {
1766 --n;
1767 bBreak = true;
1768 if( rTable[ n ]->GetBound() == *GetPoint() )
1769 {
1770 SwRangeRedline* pRedl = rTable[n];
1771 aBeforeArr.push_back(&pRedl->GetBound());
1772 bBreak = false;
1773 }
1774 if( rTable[ n ]->GetBound(false) == *GetPoint() )
1775 {
1776 SwRangeRedline* pRedl = rTable[n];
1777 aBeforeArr.push_back(&pRedl->GetBound(false));
1778 bBreak = false;
1779 }
1780 }
1781
1782 const SwNode* pKeptContentSectNode( &m_oContentSect->GetNode() ); // #i95711#
1783 {
1784 SwPaM aPam( m_oContentSect->GetNode(),
1785 *m_oContentSect->GetNode().EndOfSectionNode(), SwNodeOffset(1),
1786 SwNodeOffset( m_bDelLastPara ? -2 : -1 ) );
1787 SwContentNode* pCNd = aPam.GetPointContentNode();
1788 if( pCNd )
1789 aPam.GetPoint()->SetContent( pCNd->Len() );
1790 else
1791 aPam.GetPoint()->Adjust(SwNodeOffset(+1));
1792
1793 SwFormatColl* pColl = pCNd && pCNd->Len() && aPam.GetPoint()->GetNode() !=
1794 aPam.GetMark()->GetNode()
1795 ? pCNd->GetFormatColl() : nullptr;
1796
1797 SwNodeIndex aNdIdx( GetPoint()->GetNode(), -1 );
1798 const sal_Int32 nPos = GetPoint()->GetContentIndex();
1799
1800 SwPosition aPos( *GetPoint() );
1801 if( m_bDelLastPara && *aPam.GetPoint() == *aPam.GetMark() )
1802 {
1803 aPos.Adjust(SwNodeOffset(-1));
1804
1806 }
1807 else
1808 {
1809 rDoc.getIDocumentContentOperations().MoveRange( aPam, aPos,
1811 }
1812
1813 SetMark();
1814 *GetPoint() = aPos;
1815 GetMark()->Assign(aNdIdx.GetIndex() + 1);
1816 pCNd = GetMark()->GetNode().GetContentNode();
1817 if( pCNd )
1818 GetMark()->SetContent( nPos );
1819
1820 if( m_bDelLastPara )
1821 {
1823 pCNd = GetPointContentNode();
1824 m_bDelLastPara = false;
1825 }
1826 else if( pColl )
1827 pCNd = GetPointContentNode();
1828
1829 if( pColl && pCNd )
1830 pCNd->ChgFormatColl( pColl );
1831 }
1832
1833 // #i95771#
1834 // Under certain conditions the previous <SwDoc::Move(..)> has already
1835 // removed the change tracking section of this <SwRangeRedline> instance from
1836 // the change tracking nodes area.
1837 // Thus, check if <pContentSect> still points to the change tracking section
1838 // by comparing it with the "indexed" <SwNode> instance copied before
1839 // perform the intrinsic move.
1840 // Note: Such condition is e.g. a "delete" change tracking only containing a table.
1841 if ( &m_oContentSect->GetNode() == pKeptContentSectNode )
1842 {
1844 }
1845 m_oContentSect.reset();
1846
1847 // adjustment of redline table positions must take start and
1848 // end into account, not point and mark.
1849 for( auto& pItem : aBeforeArr )
1850 *pItem = *Start();
1851 for( auto& pItem : aBehindArr )
1852 *pItem = *End();
1853 }
1854 else
1856}
1857
1858// for Undo
1860{
1861 if( !m_oContentSect )
1862 {
1863 m_oContentSect = rIdx;
1864 m_bIsVisible = false;
1865 }
1866 else
1867 {
1868 OSL_FAIL("SwRangeRedline::SetContentIdx: invalid state");
1869 }
1870}
1871
1872// for Undo
1874{
1875 if( m_oContentSect )
1876 {
1877 m_oContentSect.reset();
1878 }
1879 else
1880 {
1881 OSL_FAIL("SwRangeRedline::ClearContentIdx: invalid state");
1882 }
1883}
1884
1886{
1887 return IsVisible() && rRedl.IsVisible() &&
1889}
1890
1891void SwRangeRedline::PushData( const SwRangeRedline& rRedl, bool bOwnAsNext )
1892{
1893 SwRedlineData* pNew = new SwRedlineData( *rRedl.m_pRedlineData, false );
1894 if( bOwnAsNext )
1895 {
1896 pNew->m_pNext = m_pRedlineData;
1897 m_pRedlineData = pNew;
1898 }
1899 else
1900 {
1902 m_pRedlineData->m_pNext = pNew;
1903 }
1904}
1905
1907{
1908 if( !m_pRedlineData->m_pNext )
1909 return false;
1911 m_pRedlineData = pCur->m_pNext;
1912 pCur->m_pNext = nullptr;
1913 delete pCur;
1914 return true;
1915}
1916
1918{
1919 sal_uInt16 nRet = 1;
1920 for( SwRedlineData* pCur = m_pRedlineData; pCur->m_pNext; pCur = pCur->m_pNext )
1921 ++nRet;
1922 return nRet;
1923}
1924
1925std::size_t SwRangeRedline::GetAuthor( sal_uInt16 nPos ) const
1926{
1928}
1929
1930OUString const & SwRangeRedline::GetAuthorString( sal_uInt16 nPos ) const
1931{
1932 return SW_MOD()->GetRedlineAuthor(GetRedlineData(nPos).m_nAuthor);
1933}
1934
1935const DateTime& SwRangeRedline::GetTimeStamp( sal_uInt16 nPos ) const
1936{
1938}
1939
1940RedlineType SwRangeRedline::GetType( sal_uInt16 nPos ) const
1941{
1942 return GetRedlineData(nPos).m_eType;
1943}
1944
1946{
1947 return GetText().getLength() == 1 && GetText()[0] == CH_TXTATR_INWORD;
1948}
1949
1950const OUString& SwRangeRedline::GetComment( sal_uInt16 nPos ) const
1951{
1953}
1954
1956{
1957 if (*Start() < *rCmp.Start())
1958 return true;
1959
1960 return *Start() == *rCmp.Start() && *End() < *rCmp.End();
1961}
1962
1963const SwRedlineData & SwRangeRedline::GetRedlineData(const sal_uInt16 nPos) const
1964{
1966
1967 sal_uInt16 nP = nPos;
1968
1969 while (nP > 0 && nullptr != pCur->m_pNext)
1970 {
1971 pCur = pCur->m_pNext;
1972
1973 nP--;
1974 }
1975
1976 SAL_WARN_IF( nP != 0, "sw.core", "Pos " << nPos << " is " << nP << " too big");
1977
1978 return *pCur;
1979}
1980
1981OUString SwRangeRedline::GetDescr(bool bSimplified)
1982{
1983 // get description of redline data (e.g.: "insert $1")
1984 OUString aResult = GetRedlineData().GetDescr();
1985
1986 SwPaM * pPaM = nullptr;
1987 bool bDeletePaM = false;
1988
1989 // if this redline is visible the content is in this PaM
1990 if (!m_oContentSect.has_value())
1991 {
1992 pPaM = this;
1993 }
1994 else // otherwise it is saved in pContentSect
1995 {
1996 pPaM = new SwPaM( m_oContentSect->GetNode(), *m_oContentSect->GetNode().EndOfSectionNode() );
1997 bDeletePaM = true;
1998 }
1999
2000 OUString sDescr = DenoteSpecialCharacters(pPaM->GetText().replace('\n', ' '), /*bQuoted=*/!bSimplified);
2001 if (const SwTextNode *pTextNode = pPaM->GetPointNode().GetTextNode())
2002 {
2003 if (const SwTextAttr* pTextAttr = pTextNode->GetFieldTextAttrAt(pPaM->GetPoint()->GetContentIndex() - 1, ::sw::GetTextAttrMode::Default))
2004 {
2005 sDescr = ( bSimplified ? "" : SwResId(STR_START_QUOTE) )
2006 + pTextAttr->GetFormatField().GetField()->GetFieldName()
2007 + ( bSimplified ? "" : SwResId(STR_END_QUOTE) );
2008 }
2009 }
2010
2011 // replace $1 in description by description of the redlines text
2012 const OUString aTmpStr = ShortenString(sDescr, nUndoStringLength, SwResId(STR_LDOTS));
2013
2014 if (!bSimplified)
2015 {
2016 SwRewriter aRewriter;
2017 aRewriter.AddRule(UndoArg1, aTmpStr);
2018
2019 aResult = aRewriter.Apply(aResult);
2020 }
2021 else
2022 {
2023 aResult = aTmpStr;
2024 // more shortening
2025 sal_Int32 nPos = aTmpStr.indexOf(SwResId(STR_LDOTS));
2026 if (nPos > 5)
2027 aResult = aTmpStr.copy(0, nPos + SwResId(STR_LDOTS).getLength());
2028 }
2029
2030 if (bDeletePaM)
2031 delete pPaM;
2032
2033 return aResult;
2034}
2035
2037{
2038 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwRangeRedline"));
2039
2040 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
2041 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("id"), BAD_CAST(OString::number(GetSeqNo()).getStr()));
2042 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("author"), BAD_CAST(SW_MOD()->GetRedlineAuthor(GetAuthor()).toUtf8().getStr()));
2043 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("date"), BAD_CAST(DateTimeToOString(GetTimeStamp()).getStr()));
2044 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("descr"), BAD_CAST(const_cast<SwRangeRedline*>(this)->GetDescr().toUtf8().getStr()));
2045
2046 OString sRedlineType;
2047 switch (GetType())
2048 {
2049 case RedlineType::Insert:
2050 sRedlineType = "REDLINE_INSERT";
2051 break;
2052 case RedlineType::Delete:
2053 sRedlineType = "REDLINE_DELETE";
2054 break;
2055 case RedlineType::Format:
2056 sRedlineType = "REDLINE_FORMAT";
2057 break;
2058 default:
2059 sRedlineType = "UNKNOWN";
2060 break;
2061 }
2062 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("type"), BAD_CAST(sRedlineType.getStr()));
2063
2064 SwPaM::dumpAsXml(pWriter);
2065
2066 (void)xmlTextWriterEndElement(pWriter);
2067}
2068
2070{
2071 m_aExtraRedlines.push_back( p );
2072 //p->CallDisplayFunc();
2073}
2074
2075void SwExtraRedlineTable::DeleteAndDestroy(sal_uInt16 const nPos)
2076{
2077 /*
2078 SwDoc* pDoc = 0;
2079 if( !nP && nL && nL == size() )
2080 pDoc = front()->GetDoc();
2081 */
2082
2083 delete m_aExtraRedlines[nPos];
2084 m_aExtraRedlines.erase(m_aExtraRedlines.begin() + nPos);
2085
2086 /*
2087 SwViewShell* pSh;
2088 if( pDoc && !pDoc->IsInDtor() &&
2089 0 != ( pSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() ) )
2090 pSh->InvalidateWindows( SwRect( 0, 0, SAL_MAX_INT32, SAL_MAX_INT32 ) );
2091 */
2092}
2093
2095{
2096 while (!m_aExtraRedlines.empty())
2097 {
2098 auto const pRedline = m_aExtraRedlines.back();
2099 m_aExtraRedlines.pop_back();
2100 delete pRedline;
2101 }
2102}
2103
2105{
2106}
2107
2109 : m_aRedlineData(rData)
2110 , m_rTableLine(rTableLine)
2111{
2112}
2113
2115{
2116}
2117
2119 : m_aRedlineData(rData)
2120 , m_rTableBox(rTableBox)
2121{
2122}
2123
2125{
2126}
2127
2128/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@ CheckPosInFly
check if target position is in fly anchored at source range
@ ShowDelete
show all deletes
@ On
RedlineFlags on.
@ ShowInsert
show all inserts
@ Ignore
ignore Redlines
OUString SwRedlineTypeToOUString(RedlineType eType)
@ UndoArg1
Definition: SwRewriter.hxx:29
OUString DenoteSpecialCharacters(std::u16string_view aStr, bool bQuoted=true)
Denotes special characters in a string.
Definition: undel.cxx:716
OUString ShortenString(const OUString &rStr, sal_Int32 nLength, std::u16string_view aFillStr)
Shortens a string to a maximum length.
Definition: undobj.cxx:1558
const int nUndoStringLength
Definition: UndoCore.hxx:243
css::util::DateTime GetUNODateTime() const
virtual bool MoveRange(SwPaM &, SwPosition &, SwMoveFlags)=0
virtual bool AppendTextNode(SwPosition &rPos)=0
virtual bool DeleteAndJoin(SwPaM &, SwDeleteFlags flags=SwDeleteFlags::Default)=0
complete delete of a given PaM
virtual bool CopyRange(SwPaM &rPam, SwPosition &rPos, SwCopyFlags flags) const =0
Copy a selected content range to a position.
virtual void DeleteSection(SwNode *pNode)=0
Delete section containing the node.
virtual void DeleteRange(SwPaM &)=0
Delete a range SwFlyFrameFormat.
virtual bool DelFullPara(SwPaM &)=0
Delete full paragraphs.
virtual void MoveAndJoin(SwPaM &, SwPosition &)=0
Move a range.
virtual void InsertItemSet(const SwPaM &rRg, const SfxItemSet &, const SetAttrMode nFlags=SetAttrMode::DEFAULT, SwRootFrame const *pLayout=nullptr)=0
virtual bool InsertPoolItem(const SwPaM &rRg, const SfxPoolItem &, const SetAttrMode nFlags=SetAttrMode::DEFAULT, SwRootFrame const *pLayout=nullptr, SwTextAttr **ppNewTextAttr=nullptr)=0
Insert an attribute.
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
wrapper iterator: wraps iterator of implementation while hiding MarkBase class; only IMark instances ...
Provides access to the marks of a document.
virtual const_iterator_t getAnnotationMarksEnd() const =0
virtual ::sw::mark::IMark * makeAnnotationBookmark(const SwPaM &rPaM, const OUString &rProposedName, MarkType eMark, ::sw::mark::InsertMode eMode, SwPosition const *pSepPos=nullptr)=0
virtual const_iterator_t getAnnotationMarksBegin() const =0
virtual const_iterator_t findAnnotationBookmark(const OUString &rName) const =0
virtual const_iterator_t getBookmarksEnd() const =0
returns a STL-like random access iterator to the end of the sequence of IBookmarks.
virtual bool IsRedlineMove() const =0
virtual void SetRedlineMove(bool bFlag)=0
virtual void SetRedlineFlags_intern(RedlineFlags eMode)=0
Set a new redline mode.
virtual const SwRedlineTable & GetRedlineTable() const =0
virtual RedlineFlags GetRedlineFlags() const =0
Query the currently set redline mode.
virtual void SetModified()=0
Must be called manually at changes of format.
virtual SwTextFormatColl * GetTextCollFromPool(sal_uInt16 nId, bool bRegardLanguage=true)=0
Return "Auto-Collection with ID.
const SfxPoolItem * GetCurItem() const
const SfxPoolItem * NextItem()
sal_uInt16 Count() const
ViewShellDocId GetDocId() const override
static SAL_WARN_UNUSED_RESULT SfxViewShell * GetNext(const SfxViewShell &rPrev, bool bOnlyVisible=true, const std::function< bool(const SfxViewShell *)> &isViewShell=nullptr)
static SAL_WARN_UNUSED_RESULT SfxViewShell * GetFirst(bool bOnlyVisible=true, const std::function< bool(const SfxViewShell *)> &isViewShell=nullptr)
static SAL_WARN_UNUSED_RESULT SfxViewShell * Current()
virtual void libreOfficeKitViewCallback(int nType, const char *pPayload) const override
SwFormatColl * GetFormatColl() const
Definition: node.hxx:497
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1225
virtual sal_Int32 Len() const
Definition: node.cxx:1258
virtual SwFormatColl * ChgFormatColl(SwFormatColl *)
Definition: node.cxx:1260
SwRect FindLayoutRect(const bool bPrtArea=false, const Point *pPoint=nullptr) const
Definition: node.cxx:1233
Definition: doc.hxx:195
bool IsCopyIsMove() const
Definition: doc.hxx:1384
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:402
void SetCopyIsMove(bool bFlag)
Definition: doc.hxx:1385
bool IsInDtor() const
Definition: doc.hxx:415
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:323
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:152
SwNodes & GetNodes()
Definition: doc.hxx:420
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:343
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:413
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1877
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:434
::sw::DocumentContentOperationsManager const & GetDocumentContentOperationsManager() const
Definition: doc.cxx:333
SwTextFormatColl * FindTextFormatCollByName(const OUString &rName) const
Definition: doc.hxx:810
bool SetTextFormatColl(const SwPaM &rRg, SwTextFormatColl *pFormat, const bool bReset=true, const bool bResetListAttrs=false, SwRootFrame const *pLayout=nullptr)
Add 4th optional parameter <bResetListAttrs>.
Definition: docfmt.cxx:1081
void Insert(SwExtraRedline *p)
Definition: docredln.cxx:2069
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: docredln.cxx:95
std::vector< SwExtraRedline * > m_aExtraRedlines
Definition: docary.hxx:284
void DeleteAndDestroyAll()
Definition: docredln.cxx:2094
bool DeleteTableRowRedline(SwDoc *pDoc, const SwTableLine &rTableLine, bool bSaveInUndo, RedlineType nRedlineTypeToDelete)
Definition: docredln.cxx:190
bool DeleteTableCellRedline(SwDoc *pDoc, const SwTableBox &rTableBox, bool bSaveInUndo, RedlineType nRedlineTypeToDelete)
Definition: docredln.cxx:234
SW_DLLPUBLIC bool DeleteAllTableRedlines(SwDoc &rDoc, const SwTable &rTable, bool bSaveInUndo, RedlineType nRedlineTypeToDelete)
Definition: docredln.cxx:139
void DeleteAndDestroy(sal_uInt16 nPos)
Definition: docredln.cxx:2075
sal_uInt16 GetSize() const
Definition: docary.hxx:296
SwExtraRedline * GetRedline(sal_uInt16 uIndex) const
Definition: docary.hxx:297
Base object for 'Redlines' that are not of 'Ranged' type (like table row insert\delete)
Definition: redline.hxx:289
virtual ~SwExtraRedline()
Definition: docredln.cxx:2104
SwFormatColl is just an SwFormat subclass that defaults to m_bAutoFormat=false, expressing that this ...
Definition: fmtcol.hxx:38
Base class of the Writer layout elements.
Definition: frame.hxx:315
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNode & GetNode() const
Definition: ndindex.hxx:123
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:111
Base class of the Writer document model elements.
Definition: node.hxx:98
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:903
SwNodeOffset GetIndex() const
Definition: node.hxx:312
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:744
bool IsContentNode() const
Definition: node.hxx:679
bool IsStartNode() const
Definition: node.hxx:675
bool IsSectionNode() const
Definition: node.hxx:695
bool IsTableNode() const
Definition: node.hxx:691
bool IsTextNode() const
Definition: node.hxx:687
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:380
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:153
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:728
SwContentNode * GetContentNode()
Definition: node.hxx:666
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:733
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:165
static SwStartNode * MakeEmptySection(SwNode &rWhere, SwStartNodeType=SwNormalStartNode)
Create an empty section of Start- and EndNote.
Definition: nodes.cxx:1917
SwStartNode * MakeTextSection(const SwNode &rWhere, SwStartNodeType eSttNdTyp, SwTextFormatColl *pColl)
Definition: nodes.cxx:1925
SwNode & GetEndOfRedlines() const
Section for all Redlines.
Definition: ndarr.hxx:160
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1299
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:187
const SwPosition * GetMark() const
Definition: pam.hxx:263
SwNode & GetPointNode() const
Definition: pam.hxx:283
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: pam.cxx:1357
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:642
void Exchange()
Definition: pam.cxx:656
std::pair< const SwPosition *, const SwPosition * > StartEnd() const
Because sometimes the cost of the operator<= can add up.
Definition: pam.hxx:277
SwContentNode * GetPointContentNode() const
Definition: pam.hxx:287
const SwPosition * End() const
Definition: pam.hxx:271
SwPaM(SwPaM const &rPaM)=delete
SwDoc & GetDoc() const
Definition: pam.hxx:299
OUString GetText() const
Definition: pam.cxx:1282
SwPosition & GetBound(bool bOne=true)
Definition: pam.hxx:301
void DeleteMark()
Definition: pam.hxx:231
const SwPosition * GetPoint() const
Definition: pam.hxx:261
const SwPosition * Start() const
Definition: pam.hxx:266
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:259
void CallDisplayFunc(size_t nMyPos)
Definition: docredln.cxx:1245
void CopyToSection()
Definition: docredln.cxx:1580
sal_uInt32 GetId() const
Definition: redline.hxx:194
void Show(sal_uInt16 nLoop, size_t nMyPos, bool bForced=false)
Definition: docredln.cxx:1256
void InvalidateRange(Invalidation)
Initiate the layout.
Definition: docredln.cxx:1389
void ClearContentIdx()
Definition: docredln.cxx:1873
const OUString & GetComment(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1950
sal_uInt16 GetStackCount() const
Definition: docredln.cxx:1917
static sal_uInt32 s_nLastId
Definition: redline.hxx:177
void MaybeNotifyRedlinePositionModification(tools::Long nTop)
Definition: docredln.cxx:1201
std::size_t GetAuthor(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1925
const SwNodeIndex * GetContentIdx() const
Definition: redline.hxx:195
void DelCopyOfSection(size_t nMyPos)
Definition: docredln.cxx:1654
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:200
void Hide(sal_uInt16 nLoop, size_t nMyPos, bool bForced=false)
Definition: docredln.cxx:1310
bool operator<(const SwRangeRedline &) const
Definition: docredln.cxx:1955
bool m_bDelLastPara
Definition: redline.hxx:168
std::optional< SwNodeIndex > m_oContentSect
Definition: redline.hxx:165
OUString const & GetAuthorString(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1930
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: docredln.cxx:2036
bool IsAnnotation() const
Definition: docredln.cxx:1945
virtual ~SwRangeRedline() override
Definition: docredln.cxx:1173
OUString GetDescr(bool bSimplified=false)
Returns textual description of a redline data element of this redline.
Definition: docredln.cxx:1981
void SetStart(const SwPosition &rPos, SwPosition *pSttPtr=nullptr)
Definition: docredln.cxx:1213
void SetEnd(const SwPosition &rPos, SwPosition *pEndPtr=nullptr)
Definition: docredln.cxx:1221
void ShowOriginal(sal_uInt16 nLoop, size_t nMyPos, bool bForced=false)
Definition: docredln.cxx:1346
const DateTime & GetTimeStamp(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1935
void SetMoved()
Definition: redline.hxx:281
bool HasValidRange() const
Do we have a valid selection?
Definition: docredln.cxx:1230
std::optional< tools::Long > m_oLOKLastNodeTop
Definition: redline.hxx:166
void SetContentIdx(const SwNodeIndex &)
Definition: docredln.cxx:1859
void PushData(const SwRangeRedline &rRedl, bool bOwnAsNext=true)
Definition: docredln.cxx:1891
void MoveToSection()
Definition: docredln.cxx:1507
void SetComment(const OUString &rS)
Definition: redline.hxx:225
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1940
SwRedlineData * m_pRedlineData
Definition: redline.hxx:164
bool CanCombine(const SwRangeRedline &rRedl) const
Definition: docredln.cxx:1885
void MoveFromSection(size_t nMyPos)
Definition: docredln.cxx:1738
const SwRedlineData & GetRedlineData(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1963
bool m_bIsVisible
Definition: redline.hxx:169
sal_uInt16 GetSeqNo() const
Definition: redline.hxx:237
SwRangeRedline(RedlineType eType, const SwPaM &rPam)
Definition: docredln.cxx:1111
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
std::size_t m_nAuthor
Definition: redline.hxx:94
SwRedlineData * m_pNext
Definition: redline.hxx:89
DateTime m_aStamp
Definition: redline.hxx:93
SwRedlineExtraData * m_pExtraData
Definition: redline.hxx:90
OUString GetDescr() const
Definition: docredln.cxx:1104
RedlineType m_eType
Definition: redline.hxx:95
OUString m_sComment
Definition: redline.hxx:92
bool CanCombine(const SwRedlineData &rCmp) const
Definition: docredln.cxx:1062
SwRedlineData(RedlineType eT, std::size_t nAut)
Definition: docredln.cxx:1013
bool m_bMoved
Definition: redline.hxx:98
const OUString & GetComment() const
Definition: redline.hxx:129
void SetExtraData(const SwRedlineExtraData *pData)
ExtraData is copied.
Definition: docredln.cxx:1079
const DateTime & GetTimeStamp() const
Definition: redline.hxx:130
RedlineType GetType() const
Definition: redline.hxx:126
void SetItemSet(const SfxItemSet &rSet)
Definition: docredln.cxx:947
virtual bool operator==(const SwRedlineExtraData &) const override
Definition: docredln.cxx:938
SwRedlineExtraData_FormatColl(OUString aColl, sal_uInt16 nPoolFormatId, const SfxItemSet *pSet=nullptr, bool bFormatAll=true)
Definition: docredln.cxx:873
virtual void Reject(SwPaM &rPam) const override
Definition: docredln.cxx:892
std::unique_ptr< SfxItemSet > m_pSet
Definition: redline.hxx:55
virtual SwRedlineExtraData * CreateNew() const override
Definition: docredln.cxx:887
virtual ~SwRedlineExtraData_FormatColl() override
Definition: docredln.cxx:883
virtual ~SwRedlineExtraData_Format() override
Definition: docredln.cxx:971
virtual SwRedlineExtraData * CreateNew() const override
Definition: docredln.cxx:975
virtual bool operator==(const SwRedlineExtraData &) const override
Definition: docredln.cxx:997
virtual void Reject(SwPaM &rPam) const override
Definition: docredln.cxx:980
std::vector< sal_uInt16 > m_aWhichIds
Definition: redline.hxx:74
SwRedlineExtraData_Format(const SwRedlineExtraData_Format &rCpy)
Definition: docredln.cxx:964
virtual void Reject(SwPaM &rPam) const
Definition: docredln.cxx:864
virtual ~SwRedlineExtraData()
Definition: docredln.cxx:860
virtual bool operator==(const SwRedlineExtraData &) const
Definition: docredln.cxx:868
void CheckOverlapping(vector_type::const_iterator it)
Definition: docredln.cxx:441
size_type FindNextSeqNo(sal_uInt16 nSeqNo, size_type nSttPos) const
Search next or previous Redline with the same Seq.
Definition: docredln.cxx:686
bool InsertWithValidRanges(SwRangeRedline *&p, size_type *pInsPos=nullptr)
Definition: docredln.cxx:584
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: docredln.cxx:849
size_type FindPrevOfSeqNo(size_type nSttPos) const
Definition: docredln.cxx:678
vector_type maVector
Definition: docary.hxx:225
size_type FindPrevSeqNo(sal_uInt16 nSeqNo, size_type nSttPos) const
Definition: docredln.cxx:709
size_type FindNextOfSeqNo(size_type nSttPos) const
Definition: docredln.cxx:671
bool isMoved(size_type tableIndex) const
Definition: docredln.cxx:756
bool Insert(SwRangeRedline *&p)
Definition: docredln.cxx:415
static void LOKRedlineNotification(RedlineNotification eType, SwRangeRedline *pRedline)
Emits LOK notification about one addition / removal of a redline item.
Definition: docredln.cxx:343
bool m_bHasOverlappingElements
Sometimes we load bad data, and we need to know if we can use fast binary search, or if we have to fa...
Definition: docary.hxx:228
void DeleteAndDestroy(size_type nPos)
Definition: docredln.cxx:663
static constexpr size_type npos
Definition: docary.hxx:223
size_type size() const
Definition: docary.hxx:267
vector_type::const_iterator begin() const
Definition: docary.hxx:269
void Remove(size_type nPos)
Definition: docredln.cxx:634
vector_type::size_type size_type
Definition: docary.hxx:222
void DeleteAndDestroyAll()
Definition: docredln.cxx:651
size_type GetPos(const SwRangeRedline *p) const
Definition: docredln.cxx:618
const SwRangeRedline * FindAtPosition(const SwPosition &startPosition, size_type &tableIndex, bool next=true) const
Find the redline at the given position.
Definition: docredln.cxx:730
void AddRule(SwUndoArg eWhat, const OUString &rWith)
Definition: SwRewriter.cxx:25
OUString Apply(const OUString &rStr) const
Definition: SwRewriter.cxx:39
The root element of a Writer document layout.
Definition: rootfrm.hxx:83
const SwCursorShell * GetShell() const
Definition: viscrs.hxx:127
Represents the current text cursor of one opened edit window.
Definition: viscrs.hxx:140
virtual void FillRects() override
Definition: viscrs.cxx:948
const Point & GetEndPos() const
Definition: viscrs.hxx:171
const Point & GetSttPos() const
Definition: viscrs.hxx:169
virtual void SetMark() override
Unless this is called, the getter method of Mark will return Point.
Definition: viscrs.cxx:939
Starts a section of nodes in the document model.
Definition: node.hxx:348
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:436
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:488
Redline that holds information about a table-cell that had some change.
Definition: redline.hxx:321
virtual ~SwTableCellRedline() override
Definition: docredln.cxx:2124
SwTableCellRedline(const SwRedlineData &rData, const SwTableBox &rTableBox)
Definition: docredln.cxx:2118
const SwTableBox & GetTableBox() const
Definition: redline.hxx:334
const SwRedlineData & GetRedlineData() const
Definition: redline.hxx:336
SwTableLine is one table row in the document model.
Definition: swtable.hxx:374
const SwTable & GetTable() const
Definition: node.hxx:542
Redline that holds information about a table-row that had some change.
Definition: redline.hxx:300
const SwTableLine & GetTableLine() const
Definition: redline.hxx:313
const SwRedlineData & GetRedlineData() const
Definition: redline.hxx:315
virtual ~SwTableRowRedline() override
Definition: docredln.cxx:2114
SwTableRowRedline(const SwRedlineData &rData, const SwTableLine &rTableLine)
Definition: docredln.cxx:2108
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:113
A wrapper around SfxPoolItem to store the start position of (usually) a text portion,...
Definition: txatbase.hxx:44
Represents the style of a paragraph.
Definition: fmtcol.hxx:61
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:166
void ClearPara()
Removes the Line information from the Cache but retains the entry itself.
Definition: txtcache.cxx:104
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:112
void CopyCollFormat(SwTextNode &rDestNd, bool bUndoForChgFormatColl=true)
Copy collection with all auto formats to dest-node.
Definition: ndcopy.cxx:339
const OUString & GetText() const
Definition: ndtxt.hxx:244
void TriggerNodeUpdate(const sw::LegacyModifyHint &)
for hanging TextFormatCollections somewhere else (Outline-Numbering!)
Definition: ndtxt.cxx:5474
SwTextFormatColl * GetTextColl() const
Definition: ndtxt.hxx:897
bool IsShowChangesInMargin() const
Definition: viewopt.hxx:457
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:434
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2159
void InvalidateWindows(const SwRect &rRect)
Definition: viewsh.cxx:556
Definition: view.hxx:146
SwWrtShell & GetWrtShell() const
Definition: view.hxx:421
const Value & back() const
const_iterator begin() const
const_iterator find(const Value &x) const
size_type erase(const Value &x)
bool empty() const
void erase_at(size_t index)
const_iterator end() const
size_type size() const
const Value & front() const
std::pair< const_iterator, bool > insert(Value &&x)
void CopyWithFlyInFly(const SwNodeRange &rRg, SwNode &rInsPos, const std::pair< const SwPaM &, const SwPosition & > *pCopiedPaM=nullptr, bool bMakeNewFrames=true, bool bDelRedlines=true, bool bCopyFlyAtFly=false, SwCopyFlags flags=SwCopyFlags::Default) const
note: rRg/rInsPos exclude a partially selected start text node; pCopiedPaM includes a partially selec...
new delete redline is created
Definition: hints.hxx:125
delete redline is removed
Definition: hints.hxx:135
virtual void SetShortName(const OUString &)=0
virtual void SetKeyCode(const vcl::KeyCode &)=0
void SetNanoSec(sal_uInt32 nNewNanoSec)
RedlineType
TOOLS_DLLPUBLIC OString DateTimeToOString(const DateTime &rDateTime)
struct _xmlTextWriter * xmlTextWriterPtr
RedlineNotification
Definition: docary.hxx:215
void sw_DebugRedline(const SwDoc *pDoc)
Definition: docredln.cxx:71
const TranslateId STR_REDLINE_ARY[]
Definition: docredln.cxx:1090
static bool CheckPosition(const SwPosition *pStt, const SwPosition *pEnd)
Definition: docredln.cxx:112
static bool deltaOneMinute(DateTime const &t1, DateTime const &t2)
Definition: docredln.cxx:1052
void MaybeNotifyRedlineModification(SwRangeRedline &rRedline, SwDoc &rDoc)
Definition: docredln.cxx:1185
static void lcl_storeAnnotationMarks(SwDoc &rDoc, const SwPosition *pStt, const SwPosition *pEnd)
Definition: docredln.cxx:1471
#define max(a, b)
const EnumerationType m_eType
#define FRM_CNTNT
Definition: frame.hxx:103
SwFrameType
Definition: frame.hxx:75
#define CH_TXTATR_INWORD
Definition: hintids.hxx:176
constexpr TypedWhichId< SwFormatChg > RES_FMT_CHG(168)
const SfxPoolItem * GetDfltAttr(sal_uInt16 nWhich)
Get the default attribute from corresponding default attribute table.
Definition: hints.cxx:147
void * p
sal_Int64 n
sal_uInt16 nPos
#define SAL_WARN_IF(condition, area, stream)
std::unique_ptr< sal_Int32[]> pData
double getLength(const B2DPolygon &rCandidate)
OString join(std::string_view rSeparator, const std::vector< OString > &rSequence)
int i
std::u16string_view trim(std::u16string_view str)
Dialog to specify the properties of date form field.
std::vector< std::unique_ptr< SwRangeRedline > > GetAllValidRanges(std::unique_ptr< SwRangeRedline > p)
Definition: docredln.cxx:482
long Long
OUString toISO8601(const css::util::DateTime &rDateTime)
@ SwNormalStartNode
Definition: ndtyp.hxx:52
o3tl::strong_int< sal_Int32, struct Tag_SwNodeOffset > SwNodeOffset
Definition: nodeoffset.hxx:16
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
SwNodeOffset abs(const SwNodeOffset &a)
Definition: nodeoffset.hxx:34
SwContentNode * GoPreviousPos(SwPosition *pIdx, bool bChk)
Definition: pam.cxx:439
SwContentNode * GetNode(SwPaM &rPam, bool &rbFirst, SwMoveFnCollection const &fnMove, bool const bInReadOnly, SwRootFrame const *const i_pLayout)
This function returns the next node in direction of search.
Definition: pam.cxx:1020
void GoEndSection(SwPosition *pPos)
go to the end of the current base section
Definition: pam.cxx:1138
@ RES_POOLCOLL_STANDARD
Standard.
Definition: poolfmt.hxx:250
QPRO_FUNC_TYPE nType
static SfxItemSet & rSet
bool operator()(SwRangeRedline *const &lhs, SwRangeRedline *const &rhs) const
Definition: docredln.cxx:608
Marks a position in the document model.
Definition: pam.hxx:37
void Adjust(SwNodeOffset nDelta)
Adjust node position, and resets content position to zero.
Definition: pam.cxx:256
SwNode & GetNode() const
Definition: pam.hxx:80
void SetMark(const sw::mark::IMark *pMark)
Definition: pam.hxx:85
void Assign(const SwNode &rNd, SwNodeOffset nDelta, sal_Int32 nContentOffset=0)
These all set both nNode and nContent.
Definition: pam.cxx:230
void SetContent(sal_Int32 nContentIndex)
Set content index, only valid to call this if the position points to a SwContentNode subclass.
Definition: pam.cxx:266
SwNodeOffset GetNodeIndex() const
Definition: pam.hxx:77
const SwNodes & GetNodes() const
Definition: pam.hxx:78
void SetRedline(SwRangeRedline *pRangeRedline)
Definition: pam.hxx:86
sal_Int32 GetContentIndex() const
Definition: pam.hxx:84
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:168
#define SW_MOD()
Definition: swmodule.hxx:256
std::vector< SwRect > SwRects
Definition: swregion.hxx:26
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:57
#define SAL_MAX_INT32