LibreOffice Module sw (master)  1
undobj.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 
22 #include <IShellCursorSupplier.hxx>
23 #include <txtftn.hxx>
24 #include <fmtanchr.hxx>
25 #include <ftnidx.hxx>
26 #include <frmfmt.hxx>
27 #include <doc.hxx>
28 #include <UndoManager.hxx>
30 #include <docary.hxx>
31 #include <swundo.hxx>
32 #include <pam.hxx>
33 #include <ndtxt.hxx>
34 #include <UndoCore.hxx>
35 #include <rolbck.hxx>
36 #include <ndnotxt.hxx>
37 #include <IMark.hxx>
38 #include <mvsave.hxx>
39 #include <redline.hxx>
40 #include <crossrefbookmark.hxx>
41 #include <strings.hrc>
42 #include <docsh.hxx>
43 #include <view.hxx>
44 #include <frameformats.hxx>
45 #include <sal/log.hxx>
46 
47 // This class saves the Pam as integers and can recompose those into a PaM
49  : m_nSttNode( 0 ), m_nEndNode( 0 ), m_nSttContent( 0 ), m_nEndContent( 0 )
50 {
51 }
52 
53 SwUndRng::SwUndRng( const SwPaM& rPam )
54 {
55  SetValues( rPam );
56 }
57 
58 void SwUndRng::SetValues( const SwPaM& rPam )
59 {
60  const SwPosition *pStt = rPam.Start();
61  if( rPam.HasMark() )
62  {
63  const SwPosition *pEnd = rPam.GetPoint() == pStt
64  ? rPam.GetMark()
65  : rPam.GetPoint();
66  m_nEndNode = pEnd->nNode.GetIndex();
68  }
69  else
70  {
71  // no selection !!
72  m_nEndNode = 0;
74  }
75 
76  m_nSttNode = pStt->nNode.GetIndex();
78 }
79 
80 void SwUndRng::SetPaM( SwPaM & rPam, bool bCorrToContent ) const
81 {
82  rPam.DeleteMark();
83  rPam.GetPoint()->nNode = m_nSttNode;
84  SwNode& rNd = rPam.GetNode();
85  if( rNd.IsContentNode() )
87  else if( bCorrToContent )
89  else
90  rPam.GetPoint()->nContent.Assign( nullptr, 0 );
91 
92  if( !m_nEndNode && COMPLETE_STRING == m_nEndContent ) // no selection
93  return ;
94 
95  rPam.SetMark();
97  return; // nothing left to do
98 
99  rPam.GetPoint()->nNode = m_nEndNode;
100  if( rPam.GetNode().IsContentNode() )
102  else if( bCorrToContent )
104  else
105  rPam.GetPoint()->nContent.Assign( nullptr, 0 );
106 }
107 
109  ::sw::UndoRedoContext & rContext, bool const bCorrToContent) const
110 {
111  SwPaM & rPaM( rContext.GetCursorSupplier().CreateNewShellCursor() );
112  SetPaM( rPaM, bCorrToContent );
113  return rPaM;
114 }
115 
117  const sal_uLong* pEndIdx )
118 {
119  SwNodeIndex aIdx( rDoc.GetNodes(), nSttIdx );
120  SwNodeIndex aEndIdx( rDoc.GetNodes(), pEndIdx ? *pEndIdx
121  : aIdx.GetNode().EndOfSectionIndex() );
122  SwPosition aPos( rDoc.GetNodes().GetEndOfPostIts() );
123  SwDoc::CorrAbs( aIdx, aEndIdx, aPos, true );
124 }
125 
126 void SwUndo::RemoveIdxFromRange( SwPaM& rPam, bool bMoveNext )
127 {
128  const SwPosition* pEnd = rPam.End();
129  if( bMoveNext )
130  {
131  if( pEnd != rPam.GetPoint() )
132  rPam.Exchange();
133 
134  SwNodeIndex aStt( rPam.GetMark()->nNode );
135  SwNodeIndex aEnd( rPam.GetPoint()->nNode );
136 
137  if( !rPam.Move( fnMoveForward ) )
138  {
139  rPam.Exchange();
140  if( !rPam.Move( fnMoveBackward ) )
141  {
142  rPam.GetPoint()->nNode = rPam.GetDoc()->GetNodes().GetEndOfPostIts();
143  rPam.GetPoint()->nContent.Assign( nullptr, 0 );
144  }
145  }
146 
147  SwDoc::CorrAbs( aStt, aEnd, *rPam.GetPoint(), true );
148  }
149  else
150  SwDoc::CorrAbs( rPam, *pEnd, true );
151 }
152 
153 void SwUndo::RemoveIdxRel( sal_uLong nIdx, const SwPosition& rPos )
154 {
155  // Move only the Cursor. Bookmarks/TOXMarks/etc. are done by the corresponding
156  // JoinNext/JoinPrev
157  SwNodeIndex aIdx( rPos.nNode.GetNode().GetNodes(), nIdx );
158  ::PaMCorrRel( aIdx, rPos );
159 }
160 
161 SwUndo::SwUndo(SwUndoId const nId, const SwDoc* pDoc)
162  : m_nId(nId), m_nOrigRedlineFlags(RedlineFlags::NONE)
163  , m_nViewShellId(CreateViewShellId(pDoc))
164  , m_isRepeatIgnored(false)
165  , m_bCacheComment(true)
166 {
167 }
168 
170 {
171  ViewShellId nRet(-1);
172 
173  if (const SwDocShell* pDocShell = pDoc->GetDocShell())
174  {
175  if (const SwView* pView = pDocShell->GetView())
176  nRet = pView->GetViewShellId();
177  }
178 
179  return nRet;
180 }
181 
182 bool SwUndo::IsDelBox() const
183 {
186 }
187 
189 {
190 }
191 
192 namespace {
193 
194 class UndoRedoRedlineGuard
195 {
196 public:
197  UndoRedoRedlineGuard(::sw::UndoRedoContext const & rContext, SwUndo const & rUndo)
198  : m_rRedlineAccess(rContext.GetDoc().getIDocumentRedlineAccess())
199  , m_eMode(m_rRedlineAccess.GetRedlineFlags())
200  {
201  RedlineFlags const eTmpMode = rUndo.GetRedlineFlags();
202  if ((RedlineFlags::ShowMask & eTmpMode) != (RedlineFlags::ShowMask & m_eMode))
203  {
204  m_rRedlineAccess.SetRedlineFlags( eTmpMode );
205  }
206  m_rRedlineAccess.SetRedlineFlags_intern( eTmpMode | RedlineFlags::Ignore );
207  }
208  ~UndoRedoRedlineGuard()
209  {
210  m_rRedlineAccess.SetRedlineFlags(m_eMode);
211  }
212 private:
213  IDocumentRedlineAccess & m_rRedlineAccess;
214  RedlineFlags const m_eMode;
215 };
216 
217 }
218 
220 {
221  assert(false); // SwUndo::Undo(): ERROR: must call UndoWithContext instead
222 }
223 
225 {
226  assert(false); // SwUndo::Redo(): ERROR: must call RedoWithContext instead
227 }
228 
230 {
231  ::sw::UndoRedoContext *const pContext(
232  dynamic_cast< ::sw::UndoRedoContext * >(& rContext));
233  assert(pContext);
234  const UndoRedoRedlineGuard aUndoRedoRedlineGuard(*pContext, *this);
235  UndoImpl(*pContext);
236 }
237 
239 {
240  ::sw::UndoRedoContext *const pContext(
241  dynamic_cast< ::sw::UndoRedoContext * >(& rContext));
242  assert(pContext);
243  const UndoRedoRedlineGuard aUndoRedoRedlineGuard(*pContext, *this);
244  RedoImpl(*pContext);
245 }
246 
248 {
249  if (m_isRepeatIgnored)
250  {
251  return; // ignore Repeat for multi-selections
252  }
253  ::sw::RepeatContext *const pRepeatContext(
254  dynamic_cast< ::sw::RepeatContext * >(& rContext));
255  assert(pRepeatContext);
256  RepeatImpl(*pRepeatContext);
257 }
258 
259 bool SwUndo::CanRepeat(SfxRepeatTarget & rContext) const
260 {
261  assert(dynamic_cast< ::sw::RepeatContext * >(& rContext));
262  (void)rContext;
263  // a MultiSelection action that doesn't do anything must still return true
265 }
266 
268 {
269 }
270 
272 {
273  const char *pId = nullptr;
274  switch (eId)
275  {
276  case SwUndoId::EMPTY:
277  pId = STR_CANT_UNDO;
278  break;
279  case SwUndoId::START:
280  case SwUndoId::END:
281  break;
282  case SwUndoId::DELETE:
283  pId = STR_DELETE_UNDO;
284  break;
285  case SwUndoId::INSERT:
286  pId = STR_INSERT_UNDO;
287  break;
288  case SwUndoId::OVERWRITE:
289  pId = STR_OVR_UNDO;
290  break;
291  case SwUndoId::SPLITNODE:
292  pId = STR_SPLITNODE_UNDO;
293  break;
294  case SwUndoId::INSATTR:
295  pId = STR_INSATTR_UNDO;
296  break;
298  pId = STR_SETFMTCOLL_UNDO;
299  break;
300  case SwUndoId::RESETATTR:
301  pId = STR_RESET_ATTR_UNDO;
302  break;
304  pId = STR_INSFMT_ATTR_UNDO;
305  break;
307  pId = STR_INSERT_DOC_UNDO;
308  break;
309  case SwUndoId::COPY:
310  pId = STR_COPY_UNDO;
311  break;
312  case SwUndoId::INSTABLE:
313  pId = STR_INSTABLE_UNDO;
314  break;
316  pId = STR_TABLETOTEXT_UNDO;
317  break;
319  pId = STR_TEXTTOTABLE_UNDO;
320  break;
321  case SwUndoId::SORT_TXT:
322  pId = STR_SORT_TXT;
323  break;
324  case SwUndoId::INSLAYFMT:
325  pId = STR_INSERTFLY;
326  break;
328  pId = STR_TABLEHEADLINE;
329  break;
331  pId = STR_INSERTSECTION;
332  break;
334  pId = STR_OUTLINE_LR;
335  break;
337  pId = STR_OUTLINE_UD;
338  break;
339  case SwUndoId::INSNUM:
340  pId = STR_INSNUM;
341  break;
342  case SwUndoId::NUMUP:
343  pId = STR_NUMUP;
344  break;
345  case SwUndoId::MOVENUM:
346  pId = STR_MOVENUM;
347  break;
349  pId = STR_INSERTDRAW;
350  break;
352  pId = STR_NUMORNONUM;
353  break;
355  pId = STR_INC_LEFTMARGIN;
356  break;
358  pId = STR_DEC_LEFTMARGIN;
359  break;
361  pId = STR_INSERTLABEL;
362  break;
364  pId = STR_SETNUMRULESTART;
365  break;
366  case SwUndoId::CHGFTN:
367  pId = STR_CHANGEFTN;
368  break;
369  case SwUndoId::REDLINE:
370  SAL_INFO("sw.core", "Should NEVER be used/translated");
371  return "$1";
373  pId = STR_ACCEPT_REDLINE;
374  break;
376  pId = STR_REJECT_REDLINE;
377  break;
379  pId = STR_SPLIT_TABLE;
380  break;
382  pId = STR_DONTEXPAND;
383  break;
385  pId = STR_AUTOCORRECT;
386  break;
388  pId = STR_MERGE_TABLE;
389  break;
391  pId = STR_TRANSLITERATE;
392  break;
394  pId = STR_PASTE_CLIPBOARD_UNDO;
395  break;
396  case SwUndoId::TYPING:
397  pId = STR_TYPING_UNDO;
398  break;
399  case SwUndoId::MOVE:
400  pId = STR_MOVE_UNDO;
401  break;
403  pId = STR_INSERT_GLOSSARY;
404  break;
406  pId = STR_DELBOOKMARK;
407  break;
409  pId = STR_INSBOOKMARK;
410  break;
411  case SwUndoId::SORT_TBL:
412  pId = STR_SORT_TBL;
413  break;
414  case SwUndoId::DELLAYFMT:
415  pId = STR_DELETEFLY;
416  break;
418  pId = STR_AUTOFORMAT;
419  break;
420  case SwUndoId::REPLACE:
421  pId = STR_REPLACE;
422  break;
424  pId = STR_DELETESECTION;
425  break;
427  pId = STR_CHANGESECTION;
428  break;
430  pId = STR_CHANGEDEFATTR;
431  break;
432  case SwUndoId::DELNUM:
433  pId = STR_DELNUM;
434  break;
435  case SwUndoId::DRAWUNDO:
436  pId = STR_DRAWUNDO;
437  break;
438  case SwUndoId::DRAWGROUP:
439  pId = STR_DRAWGROUP;
440  break;
442  pId = STR_DRAWUNGROUP;
443  break;
445  pId = STR_DRAWDELETE;
446  break;
447  case SwUndoId::REREAD:
448  pId = STR_REREAD;
449  break;
450  case SwUndoId::DELGRF:
451  pId = STR_DELGRF;
452  break;
454  pId = STR_TABLE_ATTR;
455  break;
457  pId = STR_UNDO_TABLE_AUTOFMT;
458  break;
460  pId = STR_UNDO_TABLE_INSCOL;
461  break;
463  pId = STR_UNDO_TABLE_INSROW;
464  break;
466  pId = STR_UNDO_TABLE_DELBOX;
467  break;
469  pId = STR_UNDO_TABLE_SPLIT;
470  break;
472  pId = STR_UNDO_TABLE_MERGE;
473  break;
474  case SwUndoId::TBLNUMFMT:
475  pId = STR_TABLE_NUMFORMAT;
476  break;
477  case SwUndoId::INSTOX:
478  pId = STR_INSERT_TOX;
479  break;
481  pId = STR_CLEAR_TOX_RANGE;
482  break;
483  case SwUndoId::TBLCPYTBL:
484  pId = STR_TABLE_TBLCPYTBL;
485  break;
486  case SwUndoId::CPYTBL:
487  pId = STR_TABLE_CPYTBL;
488  break;
490  pId = STR_INS_FROM_SHADOWCRSR;
491  break;
492  case SwUndoId::CHAINE:
493  pId = STR_UNDO_CHAIN;
494  break;
495  case SwUndoId::UNCHAIN:
496  pId = STR_UNDO_UNCHAIN;
497  break;
498  case SwUndoId::FTNINFO:
499  pId = STR_UNDO_FTNINFO;
500  break;
502  pId = STR_UNDO_COMPAREDOC;
503  break;
505  pId = STR_UNDO_SETFLYFRMFMT;
506  break;
508  pId = STR_UNDO_SETRUBYATTR;
509  break;
510  case SwUndoId::TOXCHANGE:
511  pId = STR_TOXCHANGE;
512  break;
514  pId = STR_UNDO_PAGEDESC_CREATE;
515  break;
517  pId = STR_UNDO_PAGEDESC;
518  break;
520  pId = STR_UNDO_PAGEDESC_DELETE;
521  break;
523  pId = STR_UNDO_HEADER_FOOTER;
524  break;
525  case SwUndoId::FIELD:
526  pId = STR_UNDO_FIELD;
527  break;
529  pId = STR_UNDO_TXTFMTCOL_CREATE;
530  break;
532  pId = STR_UNDO_TXTFMTCOL_DELETE;
533  break;
535  pId = STR_UNDO_TXTFMTCOL_RENAME;
536  break;
538  pId = STR_UNDO_CHARFMT_CREATE;
539  break;
541  pId = STR_UNDO_CHARFMT_DELETE;
542  break;
544  pId = STR_UNDO_CHARFMT_RENAME;
545  break;
547  pId = STR_UNDO_FRMFMT_CREATE;
548  break;
550  pId = STR_UNDO_FRMFMT_DELETE;
551  break;
553  pId = STR_UNDO_FRMFMT_RENAME;
554  break;
556  pId = STR_UNDO_NUMRULE_CREATE;
557  break;
559  pId = STR_UNDO_NUMRULE_DELETE;
560  break;
562  pId = STR_UNDO_NUMRULE_RENAME;
563  break;
565  pId = STR_UNDO_BOOKMARK_RENAME;
566  break;
568  pId = STR_UNDO_INDEX_ENTRY_INSERT;
569  break;
571  pId = STR_UNDO_INDEX_ENTRY_DELETE;
572  break;
574  pId = STR_UNDO_COL_DELETE;
575  break;
577  pId = STR_UNDO_ROW_DELETE;
578  break;
580  pId = STR_UNDO_PAGEDESC_RENAME;
581  break;
582  case SwUndoId::NUMDOWN:
583  pId = STR_NUMDOWN;
584  break;
586  pId = STR_UNDO_FLYFRMFMT_TITLE;
587  break;
589  pId = STR_UNDO_FLYFRMFMT_DESCRIPTION;
590  break;
592  pId = STR_UNDO_TBLSTYLE_CREATE;
593  break;
595  pId = STR_UNDO_TBLSTYLE_DELETE;
596  break;
598  pId = STR_UNDO_TBLSTYLE_UPDATE;
599  break;
601  pId = STR_REPLACE_UNDO;
602  break;
604  pId = STR_INSERT_PAGE_BREAK_UNDO;
605  break;
607  pId = STR_INSERT_COLUMN_BREAK_UNDO;
608  break;
610  pId = STR_INSERT_ENV_UNDO;
611  break;
613  pId = STR_DRAG_AND_COPY;
614  break;
616  pId = STR_DRAG_AND_MOVE;
617  break;
619  pId = STR_INSERT_CHART;
620  break;
622  pId = STR_INSERT_FOOTNOTE;
623  break;
625  pId = STR_INSERT_URLBTN;
626  break;
628  pId = STR_INSERT_URLTXT;
629  break;
631  pId = STR_DELETE_INVISIBLECNTNT;
632  break;
634  pId = STR_REPLACE_STYLE;
635  break;
637  pId = STR_DELETE_PAGE_BREAK;
638  break;
640  pId = STR_TEXT_CORRECTION;
641  break;
643  pId = STR_UNDO_TABLE_DELETE;
644  break;
645  case SwUndoId::CONFLICT:
646  break;
648  pId = STR_PARAGRAPH_SIGN_UNDO;
649  break;
651  pId = STR_UNDO_INSERT_FORM_FIELD;
652  break;
653  }
654 
655  assert(pId);
656  return SwResId(pId);
657 }
658 
659 OUString SwUndo::GetComment() const
660 {
661  OUString aResult;
662 
663  if (m_bCacheComment)
664  {
665  if (! maComment)
666  {
668 
669  SwRewriter aRewriter = GetRewriter();
670 
671  maComment = aRewriter.Apply(*maComment);
672  }
673 
674  aResult = *maComment;
675  }
676  else
677  {
678  aResult = GetUndoComment(GetId());
679 
680  SwRewriter aRewriter = GetRewriter();
681 
682  aResult = aRewriter.Apply(aResult);
683  }
684 
685  return aResult;
686 }
687 
689 {
690  return m_nViewShellId;
691 }
692 
694 {
695  SwRewriter aResult;
696 
697  return aResult;
698 }
699 
701 {}
702 
703 SwUndoSaveContent::~SwUndoSaveContent() COVERITY_NOEXCEPT_FALSE
704 {
705 }
706 
708 {
709  xmlTextWriterStartElement(pWriter, BAD_CAST("SwUndoSaveContent"));
710  xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
711 
712  if (m_pHistory)
713  {
714  m_pHistory->dumpAsXml(pWriter);
715  }
716 
717  xmlTextWriterEndElement(pWriter);
718 }
719 
720 // This is needed when deleting content. For REDO all contents will be moved
721 // into the UndoNodesArray. These methods always create a new node to insert
722 // content. As a result, the attributes will not be expanded.
723 // - MoveTo moves from NodesArray into UndoNodesArray
724 // - MoveFrom moves from UndoNodesArray into NodesArray
725 
726 // If pEndNdIdx is given, Undo/Redo calls -Ins/DelFly. In that case the whole
727 // section should be moved.
729  sal_uLong* pEndNdIdx )
730 {
731  SwDoc& rDoc = *rPaM.GetDoc();
732  ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
733 
734  SwNoTextNode* pCpyNd = rPaM.GetNode().GetNoTextNode();
735 
736  // here comes the actual delete (move)
737  SwNodes & rNds = rDoc.GetUndoManager().GetUndoNodes();
738  SwPosition aPos( pEndNdIdx ? rNds.GetEndOfPostIts()
739  : rNds.GetEndOfExtras() );
740 
741  const SwPosition* pStt = rPaM.Start(), *pEnd = rPaM.End();
742 
743  sal_uLong nTmpMvNode = aPos.nNode.GetIndex();
744 
745  if( pCpyNd || pEndNdIdx )
746  {
747  SwNodeRange aRg( pStt->nNode, 0, pEnd->nNode, 1 );
748  rDoc.GetNodes().MoveNodes( aRg, rNds, aPos.nNode, true );
749  aPos.nContent = 0;
750  --aPos.nNode;
751  }
752  else
753  {
754  rDoc.GetNodes().MoveRange( rPaM, aPos, rNds );
755  }
756  if( pEndNdIdx )
757  *pEndNdIdx = aPos.nNode.GetIndex();
758 
759  // old position
760  aPos.nNode = nTmpMvNode;
761  if( pNodeIdx )
762  *pNodeIdx = aPos.nNode;
763 }
764 
766  SwPosition& rInsPos,
767  const sal_uLong* pEndNdIdx, bool const bForceCreateFrames)
768 {
769  // here comes the recovery
770  SwNodes & rNds = rDoc.GetUndoManager().GetUndoNodes();
771  if( nNodeIdx == rNds.GetEndOfPostIts().GetIndex() )
772  return; // nothing saved
773 
774  ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
775 
776  SwPaM aPaM( rInsPos );
777  if( pEndNdIdx ) // than get the section from it
778  aPaM.GetPoint()->nNode.Assign( rNds, *pEndNdIdx );
779  else
780  {
781  aPaM.GetPoint()->nNode = rNds.GetEndOfExtras();
782  GoInContent( aPaM, fnMoveBackward );
783  }
784 
785  SwTextNode* pTextNd = aPaM.GetNode().GetTextNode();
786  if (!pEndNdIdx && pTextNd)
787  {
788  aPaM.SetMark();
789  aPaM.GetPoint()->nNode = nNodeIdx;
790  aPaM.GetPoint()->nContent.Assign(aPaM.GetContentNode(), 0);
791 
792  SaveRedlEndPosForRestore aRedlRest( rInsPos.nNode, rInsPos.nContent.GetIndex() );
793 
794  rNds.MoveRange( aPaM, rInsPos, rDoc.GetNodes() );
795 
796  // delete the last Node as well
797  if( !aPaM.GetPoint()->nContent.GetIndex() ||
798  ( aPaM.GetPoint()->nNode++ && // still empty Nodes at the end?
799  &rNds.GetEndOfExtras() != &aPaM.GetPoint()->nNode.GetNode() ))
800  {
801  aPaM.GetPoint()->nContent.Assign( nullptr, 0 );
802  aPaM.SetMark();
803  rNds.Delete( aPaM.GetPoint()->nNode,
804  rNds.GetEndOfExtras().GetIndex() -
805  aPaM.GetPoint()->nNode.GetIndex() );
806  }
807 
808  aRedlRest.Restore();
809  }
810  else
811  {
812  SwNodeRange aRg( rNds, nNodeIdx, rNds, (pEndNdIdx
813  ? ((*pEndNdIdx) + 1)
814  : rNds.GetEndOfExtras().GetIndex() ) );
815  rNds.MoveNodes(aRg, rDoc.GetNodes(), rInsPos.nNode, nullptr == pEndNdIdx || bForceCreateFrames);
816 
817  }
818 }
819 
820 // These two methods move the Point of Pam backwards/forwards. With that, one
821 // can span an area for a Undo/Redo. (The Point is then positioned in front of
822 // the area to manipulate!)
823 // The flag indicates if there is still content in front of Point.
825 {
826  rPam.SetMark();
827  if( rPam.Move( fnMoveBackward ))
828  return true;
829 
830  // If there is no content onwards, set Point simply to the previous position
831  // (Node and Content, so that Content will be detached!)
832  --rPam.GetPoint()->nNode;
833  rPam.GetPoint()->nContent.Assign( nullptr, 0 );
834  return false;
835 }
836 
837 void SwUndoSaveContent::MovePtForward( SwPaM& rPam, bool bMvBkwrd )
838 {
839  // Was there content before this position?
840  if( bMvBkwrd )
841  rPam.Move( fnMoveForward );
842  else
843  {
844  ++rPam.GetPoint()->nNode;
845  SwContentNode* pCNd = rPam.GetContentNode();
846  if( pCNd )
847  pCNd->MakeStartIndex( &rPam.GetPoint()->nContent );
848  else
849  rPam.Move( fnMoveForward );
850  }
851 }
852 
853 // Delete all objects that have ContentIndices to the given area.
854 // Currently (1994) these exist:
855 // - Footnotes
856 // - Flys
857 // - Bookmarks
858 
859 // #i81002# - extending method
860 // delete certain (not all) cross-reference bookmarks at text node of <rMark>
861 // and at text node of <rPoint>, if these text nodes aren't the same.
863  const SwPosition& rPoint,
864  DelContentType nDelContentType )
865 {
866  const SwPosition *pStt = rMark < rPoint ? &rMark : &rPoint,
867  *pEnd = &rMark == pStt ? &rPoint : &rMark;
868 
869  SwDoc* pDoc = rMark.nNode.GetNode().GetDoc();
870 
871  ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
872 
873  // 1. Footnotes
874  if( DelContentType::Ftn & nDelContentType )
875  {
876  SwFootnoteIdxs& rFootnoteArr = pDoc->GetFootnoteIdxs();
877  if( !rFootnoteArr.empty() )
878  {
879  const SwNode* pFootnoteNd;
880  size_t nPos = 0;
881  rFootnoteArr.SeekEntry( pStt->nNode, &nPos );
882  SwTextFootnote* pSrch;
883 
884  // for now delete all that come afterwards
885  while( nPos < rFootnoteArr.size() && ( pFootnoteNd =
886  &( pSrch = rFootnoteArr[ nPos ] )->GetTextNode())->GetIndex()
887  <= pEnd->nNode.GetIndex() )
888  {
889  const sal_Int32 nFootnoteSttIdx = pSrch->GetStart();
890  if( (DelContentType::CheckNoCntnt & nDelContentType )
891  ? (&pEnd->nNode.GetNode() == pFootnoteNd )
892  : (( &pStt->nNode.GetNode() == pFootnoteNd &&
893  pStt->nContent.GetIndex() > nFootnoteSttIdx) ||
894  ( &pEnd->nNode.GetNode() == pFootnoteNd &&
895  nFootnoteSttIdx >= pEnd->nContent.GetIndex() )) )
896  {
897  ++nPos; // continue searching
898  continue;
899  }
900 
901 // FIXME: duplicated code here and below -> refactor?
902  // Unfortunately an index needs to be created. Otherwise there
903  // will be problems with TextNode because the index will be
904  // deleted in the DTOR of SwFootnote!
905  SwTextNode* pTextNd = const_cast<SwTextNode*>(static_cast<const SwTextNode*>(pFootnoteNd));
906  if( !m_pHistory )
907  m_pHistory.reset( new SwHistory );
908  SwTextAttr* const pFootnoteHint =
909  pTextNd->GetTextAttrForCharAt( nFootnoteSttIdx );
910  assert(pFootnoteHint);
911  SwIndex aIdx( pTextNd, nFootnoteSttIdx );
912  m_pHistory->Add( pFootnoteHint, pTextNd->GetIndex(), false );
913  pTextNd->EraseText( aIdx, 1 );
914  }
915 
916  while( nPos-- && ( pFootnoteNd = &( pSrch = rFootnoteArr[ nPos ] )->
917  GetTextNode())->GetIndex() >= pStt->nNode.GetIndex() )
918  {
919  const sal_Int32 nFootnoteSttIdx = pSrch->GetStart();
920  if( !(DelContentType::CheckNoCntnt & nDelContentType) && (
921  ( &pStt->nNode.GetNode() == pFootnoteNd &&
922  pStt->nContent.GetIndex() > nFootnoteSttIdx ) ||
923  ( &pEnd->nNode.GetNode() == pFootnoteNd &&
924  nFootnoteSttIdx >= pEnd->nContent.GetIndex() )))
925  continue; // continue searching
926 
927  // Unfortunately an index needs to be created. Otherwise there
928  // will be problems with TextNode because the index will be
929  // deleted in the DTOR of SwFootnote!
930  SwTextNode* pTextNd = const_cast<SwTextNode*>(static_cast<const SwTextNode*>(pFootnoteNd));
931  if( !m_pHistory )
932  m_pHistory.reset( new SwHistory );
933  SwTextAttr* const pFootnoteHint =
934  pTextNd->GetTextAttrForCharAt( nFootnoteSttIdx );
935  assert(pFootnoteHint);
936  SwIndex aIdx( pTextNd, nFootnoteSttIdx );
937  m_pHistory->Add( pFootnoteHint, pTextNd->GetIndex(), false );
938  pTextNd->EraseText( aIdx, 1 );
939  }
940  }
941  }
942 
943  // 2. Flys
944  if( DelContentType::Fly & nDelContentType )
945  {
946  sal_uInt16 nChainInsPos = m_pHistory ? m_pHistory->Count() : 0;
947  const SwFrameFormats& rSpzArr = *pDoc->GetSpzFrameFormats();
948  if( !rSpzArr.empty() )
949  {
950  SwFrameFormat* pFormat;
951  const SwFormatAnchor* pAnchor;
952  size_t n = rSpzArr.size();
953  const SwPosition* pAPos;
954 
955  while( n && !rSpzArr.empty() )
956  {
957  pFormat = rSpzArr[--n];
958  pAnchor = &pFormat->GetAnchor();
959  switch( pAnchor->GetAnchorId() )
960  {
961  case RndStdIds::FLY_AS_CHAR:
962  if( nullptr != (pAPos = pAnchor->GetContentAnchor() ) &&
963  (( DelContentType::CheckNoCntnt & nDelContentType )
964  ? ( pStt->nNode <= pAPos->nNode &&
965  pAPos->nNode < pEnd->nNode )
966  : ( *pStt <= *pAPos && *pAPos < *pEnd )) )
967  {
968  if( !m_pHistory )
969  m_pHistory.reset( new SwHistory );
970  SwTextNode *const pTextNd =
971  pAPos->nNode.GetNode().GetTextNode();
972  SwTextAttr* const pFlyHint = pTextNd->GetTextAttrForCharAt(
973  pAPos->nContent.GetIndex());
974  assert(pFlyHint);
975  m_pHistory->Add( pFlyHint, 0, false );
976  // reset n so that no Format is skipped
977  n = n >= rSpzArr.size() ? rSpzArr.size() : n+1;
978  }
979  break;
980  case RndStdIds::FLY_AT_PARA:
981  {
982  pAPos = pAnchor->GetContentAnchor();
983  if (pAPos &&
984  pStt->nNode <= pAPos->nNode && pAPos->nNode <= pEnd->nNode)
985  {
986  if (!m_pHistory)
987  m_pHistory.reset( new SwHistory );
988 
989  if (!(DelContentType::Replace & nDelContentType)
990  && IsSelectFrameAnchoredAtPara(*pAPos, *pStt, *pEnd, nDelContentType))
991  {
992  m_pHistory->AddDeleteFly(*pFormat, nChainInsPos);
993  // reset n so that no Format is skipped
994  n = n >= rSpzArr.size() ? rSpzArr.size() : n+1;
995  }
996  // Moving the anchor?
998  & nDelContentType) &&
999  // at least for calls from SwUndoDelete,
1000  // this should work - other Undos don't
1001  // remember the order of the cursor
1002  (rPoint.nNode.GetIndex() == pAPos->nNode.GetIndex())
1003  // Do not try to move the anchor to a table!
1004  && rMark.nNode.GetNode().IsTextNode())
1005  {
1006  m_pHistory->AddChangeFlyAnchor(*pFormat);
1007  SwFormatAnchor aAnch( *pAnchor );
1008  SwPosition aPos( rMark.nNode );
1009  aAnch.SetAnchor( &aPos );
1010  pFormat->SetFormatAttr( aAnch );
1011  }
1012  }
1013  }
1014  break;
1015  case RndStdIds::FLY_AT_CHAR:
1016  if( nullptr != (pAPos = pAnchor->GetContentAnchor() ) &&
1017  ( pStt->nNode <= pAPos->nNode && pAPos->nNode <= pEnd->nNode ) )
1018  {
1019  if( !m_pHistory )
1020  m_pHistory.reset( new SwHistory );
1021  if (!(DelContentType::Replace & nDelContentType)
1023  *pAPos, *pStt, *pEnd, nDelContentType))
1024  {
1025  m_pHistory->AddDeleteFly(*pFormat, nChainInsPos);
1026  n = n >= rSpzArr.size() ? rSpzArr.size() : n+1;
1027  }
1028  else if (!((DelContentType::CheckNoCntnt |
1030  & nDelContentType))
1031  {
1032  if( *pStt <= *pAPos && *pAPos < *pEnd )
1033  {
1034  // These are the objects anchored
1035  // between section start and end position
1036  // Do not try to move the anchor to a table!
1037  if( rMark.nNode.GetNode().GetTextNode() )
1038  {
1039  m_pHistory->AddChangeFlyAnchor(*pFormat);
1040  SwFormatAnchor aAnch( *pAnchor );
1041  aAnch.SetAnchor( &rMark );
1042  pFormat->SetFormatAttr( aAnch );
1043  }
1044  }
1045  }
1046  }
1047  break;
1048  case RndStdIds::FLY_AT_FLY:
1049 
1050  if( nullptr != (pAPos = pAnchor->GetContentAnchor() ) &&
1051  pStt->nNode == pAPos->nNode )
1052  {
1053  if( !m_pHistory )
1054  m_pHistory.reset( new SwHistory );
1055 
1056  m_pHistory->AddDeleteFly(*pFormat, nChainInsPos);
1057 
1058  // reset n so that no Format is skipped
1059  n = n >= rSpzArr.size() ? rSpzArr.size() : n+1;
1060  }
1061  break;
1062  default: break;
1063  }
1064  }
1065  }
1066  }
1067 
1068  // 3. Bookmarks
1069  if( DelContentType::Bkm & nDelContentType )
1070  {
1071  IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1072  if( pMarkAccess->getAllMarksCount() )
1073  {
1074  for( sal_Int32 n = 0; n < pMarkAccess->getAllMarksCount(); ++n )
1075  {
1076  // #i81002#
1077  bool bSavePos = false;
1078  bool bSaveOtherPos = false;
1079  const ::sw::mark::IMark *const pBkmk = pMarkAccess->getAllMarksBegin()[n];
1080  auto const type(IDocumentMarkAccess::GetType(*pBkmk));
1081 
1082  if( DelContentType::CheckNoCntnt & nDelContentType )
1083  {
1084  if ( pStt->nNode <= pBkmk->GetMarkPos().nNode
1085  && pBkmk->GetMarkPos().nNode < pEnd->nNode )
1086  {
1087  bSavePos = true;
1088  }
1089  if ( pBkmk->IsExpanded()
1090  && pStt->nNode <= pBkmk->GetOtherMarkPos().nNode
1091  && pBkmk->GetOtherMarkPos().nNode < pEnd->nNode )
1092  {
1093  bSaveOtherPos = true;
1094  }
1095  }
1096  else
1097  {
1098  // #i92125#
1099  // keep cross-reference bookmarks, if content inside one paragraph is deleted.
1100  if ( rMark.nNode == rPoint.nNode
1103  {
1104  continue;
1105  }
1106 
1107  bool bMaybe = false;
1108  if ( *pStt <= pBkmk->GetMarkPos() && pBkmk->GetMarkPos() <= *pEnd )
1109  {
1110  if ( pBkmk->GetMarkPos() == *pEnd
1111  || ( *pStt == pBkmk->GetMarkPos() && pBkmk->IsExpanded() ) )
1112  bMaybe = true;
1113  else
1114  bSavePos = true;
1115  }
1116  if( pBkmk->IsExpanded() &&
1117  *pStt <= pBkmk->GetOtherMarkPos() && pBkmk->GetOtherMarkPos() <= *pEnd )
1118  {
1119  if ( bSavePos || bSaveOtherPos
1120  || (*pStt < pBkmk->GetOtherMarkPos() && pBkmk->GetOtherMarkPos() < *pEnd)
1125  {
1126  if( bMaybe )
1127  bSavePos = true;
1128  bSaveOtherPos = true;
1129  }
1130  }
1131 
1132  if ( !bSavePos && !bSaveOtherPos
1133  && dynamic_cast< const ::sw::mark::CrossRefBookmark* >(pBkmk) )
1134  {
1135  // certain special handling for cross-reference bookmarks
1136  const bool bDifferentTextNodesAtMarkAndPoint =
1137  rMark.nNode != rPoint.nNode
1138  && rMark.nNode.GetNode().GetTextNode()
1139  && rPoint.nNode.GetNode().GetTextNode();
1140  if ( bDifferentTextNodesAtMarkAndPoint )
1141  {
1142  // delete cross-reference bookmark at <pStt>, if only part of
1143  // <pEnd> text node content is deleted.
1144  if( pStt->nNode == pBkmk->GetMarkPos().nNode
1145  && pEnd->nContent.GetIndex() != pEnd->nNode.GetNode().GetTextNode()->Len() )
1146  {
1147  bSavePos = true;
1148  bSaveOtherPos = false; // cross-reference bookmarks are not expanded
1149  }
1150  // delete cross-reference bookmark at <pEnd>, if only part of
1151  // <pStt> text node content is deleted.
1152  else if( pEnd->nNode == pBkmk->GetMarkPos().nNode &&
1153  pStt->nContent.GetIndex() != 0 )
1154  {
1155  bSavePos = true;
1156  bSaveOtherPos = false; // cross-reference bookmarks are not expanded
1157  }
1158  }
1159  }
1161  {
1162  // delete annotation marks, if its end position is covered by the deletion
1163  const SwPosition& rAnnotationEndPos = pBkmk->GetMarkEnd();
1164  if ( *pStt < rAnnotationEndPos && rAnnotationEndPos <= *pEnd )
1165  {
1166  bSavePos = true;
1167  bSaveOtherPos = pBkmk->IsExpanded(); //tdf#90138, only save the other pos if there is one
1168  }
1169  }
1170  }
1171 
1172  if ( bSavePos || bSaveOtherPos )
1173  {
1175  {
1176  if( !m_pHistory )
1177  m_pHistory.reset( new SwHistory );
1178  m_pHistory->Add( *pBkmk, bSavePos, bSaveOtherPos );
1179  }
1180  if ( bSavePos
1181  && ( bSaveOtherPos
1182  || !pBkmk->IsExpanded() ) )
1183  {
1184  pMarkAccess->deleteMark(pMarkAccess->getAllMarksBegin()+n);
1185  n--;
1186  }
1187  }
1188  }
1189  }
1190  }
1191 }
1192 
1193 // save a complete section into UndoNodes array
1195  : m_nMoveLen( 0 ), m_nStartPos( ULONG_MAX )
1196 {
1197 }
1198 
1200 {
1201  if (m_pMovedStart) // delete also the section from UndoNodes array
1202  {
1203  // SaveSection saves the content in the PostIt section.
1204  SwNodes& rUNds = m_pMovedStart->GetNode().GetNodes();
1205  rUNds.Delete( *m_pMovedStart, m_nMoveLen );
1206 
1207  m_pMovedStart.reset();
1208  }
1209  m_pRedlineSaveData.reset();
1210 }
1211 
1213 {
1214  SwNodeRange aRg( rSttIdx.GetNode(), *rSttIdx.GetNode().EndOfSectionNode() );
1215  SaveSection( aRg );
1216 }
1217 
1219  const SwNodeRange& rRange, bool const bExpandNodes)
1220 {
1221  SwPaM aPam( rRange.aStart, rRange.aEnd );
1222 
1223  // delete all footnotes, fly frames, bookmarks
1224  DelContentIndex( *aPam.GetMark(), *aPam.GetPoint() );
1225 
1226  // redlines *before* CorrAbs, because DelBookmarks will make them 0-length
1227  // but *after* DelContentIndex because that also may use FillSaveData (in
1228  // flys) and that will be restored *after* this one...
1231  {
1232  m_pRedlineSaveData.reset();
1233  }
1234 
1235  {
1236  // move certain indexes out of deleted range
1237  SwNodeIndex aSttIdx( aPam.Start()->nNode.GetNode() );
1238  SwNodeIndex aEndIdx( aPam.End()->nNode.GetNode() );
1239  SwNodeIndex aMvStt( aEndIdx, 1 );
1240  SwDoc::CorrAbs( aSttIdx, aEndIdx, SwPosition( aMvStt ), true );
1241  }
1242 
1243  m_nStartPos = rRange.aStart.GetIndex();
1244 
1245  if (bExpandNodes)
1246  {
1247  --aPam.GetPoint()->nNode;
1248  ++aPam.GetMark()->nNode;
1249  }
1250 
1251  SwContentNode* pCNd = aPam.GetContentNode( false );
1252  if( pCNd )
1253  aPam.GetMark()->nContent.Assign( pCNd, 0 );
1254  pCNd = aPam.GetContentNode();
1255  if( nullptr != pCNd )
1256  aPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
1257 
1258  // Keep positions as SwIndex so that this section can be deleted in DTOR
1259  sal_uLong nEnd;
1260  m_pMovedStart.reset(new SwNodeIndex(rRange.aStart));
1261  MoveToUndoNds(aPam, m_pMovedStart.get(), &nEnd);
1262  m_nMoveLen = nEnd - m_pMovedStart->GetIndex() + 1;
1263 }
1264 
1266  sal_uInt16 nSectType )
1267 {
1268  if( ULONG_MAX != m_nStartPos ) // was there any content?
1269  {
1270  // check if the content is at the old position
1271  SwNodeIndex aSttIdx( pDoc->GetNodes(), m_nStartPos );
1272 
1273  // move the content from UndoNodes array into Fly
1274  SwStartNode* pSttNd = SwNodes::MakeEmptySection( aSttIdx,
1275  static_cast<SwStartNodeType>(nSectType) );
1276 
1277  RestoreSection( pDoc, SwNodeIndex( *pSttNd->EndOfSectionNode() ));
1278 
1279  if( pIdx )
1280  *pIdx = *pSttNd;
1281  }
1282 }
1283 
1285  SwDoc *const pDoc, const SwNodeIndex& rInsPos, bool bForceCreateFrames)
1286 {
1287  if( ULONG_MAX != m_nStartPos ) // was there any content?
1288  {
1289  SwPosition aInsPos( rInsPos );
1290  sal_uLong nEnd = m_pMovedStart->GetIndex() + m_nMoveLen - 1;
1291  MoveFromUndoNds(*pDoc, m_pMovedStart->GetIndex(), aInsPos, &nEnd, bForceCreateFrames);
1292 
1293  // destroy indices again, content was deleted from UndoNodes array
1294  m_pMovedStart.reset();
1295  m_nMoveLen = 0;
1296 
1297  if( m_pRedlineSaveData )
1298  {
1300  m_pRedlineSaveData.reset();
1301  }
1302  }
1303 }
1304 
1305 // save and set the RedlineData
1307  SwComparePosition eCmpPos,
1308  const SwPosition& rSttPos,
1309  const SwPosition& rEndPos,
1310  SwRangeRedline& rRedl,
1311  bool bCopyNext )
1312  : SwUndRng( rRedl )
1313  , SwRedlineData( rRedl.GetRedlineData(), bCopyNext )
1314 {
1315  assert( SwComparePosition::Outside == eCmpPos ||
1316  !rRedl.GetContentIdx() ); // "Redline with Content"
1317 
1318  switch (eCmpPos)
1319  {
1320  case SwComparePosition::OverlapBefore: // Pos1 overlaps Pos2 at the beginning
1321  m_nEndNode = rEndPos.nNode.GetIndex();
1322  m_nEndContent = rEndPos.nContent.GetIndex();
1323  break;
1324 
1325  case SwComparePosition::OverlapBehind: // Pos1 overlaps Pos2 at the end
1326  m_nSttNode = rSttPos.nNode.GetIndex();
1327  m_nSttContent = rSttPos.nContent.GetIndex();
1328  break;
1329 
1330  case SwComparePosition::Inside: // Pos1 lays completely in Pos2
1331  m_nSttNode = rSttPos.nNode.GetIndex();
1332  m_nSttContent = rSttPos.nContent.GetIndex();
1333  m_nEndNode = rEndPos.nNode.GetIndex();
1334  m_nEndContent = rEndPos.nContent.GetIndex();
1335  break;
1336 
1337  case SwComparePosition::Outside: // Pos2 lays completely in Pos1
1338  if ( rRedl.GetContentIdx() )
1339  {
1340  // than move section into UndoArray and memorize it
1341  SaveSection( *rRedl.GetContentIdx() );
1342  rRedl.SetContentIdx( nullptr );
1343  }
1344  break;
1345 
1346  case SwComparePosition::Equal: // Pos1 is exactly as big as Pos2
1347  break;
1348 
1349  default:
1350  assert(false);
1351  }
1352 
1353 #if OSL_DEBUG_LEVEL > 0
1355 #endif
1356 }
1357 
1359 {
1360 }
1361 
1363 {
1364  SwDoc& rDoc = *rPam.GetDoc();
1365  SwRangeRedline* pRedl = new SwRangeRedline( *this, rPam );
1366 
1367  if( GetMvSttIdx() )
1368  {
1369  SwNodeIndex aIdx( rDoc.GetNodes() );
1370  RestoreSection( &rDoc, &aIdx, SwNormalStartNode );
1371  if( GetHistory() )
1372  GetHistory()->Rollback( &rDoc );
1373  pRedl->SetContentIdx( &aIdx );
1374  }
1375  SetPaM( *pRedl );
1376  // First, delete the "old" so that in an Append no unexpected things will
1377  // happen, e.g. a delete in an insert. In the latter case the just restored
1378  // content will be deleted and not the one you originally wanted.
1379  rDoc.getIDocumentRedlineAccess().DeleteRedline( *pRedl, false, RedlineType::Any );
1380 
1383  //#i92154# let UI know about a new redline with comment
1384  if (rDoc.GetDocShell() && (!pRedl->GetComment().isEmpty()) )
1385  rDoc.GetDocShell()->Broadcast(SwRedlineHint());
1386 
1387  auto const result(rDoc.getIDocumentRedlineAccess().AppendRedline(pRedl, true));
1388  assert(result != IDocumentRedlineAccess::AppendResult::IGNORED); // SwRedlineSaveData::RedlineToDoc: insert redline failed
1389  (void) result; // unused in non-debug
1391 }
1392 
1394  const SwPaM& rRange,
1395  SwRedlineSaveDatas& rSData,
1396  bool bDelRange,
1397  bool bCopyNext )
1398 {
1399  rSData.clear();
1400 
1401  const SwPosition* pStt = rRange.Start();
1402  const SwPosition* pEnd = rRange.End();
1403  const SwRedlineTable& rTable = rRange.GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
1405  rRange.GetDoc()->getIDocumentRedlineAccess().GetRedline( *pStt, &n );
1406  for ( ; n < rTable.size(); ++n )
1407  {
1408  SwRangeRedline* pRedl = rTable[n];
1409 
1410  const SwComparePosition eCmpPos =
1411  ComparePosition( *pStt, *pEnd, *pRedl->Start(), *pRedl->End() );
1412  if ( eCmpPos != SwComparePosition::Before
1413  && eCmpPos != SwComparePosition::Behind
1414  && eCmpPos != SwComparePosition::CollideEnd
1415  && eCmpPos != SwComparePosition::CollideStart )
1416  {
1417 
1418  rSData.push_back(std::unique_ptr<SwRedlineSaveData, o3tl::default_delete<SwRedlineSaveData>>(new SwRedlineSaveData(eCmpPos, *pStt, *pEnd, *pRedl, bCopyNext)));
1419  }
1420  }
1421  if( !rSData.empty() && bDelRange )
1422  {
1423  rRange.GetDoc()->getIDocumentRedlineAccess().DeleteRedline( rRange, false, RedlineType::Any );
1424  }
1425  return !rSData.empty();
1426 }
1427 
1429  const SwPaM& rRange,
1430  SwRedlineSaveDatas& rSData )
1431 {
1432  rSData.clear();
1433 
1434  const SwPosition *pStt = rRange.Start(), *pEnd = rRange.End();
1435  const SwRedlineTable& rTable = rRange.GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
1437  rRange.GetDoc()->getIDocumentRedlineAccess().GetRedline( *pStt, &n );
1438  for ( ; n < rTable.size(); ++n )
1439  {
1440  SwRangeRedline* pRedl = rTable[n];
1441  if ( RedlineType::Format == pRedl->GetType() )
1442  {
1443  const SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRedl->Start(), *pRedl->End() );
1444  if ( eCmpPos != SwComparePosition::Before
1445  && eCmpPos != SwComparePosition::Behind
1446  && eCmpPos != SwComparePosition::CollideEnd
1447  && eCmpPos != SwComparePosition::CollideStart )
1448  {
1449  rSData.push_back(std::unique_ptr<SwRedlineSaveData, o3tl::default_delete<SwRedlineSaveData>>(new SwRedlineSaveData(eCmpPos, *pStt, *pEnd, *pRedl, true)));
1450  }
1451 
1452  }
1453  }
1454  return !rSData.empty();
1455 }
1456 
1457 
1459 {
1462  SwPaM aPam( rDoc.GetNodes().GetEndOfContent() );
1463 
1464  for( size_t n = rSData.size(); n; )
1465  rSData[ --n ].RedlineToDoc( aPam );
1466 
1467 #if OSL_DEBUG_LEVEL > 0
1468  // check redline count against count saved in RedlineSaveData object
1469  assert(rSData.empty() ||
1470  (rSData[0].m_nRedlineCount == rDoc.getIDocumentRedlineAccess().GetRedlineTable().size()));
1471  // "redline count not restored properly"
1472 #endif
1473 
1475 }
1476 
1478 {
1479  for( size_t n = rSData.size(); n; )
1480  if( rSData[ --n ].GetMvSttIdx() )
1481  return true;
1482  return false;
1483 }
1484 
1486  const SwRedlineSaveDatas& rCheck, bool bCurrIsEnd )
1487 {
1488  if( rCurr.size() != rCheck.size() )
1489  return false;
1490 
1491  for( size_t n = 0; n < rCurr.size(); ++n )
1492  {
1493  const SwRedlineSaveData& rSet = rCurr[ n ];
1494  const SwRedlineSaveData& rGet = rCheck[ n ];
1495  if( rSet.m_nSttNode != rGet.m_nSttNode ||
1496  rSet.GetMvSttIdx() || rGet.GetMvSttIdx() ||
1497  ( bCurrIsEnd ? rSet.m_nSttContent != rGet.m_nEndContent
1498  : rSet.m_nEndContent != rGet.m_nSttContent ) ||
1499  !rGet.CanCombine( rSet ) )
1500  {
1501  return false;
1502  }
1503  }
1504 
1505  for( size_t n = 0; n < rCurr.size(); ++n )
1506  {
1507  SwRedlineSaveData& rSet = rCurr[ n ];
1508  const SwRedlineSaveData& rGet = rCheck[ n ];
1509  if( bCurrIsEnd )
1510  rSet.m_nSttContent = rGet.m_nSttContent;
1511  else
1512  rSet.m_nEndContent = rGet.m_nEndContent;
1513  }
1514  return true;
1515 }
1516 
1517 OUString ShortenString(const OUString & rStr, sal_Int32 nLength, const OUString & rFillStr)
1518 {
1519  assert(nLength - rFillStr.getLength() >= 2);
1520 
1521  if (rStr.getLength() <= nLength)
1522  return rStr;
1523 
1524  nLength -= rFillStr.getLength();
1525  if ( nLength < 2 )
1526  nLength = 2;
1527 
1528  const sal_Int32 nFrontLen = nLength - nLength / 2;
1529  const sal_Int32 nBackLen = nLength - nFrontLen;
1530 
1531  return rStr.copy(0, nFrontLen)
1532  + rFillStr
1533  + rStr.copy(rStr.getLength() - nBackLen);
1534 }
1535 
1536 static bool IsAtEndOfSection(SwPosition const& rAnchorPos)
1537 {
1538  SwNodeIndex node(*rAnchorPos.nNode.GetNode().EndOfSectionNode());
1539  SwContentNode *const pNode(SwNodes::GoPrevious(&node));
1540  assert(pNode);
1541  assert(rAnchorPos.nNode <= node); // last valid anchor pos is last content
1542  return node == rAnchorPos.nNode
1543  // at-para fly has no SwIndex!
1544  && (rAnchorPos.nContent == pNode->Len() || rAnchorPos.nContent.GetIdxReg() == nullptr);
1545 }
1546 
1547 static bool IsAtStartOfSection(SwPosition const& rAnchorPos)
1548 {
1549  SwNodes const& rNodes(rAnchorPos.nNode.GetNodes());
1550  SwNodeIndex node(*rAnchorPos.nNode.GetNode().StartOfSectionNode());
1551  SwContentNode *const pNode(rNodes.GoNext(&node));
1552  assert(pNode);
1553  (void) pNode;
1554  assert(node <= rAnchorPos.nNode);
1555  return node == rAnchorPos.nNode && rAnchorPos.nContent == 0;
1556 }
1557 
1559 static bool IsAtEndOfSection2(SwPosition const& rPos)
1560 {
1561  return rPos.nNode.GetNode().IsEndNode()
1562  || IsAtEndOfSection(rPos);
1563 }
1564 
1565 static bool IsAtStartOfSection2(SwPosition const& rPos)
1566 {
1567  return rPos.nNode.GetNode().IsStartNode()
1568  || IsAtStartOfSection(rPos);
1569 }
1570 
1572  SwPosition const& rStart, SwPosition const& rEnd)
1573 {
1574  // check if the selection is backspace/delete created by DelLeft/DelRight
1575  return rStart.nNode.GetIndex() + 1 != rEnd.nNode.GetIndex()
1576  || rEnd.nContent != 0
1577  || rStart.nContent != rStart.nNode.GetNode().GetTextNode()->Len();
1578 }
1579 
1581  SwPosition const & rStart, SwPosition const & rEnd,
1582  DelContentType const nDelContentType)
1583 {
1584  assert(rStart <= rEnd);
1585 
1586  // CheckNoCntnt means DelFullPara which is obvious to handle
1587  if (DelContentType::CheckNoCntnt & nDelContentType)
1588  { // exclude selection end node because it won't be deleted
1589  return (rAnchorPos.nNode < rEnd.nNode)
1590  && (rStart.nNode <= rAnchorPos.nNode);
1591  }
1592 
1593  if ((nDelContentType & DelContentType::WriterfilterHack)
1594  && rAnchorPos.GetDoc()->IsInWriterfilterImport())
1595  { // FIXME hack for writerfilter RemoveLastParagraph() and MakeFlyAndMove(); can't test file format more specific?
1596  return (rStart < rAnchorPos) && (rAnchorPos < rEnd);
1597  }
1598 
1599  if (nDelContentType & DelContentType::ExcludeFlyAtStartEnd)
1600  { // exclude selection start and end node
1601  return (rAnchorPos.nNode < rEnd.nNode)
1602  && (rStart.nNode < rAnchorPos.nNode);
1603  }
1604 
1605  // in general, exclude the start and end position
1606  return ((rStart < rAnchorPos)
1607  || (rStart == rAnchorPos
1608  // special case: fully deleted node
1609  && ((rStart.nNode != rEnd.nNode && rStart.nContent == 0
1610  // but not if the selection is backspace/delete!
1611  && IsNotBackspaceHeuristic(rStart, rEnd))
1612  || (IsAtStartOfSection(rAnchorPos) && IsAtEndOfSection2(rEnd)))))
1613  && ((rAnchorPos < rEnd)
1614  || (rAnchorPos == rEnd
1615  // special case: fully deleted node
1616  && ((rEnd.nNode != rStart.nNode && rEnd.nContent == rEnd.nNode.GetNode().GetTextNode()->Len()
1617  && IsNotBackspaceHeuristic(rStart, rEnd))
1618  || (IsAtEndOfSection(rAnchorPos) && IsAtStartOfSection2(rStart)))));
1619 }
1620 
1621 bool IsSelectFrameAnchoredAtPara(SwPosition const & rAnchorPos,
1622  SwPosition const & rStart, SwPosition const & rEnd,
1623  DelContentType const nDelContentType)
1624 {
1625  assert(rStart <= rEnd);
1626 
1627  // CheckNoCntnt means DelFullPara which is obvious to handle
1628  if (DelContentType::CheckNoCntnt & nDelContentType)
1629  { // exclude selection end node because it won't be deleted
1630  return (rAnchorPos.nNode < rEnd.nNode)
1631  && (rStart.nNode <= rAnchorPos.nNode);
1632  }
1633 
1634  if ((nDelContentType & DelContentType::WriterfilterHack)
1635  && rAnchorPos.GetDoc()->IsInWriterfilterImport())
1636  { // FIXME hack for writerfilter RemoveLastParagraph() and MakeFlyAndMove(); can't test file format more specific?
1637  // but it MUST NOT be done during the SetRedlineFlags at the end of ODF
1638  // import, where the IsInXMLImport() cannot be checked because the
1639  // stupid code temp. overrides it - instead rely on setting the ALLFLYS
1640  // flag in MoveFromSection() and converting that to CheckNoCntnt with
1641  // adjusted cursor!
1642  return (rStart.nNode < rAnchorPos.nNode) && (rAnchorPos.nNode < rEnd.nNode);
1643  }
1644 
1645  // in general, exclude the start and end position
1646  return ((rStart.nNode < rAnchorPos.nNode)
1647  || (rStart.nNode == rAnchorPos.nNode
1648  && !(nDelContentType & DelContentType::ExcludeFlyAtStartEnd)
1649  // special case: fully deleted node
1650  && ((rStart.nNode != rEnd.nNode && rStart.nContent == 0
1651  // but not if the selection is backspace/delete!
1652  && IsNotBackspaceHeuristic(rStart, rEnd))
1653  || (IsAtStartOfSection2(rStart) && IsAtEndOfSection2(rEnd)))))
1654  && ((rAnchorPos.nNode < rEnd.nNode)
1655  || (rAnchorPos.nNode == rEnd.nNode
1656  && !(nDelContentType & DelContentType::ExcludeFlyAtStartEnd)
1657  // special case: fully deleted node
1658  && ((rEnd.nNode != rStart.nNode && rEnd.nContent == rEnd.nNode.GetNode().GetTextNode()->Len()
1659  && IsNotBackspaceHeuristic(rStart, rEnd))
1660  || (IsAtEndOfSection2(rEnd) && IsAtStartOfSection2(rStart)))));
1661 }
1662 
1663 bool IsFlySelectedByCursor(SwDoc const & rDoc,
1664  SwPosition const & rStart, SwPosition const & rEnd)
1665 {
1666  for (SwFrameFormat const*const pFly : *rDoc.GetSpzFrameFormats())
1667  {
1668  SwFormatAnchor const& rAnchor(pFly->GetAnchor());
1669  switch (rAnchor.GetAnchorId())
1670  {
1671  case RndStdIds::FLY_AT_CHAR:
1672  case RndStdIds::FLY_AT_PARA:
1673  {
1674  SwPosition const*const pAnchorPos(rAnchor.GetContentAnchor());
1675  // can this really be null?
1676  if (pAnchorPos != nullptr
1677  && ((rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR)
1678  ? IsDestroyFrameAnchoredAtChar(*pAnchorPos, rStart, rEnd)
1679  : IsSelectFrameAnchoredAtPara(*pAnchorPos, rStart, rEnd)))
1680  {
1681  return true;
1682  }
1683  }
1684  break;
1685  default: // other types not relevant
1686  break;
1687  }
1688  }
1689  return false;
1690 }
1691 
1692 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static bool IsAtEndOfSection(SwPosition const &rAnchorPos)
Definition: undobj.cxx:1536
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:682
Starts a section of nodes in the document model.
Definition: node.hxx:303
SwPaM & AddUndoRedoPaM(::sw::UndoRedoContext &, bool const bCorrToContent=false) const
Definition: undobj.cxx:108
virtual sal_Int32 Len() const
Definition: node.cxx:1223
void DeleteMark()
Definition: pam.hxx:177
sal_uLong m_nStartPos
Definition: undobj.hxx:205
sal_uLong GetIndex() const
Definition: node.hxx:282
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
bool GoInContent(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:963
std::unique_ptr< SwRedlineSaveDatas > m_pRedlineSaveData
Definition: undobj.hxx:203
Marks a position in the document model.
Definition: pam.hxx:35
std::unique_ptr< SwHistory > m_pHistory
Definition: undobj.hxx:166
SwNodes const & GetUndoNodes() const
Definition: docundo.cxx:73
void SetContentIdx(const SwNodeIndex *)
Definition: docredln.cxx:1660
SwComparePosition ComparePosition(const T &rStt1, const T &rEnd1, const T &rStt2, const T &rEnd2)
Definition: pam.hxx:77
static bool IsAtStartOfSection(SwPosition const &rAnchorPos)
Definition: undobj.cxx:1547
SwUndoId
Definition: swundo.hxx:29
SwDocShell * GetDocShell()
Definition: doc.hxx:1348
virtual SwPaM & CreateNewShellCursor()=0
virtual AppendResult AppendRedline(SwRangeRedline *pNewRedl, bool bCallDelete)=0
Append a new redline.
size_t size() const
Definition: UndoCore.hxx:76
bool Rollback(SwDoc *pDoc, sal_uInt16 nStart=0)
Definition: rolbck.cxx:1203
virtual void SetRedlineFlags_intern(RedlineFlags eMode)=0
Set a new redline mode.
static bool FillSaveDataForFormat(const SwPaM &, SwRedlineSaveDatas &)
Definition: undobj.cxx:1428
SwNodeIndex nNode
Definition: pam.hxx:37
virtual void Repeat(SfxRepeatTarget &) override
Definition: undobj.cxx:247
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:274
sal_uIntPtr sal_uLong
Pos1 is as large as Pos2.
static SW_DLLPUBLIC MarkType GetType(const ::sw::mark::IMark &rMark)
Returns the MarkType used to create the mark.
Definition: docbm.cxx:474
const SwPosition * GetMark() const
Definition: pam.hxx:209
sal_uLong m_nEndNode
Definition: undobj.hxx:229
Pos1 completely contained in Pos2.
sal_Int64 n
static ViewShellId CreateViewShellId(const SwDoc *pDoc)
Try to obtain the view shell ID of the current view.
Definition: undobj.cxx:169
Provides access to the marks of a document.
Definition: doc.hxx:184
virtual ~SwUndoSaveContent() COVERITY_NOEXCEPT_FALSE
Definition: undobj.cxx:703
SwRedlineSaveData(SwComparePosition eCmpPos, const SwPosition &rSttPos, const SwPosition &rEndPos, SwRangeRedline &rRedl, bool bCopyNext)
Definition: undobj.cxx:1306
static SwContentNode * GoPrevious(SwNodeIndex *)
Definition: nodes.cxx:1298
static bool IsAtStartOfSection2(SwPosition const &rPos)
Definition: undobj.cxx:1565
SwNode & GetNode() const
Definition: ndindex.hxx:119
bool IsSelectFrameAnchoredAtPara(SwPosition const &rAnchorPos, SwPosition const &rStart, SwPosition const &rEnd, DelContentType const nDelContentType)
is a fly anchored at paragraph at rAnchorPos selected?
Definition: undobj.cxx:1621
const SwHistory * GetHistory() const
Definition: undobj.hxx:220
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1682
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:143
SwNode & GetEndOfPostIts() const
A still empty section.
Definition: ndarr.hxx:152
static void RemoveIdxFromSection(SwDoc &, sal_uLong nSttIdx, const sal_uLong *pEndIdx=nullptr)
Definition: undobj.cxx:116
bool IsDestroyFrameAnchoredAtChar(SwPosition const &rAnchorPos, SwPosition const &rStart, SwPosition const &rEnd, DelContentType const nDelContentType)
will DelContentIndex destroy a frame anchored at character at rAnchorPos?
Definition: undobj.cxx:1580
virtual void RepeatImpl(::sw::RepeatContext &)
Definition: undobj.cxx:267
SwUndoId GetId() const
Definition: undobj.hxx:101
bool CanCombine(const SwRedlineData &rCmp) const
Definition: docredln.cxx:927
const SwFrameFormats * GetSpzFrameFormats() const
Definition: doc.hxx:739
IShellCursorSupplier & GetCursorSupplier()
Definition: UndoCore.hxx:96
SwUndRng()
Definition: undobj.cxx:48
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: undobj.cxx:707
size_type size() const
Definition: docary.hxx:266
void push_back(std::unique_ptr< SwRedlineSaveData, o3tl::default_delete< SwRedlineSaveData >> pNew)
Definition: UndoCore.hxx:77
SwContentNode * GetContentNode(bool bPoint=true) const
Definition: pam.hxx:229
void SetValues(const SwPaM &rPam)
Definition: undobj.cxx:58
SwTextAttr * GetTextAttrForCharAt(const sal_Int32 nIndex, const sal_uInt16 nWhich=RES_TXTATR_END) const
get the text attribute at position nIndex which owns the dummy character CH_TXTATR_* at that position...
Definition: ndtxt.cxx:3051
Pos1 end touches at Pos2 start.
sal_uLong m_nMoveLen
Definition: undobj.hxx:204
void Delete(const SwNodeIndex &rPos, sal_uLong nNodes=1)
delete nodes
Definition: nodes.cxx:1069
sal_uInt16 m_nRedlineCount
Definition: UndoCore.hxx:63
SwNodeIndex * GetMvSttIdx() const
Definition: UndoCore.hxx:57
SwIndex nContent
Definition: pam.hxx:38
SwDoc * GetDoc() const
Returns the document this position is in.
Definition: pam.cxx:178
SwNodeIndex aStart
Definition: ndindex.hxx:132
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
sal_Int32 GetStart() const
Definition: txatbase.hxx:82
virtual SwRewriter GetRewriter() const
Returns the rewriter for this object.
Definition: undobj.cxx:693
bool IsStartNode() const
Definition: node.hxx:624
Pos2 completely contained in Pos1.
static bool CanRedlineGroup(SwRedlineSaveDatas &rCurr, const SwRedlineSaveDatas &rCheck, bool bCurrIsEnd)
Definition: undobj.cxx:1485
bool empty() const
Pos1 before Pos2.
RedlineFlags on.
static void MoveToUndoNds(SwPaM &rPam, SwNodeIndex *pNodeIdx, sal_uLong *pEndNdIdx=nullptr)
Definition: undobj.cxx:728
size_type size() const
static void RemoveIdxFromRange(SwPaM &rPam, bool bMoveNext)
Definition: undobj.cxx:126
virtual bool CanRepeat(SfxRepeatTarget &) const override
Definition: undobj.cxx:259
RedlineFlags GetRedlineFlags() const
Definition: undobj.hxx:119
Specific frame formats (frames, DrawObjects).
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:163
virtual std::unique_ptr< ILazyDeleter > deleteMark(const IDocumentMarkAccess::const_iterator_t &ppMark)=0
Deletes a mark.
virtual const_iterator_t getAllMarksBegin() const =0
returns a STL-like random access iterator to the begin of the sequence of marks.
bool IsContentNode() const
Definition: node.hxx:628
static void MovePtForward(SwPaM &rPam, bool bMvBkwrd)
Definition: undobj.cxx:837
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
struct _xmlTextWriter * xmlTextWriterPtr
virtual void UndoImpl(::sw::UndoRedoContext &)=0
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:501
static bool IsNotBackspaceHeuristic(SwPosition const &rStart, SwPosition const &rEnd)
Definition: undobj.cxx:1571
SwTextFootnote * SeekEntry(const SwNodeIndex &rIdx, size_t *pPos=nullptr) const
Definition: ftnidx.cxx:409
Style of a layout element.
Definition: frmfmt.hxx:57
::sw::UndoManager & GetUndoManager()
Definition: doc.cxx:132
static bool HasHiddenRedlines(const SwRedlineSaveDatas &rSData)
Definition: undobj.cxx:1477
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:131
const SwPosition * GetPoint() const
Definition: pam.hxx:207
Pos1 start touches at Pos2 end.
void DelContentIndex(const SwPosition &pMark, const SwPosition &pPoint, DelContentType nDelContentType=DelContentType::AllMask)
Definition: undobj.cxx:862
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:206
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
OUString Apply(const OUString &rStr) const
Definition: SwRewriter.cxx:43
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
OUString ShortenString(const OUString &rStr, sal_Int32 nLength, const OUString &rFillStr)
Shortens a string to a maximum length.
Definition: undobj.cxx:1517
static void SetSaveData(SwDoc &rDoc, SwRedlineSaveDatas &rSData)
Definition: undobj.cxx:1458
void Exchange()
Definition: pam.cxx:489
virtual bool DeleteRedline(const SwPaM &rPam, bool bSaveInUndo, RedlineType nDelType)=0
SwContentNode * GetContentNode()
Definition: node.hxx:615
vector_type::size_type size_type
Definition: docary.hxx:228
FlyAnchors.
Definition: fmtanchr.hxx:34
void MakeStartIndex(SwIndex *pIdx)
Definition: node.hxx:391
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
SwNoTextNode * GetNoTextNode()
Definition: ndnotxt.hxx:96
ViewShellId m_nViewShellId
Definition: undobj.hxx:57
sal_Int32 m_nEndContent
Definition: undobj.hxx:230
SwDoc * GetDoc()
Definition: node.hxx:702
SwDoc * GetDoc() const
Definition: pam.hxx:243
virtual void UndoWithContext(SfxUndoContext &) override
Definition: undobj.cxx:229
Marks a character position inside a document model node.
Definition: index.hxx:37
void PaMCorrRel(const SwNodeIndex &rOldNode, const SwPosition &rNewPos, const sal_Int32 nOffset)
Sets all PaMs in OldNode to relative Pos.
Definition: doccorr.cxx:240
std::optional< OUString > maComment
Definition: undobj.hxx:62
Marks a node in the document model.
Definition: ndindex.hxx:31
bool m_bCacheComment
Definition: undobj.hxx:61
bool IsEndNode() const
Definition: node.hxx:632
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:693
static bool MovePtBackward(SwPaM &rPam)
Definition: undobj.cxx:824
OUString SwResId(const char *pId)
Definition: swmodule.cxx:178
bool empty() const
virtual OUString GetComment() const override
Returns textual comment for this undo object.
Definition: undobj.cxx:659
std::unique_ptr< SwNodeIndex > m_pMovedStart
Definition: undobj.hxx:202
const SwPosition * Start() const
Definition: pam.hxx:212
void RedlineToDoc(SwPaM const &rPam)
Definition: undobj.cxx:1362
virtual const SwRangeRedline * GetRedline(const SwPosition &rPos, SwRedlineTable::size_type *pFndPos) const =0
sal_uLong m_nSttNode
Definition: undobj.hxx:229
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:458
const OUString & GetComment(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1739
ignore Redlines
void EraseText(const SwIndex &rIdx, const sal_Int32 nCount=SAL_MAX_INT32, const SwInsertFlags nMode=SwInsertFlags::DEFAULT)
delete text content ATTENTION: must not be called with a range that overlaps the start of an attribut...
Definition: ndtxt.cxx:2660
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
void RestoreSection(SwDoc *pDoc, SwNodeIndex *pIdx, sal_uInt16 nSectType)
Definition: undobj.cxx:1265
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:334
void SetPaM(SwPaM &, bool bCorrToContent=false) const
Definition: undobj.cxx:80
static void MoveFromUndoNds(SwDoc &rDoc, sal_uLong nNodeIdx, SwPosition &rInsPos, const sal_uLong *pEndNdIdx=nullptr, bool bForceCreateFrames=false)
Definition: undobj.cxx:765
DelContentType
Definition: undobj.hxx:133
virtual sal_Int32 getAllMarksCount() const =0
returns the number of marks.
void CorrAbs(const SwNodeIndex &rOldNode, const SwPosition &rNewPos, const sal_Int32 nOffset=0, bool bMoveCursor=false)
Definition: doccorr.cxx:167
Pos1 overlaps Pos2 at the end.
const SwNodes & GetNodes() const
Definition: ndindex.hxx:156
virtual ~SwUndo() override
Definition: undobj.cxx:188
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:59
#define SAL_INFO(area, stream)
sal_Int32 GetIndex() const
Definition: index.hxx:95
SwNodes & GetNodes()
Definition: doc.hxx:403
SwUndo(SwUndoId const nId, const SwDoc *pDoc)
Definition: undobj.cxx:161
const SwPosition * End() const
Definition: pam.hxx:217
SwNodeIndex aEnd
Definition: ndindex.hxx:133
bool m_isRepeatIgnored
for multi-selection, only repeat 1st selection
Definition: undobj.hxx:58
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1734
virtual void Redo() override
Definition: undobj.cxx:224
virtual void RedoWithContext(SfxUndoContext &) override
Definition: undobj.cxx:238
static void RemoveIdxRel(sal_uLong, const SwPosition &)
Definition: undobj.cxx:153
bool empty() const
Definition: UndoCore.hxx:75
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:58
friend class SwRangeRedline
Definition: redline.hxx:89
virtual void RedoImpl(::sw::UndoRedoContext &)=0
OUString GetUndoComment(SwUndoId eId)
Definition: undobj.cxx:271
virtual void Undo() override
Definition: undobj.cxx:219
Any result
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:628
ResultType type
virtual RedlineFlags GetRedlineFlags() const =0
Query the currently set redline mode.
size_t size() const
bool IsFlySelectedByCursor(SwDoc const &rDoc, SwPosition const &rStart, SwPosition const &rEnd)
check at-char and at-para flys in rDoc
Definition: undobj.cxx:1663
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:475
Pos1 behind Pos2.
static bool FillSaveData(const SwPaM &rRange, SwRedlineSaveDatas &rSData, bool bDelRange=true, bool bCopyNext=true)
Definition: undobj.cxx:1393
virtual const SwRedlineTable & GetRedlineTable() const =0
ViewShellId GetViewShellId() const override
See SfxUndoAction::GetViewShellId().
Definition: undobj.cxx:688
const SwIndexReg * GetIdxReg() const
Definition: index.hxx:101
SwNode & GetEndOfExtras() const
This is the last EndNode of a special section.
Definition: ndarr.hxx:161
bool IsTextNode() const
Definition: node.hxx:636
sal_uInt32 m_nId
void SaveSection(const SwNodeIndex &rSttIdx)
Definition: undobj.cxx:1212
SwNodeIndex * GetContentIdx() const
Definition: redline.hxx:184
bool IsDelBox() const
Definition: undobj.cxx:182
const sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:61
Pos1 overlaps Pos2 at the beginning.
sal_Int32 m_nSttContent
Definition: undobj.hxx:230
Definition: view.hxx:144
sal_uInt16 nPos
bool IsInWriterfilterImport() const
Definition: doc.hxx:969
SwComparePosition
Definition: pam.hxx:64
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:836
static bool IsAtEndOfSection2(SwPosition const &rPos)
passed start / end position could be on section start / end node
Definition: undobj.cxx:1559
void SetAnchor(const SwPosition *pPos)
Definition: atrfrm.cxx:1483
bool MoveNodes(const SwNodeRange &, SwNodes &rNodes, const SwNodeIndex &, bool bNewFrames=true)
move the node pointer
Definition: nodes.cxx:394
static SwStartNode * MakeEmptySection(const SwNodeIndex &rIdx, SwStartNodeType=SwNormalStartNode)
Create an empty section of Start- and EndNote.
Definition: nodes.cxx:1873
Base class of the Writer document model elements.
Definition: node.hxx:79
void MoveRange(SwPaM &, SwPosition &, SwNodes &rNodes)
move a range
Definition: nodes.cxx:1420
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo