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