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