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