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