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->GetNodeIndex();
68 }
69 else
70 {
71 // no selection !!
74 }
75
76 m_nSttNode = pStt->GetNodeIndex();
78}
79
80void SwUndRng::SetPaM( SwPaM & rPam, bool bCorrToContent ) const
81{
82 rPam.DeleteMark();
84 SwNode& rNd = rPam.GetPointNode();
85 if( !rNd.IsContentNode() && bCorrToContent )
87
88 if( !m_nEndNode && COMPLETE_STRING == m_nEndContent ) // no selection
89 return ;
90
91 rPam.SetMark();
93 return; // nothing left to do
94
96 if( !rPam.GetPointNode().IsContentNode() && bCorrToContent )
98}
99
101 ::sw::UndoRedoContext & rContext, bool const bCorrToContent) const
102{
103 SwCursor & rPaM( rContext.GetCursorSupplier().CreateNewShellCursor() );
104 SetPaM( rPaM, bCorrToContent );
105 return rPaM;
106}
107
109 const SwNodeOffset* pEndIdx )
110{
111 SwNodeIndex aIdx( rDoc.GetNodes(), nSttIdx );
112 SwNodeIndex aEndIdx( rDoc.GetNodes(), pEndIdx ? *pEndIdx
113 : aIdx.GetNode().EndOfSectionIndex() );
114 SwPosition aPos( rDoc.GetNodes().GetEndOfPostIts() );
115 SwDoc::CorrAbs( aIdx, aEndIdx, aPos, true );
116}
117
118void SwUndo::RemoveIdxFromRange( SwPaM& rPam, bool bMoveNext )
119{
120 const SwPosition* pEnd = rPam.End();
121 if( bMoveNext )
122 {
123 if( pEnd != rPam.GetPoint() )
124 rPam.Exchange();
125
126 SwNodeIndex aStt( rPam.GetMark()->GetNode() );
127 SwNodeIndex aEnd( rPam.GetPoint()->GetNode() );
128
129 if( !rPam.Move( fnMoveForward ) )
130 {
131 rPam.Exchange();
132 if( !rPam.Move( fnMoveBackward ) )
133 {
134 rPam.GetPoint()->Assign( rPam.GetDoc().GetNodes().GetEndOfPostIts() );
135 }
136 }
137
138 SwDoc::CorrAbs( aStt, aEnd, *rPam.GetPoint(), true );
139 }
140 else
141 SwDoc::CorrAbs( rPam, *pEnd, true );
142}
143
145{
146 // Move only the Cursor. Bookmarks/TOXMarks/etc. are done by the corresponding
147 // JoinNext/JoinPrev
148 ::PaMCorrRel( *rPos.GetNode().GetNodes()[nIdx], rPos );
149}
150
151SwUndo::SwUndo(SwUndoId const nId, const SwDoc* pDoc)
152 : m_nId(nId), m_nOrigRedlineFlags(RedlineFlags::NONE)
153 , m_nViewShellId(CreateViewShellId(pDoc))
154 , m_isRepeatIgnored(false)
155 , m_bCacheComment(true)
156{
157}
158
160{
161 ViewShellId nRet(-1);
162
163 if (const SwDocShell* pDocShell = pDoc->GetDocShell())
164 {
165 if (const SwView* pView = pDocShell->GetView())
166 nRet = pView->GetViewShellId();
167 }
168
169 return nRet;
170}
171
173{
176}
177
179{
180}
181
182namespace {
183
184class UndoRedoRedlineGuard
185{
186public:
187 UndoRedoRedlineGuard(::sw::UndoRedoContext const & rContext, SwUndo const & rUndo)
188 : m_rRedlineAccess(rContext.GetDoc().getIDocumentRedlineAccess())
189 , m_eMode(m_rRedlineAccess.GetRedlineFlags())
190 {
191 RedlineFlags const eTmpMode = rUndo.GetRedlineFlags();
192 if ((RedlineFlags::ShowMask & eTmpMode) != (RedlineFlags::ShowMask & m_eMode))
193 {
194 m_rRedlineAccess.SetRedlineFlags( eTmpMode );
195 }
196 m_rRedlineAccess.SetRedlineFlags_intern( eTmpMode | RedlineFlags::Ignore );
197 }
198 ~UndoRedoRedlineGuard()
199 {
200 m_rRedlineAccess.SetRedlineFlags(m_eMode);
201 }
202private:
203 IDocumentRedlineAccess & m_rRedlineAccess;
204 RedlineFlags const m_eMode;
205};
206
207}
208
210{
211 assert(false); // SwUndo::Undo(): ERROR: must call UndoWithContext instead
212}
213
215{
216 assert(false); // SwUndo::Redo(): ERROR: must call RedoWithContext instead
217}
218
220{
221 ::sw::UndoRedoContext *const pContext(
222 dynamic_cast< ::sw::UndoRedoContext * >(& rContext));
223 assert(pContext);
224 const UndoRedoRedlineGuard aUndoRedoRedlineGuard(*pContext, *this);
225 UndoImpl(*pContext);
226}
227
229{
230 ::sw::UndoRedoContext *const pContext(
231 dynamic_cast< ::sw::UndoRedoContext * >(& rContext));
232 assert(pContext);
233 const UndoRedoRedlineGuard aUndoRedoRedlineGuard(*pContext, *this);
234 RedoImpl(*pContext);
235}
236
238{
240 {
241 return; // ignore Repeat for multi-selections
242 }
243 ::sw::RepeatContext *const pRepeatContext(
244 dynamic_cast< ::sw::RepeatContext * >(& rContext));
245 assert(pRepeatContext);
246 RepeatImpl(*pRepeatContext);
247}
248
249bool SwUndo::CanRepeat(SfxRepeatTarget & rContext) const
250{
251 assert(dynamic_cast< ::sw::RepeatContext * >(& rContext));
252 (void)rContext;
253 // a MultiSelection action that doesn't do anything must still return true
255}
256
258{
259}
260
262{
263 TranslateId pId;
264 switch (eId)
265 {
266 case SwUndoId::EMPTY:
267 pId = STR_CANT_UNDO;
268 break;
269 case SwUndoId::START:
270 case SwUndoId::END:
271 break;
272 case SwUndoId::DELETE:
273 pId = STR_DELETE_UNDO;
274 break;
275 case SwUndoId::INSERT:
276 pId = STR_INSERT_UNDO;
277 break;
279 pId = STR_OVR_UNDO;
280 break;
282 pId = STR_SPLITNODE_UNDO;
283 break;
285 pId = STR_INSATTR_UNDO;
286 break;
288 pId = STR_SETFMTCOLL_UNDO;
289 break;
291 pId = STR_RESET_ATTR_UNDO;
292 break;
294 pId = STR_INSFMT_ATTR_UNDO;
295 break;
297 pId = STR_INSERT_DOC_UNDO;
298 break;
299 case SwUndoId::COPY:
300 pId = STR_COPY_UNDO;
301 break;
303 pId = STR_INSTABLE_UNDO;
304 break;
306 pId = STR_TABLETOTEXT_UNDO;
307 break;
309 pId = STR_TEXTTOTABLE_UNDO;
310 break;
312 pId = STR_SORT_TXT;
313 break;
315 pId = STR_INSERTFLY;
316 break;
318 pId = STR_TABLEHEADLINE;
319 break;
321 pId = STR_INSERTSECTION;
322 break;
324 pId = STR_OUTLINE_LR;
325 break;
327 pId = STR_OUTLINE_UD;
328 break;
330 pId = STR_OUTLINE_EDIT;
331 break;
332 case SwUndoId::INSNUM:
333 pId = STR_INSNUM;
334 break;
335 case SwUndoId::NUMUP:
336 pId = STR_NUMUP;
337 break;
339 pId = STR_MOVENUM;
340 break;
342 pId = STR_INSERTDRAW;
343 break;
345 pId = STR_NUMORNONUM;
346 break;
348 pId = STR_INC_LEFTMARGIN;
349 break;
351 pId = STR_DEC_LEFTMARGIN;
352 break;
354 pId = STR_INSERTLABEL;
355 break;
357 pId = STR_SETNUMRULESTART;
358 break;
359 case SwUndoId::CHGFTN:
360 pId = STR_CHANGEFTN;
361 break;
363 SAL_INFO("sw.core", "Should NEVER be used/translated");
364 return "$1";
366 pId = STR_ACCEPT_REDLINE;
367 break;
369 pId = STR_REJECT_REDLINE;
370 break;
372 pId = STR_SPLIT_TABLE;
373 break;
375 pId = STR_DONTEXPAND;
376 break;
378 pId = STR_AUTOCORRECT;
379 break;
381 pId = STR_MERGE_TABLE;
382 break;
384 pId = STR_TRANSLITERATE;
385 break;
387 pId = STR_PASTE_CLIPBOARD_UNDO;
388 break;
389 case SwUndoId::TYPING:
390 pId = STR_TYPING_UNDO;
391 break;
392 case SwUndoId::MOVE:
393 pId = STR_MOVE_UNDO;
394 break;
396 pId = STR_INSERT_GLOSSARY;
397 break;
399 pId = STR_DELBOOKMARK;
400 break;
402 pId = STR_INSBOOKMARK;
403 break;
405 pId = STR_SORT_TBL;
406 break;
408 pId = STR_DELETEFLY;
409 break;
411 pId = STR_AUTOFORMAT;
412 break;
414 pId = STR_REPLACE;
415 break;
417 pId = STR_DELETESECTION;
418 break;
420 pId = STR_CHANGESECTION;
421 break;
423 pId = STR_CHANGEDEFATTR;
424 break;
425 case SwUndoId::DELNUM:
426 pId = STR_DELNUM;
427 break;
429 pId = STR_DRAWUNDO;
430 break;
432 pId = STR_DRAWGROUP;
433 break;
435 pId = STR_DRAWUNGROUP;
436 break;
438 pId = STR_DRAWDELETE;
439 break;
440 case SwUndoId::REREAD:
441 pId = STR_REREAD;
442 break;
443 case SwUndoId::DELGRF:
444 pId = STR_DELGRF;
445 break;
447 pId = STR_TABLE_ATTR;
448 break;
450 pId = STR_UNDO_TABLE_AUTOFMT;
451 break;
453 pId = STR_UNDO_TABLE_INSCOL;
454 break;
456 pId = STR_UNDO_TABLE_INSROW;
457 break;
459 pId = STR_UNDO_TABLE_DELBOX;
460 break;
462 pId = STR_UNDO_TABLE_SPLIT;
463 break;
465 pId = STR_UNDO_TABLE_MERGE;
466 break;
468 pId = STR_TABLE_NUMFORMAT;
469 break;
470 case SwUndoId::INSTOX:
471 pId = STR_INSERT_TOX;
472 break;
474 pId = STR_CLEAR_TOX_RANGE;
475 break;
477 pId = STR_TABLE_TBLCPYTBL;
478 break;
479 case SwUndoId::CPYTBL:
480 pId = STR_TABLE_CPYTBL;
481 break;
483 pId = STR_INS_FROM_SHADOWCRSR;
484 break;
485 case SwUndoId::CHAINE:
486 pId = STR_UNDO_CHAIN;
487 break;
489 pId = STR_UNDO_UNCHAIN;
490 break;
492 pId = STR_UNDO_FTNINFO;
493 break;
495 pId = STR_UNDO_COMPAREDOC;
496 break;
498 pId = STR_UNDO_SETFLYFRMFMT;
499 break;
501 pId = STR_UNDO_SETRUBYATTR;
502 break;
504 pId = STR_TOXCHANGE;
505 break;
507 pId = STR_UNDO_PAGEDESC_CREATE;
508 break;
510 pId = STR_UNDO_PAGEDESC;
511 break;
513 pId = STR_UNDO_PAGEDESC_DELETE;
514 break;
516 pId = STR_UNDO_HEADER_FOOTER;
517 break;
518 case SwUndoId::FIELD:
519 pId = STR_UNDO_FIELD;
520 break;
522 pId = STR_UNDO_TXTFMTCOL_CREATE;
523 break;
525 pId = STR_UNDO_TXTFMTCOL_DELETE;
526 break;
528 pId = STR_UNDO_TXTFMTCOL_RENAME;
529 break;
531 pId = STR_UNDO_CHARFMT_CREATE;
532 break;
534 pId = STR_UNDO_CHARFMT_DELETE;
535 break;
537 pId = STR_UNDO_CHARFMT_RENAME;
538 break;
540 pId = STR_UNDO_FRMFMT_CREATE;
541 break;
543 pId = STR_UNDO_FRMFMT_DELETE;
544 break;
546 pId = STR_UNDO_FRMFMT_RENAME;
547 break;
549 pId = STR_UNDO_NUMRULE_CREATE;
550 break;
552 pId = STR_UNDO_NUMRULE_DELETE;
553 break;
555 pId = STR_UNDO_NUMRULE_RENAME;
556 break;
558 pId = STR_UNDO_BOOKMARK_RENAME;
559 break;
561 pId = STR_UNDO_INDEX_ENTRY_INSERT;
562 break;
564 pId = STR_UNDO_INDEX_ENTRY_DELETE;
565 break;
567 pId = STR_UNDO_COL_DELETE;
568 break;
570 pId = STR_UNDO_ROW_DELETE;
571 break;
573 pId = STR_UNDO_PAGEDESC_RENAME;
574 break;
576 pId = STR_NUMDOWN;
577 break;
579 pId = STR_UNDO_FLYFRMFMT_TITLE;
580 break;
582 pId = STR_UNDO_FLYFRMFMT_DESCRIPTION;
583 break;
585 pId = STR_UNDO_TBLSTYLE_CREATE;
586 break;
588 pId = STR_UNDO_TBLSTYLE_DELETE;
589 break;
591 pId = STR_UNDO_TBLSTYLE_UPDATE;
592 break;
594 pId = STR_REPLACE_UNDO;
595 break;
597 pId = STR_INSERT_PAGE_BREAK_UNDO;
598 break;
600 pId = STR_INSERT_COLUMN_BREAK_UNDO;
601 break;
603 pId = STR_INSERT_ENV_UNDO;
604 break;
606 pId = STR_DRAG_AND_COPY;
607 break;
609 pId = STR_DRAG_AND_MOVE;
610 break;
612 pId = STR_INSERT_CHART;
613 break;
615 pId = STR_INSERT_FOOTNOTE;
616 break;
618 pId = STR_INSERT_URLBTN;
619 break;
621 pId = STR_INSERT_URLTXT;
622 break;
624 pId = STR_DELETE_INVISIBLECNTNT;
625 break;
627 pId = STR_REPLACE_STYLE;
628 break;
630 pId = STR_DELETE_PAGE_BREAK;
631 break;
633 pId = STR_TEXT_CORRECTION;
634 break;
636 pId = STR_UNDO_TABLE_DELETE;
637 break;
639 break;
641 pId = STR_PARAGRAPH_SIGN_UNDO;
642 break;
644 pId = STR_UNDO_INSERT_FORM_FIELD;
645 break;
646 }
647
648 assert(pId);
649 return SwResId(pId);
650}
651
652OUString SwUndo::GetComment() const
653{
654 OUString aResult;
655
656 if (m_bCacheComment)
657 {
658 if (! maComment)
659 {
661
662 SwRewriter aRewriter = GetRewriter();
663
664 maComment = aRewriter.Apply(*maComment);
665 }
666
667 aResult = *maComment;
668 }
669 else
670 {
671 aResult = GetUndoComment(GetId());
672
673 SwRewriter aRewriter = GetRewriter();
674
675 aResult = aRewriter.Apply(aResult);
676 }
677
678 return aResult;
679}
680
682{
683 return m_nViewShellId;
684}
685
687{
688 SwRewriter aResult;
689
690 return aResult;
691}
692
694{}
695
697{
698}
699
701{
702 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwUndoSaveContent"));
703 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
704
705 if (m_pHistory)
706 {
707 m_pHistory->dumpAsXml(pWriter);
708 }
709
710 (void)xmlTextWriterEndElement(pWriter);
711}
712
713// This is needed when deleting content. For REDO all contents will be moved
714// into the UndoNodesArray. These methods always create a new node to insert
715// content. As a result, the attributes will not be expanded.
716// - MoveTo moves from NodesArray into UndoNodesArray
717// - MoveFrom moves from UndoNodesArray into NodesArray
718
719// If pEndNdIdx is given, Undo/Redo calls -Ins/DelFly. In that case the whole
720// section should be moved.
722 SwNodeOffset* pEndNdIdx )
723{
724 SwDoc& rDoc = rPaM.GetDoc();
725 ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
726
727 SwNoTextNode* pCpyNd = rPaM.GetPointNode().GetNoTextNode();
728
729 // here comes the actual delete (move)
730 SwNodes & rNds = rDoc.GetUndoManager().GetUndoNodes();
731 SwPosition aPos( pEndNdIdx ? rNds.GetEndOfPostIts()
732 : rNds.GetEndOfExtras() );
733
734 const SwPosition* pStt = rPaM.Start(), *pEnd = rPaM.End();
735
736 SwNodeOffset nTmpMvNode = aPos.GetNodeIndex();
737
738 if( pCpyNd || pEndNdIdx )
739 {
740 SwNodeRange aRg( pStt->GetNode(), SwNodeOffset(0), pEnd->GetNode(), SwNodeOffset(1) );
741 rDoc.GetNodes().MoveNodes( aRg, rNds, aPos.GetNode(), true );
742 aPos.Adjust(SwNodeOffset(-1));
743 }
744 else
745 {
746 rDoc.GetNodes().MoveRange( rPaM, aPos, rNds );
747 }
748 if( pEndNdIdx )
749 *pEndNdIdx = aPos.GetNodeIndex();
750
751 // old position
752 aPos.Assign(nTmpMvNode);
753 if( pNodeIdx )
754 *pNodeIdx = aPos.GetNode();
755}
756
758 SwPosition& rInsPos,
759 const SwNodeOffset* pEndNdIdx, bool const bForceCreateFrames)
760{
761 // here comes the recovery
762 SwNodes & rNds = rDoc.GetUndoManager().GetUndoNodes();
763 if( nNodeIdx == rNds.GetEndOfPostIts().GetIndex() )
764 return; // nothing saved
765
766 ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
767
768 SwPaM aPaM( rInsPos );
769 if( pEndNdIdx ) // than get the section from it
770 aPaM.GetPoint()->Assign( *rNds[SwNodeOffset(0)], *pEndNdIdx );
771 else
772 {
773 aPaM.GetPoint()->Assign( rNds.GetEndOfExtras() );
775 }
776
777 SwTextNode* pTextNd = aPaM.GetPointNode().GetTextNode();
778 if (!pEndNdIdx && pTextNd)
779 {
780 aPaM.SetMark();
781 aPaM.GetPoint()->Assign(nNodeIdx, 0);
782
783 SaveRedlEndPosForRestore aRedlRest( rInsPos.GetNode(), rInsPos.GetContentIndex() );
784
785 rNds.MoveRange( aPaM, rInsPos, rDoc.GetNodes() );
786
787 // delete the last Node as well
788 bool bDeleteLastNode = false;
789 if( !aPaM.GetPoint()->GetContentIndex() )
790 bDeleteLastNode = true;
791 else
792 {
793 // still empty Nodes at the end?
794 aPaM.GetPoint()->Adjust(SwNodeOffset(1));
795 if ( &rNds.GetEndOfExtras() != &aPaM.GetPoint()->GetNode() )
796 bDeleteLastNode = true;
797 }
798 if( bDeleteLastNode )
799 {
800 SwNode& rDelNode = aPaM.GetPoint()->GetNode();
801 SwNodeOffset nDelOffset = rNds.GetEndOfExtras().GetIndex() -
802 aPaM.GetPoint()->GetNodeIndex();
803 //move it so we don't have SwContentIndex pointing at a node when it is deleted.
804 aPaM.GetPoint()->Adjust(SwNodeOffset(-1));
805 aPaM.SetMark();
806 rNds.Delete( rDelNode, nDelOffset );
807 }
808
809 aRedlRest.Restore();
810 }
811 else
812 {
813 SwNodeRange aRg( rNds, nNodeIdx, (pEndNdIdx
814 ? ((*pEndNdIdx) + 1)
815 : rNds.GetEndOfExtras().GetIndex() ) );
816 rNds.MoveNodes(aRg, rDoc.GetNodes(), rInsPos.GetNode(), nullptr == pEndNdIdx || bForceCreateFrames);
817
818 }
819}
820
821// These two methods move the Point of Pam backwards/forwards. With that, one
822// can span an area for a Undo/Redo. (The Point is then positioned in front of
823// the area to manipulate!)
824// The flag indicates if there is still content in front of Point.
826{
827 rPam.SetMark();
828 if( rPam.Move( fnMoveBackward ))
829 return true;
830
831 // If there is no content onwards, set Point simply to the previous position
832 // (Node and Content, so that Content will be detached!)
833 rPam.GetPoint()->Adjust(SwNodeOffset(-1));
834 return false;
835}
836
837void SwUndoSaveContent::MovePtForward( SwPaM& rPam, bool bMvBkwrd )
838{
839 // Was there content before this position?
840 if( bMvBkwrd )
841 rPam.Move( fnMoveForward );
842 else
843 {
844 rPam.GetPoint()->Adjust(SwNodeOffset(1));
845 SwContentNode* pCNd = rPam.GetPointContentNode();
846 if( !pCNd )
847 rPam.Move( fnMoveForward );
848 }
849}
850
851// Delete all objects that have ContentIndices to the given area.
852// Currently (1994) these exist:
853// - Footnotes
854// - Flys
855// - Bookmarks
856
857// #i81002# - extending method
858// delete certain (not all) cross-reference bookmarks at text node of <rMark>
859// and at text node of <rPoint>, if these text nodes aren't the same.
861 const SwPosition& rPoint,
862 DelContentType nDelContentType )
863{
864 const SwPosition *pStt = rMark < rPoint ? &rMark : &rPoint,
865 *pEnd = &rMark == pStt ? &rPoint : &rMark;
866
867 SwDoc& rDoc = rMark.GetNode().GetDoc();
868
869 // if it's not in the doc array, probably missing some invalidation somewhere
870 assert(&rPoint.GetNodes() == &rDoc.GetNodes());
871 assert(&rMark.GetNodes() == &rDoc.GetNodes());
872
873 ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
874
875 // 1. Footnotes
876 if( DelContentType::Ftn & nDelContentType )
877 {
878 SwFootnoteIdxs& rFootnoteArr = rDoc.GetFootnoteIdxs();
879 if( !rFootnoteArr.empty() )
880 {
881 const SwNode* pFootnoteNd;
882 size_t nPos = 0;
883 rFootnoteArr.SeekEntry( pStt->GetNode(), &nPos );
884 SwTextFootnote* pSrch;
885
886 // for now delete all that come afterwards
887 while( nPos < rFootnoteArr.size() && ( pFootnoteNd =
888 &( pSrch = rFootnoteArr[ nPos ] )->GetTextNode())->GetIndex()
889 <= pEnd->GetNodeIndex() )
890 {
891 const sal_Int32 nFootnoteSttIdx = pSrch->GetStart();
892 if( (DelContentType::CheckNoCntnt & nDelContentType )
893 ? (&pEnd->GetNode() == pFootnoteNd )
894 : (( &pStt->GetNode() == pFootnoteNd &&
895 pStt->GetContentIndex() > nFootnoteSttIdx) ||
896 ( &pEnd->GetNode() == pFootnoteNd &&
897 nFootnoteSttIdx >= pEnd->GetContentIndex() )) )
898 {
899 ++nPos; // continue searching
900 continue;
901 }
902
903// FIXME: duplicated code here and below -> refactor?
904 // Unfortunately an index needs to be created. Otherwise there
905 // will be problems with TextNode because the index will be
906 // deleted in the DTOR of SwFootnote!
907 SwTextNode* pTextNd = const_cast<SwTextNode*>(static_cast<const SwTextNode*>(pFootnoteNd));
908 if( !m_pHistory )
909 m_pHistory.reset( new SwHistory );
910 SwTextAttr* const pFootnoteHint =
911 pTextNd->GetTextAttrForCharAt( nFootnoteSttIdx );
912 assert(pFootnoteHint);
913 SwContentIndex aIdx( pTextNd, nFootnoteSttIdx );
914 m_pHistory->Add( pFootnoteHint, pTextNd->GetIndex(), false );
915 pTextNd->EraseText( aIdx, 1 );
916 }
917
918 while( nPos-- && ( pFootnoteNd = &( pSrch = rFootnoteArr[ nPos ] )->
919 GetTextNode())->GetIndex() >= pStt->GetNodeIndex() )
920 {
921 const sal_Int32 nFootnoteSttIdx = pSrch->GetStart();
922 if( !(DelContentType::CheckNoCntnt & nDelContentType) && (
923 ( &pStt->GetNode() == pFootnoteNd &&
924 pStt->GetContentIndex() > nFootnoteSttIdx ) ||
925 ( &pEnd->GetNode() == pFootnoteNd &&
926 nFootnoteSttIdx >= pEnd->GetContentIndex() )))
927 continue; // continue searching
928
929 // Unfortunately an index needs to be created. Otherwise there
930 // will be problems with TextNode because the index will be
931 // deleted in the DTOR of SwFootnote!
932 SwTextNode* pTextNd = const_cast<SwTextNode*>(static_cast<const SwTextNode*>(pFootnoteNd));
933 if( !m_pHistory )
934 m_pHistory.reset( new SwHistory );
935 SwTextAttr* const pFootnoteHint =
936 pTextNd->GetTextAttrForCharAt( nFootnoteSttIdx );
937 assert(pFootnoteHint);
938 SwContentIndex aIdx( pTextNd, nFootnoteSttIdx );
939 m_pHistory->Add( pFootnoteHint, pTextNd->GetIndex(), false );
940 pTextNd->EraseText( aIdx, 1 );
941 }
942 }
943 }
944
945 // 2. Flys
946 if( DelContentType::Fly & nDelContentType )
947 {
948 sal_uInt16 nChainInsPos = m_pHistory ? m_pHistory->Count() : 0;
949 const SwFrameFormats& rSpzArr = *rDoc.GetSpzFrameFormats();
950 if( !rSpzArr.empty() )
951 {
952 SwFrameFormat* pFormat;
953 const SwFormatAnchor* pAnchor;
954 size_t n = rSpzArr.size();
955 const SwPosition* pAPos;
956
957 while( n && !rSpzArr.empty() )
958 {
959 pFormat = rSpzArr[--n];
960 pAnchor = &pFormat->GetAnchor();
961 switch( pAnchor->GetAnchorId() )
962 {
963 case RndStdIds::FLY_AS_CHAR:
964 if( nullptr != (pAPos = pAnchor->GetContentAnchor() ) &&
965 (( DelContentType::CheckNoCntnt & nDelContentType )
966 ? ( pStt->GetNode() <= pAPos->GetNode() &&
967 pAPos->GetNode() < pEnd->GetNode() )
968 : ( *pStt <= *pAPos && *pAPos < *pEnd )) )
969 {
970 if( !m_pHistory )
971 m_pHistory.reset( new SwHistory );
972 SwTextNode *const pTextNd =
973 pAPos->GetNode().GetTextNode();
974 SwTextAttr* const pFlyHint = pTextNd->GetTextAttrForCharAt(
975 pAPos->GetContentIndex());
976 assert(pFlyHint);
977 m_pHistory->Add( pFlyHint, SwNodeOffset(0), false );
978 // reset n so that no Format is skipped
979 n = n >= rSpzArr.size() ? rSpzArr.size() : n+1;
980 }
981 break;
982 case RndStdIds::FLY_AT_PARA:
983 {
984 pAPos = pAnchor->GetContentAnchor();
985 if (pAPos &&
986 pStt->GetNode() <= pAPos->GetNode() && pAPos->GetNode() <= pEnd->GetNode())
987 {
988 if (!m_pHistory)
989 m_pHistory.reset( new SwHistory );
990
991 if (!(DelContentType::Replace & nDelContentType)
992 && IsSelectFrameAnchoredAtPara(*pAPos, *pStt, *pEnd, nDelContentType))
993 {
994 m_pHistory->AddDeleteFly(*pFormat, nChainInsPos);
995 // reset n so that no Format is skipped
996 n = n >= rSpzArr.size() ? rSpzArr.size() : n+1;
997 }
998 // Moving the anchor?
1000 & nDelContentType) &&
1001 // for SwUndoDelete: rPoint is the node that
1002 // will be Joined - so anchor should be moved
1003 // off it - but UndoImpl() split will insert
1004 // new node *before* existing one so a no-op
1005 // may need to be done here to add it to
1006 // history for Undo.
1007 (rPoint.GetNodeIndex() == pAPos->GetNodeIndex()
1008 || pStt->GetNodeIndex() == pAPos->GetNodeIndex())
1009 // Do not try to move the anchor to a table!
1010 && rMark.GetNode().IsTextNode())
1011 {
1012 m_pHistory->AddChangeFlyAnchor(*pFormat);
1013 SwFormatAnchor aAnch( *pAnchor );
1014 SwPosition aPos( rMark.GetNode() );
1015 aAnch.SetAnchor( &aPos );
1016 pFormat->SetFormatAttr( aAnch );
1017 }
1018 }
1019 }
1020 break;
1021 case RndStdIds::FLY_AT_CHAR:
1022 if( nullptr != (pAPos = pAnchor->GetContentAnchor() ) &&
1023 ( pStt->GetNode() <= pAPos->GetNode() && pAPos->GetNode() <= pEnd->GetNode() ) )
1024 {
1025 if( !m_pHistory )
1026 m_pHistory.reset( new SwHistory );
1027 if (!(DelContentType::Replace & nDelContentType)
1029 *pAPos, *pStt, *pEnd, nDelContentType))
1030 {
1031 m_pHistory->AddDeleteFly(*pFormat, nChainInsPos);
1032 n = n >= rSpzArr.size() ? rSpzArr.size() : n+1;
1033 }
1034 else if (!((DelContentType::CheckNoCntnt |
1036 & nDelContentType))
1037 {
1038 if( *pStt <= *pAPos && *pAPos < *pEnd )
1039 {
1040 // These are the objects anchored
1041 // between section start and end position
1042 // Do not try to move the anchor to a table!
1043 if( rMark.GetNode().GetTextNode() )
1044 {
1045 m_pHistory->AddChangeFlyAnchor(*pFormat);
1046 SwFormatAnchor aAnch( *pAnchor );
1047 aAnch.SetAnchor( &rMark );
1048 pFormat->SetFormatAttr( aAnch );
1049 }
1050 }
1051 }
1052 }
1053 break;
1054 case RndStdIds::FLY_AT_FLY:
1055
1056 if( nullptr != (pAPos = pAnchor->GetContentAnchor() ) &&
1057 pStt->GetNode() == pAPos->GetNode() )
1058 {
1059 if( !m_pHistory )
1060 m_pHistory.reset( new SwHistory );
1061
1062 m_pHistory->AddDeleteFly(*pFormat, nChainInsPos);
1063
1064 // reset n so that no Format is skipped
1065 n = n >= rSpzArr.size() ? rSpzArr.size() : n+1;
1066 }
1067 break;
1068 default: break;
1069 }
1070 }
1071 }
1072 }
1073
1074 // 3. Bookmarks
1075 if( !(DelContentType::Bkm & nDelContentType) )
1076 return;
1077
1078 IDocumentMarkAccess* const pMarkAccess = rDoc.getIDocumentMarkAccess();
1079 if( !pMarkAccess->getAllMarksCount() )
1080 return;
1081
1082 for( sal_Int32 n = 0; n < pMarkAccess->getAllMarksCount(); ++n )
1083 {
1084 // #i81002#
1085 bool bSavePos = false;
1086 bool bSaveOtherPos = false;
1087 const ::sw::mark::IMark *const pBkmk = pMarkAccess->getAllMarksBegin()[n];
1088 auto const type(IDocumentMarkAccess::GetType(*pBkmk));
1089
1090 if( DelContentType::CheckNoCntnt & nDelContentType )
1091 {
1092 if ( pStt->GetNode() <= pBkmk->GetMarkPos().GetNode()
1093 && pBkmk->GetMarkPos().GetNode() < pEnd->GetNode() )
1094 {
1095 bSavePos = true;
1096 }
1097 if ( pBkmk->IsExpanded()
1098 && pStt->GetNode() <= pBkmk->GetOtherMarkPos().GetNode()
1099 && pBkmk->GetOtherMarkPos().GetNode() < pEnd->GetNode() )
1100 {
1101 bSaveOtherPos = true;
1102 }
1103 }
1104 else
1105 {
1106 // #i92125#
1107 // keep cross-reference bookmarks, if content inside one paragraph is deleted.
1108 if ( rMark.GetNode() == rPoint.GetNode()
1111 {
1112 continue;
1113 }
1114
1115 bool bMaybe = false;
1116 if ( *pStt <= pBkmk->GetMarkPos() && pBkmk->GetMarkPos() <= *pEnd )
1117 {
1118 if ( pBkmk->GetMarkPos() == *pEnd
1119 || ( *pStt == pBkmk->GetMarkPos() && pBkmk->IsExpanded() ) )
1120 bMaybe = true;
1121 else
1122 bSavePos = true;
1123 }
1124 if( pBkmk->IsExpanded() &&
1125 *pStt <= pBkmk->GetOtherMarkPos() && pBkmk->GetOtherMarkPos() <= *pEnd )
1126 {
1127 assert(!bSaveOtherPos);
1128 if ( bSavePos
1129 || (*pStt < pBkmk->GetOtherMarkPos() && pBkmk->GetOtherMarkPos() < *pEnd)
1130 || (bMaybe
1135 || (bMaybe
1136 && !(nDelContentType & DelContentType::Replace)
1138 && pStt->GetContentIndex() == 0 // entire paragraph deleted?
1139 && pEnd->GetContentIndex() == pEnd->GetNode().GetTextNode()->Len()))
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.GetNode() != rPoint.GetNode()
1153 && rMark.GetNode().GetTextNode()
1154 && rPoint.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->GetNode() == pBkmk->GetMarkPos().GetNode()
1160 && pEnd->GetContentIndex() != pEnd->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->GetNode() == pBkmk->GetMarkPos().GetNode() &&
1168 pStt->GetContentIndex() != 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_oMovedStart) // delete also the section from UndoNodes array
1215 {
1216 // SaveSection saves the content in the PostIt section.
1217 SwNodes& rUNds = m_oMovedStart->GetNode().GetNodes();
1218 // cid#1486004 Uncaught exception
1220
1221 m_oMovedStart.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()->GetNode() );
1252 SwNodeIndex aEndIdx( aPam.End()->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()->Adjust(SwNodeOffset(-1));
1262 aPam.GetMark()->Adjust(SwNodeOffset(+1));
1263 }
1264
1265 SwContentNode* pCNd = aPam.GetMarkContentNode();
1266 if( pCNd )
1267 aPam.GetMark()->SetContent( 0 );
1268 pCNd = aPam.GetPointContentNode();
1269 if( nullptr != pCNd )
1270 aPam.GetPoint()->SetContent( pCNd->Len() );
1271
1272 // Keep positions as SwContentIndex so that this section can be deleted in DTOR
1273 SwNodeOffset nEnd;
1274 m_oMovedStart = rRange.aStart;
1275 MoveToUndoNds(aPam, &*m_oMovedStart, &nEnd);
1276 m_nMoveLen = nEnd - m_oMovedStart->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.GetNode(),
1290 static_cast<SwStartNodeType>(nSectType) );
1291
1292 RestoreSection( pDoc, *pSttNd->EndOfSectionNode() );
1293
1294 if( pIdx )
1295 *pIdx = *pSttNd;
1296}
1297
1299 SwDoc *const pDoc, const SwNode& 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_oMovedStart->GetIndex() + m_nMoveLen - 1;
1306 MoveFromUndoNds(*pDoc, m_oMovedStart->GetIndex(), aInsPos, &nEnd, bForceCreateFrames);
1307
1308 // destroy indices again, content was deleted from UndoNodes array
1309 m_oMovedStart.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.GetNodeIndex();
1341 m_nEndContent = rEndPos.GetContentIndex();
1342 break;
1343
1344 case SwComparePosition::OverlapBehind: // Pos1 overlaps Pos2 at the end
1345 m_nSttNode = rSttPos.GetNodeIndex();
1346 m_nSttContent = rSttPos.GetContentIndex();
1347 break;
1348
1349 case SwComparePosition::Inside: // Pos1 lays completely in Pos2
1350 m_nSttNode = rSttPos.GetNodeIndex();
1351 m_nSttContent = rSttPos.GetContentIndex();
1352 m_nEndNode = rEndPos.GetNodeIndex();
1353 m_nEndContent = rEndPos.GetContentIndex();
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.ClearContentIdx();
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 auto [pStt, pEnd] = rRange.StartEnd(); // SwPosition*
1424 rRange.GetDoc().getIDocumentRedlineAccess().GetRedline( *pStt, &n );
1425 for ( ; n < rTable.size(); ++n )
1426 {
1427 SwRangeRedline* pRedl = rTable[n];
1428
1429 const SwComparePosition eCmpPos =
1430 ComparePosition( *pStt, *pEnd, *pRedl->Start(), *pRedl->End() );
1431 if ( eCmpPos != SwComparePosition::Before
1432 && eCmpPos != SwComparePosition::Behind
1433 && eCmpPos != SwComparePosition::CollideEnd
1434 && eCmpPos != SwComparePosition::CollideStart )
1435 {
1436
1437 rSData.push_back(std::unique_ptr<SwRedlineSaveData>(new SwRedlineSaveData(eCmpPos, *pStt, *pEnd, *pRedl, bCopyNext)));
1438 }
1439 }
1440 if( !rSData.empty() && bDelRange )
1441 {
1442 rRange.GetDoc().getIDocumentRedlineAccess().DeleteRedline( rRange, false, RedlineType::Any );
1443 }
1444 return !rSData.empty();
1445}
1446
1448 const SwPaM& rRange,
1449 SwRedlineSaveDatas& rSData )
1450{
1451 rSData.clear();
1452
1453 const SwPosition *pStt = rRange.Start(), *pEnd = rRange.End();
1456 rRange.GetDoc().getIDocumentRedlineAccess().GetRedline( *pStt, &n );
1457 for ( ; n < rTable.size(); ++n )
1458 {
1459 SwRangeRedline* pRedl = rTable[n];
1460 if ( RedlineType::Format == pRedl->GetType() )
1461 {
1462 const SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRedl->Start(), *pRedl->End() );
1463 if ( eCmpPos != SwComparePosition::Before
1464 && eCmpPos != SwComparePosition::Behind
1465 && eCmpPos != SwComparePosition::CollideEnd
1466 && eCmpPos != SwComparePosition::CollideStart )
1467 {
1468 rSData.push_back(std::unique_ptr<SwRedlineSaveData>(new SwRedlineSaveData(eCmpPos, *pStt, *pEnd, *pRedl, true)));
1469 }
1470
1471 }
1472 }
1473 return !rSData.empty();
1474}
1475
1476
1478{
1481 SwPaM aPam( rDoc.GetNodes().GetEndOfContent() );
1482
1483 for( size_t n = rSData.size(); n; )
1484 rSData[ --n ].RedlineToDoc( aPam );
1485
1486#if OSL_DEBUG_LEVEL > 0
1487 // check redline count against count saved in RedlineSaveData object
1488 // except in the case of moved redlines
1489 assert(rSData.empty() || rSData[0].m_bRedlineMoved ||
1490 (rSData[0].m_nRedlineCount == rDoc.getIDocumentRedlineAccess().GetRedlineTable().size()));
1491 // "redline count not restored properly"
1492#endif
1493
1495}
1496
1498{
1499 for( size_t n = rSData.size(); n; )
1500 if( rSData[ --n ].GetMvSttIdx() )
1501 return true;
1502 return false;
1503}
1504
1506 const SwRedlineSaveDatas& rCheck, bool bCurrIsEnd )
1507{
1508 if( rCurr.size() != rCheck.size() )
1509 return false;
1510
1511 for( size_t n = 0; n < rCurr.size(); ++n )
1512 {
1513 const SwRedlineSaveData& rSet = rCurr[ n ];
1514 const SwRedlineSaveData& rGet = rCheck[ n ];
1515 if( rSet.m_nSttNode != rGet.m_nSttNode ||
1516 rSet.GetMvSttIdx() || rGet.GetMvSttIdx() ||
1517 ( bCurrIsEnd ? rSet.m_nSttContent != rGet.m_nEndContent
1518 : rSet.m_nEndContent != rGet.m_nSttContent ) ||
1519 !rGet.CanCombine( rSet ) )
1520 {
1521 return false;
1522 }
1523 }
1524
1525 for( size_t n = 0; n < rCurr.size(); ++n )
1526 {
1527 SwRedlineSaveData& rSet = rCurr[ n ];
1528 const SwRedlineSaveData& rGet = rCheck[ n ];
1529 if( bCurrIsEnd )
1530 rSet.m_nSttContent = rGet.m_nSttContent;
1531 else
1532 rSet.m_nEndContent = rGet.m_nEndContent;
1533 }
1534 return true;
1535}
1536
1537OUString ShortenString(const OUString & rStr, sal_Int32 nLength, std::u16string_view aFillStr)
1538{
1539 assert(nLength - aFillStr.size() >= 2);
1540
1541 if (rStr.getLength() <= nLength)
1542 return rStr;
1543
1544 nLength -= aFillStr.size();
1545 if ( nLength < 2 )
1546 nLength = 2;
1547
1548 const sal_Int32 nFrontLen = nLength - nLength / 2;
1549 const sal_Int32 nBackLen = nLength - nFrontLen;
1550
1551 return OUString::Concat(rStr.subView(0, nFrontLen))
1552 + aFillStr
1553 + rStr.subView(rStr.getLength() - nBackLen);
1554}
1555
1556static bool IsAtEndOfSection(SwPosition const& rAnchorPos)
1557{
1558 SwNodeIndex node(*rAnchorPos.GetNode().EndOfSectionNode());
1559 SwContentNode *const pNode(SwNodes::GoPrevious(&node));
1560 assert(pNode);
1561 assert(rAnchorPos.GetNode() <= node.GetNode()); // last valid anchor pos is last content
1562 return node == rAnchorPos.GetNode()
1563 // at-para fly has no SwContentIndex!
1564 && (rAnchorPos.GetContentIndex() == pNode->Len() || rAnchorPos.GetContentNode() == nullptr);
1565}
1566
1567static bool IsAtStartOfSection(SwPosition const& rAnchorPos)
1568{
1569 SwNodes const& rNodes(rAnchorPos.GetNodes());
1570 SwNodeIndex node(*rAnchorPos.GetNode().StartOfSectionNode());
1571 SwContentNode *const pNode(rNodes.GoNext(&node));
1572 assert(pNode);
1573 (void) pNode;
1574 assert(node <= rAnchorPos.GetNode());
1575 return node == rAnchorPos.GetNode() && rAnchorPos.GetContentIndex() == 0;
1576}
1577
1579static bool IsAtEndOfSection2(SwPosition const& rPos)
1580{
1581 return rPos.GetNode().IsEndNode()
1582 || IsAtEndOfSection(rPos);
1583}
1584
1585static bool IsAtStartOfSection2(SwPosition const& rPos)
1586{
1587 return rPos.GetNode().IsStartNode()
1588 || IsAtStartOfSection(rPos);
1589}
1590
1592 SwPosition const& rStart, SwPosition const& rEnd)
1593{
1594 // check if the selection is backspace/delete created by DelLeft/DelRight
1595 if (rStart.GetNodeIndex() + 1 != rEnd.GetNodeIndex())
1596 return true;
1597 if (rEnd.GetContentIndex() != 0)
1598 return true;
1599 const SwTextNode* pTextNode = rStart.GetNode().GetTextNode();
1600 if (!pTextNode || rStart.GetContentIndex() != pTextNode->Len())
1601 return true;
1602 return false;
1603}
1604
1606 SwPosition const & rStart, SwPosition const & rEnd,
1607 DelContentType const nDelContentType)
1608{
1609 assert(rStart <= rEnd);
1610
1611 // CheckNoCntnt means DelFullPara which is obvious to handle
1612 if (DelContentType::CheckNoCntnt & nDelContentType)
1613 { // exclude selection end node because it won't be deleted
1614 return (rAnchorPos.GetNode() < rEnd.GetNode())
1615 && (rStart.GetNode() <= rAnchorPos.GetNode());
1616 }
1617
1618 if ((nDelContentType & DelContentType::WriterfilterHack)
1619 && rAnchorPos.GetDoc().IsInWriterfilterImport())
1620 { // FIXME hack for writerfilter RemoveLastParagraph() and MakeFlyAndMove(); can't test file format more specific?
1621 return (rStart < rAnchorPos) && (rAnchorPos < rEnd);
1622 }
1623
1624 if (nDelContentType & DelContentType::ExcludeFlyAtStartEnd)
1625 { // exclude selection start and end node
1626 return (rAnchorPos.GetNode() < rEnd.GetNode())
1627 && (rStart.GetNode() < rAnchorPos.GetNode());
1628 }
1629
1630 // in general, exclude the start and end position
1631 return ((rStart < rAnchorPos)
1632 || (rStart == rAnchorPos
1633 // special case: fully deleted node
1634 && ((rStart.GetNode() != rEnd.GetNode() && rStart.GetContentIndex() == 0
1635 // but not if the selection is backspace/delete!
1636 && IsNotBackspaceHeuristic(rStart, rEnd))
1637 || (IsAtStartOfSection(rAnchorPos) && IsAtEndOfSection2(rEnd)))))
1638 && ((rAnchorPos < rEnd)
1639 || (rAnchorPos == rEnd
1640 // special case: fully deleted node
1641 && ((rEnd.GetNode() != rStart.GetNode() && rEnd.GetContentIndex() == rEnd.GetNode().GetTextNode()->Len()
1642 && IsNotBackspaceHeuristic(rStart, rEnd))
1643 || (IsAtEndOfSection(rAnchorPos) && IsAtStartOfSection2(rStart)))));
1644}
1645
1647 SwPosition const & rStart, SwPosition const & rEnd,
1648 DelContentType const nDelContentType)
1649{
1650 assert(rStart <= rEnd);
1651
1652 // CheckNoCntnt means DelFullPara which is obvious to handle
1653 if (DelContentType::CheckNoCntnt & nDelContentType)
1654 { // exclude selection end node because it won't be deleted
1655 return (rAnchorPos.GetNode() < rEnd.GetNode())
1656 && (rStart.GetNode() <= rAnchorPos.GetNode());
1657 }
1658
1659 if ((nDelContentType & DelContentType::WriterfilterHack)
1660 && rAnchorPos.GetDoc().IsInWriterfilterImport())
1661 { // FIXME hack for writerfilter RemoveLastParagraph() and MakeFlyAndMove(); can't test file format more specific?
1662 // but it MUST NOT be done during the SetRedlineFlags at the end of ODF
1663 // import, where the IsInXMLImport() cannot be checked because the
1664 // stupid code temp. overrides it - instead rely on setting the ALLFLYS
1665 // flag in MoveFromSection() and converting that to CheckNoCntnt with
1666 // adjusted cursor!
1667 return (rStart.GetNode() < rAnchorPos.GetNode()) && (rAnchorPos.GetNode() < rEnd.GetNode());
1668 }
1669
1670 // in general, exclude the start and end position
1671 return ((rStart.GetNode() < rAnchorPos.GetNode())
1672 || (rStart.GetNode() == rAnchorPos.GetNode()
1673 && !(nDelContentType & DelContentType::ExcludeFlyAtStartEnd)
1674 // special case: fully deleted node
1675 && ((rStart.GetNode() != rEnd.GetNode() && rStart.GetContentIndex() == 0
1676 // but not if the selection is backspace/delete!
1677 && IsNotBackspaceHeuristic(rStart, rEnd))
1678 || (IsAtStartOfSection2(rStart) && IsAtEndOfSection2(rEnd)))))
1679 && ((rAnchorPos.GetNode() < rEnd.GetNode())
1680 || (rAnchorPos.GetNode() == rEnd.GetNode()
1681 && !(nDelContentType & DelContentType::ExcludeFlyAtStartEnd)
1682 // special case: fully deleted node
1683 && ((rEnd.GetNode() != rStart.GetNode() && rEnd.GetContentIndex() == rEnd.GetNode().GetTextNode()->Len()
1684 && IsNotBackspaceHeuristic(rStart, rEnd))
1685 || (IsAtEndOfSection2(rEnd) && IsAtStartOfSection2(rStart)))));
1686}
1687
1689 SwPosition const & rStart, SwPosition const & rEnd)
1690{
1691 for (SwFrameFormat const*const pFly : *rDoc.GetSpzFrameFormats())
1692 {
1693 SwFormatAnchor const& rAnchor(pFly->GetAnchor());
1694 switch (rAnchor.GetAnchorId())
1695 {
1696 case RndStdIds::FLY_AT_CHAR:
1697 case RndStdIds::FLY_AT_PARA:
1698 {
1699 SwPosition const*const pAnchorPos(rAnchor.GetContentAnchor());
1700 // can this really be null?
1701 if (pAnchorPos != nullptr
1702 && ((rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR)
1703 ? IsDestroyFrameAnchoredAtChar(*pAnchorPos, rStart, rEnd)
1704 : IsSelectFrameAnchoredAtPara(*pAnchorPos, rStart, rEnd)))
1705 {
1706 return true;
1707 }
1708 }
1709 break;
1710 default: // other types not relevant
1711 break;
1712 }
1713 }
1714 return false;
1715}
1716
1717/* 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:476
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.
Marks a character position inside a document model content node (SwContentNode)
virtual sal_Int32 Len() const
Definition: node.cxx:1268
Definition: doc.hxx:194
void CorrAbs(const SwNode &rOldNode, const SwPosition &rNewPos, const sal_Int32 nOffset=0, bool bMoveCursor=false)
Definition: doccorr.cxx:169
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:150
SwNodes & GetNodes()
Definition: doc.hxx:417
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:341
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:642
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1814
const SwFrameFormats * GetSpzFrameFormats() const
Definition: doc.hxx:752
SwDocShell * GetDocShell()
Definition: doc.hxx:1359
::sw::UndoManager & GetUndoManager()
Definition: doc.cxx:139
bool IsInWriterfilterImport() const
Definition: doc.hxx:980
SwTextFootnote * SeekEntry(const SwNode &rNd, size_t *pPos=nullptr) const
Definition: ftnidx.cxx:408
FlyAnchors.
Definition: fmtanchr.hxx:37
void SetAnchor(const SwPosition *pPos)
Definition: atrfrm.cxx:1586
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:67
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:69
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:83
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:447
Style of a layout element.
Definition: frmfmt.hxx:62
Specific frame formats (frames, DrawObjects).
bool empty() const
size_t size() const
bool Rollback(SwDoc *pDoc, sal_uInt16 nStart=0)
Definition: rolbck.cxx:1201
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
SwNode & GetNode() const
Definition: ndindex.hxx:136
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:171
SwNodeIndex aStart
Definition: ndindex.hxx:149
SwNodeIndex aEnd
Definition: ndindex.hxx:150
Base class of the Writer document model elements.
Definition: node.hxx:98
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:897
SwNodeOffset GetIndex() const
Definition: node.hxx:312
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:742
bool IsContentNode() const
Definition: node.hxx:677
SwDoc & GetDoc()
Definition: node.hxx:233
bool IsEndNode() const
Definition: node.hxx:681
bool IsStartNode() const
Definition: node.hxx:673
bool IsTextNode() const
Definition: node.hxx:685
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:153
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:726
SwNoTextNode * GetNoTextNode()
Definition: ndnotxt.hxx:95
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:731
void MoveRange(SwPaM &, SwPosition &, SwNodes &rNodes)
move a range
Definition: nodes.cxx:1471
SwNode & GetEndOfExtras() const
This is the last EndNode of a special section.
Definition: ndarr.hxx:163
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:165
bool MoveNodes(const SwNodeRange &, SwNodes &rNodes, SwNode &rPos, bool bNewFrames=true)
move the node pointer
Definition: nodes.cxx:405
void Delete(const SwNodeIndex &rPos, SwNodeOffset nNodes=SwNodeOffset(1))
Definition: nodes.cxx:1071
static SwStartNode * MakeEmptySection(SwNode &rWhere, SwStartNodeType=SwNormalStartNode)
Create an empty section of Start- and EndNote.
Definition: nodes.cxx:1918
static SwContentNode * GoPrevious(SwNodeIndex *)
Definition: nodes.cxx:1334
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1300
SwNode & GetEndOfPostIts() const
A still empty section.
Definition: ndarr.hxx:154
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:187
const SwPosition * GetMark() const
Definition: pam.hxx:263
SwNode & GetPointNode() const
Definition: pam.hxx:283
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:642
void Exchange()
Definition: pam.cxx:656
std::pair< const SwPosition *, const SwPosition * > StartEnd() const
Because sometimes the cost of the operator<= can add up.
Definition: pam.hxx:277
SwContentNode * GetPointContentNode() const
Definition: pam.hxx:287
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:668
const SwPosition * End() const
Definition: pam.hxx:271
SwContentNode * GetMarkContentNode() const
Definition: pam.hxx:288
SwDoc & GetDoc() const
Definition: pam.hxx:299
void DeleteMark()
Definition: pam.hxx:231
const SwPosition * GetPoint() const
Definition: pam.hxx:261
const SwPosition * Start() const
Definition: pam.hxx:266
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:259
void ClearContentIdx()
Definition: docredln.cxx:1873
const OUString & GetComment(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1950
const SwNodeIndex * GetContentIdx() const
Definition: redline.hxx:189
bool IsMoved() const
Definition: redline.hxx:276
void SetContentIdx(const SwNodeIndex &)
Definition: docredln.cxx:1859
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1940
friend class SwRangeRedline
Definition: redline.hxx:88
bool CanCombine(const SwRedlineData &rCmp) const
Definition: docredln.cxx:1062
const SwNodeIndex * GetMvSttIdx() const
Definition: UndoCore.hxx:57
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
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:348
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:111
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:290
void EraseText(const SwContentIndex &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:2763
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:3141
SwPaM & AddUndoRedoPaM(::sw::UndoRedoContext &, bool const bCorrToContent=false) const
Definition: undobj.cxx:100
void SetPaM(SwPaM &, bool bCorrToContent=false) const
Definition: undobj.cxx:80
SwUndRng()
Definition: undobj.cxx:50
sal_Int32 m_nSttContent
Definition: undobj.hxx:232
SwNodeOffset m_nSttNode
Definition: undobj.hxx:231
SwNodeOffset m_nEndNode
Definition: undobj.hxx:231
sal_Int32 m_nEndContent
Definition: undobj.hxx:232
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:757
virtual ~SwUndoSaveContent() COVERITY_NOEXCEPT_FALSE
Definition: undobj.cxx:696
void DelContentIndex(const SwPosition &pMark, const SwPosition &pPoint, DelContentType nDelContentType=DelContentType::AllMask)
Definition: undobj.cxx:860
static void MoveToUndoNds(SwPaM &rPam, SwNodeIndex *pNodeIdx, SwNodeOffset *pEndNdIdx=nullptr)
Definition: undobj.cxx:721
std::unique_ptr< SwHistory > m_pHistory
Definition: undobj.hxx:167
static bool MovePtBackward(SwPaM &rPam)
Definition: undobj.cxx:825
static void MovePtForward(SwPaM &rPam, bool bMvBkwrd)
Definition: undobj.cxx:837
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: undobj.cxx:700
void SaveSection(const SwNodeIndex &rSttIdx)
Definition: undobj.cxx:1226
const SwHistory * GetHistory() const
Definition: undobj.hxx:221
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: undobj.cxx:1319
std::unique_ptr< SwRedlineSaveDatas > m_pRedlineSaveData
Definition: undobj.hxx:204
SwNodeOffset m_nStartPos
Definition: undobj.hxx:206
void RestoreSection(SwDoc *pDoc, SwNodeIndex *pIdx, sal_uInt16 nSectType)
Definition: undobj.cxx:1279
std::optional< SwNodeIndex > m_oMovedStart
Definition: undobj.hxx:203
SwNodeOffset m_nMoveLen
Definition: undobj.hxx:205
virtual SwRewriter GetRewriter() const
Returns the rewriter for this object.
Definition: undobj.cxx:686
std::optional< OUString > maComment
Definition: undobj.hxx:63
virtual void UndoImpl(::sw::UndoRedoContext &)=0
SwUndo(SwUndoId const nId, const SwDoc *pDoc)
Definition: undobj.cxx:151
virtual void Repeat(SfxRepeatTarget &) override
Definition: undobj.cxx:237
virtual void Redo() override
Definition: undobj.cxx:214
RedlineFlags GetRedlineFlags() const
Definition: undobj.hxx:120
ViewShellId GetViewShellId() const override
See SfxUndoAction::GetViewShellId().
Definition: undobj.cxx:681
virtual bool CanRepeat(SfxRepeatTarget &) const override
Definition: undobj.cxx:249
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:652
static void RemoveIdxRel(SwNodeOffset, const SwPosition &)
Definition: undobj.cxx:144
static void RemoveIdxFromRange(SwPaM &rPam, bool bMoveNext)
Definition: undobj.cxx:118
virtual void UndoWithContext(SfxUndoContext &) override
Definition: undobj.cxx:219
bool IsDelBox() const
Definition: undobj.cxx:172
static bool HasHiddenRedlines(const SwRedlineSaveDatas &rSData)
Definition: undobj.cxx:1497
static void SetSaveData(SwDoc &rDoc, SwRedlineSaveDatas &rSData)
Definition: undobj.cxx:1477
static bool CanRedlineGroup(SwRedlineSaveDatas &rCurr, const SwRedlineSaveDatas &rCheck, bool bCurrIsEnd)
Definition: undobj.cxx:1505
SwUndoId GetId() const
Definition: undobj.hxx:102
virtual void RepeatImpl(::sw::RepeatContext &)
Definition: undobj.cxx:257
bool m_bCacheComment
Definition: undobj.hxx:62
static ViewShellId CreateViewShellId(const SwDoc *pDoc)
Try to obtain the view shell ID of the current view.
Definition: undobj.cxx:159
static bool FillSaveDataForFormat(const SwPaM &, SwRedlineSaveDatas &)
Definition: undobj.cxx:1447
virtual void RedoImpl(::sw::UndoRedoContext &)=0
static void RemoveIdxFromSection(SwDoc &, SwNodeOffset nSttIdx, const SwNodeOffset *pEndIdx=nullptr)
Definition: undobj.cxx:108
virtual void Undo() override
Definition: undobj.cxx:209
bool m_isRepeatIgnored
for multi-selection, only repeat 1st selection
Definition: undobj.hxx:59
ViewShellId m_nViewShellId
Definition: undobj.hxx:58
virtual void RedoWithContext(SfxUndoContext &) override
Definition: undobj.cxx:228
virtual ~SwUndo() override
Definition: undobj.cxx:178
Definition: view.hxx:146
bool empty() const
size_type size() const
virtual SwCursor & CreateNewShellCursor()=0
SwNodes const & GetUndoNodes() const
Definition: docundo.cxx:78
IShellCursorSupplier & GetCursorSupplier()
Definition: UndoCore.hxx:97
#define suppress_fun_call_w_exception(expr)
void PaMCorrRel(const SwNode &rOldNode, const SwPosition &rNewPos, const sal_Int32 nOffset)
Sets all PaMs in OldNode to relative Pos.
Definition: doccorr.cxx:242
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:1179
SwComparePosition ComparePosition(const T &rStt1, const T &rEnd1, const T &rStt2, const T &rEnd2)
Definition: pam.hxx:122
SwComparePosition
Definition: pam.hxx:109
@ 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:60
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:61
static SfxItemSet & rSet
Marks a position in the document model.
Definition: pam.hxx:37
void Adjust(SwNodeOffset nDelta)
Adjust node position, and resets content position to zero.
Definition: pam.cxx:256
SwNode & GetNode() const
Definition: pam.hxx:80
void Assign(const SwNode &rNd, SwNodeOffset nDelta, sal_Int32 nContentOffset=0)
These all set both nNode and nContent.
Definition: pam.cxx:230
void SetContent(sal_Int32 nContentIndex)
Set content index, only valid to call this if the position points to a SwContentNode subclass.
Definition: pam.cxx:266
const SwContentNode * GetContentNode() const
Definition: pam.hxx:83
SwNodeOffset GetNodeIndex() const
Definition: pam.hxx:77
const SwNodes & GetNodes() const
Definition: pam.hxx:78
sal_Int32 GetContentIndex() const
Definition: pam.hxx:84
SwDoc & GetDoc() const
Returns the document this position is in.
Definition: pam.cxx:217
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:165
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
OUString ShortenString(const OUString &rStr, sal_Int32 nLength, std::u16string_view aFillStr)
Shortens a string to a maximum length.
Definition: undobj.cxx:1537
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:1646
static bool IsAtEndOfSection2(SwPosition const &rPos)
passed start / end position could be on section start / end node
Definition: undobj.cxx:1579
static bool IsAtStartOfSection(SwPosition const &rAnchorPos)
Definition: undobj.cxx:1567
static bool IsNotBackspaceHeuristic(SwPosition const &rStart, SwPosition const &rEnd)
Definition: undobj.cxx:1591
bool IsFlySelectedByCursor(SwDoc const &rDoc, SwPosition const &rStart, SwPosition const &rEnd)
check at-char and at-para flys in rDoc
Definition: undobj.cxx:1688
static bool IsAtStartOfSection2(SwPosition const &rPos)
Definition: undobj.cxx:1585
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:1605
OUString GetUndoComment(SwUndoId eId)
Definition: undobj.cxx:261
static bool IsAtEndOfSection(SwPosition const &rAnchorPos)
Definition: undobj.cxx:1556
DelContentType
Definition: undobj.hxx:135
sal_Int32 nLength