Coverage Report

Created: 2025-12-08 09:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/inc/undobj.hxx
Line
Count
Source
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
/// Undo for copying a header or footer from one document into another.
299
/// This needs special handling because undoing the copy needs to completely
300
/// remove it from the doc nodes; in other cases the header/footer content
301
/// is just left in the doc nodes.
302
class SwUndoCopyHeaderFooter final : public SwUndo, private SwUndoSaveSection
303
{
304
    SwNodeOffset m_aOff;
305
    UIName m_aFmtName;
306
307
    bool m_bIsHeader;
308
    bool m_bIsMaster;
309
    bool m_bIsLeft;
310
    bool m_bIsFirstMaster;
311
    bool m_bIsFirstLeft;
312
313
public:
314
    SwUndoCopyHeaderFooter(SwDoc& rDoc, SwNode& rSttNd, const UIName& rFmtName);
315
316
    virtual void UndoImpl(::sw::UndoRedoContext & rContext) override;
317
    virtual void RedoImpl(::sw::UndoRedoContext & rContext) override;
318
};
319
320
class SwUndoFlyBase : public SwUndo, private SwUndoSaveSection
321
{
322
protected:
323
    SwFrameFormat* m_pFrameFormat;          // The saved FlyFormat.
324
    SwNodeOffset m_nNodePagePos;
325
    sal_Int32 m_nContentPos;         // Page at/in paragraph.
326
    RndStdIds m_nRndId;
327
    bool m_bDelFormat;           // Delete saved format.
328
329
    void InsFly(::sw::UndoRedoContext & rContext, bool bShowSel = true);
330
    void DelFly( SwDoc& );
331
332
    SwUndoFlyBase( SwFrameFormat* pFormat, SwUndoId nUndoId );
333
334
0
    const SwNodeIndex* GetMvSttIdx() const { return SwUndoSaveSection::GetMvSttIdx(); }
335
0
    SwNodeOffset GetMvNodeCnt() const { return SwUndoSaveSection::GetMvNodeCnt(); }
336
337
public:
338
    virtual ~SwUndoFlyBase() override;
339
    void dumpAsXml(xmlTextWriterPtr pWriter) const override;
340
341
};
342
343
class SwUndoInsLayFormat final : public SwUndoFlyBase
344
{
345
    SwNodeOffset mnCursorSaveIndexPara;        // Cursor position
346
    sal_Int32 mnCursorSaveIndexPos;            // for undo
347
public:
348
    SwUndoInsLayFormat( SwFrameFormat* pFormat, SwNodeOffset nNodeIdx, sal_Int32 nCntIdx );
349
350
    virtual ~SwUndoInsLayFormat() override;
351
352
    virtual void UndoImpl( ::sw::UndoRedoContext & ) override;
353
    virtual void RedoImpl( ::sw::UndoRedoContext & ) override;
354
    virtual void RepeatImpl( ::sw::RepeatContext & ) override;
355
356
    virtual OUString GetComment() const override;
357
358
};
359
360
class SwUndoDelLayFormat final : public SwUndoFlyBase
361
{
362
    bool m_bShowSelFrame;
363
public:
364
    SwUndoDelLayFormat( SwFrameFormat* pFormat );
365
366
    virtual void UndoImpl( ::sw::UndoRedoContext & ) override;
367
    virtual void RedoImpl( ::sw::UndoRedoContext & ) override;
368
369
    void RedoForRollback();
370
371
0
    void ChgShowSel( bool bNew ) { m_bShowSelFrame = bNew; }
372
373
    virtual SwRewriter GetRewriter() const override;
374
375
};
376
377
#endif
378
379
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */