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