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