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