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