/src/libreoffice/sw/inc/undobj.hxx
Line | Count | Source (jump to first uncovered line) |
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 | | #ifndef INCLUDED_SW_INC_UNDOBJ_HXX |
20 | | #define INCLUDED_SW_INC_UNDOBJ_HXX |
21 | | |
22 | | #include <vector> |
23 | | #include <memory> |
24 | | |
25 | | #include <svl/undo.hxx> |
26 | | #include "SwRewriter.hxx" |
27 | | #include "swundo.hxx" |
28 | | #include "nodeoffset.hxx" |
29 | | #include "ndindex.hxx" |
30 | | #include <o3tl/typed_flags_set.hxx> |
31 | | #include <optional> |
32 | | |
33 | | class SwHistory; |
34 | | class SwPaM; |
35 | | struct SwPosition; |
36 | | class SwDoc; |
37 | | class SwTextFormatColl; |
38 | | class SwFrameFormat; |
39 | | class SwFormatAnchor; |
40 | | class SwNode; |
41 | | class SwRedlineData; |
42 | | class SwRedlineSaveDatas; |
43 | | enum class RedlineFlags; |
44 | | enum class RndStdIds; |
45 | | typedef struct _xmlTextWriter* xmlTextWriterPtr; |
46 | | |
47 | | namespace sw { |
48 | | class UndoRedoContext; |
49 | | class RepeatContext; |
50 | | } |
51 | | |
52 | | class SW_DLLPUBLIC SwUndo |
53 | | : public SfxUndoAction |
54 | | { |
55 | | SwUndoId const m_nId; |
56 | | RedlineFlags m_nOrigRedlineFlags; |
57 | | ViewShellId m_nViewShellId; |
58 | | bool m_isRepeatIgnored; ///< for multi-selection, only repeat 1st selection |
59 | | |
60 | | protected: |
61 | | bool m_bCacheComment; |
62 | | mutable std::optional<OUString> maComment; |
63 | | |
64 | | static void RemoveIdxFromSection( SwDoc&, SwNodeOffset nSttIdx, const SwNodeOffset* pEndIdx = nullptr ); |
65 | | static void RemoveIdxFromRange( SwPaM& rPam, bool bMoveNext ); |
66 | | static void RemoveIdxRel( SwNodeOffset, const SwPosition& ); |
67 | | |
68 | | static bool CanRedlineGroup( SwRedlineSaveDatas& rCurr, |
69 | | const SwRedlineSaveDatas& rCheck, |
70 | | bool bCurrIsEnd ); |
71 | | |
72 | | /** |
73 | | Returns the rewriter for this object. |
74 | | |
75 | | @return the rewriter for this object |
76 | | */ |
77 | | virtual SwRewriter GetRewriter() const; |
78 | | |
79 | | // the 4 methods that derived classes have to override |
80 | | // base implementation does nothing |
81 | | virtual void RepeatImpl( ::sw::RepeatContext & ); |
82 | | public: // should not be public, but ran into trouble in untbl.cxx |
83 | | virtual void UndoImpl( ::sw::UndoRedoContext & ) = 0; |
84 | | virtual void RedoImpl( ::sw::UndoRedoContext & ) = 0; |
85 | | |
86 | | private: |
87 | | /// Try to obtain the view shell ID of the current view. |
88 | | static ViewShellId CreateViewShellId(const SwDoc& rDoc); |
89 | | // SfxUndoAction |
90 | | virtual void Undo() override; |
91 | | virtual void Redo() override; |
92 | | virtual void UndoWithContext(SfxUndoContext &) override; |
93 | | virtual void RedoWithContext(SfxUndoContext &) override; |
94 | | virtual void Repeat(SfxRepeatTarget &) override; |
95 | | virtual bool CanRepeat(SfxRepeatTarget &) const override; |
96 | | |
97 | | public: |
98 | | SwUndo(SwUndoId const nId, const SwDoc& rDoc); |
99 | | virtual ~SwUndo() override; |
100 | | |
101 | 0 | SwUndoId GetId() const { return m_nId; } |
102 | | |
103 | | /** |
104 | | Returns textual comment for this undo object. |
105 | | |
106 | | The textual comment is created from the resource string |
107 | | corresponding to this object's ID. The rewriter of this object |
108 | | is applied to the resource string to get the final comment. |
109 | | |
110 | | @return textual comment for this undo object |
111 | | */ |
112 | | virtual OUString GetComment() const override; |
113 | | |
114 | | /// See SfxUndoAction::GetViewShellId(). |
115 | | ViewShellId GetViewShellId() const override; |
116 | | |
117 | | // UndoObject remembers which mode was turned on. |
118 | | // In Undo/Redo/Repeat this remembered mode is switched on. |
119 | 0 | RedlineFlags GetRedlineFlags() const { return m_nOrigRedlineFlags; } |
120 | 0 | void SetRedlineFlags( RedlineFlags eMode ) { m_nOrigRedlineFlags = eMode; } |
121 | | |
122 | | bool IsDelBox() const; |
123 | | |
124 | | // Save and set Redline data. |
125 | | static bool FillSaveData( const SwPaM& rRange, SwRedlineSaveDatas& rSData, |
126 | | bool bDelRange = true, bool bCopyNext = true ); |
127 | | static bool FillSaveDataForFormat( const SwPaM& , SwRedlineSaveDatas& ); |
128 | | static void SetSaveData( SwDoc& rDoc, SwRedlineSaveDatas& rSData ); |
129 | | static bool HasHiddenRedlines( const SwRedlineSaveDatas& rSData ); |
130 | 0 | void IgnoreRepeat() { m_isRepeatIgnored = true; } |
131 | | }; |
132 | | |
133 | | enum class DelContentType : sal_uInt16 |
134 | | { |
135 | | Ftn = 0x01, |
136 | | Fly = 0x02, |
137 | | Bkm = 0x08, |
138 | | AllMask = 0x0b, |
139 | | Replace = 0x10, |
140 | | WriterfilterHack = 0x20, |
141 | | ExcludeFlyAtStartEnd = 0x40, |
142 | | CheckNoCntnt = 0x80, |
143 | | }; |
144 | | namespace o3tl { |
145 | | template<> struct typed_flags<DelContentType> : is_typed_flags<DelContentType, 0xfb> {}; |
146 | | } |
147 | | |
148 | | /// will DelContentIndex destroy a frame anchored at character at rAnchorPos? |
149 | | bool IsDestroyFrameAnchoredAtChar(SwPosition const & rAnchorPos, |
150 | | SwPosition const & rStart, SwPosition const & rEnd, |
151 | | DelContentType const nDelContentType = DelContentType::AllMask); |
152 | | /// is a fly anchored at paragraph at rAnchorPos selected? |
153 | | bool IsSelectFrameAnchoredAtPara(SwPosition const & rAnchorPos, |
154 | | SwPosition const & rStart, SwPosition const & rEnd, |
155 | | DelContentType const nDelContentType = DelContentType::AllMask); |
156 | | /// check at-char and at-para flys in rDoc |
157 | | bool IsFlySelectedByCursor(SwDoc const & rDoc, |
158 | | SwPosition const & rStart, SwPosition const & rEnd); |
159 | | |
160 | | // This class has to be inherited into an Undo-object if it saves content |
161 | | // for Redo/Undo... |
162 | | class SwUndoSaveContent |
163 | | { |
164 | | protected: |
165 | | |
166 | | std::unique_ptr<SwHistory> m_pHistory; |
167 | | |
168 | | // Needed for deletion of content. For Redo content is moved into the |
169 | | // UndoNodesArray. These methods always create a new node to insert |
170 | | // content. So the attributes do not get expanded. |
171 | | // MoveTo: moves from the NodesArray into the UndoNodesArray. |
172 | | // MoveFrom: moves from the UndoNodesArray into the NodesArray. |
173 | | static void MoveToUndoNds( SwPaM& rPam, |
174 | | SwNodeIndex* pNodeIdx, |
175 | | SwNodeOffset* pEndNdIdx = nullptr ); |
176 | | static void MoveFromUndoNds( SwDoc& rDoc, SwNodeOffset nNodeIdx, |
177 | | SwPosition& rInsPos, |
178 | | const SwNodeOffset* pEndNdIdx = nullptr, |
179 | | bool bForceCreateFrames = false); |
180 | | |
181 | | // These two methods save and restore the Point of PaM. |
182 | | // If the point cannot be moved, a "backup" is created on the previous node. |
183 | | // Either way, it will not be moved by inserting at its original position. |
184 | | static ::std::optional<SwNodeIndex> MovePtBackward(SwPaM& rPam); |
185 | | static void MovePtForward(SwPaM& rPam, ::std::optional<SwNodeIndex> && oMvBkwrd); |
186 | | |
187 | | // Before moving stuff into UndoNodes-Array care has to be taken that |
188 | | // the content-bearing attributes are removed from the nodes-array. |
189 | | void DelContentIndex( const SwPosition& pMark, const SwPosition& pPoint, |
190 | | DelContentType nDelContentType = DelContentType::AllMask ); |
191 | | |
192 | | public: |
193 | | SwUndoSaveContent(); |
194 | | virtual ~SwUndoSaveContent() COVERITY_NOEXCEPT_FALSE; |
195 | | virtual void dumpAsXml(xmlTextWriterPtr pWriter) const; |
196 | | }; |
197 | | |
198 | | // Save a complete section in nodes-array. |
199 | | class SwUndoSaveSection : private SwUndoSaveContent |
200 | | { |
201 | | std::optional<SwNodeIndex> m_oMovedStart; |
202 | | std::unique_ptr<SwRedlineSaveDatas> m_pRedlineSaveData; |
203 | | SwNodeOffset m_nMoveLen; // Index into UndoNodes-Array. |
204 | | SwNodeOffset m_nStartPos; |
205 | | |
206 | | protected: |
207 | 0 | const SwNodeIndex* GetMvSttIdx() const { return m_oMovedStart ? &*m_oMovedStart : nullptr; } |
208 | 0 | SwNodeOffset GetMvNodeCnt() const { return m_nMoveLen; } |
209 | | |
210 | | public: |
211 | | SwUndoSaveSection(); |
212 | | ~SwUndoSaveSection(); |
213 | | |
214 | | void SaveSection( const SwNodeIndex& rSttIdx ); |
215 | | void SaveSection(const SwNodeRange& rRange, bool bExpandNodes = true); |
216 | | void RestoreSection( SwDoc& rDoc, SwNodeIndex* pIdx, sal_uInt16 nSectType ); |
217 | | void RestoreSection(SwDoc& rDoc, const SwNode& rInsPos, bool bForceCreateFrames = false); |
218 | | |
219 | 0 | const SwHistory* GetHistory() const { return m_pHistory.get(); } |
220 | 0 | SwHistory* GetHistory() { return m_pHistory.get(); } |
221 | | virtual void dumpAsXml(xmlTextWriterPtr pWriter) const; |
222 | | }; |
223 | | |
224 | | // This class saves the PaM as sal_uInt16's and is able to restore it |
225 | | // into a PaM. |
226 | | class SwUndRng |
227 | | { |
228 | | public: |
229 | | SwNodeOffset m_nSttNode, m_nEndNode; |
230 | | sal_Int32 m_nSttContent, m_nEndContent; |
231 | | |
232 | | SwUndRng(); |
233 | | SwUndRng( const SwPaM& ); |
234 | | |
235 | | void SetValues( const SwPaM& rPam ); |
236 | | void SetPaM( SwPaM&, bool bCorrToContent = false ) const; |
237 | | SwPaM & AddUndoRedoPaM( |
238 | | ::sw::UndoRedoContext &, bool const bCorrToContent = false) const; |
239 | | }; |
240 | | |
241 | | class SwUndoInsLayFormat; |
242 | | |
243 | | namespace sw { |
244 | | |
245 | | std::optional<std::vector<SwFrameFormat*>> |
246 | | GetFlysAnchoredAt(SwDoc & rDoc, SwNodeOffset nSttNode, bool isAtPageIncluded); |
247 | | |
248 | | } |
249 | | |
250 | | // base class for insertion of Document, Glossaries and Copy |
251 | | class SwUndoInserts : public SwUndo, public SwUndRng, private SwUndoSaveContent |
252 | | { |
253 | | SwTextFormatColl *m_pTextFormatColl, *m_pLastNodeColl; |
254 | | std::optional<std::vector<SwFrameFormat*>> m_pFrameFormats; |
255 | | std::vector< std::shared_ptr<SwUndoInsLayFormat> > m_FlyUndos; |
256 | | std::unique_ptr<SwRedlineData> m_pRedlineData; |
257 | | SwNodeOffset m_nDeleteTextNodes; |
258 | | SwNodeOffset m_nNodeDiff; |
259 | | /// start of Content in UndoNodes for Redo |
260 | | std::optional<SwNodeIndex> m_oUndoNodeIndex; |
261 | | sal_uInt16 m_nSetPos; // Start in the history list. |
262 | | |
263 | | protected: |
264 | | SwUndoInserts( SwUndoId nUndoId, const SwPaM& ); |
265 | | public: |
266 | | virtual ~SwUndoInserts() override; |
267 | | |
268 | | virtual void UndoImpl( ::sw::UndoRedoContext & ) override; |
269 | | virtual void RedoImpl( ::sw::UndoRedoContext & ) override; |
270 | | virtual void RepeatImpl( ::sw::RepeatContext & ) override; |
271 | | |
272 | | // Set destination range after reading. |
273 | | void SetInsertRange( const SwPaM&, bool bScanFlys = true, |
274 | | SwNodeOffset nDeleteTextNodes = SwNodeOffset(1)); |
275 | | |
276 | | static bool IsCreateUndoForNewFly(SwFormatAnchor const& rAnchor, |
277 | | SwNodeOffset const nStartNode, SwNodeOffset const nEndNode); |
278 | 0 | std::vector<SwFrameFormat*> * GetFlysAnchoredAt() { return m_pFrameFormats ? &*m_pFrameFormats : nullptr; } |
279 | | |
280 | | void dumpAsXml(xmlTextWriterPtr pWriter) const override; |
281 | | }; |
282 | | |
283 | | /// Undo for Insert -> Text from file. |
284 | | class SwUndoInsDoc final : public SwUndoInserts |
285 | | { |
286 | | public: |
287 | | SwUndoInsDoc( const SwPaM& ); |
288 | | }; |
289 | | |
290 | | /// Undo for copying from part of a document and then inserting that text, as opposed to inserting |
291 | | /// it from a file or clipboard. |
292 | | class SwUndoCpyDoc final : public SwUndoInserts |
293 | | { |
294 | | public: |
295 | | SwUndoCpyDoc( const SwPaM& ); |
296 | | }; |
297 | | |
298 | | class SwUndoFlyBase : public SwUndo, private SwUndoSaveSection |
299 | | { |
300 | | protected: |
301 | | SwFrameFormat* m_pFrameFormat; // The saved FlyFormat. |
302 | | SwNodeOffset m_nNodePagePos; |
303 | | sal_Int32 m_nContentPos; // Page at/in paragraph. |
304 | | RndStdIds m_nRndId; |
305 | | bool m_bDelFormat; // Delete saved format. |
306 | | |
307 | | void InsFly(::sw::UndoRedoContext & rContext, bool bShowSel = true); |
308 | | void DelFly( SwDoc& ); |
309 | | |
310 | | SwUndoFlyBase( SwFrameFormat* pFormat, SwUndoId nUndoId ); |
311 | | |
312 | 0 | const SwNodeIndex* GetMvSttIdx() const { return SwUndoSaveSection::GetMvSttIdx(); } |
313 | 0 | SwNodeOffset GetMvNodeCnt() const { return SwUndoSaveSection::GetMvNodeCnt(); } |
314 | | |
315 | | public: |
316 | | virtual ~SwUndoFlyBase() override; |
317 | | void dumpAsXml(xmlTextWriterPtr pWriter) const override; |
318 | | |
319 | | }; |
320 | | |
321 | | class SwUndoInsLayFormat final : public SwUndoFlyBase |
322 | | { |
323 | | SwNodeOffset mnCursorSaveIndexPara; // Cursor position |
324 | | sal_Int32 mnCursorSaveIndexPos; // for undo |
325 | | public: |
326 | | SwUndoInsLayFormat( SwFrameFormat* pFormat, SwNodeOffset nNodeIdx, sal_Int32 nCntIdx ); |
327 | | |
328 | | virtual ~SwUndoInsLayFormat() override; |
329 | | |
330 | | virtual void UndoImpl( ::sw::UndoRedoContext & ) override; |
331 | | virtual void RedoImpl( ::sw::UndoRedoContext & ) override; |
332 | | virtual void RepeatImpl( ::sw::RepeatContext & ) override; |
333 | | |
334 | | virtual OUString GetComment() const override; |
335 | | |
336 | | }; |
337 | | |
338 | | class SwUndoDelLayFormat final : public SwUndoFlyBase |
339 | | { |
340 | | bool m_bShowSelFrame; |
341 | | public: |
342 | | SwUndoDelLayFormat( SwFrameFormat* pFormat ); |
343 | | |
344 | | virtual void UndoImpl( ::sw::UndoRedoContext & ) override; |
345 | | virtual void RedoImpl( ::sw::UndoRedoContext & ) override; |
346 | | |
347 | | void RedoForRollback(); |
348 | | |
349 | 0 | void ChgShowSel( bool bNew ) { m_bShowSelFrame = bNew; } |
350 | | |
351 | | virtual SwRewriter GetRewriter() const override; |
352 | | |
353 | | }; |
354 | | |
355 | | #endif |
356 | | |
357 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |