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