1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #ifndef INCLUDED_SW_INC_UNDOBJ_HXX
20 #define INCLUDED_SW_INC_UNDOBJ_HXX
25 #include <svl/undo.hxx>
26 #include "SwRewriter.hxx"
28 #include "nodeoffset.hxx"
29 #include "ndindex.hxx"
30 #include <o3tl/typed_flags_set.hxx>
37 class SwTextFormatColl
;
43 class SwRedlineSaveDatas
;
44 enum class RedlineFlags
;
46 typedef struct _xmlTextWriter
* xmlTextWriterPtr
;
49 class UndoRedoContext
;
54 : public SfxUndoAction
57 RedlineFlags m_nOrigRedlineFlags
;
58 ViewShellId m_nViewShellId
;
59 bool m_isRepeatIgnored
; ///< for multi-selection, only repeat 1st selection
63 mutable std::optional
<OUString
> maComment
;
65 static void RemoveIdxFromSection( SwDoc
&, SwNodeOffset nSttIdx
, const SwNodeOffset
* pEndIdx
= nullptr );
66 static void RemoveIdxFromRange( SwPaM
& rPam
, bool bMoveNext
);
67 static void RemoveIdxRel( SwNodeOffset
, const SwPosition
& );
69 static bool CanRedlineGroup( SwRedlineSaveDatas
& rCurr
,
70 const SwRedlineSaveDatas
& rCheck
,
74 Returns the rewriter for this object.
76 @return the rewriter for this object
78 virtual SwRewriter
GetRewriter() const;
80 // the 4 methods that derived classes have to override
81 // base implementation does nothing
82 virtual void RepeatImpl( ::sw::RepeatContext
& );
83 public: // should not be public, but ran into trouble in untbl.cxx
84 virtual void UndoImpl( ::sw::UndoRedoContext
& ) = 0;
85 virtual void RedoImpl( ::sw::UndoRedoContext
& ) = 0;
88 /// Try to obtain the view shell ID of the current view.
89 static ViewShellId
CreateViewShellId(const SwDoc
* pDoc
);
91 virtual void Undo() override
;
92 virtual void Redo() override
;
93 virtual void UndoWithContext(SfxUndoContext
&) override
;
94 virtual void RedoWithContext(SfxUndoContext
&) override
;
95 virtual void Repeat(SfxRepeatTarget
&) override
;
96 virtual bool CanRepeat(SfxRepeatTarget
&) const override
;
99 SwUndo(SwUndoId
const nId
, const SwDoc
* pDoc
);
100 virtual ~SwUndo() override
;
102 SwUndoId
GetId() const { return m_nId
; }
105 Returns textual comment for this undo object.
107 The textual comment is created from the resource string
108 corresponding to this object's ID. The rewriter of this object
109 is applied to the resource string to get the final comment.
111 @return textual comment for this undo object
113 virtual OUString
GetComment() const override
;
115 /// See SfxUndoAction::GetViewShellId().
116 ViewShellId
GetViewShellId() const override
;
118 // UndoObject remembers which mode was turned on.
119 // In Undo/Redo/Repeat this remembered mode is switched on.
120 RedlineFlags
GetRedlineFlags() const { return m_nOrigRedlineFlags
; }
121 void SetRedlineFlags( RedlineFlags eMode
) { m_nOrigRedlineFlags
= eMode
; }
123 bool IsDelBox() const;
125 // Save and set Redline data.
126 static bool FillSaveData( const SwPaM
& rRange
, SwRedlineSaveDatas
& rSData
,
127 bool bDelRange
= true, bool bCopyNext
= true );
128 static bool FillSaveDataForFormat( const SwPaM
& , SwRedlineSaveDatas
& );
129 static void SetSaveData( SwDoc
& rDoc
, SwRedlineSaveDatas
& rSData
);
130 static bool HasHiddenRedlines( const SwRedlineSaveDatas
& rSData
);
131 void IgnoreRepeat() { m_isRepeatIgnored
= true; }
134 enum class DelContentType
: sal_uInt16
141 WriterfilterHack
= 0x20,
142 ExcludeFlyAtStartEnd
= 0x40,
146 template<> struct typed_flags
<DelContentType
> : is_typed_flags
<DelContentType
, 0xfb> {};
149 /// will DelContentIndex destroy a frame anchored at character at rAnchorPos?
150 bool IsDestroyFrameAnchoredAtChar(SwPosition
const & rAnchorPos
,
151 SwPosition
const & rStart
, SwPosition
const & rEnd
,
152 DelContentType
const nDelContentType
= DelContentType::AllMask
);
153 /// is a fly anchored at paragraph at rAnchorPos selected?
154 bool IsSelectFrameAnchoredAtPara(SwPosition
const & rAnchorPos
,
155 SwPosition
const & rStart
, SwPosition
const & rEnd
,
156 DelContentType
const nDelContentType
= DelContentType::AllMask
);
157 /// check at-char and at-para flys in rDoc
158 bool IsFlySelectedByCursor(SwDoc
const & rDoc
,
159 SwPosition
const & rStart
, SwPosition
const & rEnd
);
161 // This class has to be inherited into an Undo-object if it saves content
163 class SwUndoSaveContent
167 std::unique_ptr
<SwHistory
> m_pHistory
;
169 // Needed for deletion of content. For Redo content is moved into the
170 // UndoNodesArray. These methods always create a new node to insert
171 // content. So the attributes do not get expanded.
172 // MoveTo: moves from the NodesArray into the UndoNodesArray.
173 // MoveFrom: moves from the UndoNodesArray into the NodesArray.
174 static void MoveToUndoNds( SwPaM
& rPam
,
175 SwNodeIndex
* pNodeIdx
,
176 SwNodeOffset
* pEndNdIdx
= nullptr );
177 static void MoveFromUndoNds( SwDoc
& rDoc
, SwNodeOffset nNodeIdx
,
179 const SwNodeOffset
* pEndNdIdx
= nullptr,
180 bool bForceCreateFrames
= false);
182 // These two methods save and restore the Point of PaM.
183 // If the point cannot be moved, a "backup" is created on the previous node.
184 // Either way, it will not be moved by inserting at its original position.
185 static ::std::optional
<SwNodeIndex
> MovePtBackward(SwPaM
& rPam
);
186 static void MovePtForward(SwPaM
& rPam
, ::std::optional
<SwNodeIndex
> && oMvBkwrd
);
188 // Before moving stuff into UndoNodes-Array care has to be taken that
189 // the content-bearing attributes are removed from the nodes-array.
190 void DelContentIndex( const SwPosition
& pMark
, const SwPosition
& pPoint
,
191 DelContentType nDelContentType
= DelContentType::AllMask
);
195 virtual ~SwUndoSaveContent() COVERITY_NOEXCEPT_FALSE
;
196 virtual void dumpAsXml(xmlTextWriterPtr pWriter
) const;
199 // Save a complete section in nodes-array.
200 class SwUndoSaveSection
: private SwUndoSaveContent
202 std::optional
<SwNodeIndex
> m_oMovedStart
;
203 std::unique_ptr
<SwRedlineSaveDatas
> m_pRedlineSaveData
;
204 SwNodeOffset m_nMoveLen
; // Index into UndoNodes-Array.
205 SwNodeOffset m_nStartPos
;
208 const SwNodeIndex
* GetMvSttIdx() const { return m_oMovedStart
? &*m_oMovedStart
: nullptr; }
209 SwNodeOffset
GetMvNodeCnt() const { return m_nMoveLen
; }
213 ~SwUndoSaveSection();
215 void SaveSection( const SwNodeIndex
& rSttIdx
);
216 void SaveSection(const SwNodeRange
& rRange
, bool bExpandNodes
= true);
217 void RestoreSection( SwDoc
* pDoc
, SwNodeIndex
* pIdx
, sal_uInt16 nSectType
);
218 void RestoreSection(SwDoc
* pDoc
, const SwNode
& rInsPos
, bool bForceCreateFrames
= false);
220 const SwHistory
* GetHistory() const { return m_pHistory
.get(); }
221 SwHistory
* GetHistory() { return m_pHistory
.get(); }
222 virtual void dumpAsXml(xmlTextWriterPtr pWriter
) const;
225 // This class saves the PaM as sal_uInt16's and is able to restore it
230 SwNodeOffset m_nSttNode
, m_nEndNode
;
231 sal_Int32 m_nSttContent
, m_nEndContent
;
234 SwUndRng( const SwPaM
& );
236 void SetValues( const SwPaM
& rPam
);
237 void SetPaM( SwPaM
&, bool bCorrToContent
= false ) const;
238 SwPaM
& AddUndoRedoPaM(
239 ::sw::UndoRedoContext
&, bool const bCorrToContent
= false) const;
242 class SwUndoInsLayFormat
;
246 std::optional
<std::vector
<SwFrameFormat
*>>
247 GetFlysAnchoredAt(SwDoc
& rDoc
, SwNodeOffset nSttNode
, bool isAtPageIncluded
);
251 // base class for insertion of Document, Glossaries and Copy
252 class SwUndoInserts
: public SwUndo
, public SwUndRng
, private SwUndoSaveContent
254 SwTextFormatColl
*m_pTextFormatColl
, *m_pLastNodeColl
;
255 std::optional
<std::vector
<SwFrameFormat
*>> m_pFrameFormats
;
256 std::vector
< std::shared_ptr
<SwUndoInsLayFormat
> > m_FlyUndos
;
257 std::unique_ptr
<SwRedlineData
> m_pRedlineData
;
258 SwNodeOffset m_nDeleteTextNodes
;
259 SwNodeOffset m_nNodeDiff
;
260 /// start of Content in UndoNodes for Redo
261 std::optional
<SwNodeIndex
> m_oUndoNodeIndex
;
262 sal_uInt16 m_nSetPos
; // Start in the history list.
265 SwUndoInserts( SwUndoId nUndoId
, const SwPaM
& );
267 virtual ~SwUndoInserts() override
;
269 virtual void UndoImpl( ::sw::UndoRedoContext
& ) override
;
270 virtual void RedoImpl( ::sw::UndoRedoContext
& ) override
;
271 virtual void RepeatImpl( ::sw::RepeatContext
& ) override
;
273 // Set destination range after reading.
274 void SetInsertRange( const SwPaM
&, bool bScanFlys
= true,
275 SwNodeOffset nDeleteTextNodes
= SwNodeOffset(1));
277 static bool IsCreateUndoForNewFly(SwFormatAnchor
const& rAnchor
,
278 SwNodeOffset
const nStartNode
, SwNodeOffset
const nEndNode
);
279 std::vector
<SwFrameFormat
*> * GetFlysAnchoredAt() { return m_pFrameFormats
? &*m_pFrameFormats
: nullptr; }
281 void dumpAsXml(xmlTextWriterPtr pWriter
) const override
;
284 /// Undo for Insert -> Text from file.
285 class SwUndoInsDoc final
: public SwUndoInserts
288 SwUndoInsDoc( const SwPaM
& );
291 /// Undo for copying from part of a document and then inserting that text, as opposed to inserting
292 /// it from a file or clipboard.
293 class SwUndoCpyDoc final
: public SwUndoInserts
296 SwUndoCpyDoc( const SwPaM
& );
299 class SwUndoFlyBase
: public SwUndo
, private SwUndoSaveSection
302 SwFrameFormat
* m_pFrameFormat
; // The saved FlyFormat.
303 SwNodeOffset m_nNodePagePos
;
304 sal_Int32 m_nContentPos
; // Page at/in paragraph.
306 bool m_bDelFormat
; // Delete saved format.
308 void InsFly(::sw::UndoRedoContext
& rContext
, bool bShowSel
= true);
309 void DelFly( SwDoc
* );
311 SwUndoFlyBase( SwFrameFormat
* pFormat
, SwUndoId nUndoId
);
313 const SwNodeIndex
* GetMvSttIdx() const { return SwUndoSaveSection::GetMvSttIdx(); }
314 SwNodeOffset
GetMvNodeCnt() const { return SwUndoSaveSection::GetMvNodeCnt(); }
317 virtual ~SwUndoFlyBase() override
;
318 void dumpAsXml(xmlTextWriterPtr pWriter
) const override
;
322 class SwUndoInsLayFormat final
: public SwUndoFlyBase
324 SwNodeOffset mnCursorSaveIndexPara
; // Cursor position
325 sal_Int32 mnCursorSaveIndexPos
; // for undo
327 SwUndoInsLayFormat( SwFrameFormat
* pFormat
, SwNodeOffset nNodeIdx
, sal_Int32 nCntIdx
);
329 virtual ~SwUndoInsLayFormat() override
;
331 virtual void UndoImpl( ::sw::UndoRedoContext
& ) override
;
332 virtual void RedoImpl( ::sw::UndoRedoContext
& ) override
;
333 virtual void RepeatImpl( ::sw::RepeatContext
& ) override
;
335 virtual OUString
GetComment() const override
;
339 class SwUndoDelLayFormat final
: public SwUndoFlyBase
341 bool m_bShowSelFrame
;
343 SwUndoDelLayFormat( SwFrameFormat
* pFormat
);
345 virtual void UndoImpl( ::sw::UndoRedoContext
& ) override
;
346 virtual void RedoImpl( ::sw::UndoRedoContext
& ) override
;
348 void RedoForRollback();
350 void ChgShowSel( bool bNew
) { m_bShowSelFrame
= bNew
; }
352 virtual SwRewriter
GetRewriter() const override
;
358 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */