Coverage Report

Created: 2026-09-28 10:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/inc/ndarr.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
20
#ifndef INCLUDED_SW_INC_NDARR_HXX
21
#define INCLUDED_SW_INC_NDARR_HXX
22
23
#include <sal/config.h>
24
25
#include <limits>
26
#include <vector>
27
#include <memory>
28
#include <optional>
29
#include <tuple>
30
31
#include "bparr.hxx"
32
#include "ndtyp.hxx"
33
#include <rtl/ustring.hxx>
34
#include <o3tl/sorted_vector.hxx>
35
#include "nodeoffset.hxx"
36
37
class Graphic;
38
class SwAttrSet;
39
class SfxItemSet;
40
class SwContentNode;
41
class SwDoc;
42
class SwFrameFormat;
43
class SwGrfFormatColl;
44
class SwGrfNode;
45
class SwNode;
46
class SwNodeIndex;
47
class SwNodeRange;
48
class SwOLENode;
49
class SwPaM;
50
class SwRootFrame;
51
class SwSectionData;
52
class SwSectionFormat;
53
class SwTOXBase;
54
class SwSectionNode;
55
class SwStartNode;
56
class SwTableBoxFormat;
57
class SwTableFormat;
58
class SwTableLine;
59
class SwTableLineFormat;
60
class SwTableNode;
61
class SwTextFormatColl;
62
class SwTextNode;
63
class SwUndoTableToText;
64
class SwUndoTextToTable;
65
struct SwPosition;
66
67
namespace sw { class DocumentContentOperationsManager; }
68
namespace svt { class EmbeddedObjectRef; }
69
70
71
typedef bool (*FnForEach_SwNodes)( SwNode*, void* pArgs );
72
typedef struct _xmlTextWriter *xmlTextWriterPtr;
73
74
struct CompareSwOutlineNodes
75
{
76
    bool operator()(const SwNode* lhs, const SwNode* rhs) const;
77
};
78
79
class SwOutlineNodes : public o3tl::sorted_vector<SwNode*, CompareSwOutlineNodes>
80
{
81
public:
82
    static constexpr auto npos = std::numeric_limits<size_type>::max();
83
84
    bool Seek_Entry(const SwNode* rP, size_type* pnPos) const;
85
    static const SwNode* GetRootNode(const SwNode* pNode, bool bCheckInlineHeading = true);
86
};
87
88
struct CompareSwOutlineNodesInline
89
{
90
    bool operator()(const SwNode* lhs, const SwNode* rhs) const;
91
};
92
93
class SwOutlineNodesInline : public o3tl::sorted_vector<SwNode*, CompareSwOutlineNodesInline>
94
{
95
public:
96
    static constexpr auto npos = std::numeric_limits<size_type>::max();
97
98
    bool Seek_Entry(const SwNode* rP, size_type* pnPos) const;
99
    bool Seek_Entry_By_Anchor(const SwNode* rAnchor, size_type* pnPos) const;
100
};
101
102
struct SwTableToTextSave;
103
using SwTableToTextSaves = std::vector<std::unique_ptr<SwTableToTextSave>>;
104
105
class SwNodes final
106
    : private BigPtrArray
107
{
108
    friend class SwDoc;
109
    friend class SwNode;
110
    friend class SwNodeIndex;
111
    friend class SwStartNode;
112
    friend class ::sw::DocumentContentOperationsManager;
113
114
    void RemoveNode( SwNodeOffset nDelPos, SwNodeOffset nLen, bool bDel );
115
116
    void InsertNode( SwNode* pNode, const SwNodeIndex& rPos );
117
    void InsertNode( SwNode* pNode, SwNodeOffset nPos );
118
119
    SwDoc& m_rMyDoc;                      ///< This Doc contains the nodes-array.
120
121
    SwNode *m_pEndOfPostIts, *m_pEndOfInserts,  ///< These are the fixed ranges.
122
           *m_pEndOfAutotext, *m_pEndOfRedlines;
123
    std::unique_ptr<SwNode> m_pEndOfContent;
124
125
    mutable SwOutlineNodes m_aOutlineNodes;        ///< Array of all outline nodes.
126
127
    bool m_bInNodesDel : 1;           /**< In Case of recursive calling.
128
                                           Do not update Num/Outline. */
129
    bool m_bInDelUpdOutline : 1;         ///< Flag for updating of Outline.
130
131
    // Actions on the nodes.
132
    static void SectionUpDown( const SwNodeIndex & aStart, const SwNodeIndex & aEnd );
133
    void DelNodes( const SwNodeIndex& rStart, SwNodeOffset nCnt = SwNodeOffset(1) );
134
135
    void ChgNode( SwNodeIndex const & rDelPos, SwNodeOffset nSize,
136
                  SwNodeIndex& rInsPos, bool bNewFrames );
137
138
    void UpdateOutlineIdx( const SwNode& );   ///< Update all OutlineNodes starting from Node.
139
140
    void CopyNodes( const SwNodeRange&, SwNode& rPos,
141
                    bool bNewFrames, bool bTableInsDummyNode = false ) const;
142
    void DelDummyNodes( const SwNodeRange& rRg );
143
144
    SwNodes(SwNodes const&) = delete;
145
    SwNodes& operator=(SwNodes const&) = delete;
146
147
    SwNodes(SwDoc& rDoc);
148
149
public:
150
    ~SwNodes();
151
152
    typedef std::vector<SwNodeRange> NodeRanges_t;
153
    typedef std::vector<NodeRanges_t> TableRanges_t;
154
155
    SwNode* operator[]( SwNodeOffset n ) const; // defined in node.hxx
156
157
6.63M
    SwNodeOffset Count() const { return SwNodeOffset(BigPtrArray::Count()); }
158
    void ForEach( FnForEach_SwNodes fnForEach, void* pArgs = nullptr )
159
0
    {
160
0
        ForEach( SwNodeOffset(0), Count(), fnForEach, pArgs );
161
0
    }
162
    void ForEach( SwNodeOffset nStt, SwNodeOffset nEnd, FnForEach_SwNodes fnForEach, void* pArgs );
163
    void ForEach( const SwNode& rStart, const SwNode& rEnd,
164
                    FnForEach_SwNodes fnForEach, void* pArgs );
165
    void ForEach( const SwNodeIndex& rStart, const SwNodeIndex& rEnd,
166
                    FnForEach_SwNodes fnForEach, void* pArgs );
167
168
    /// A still empty section.
169
70.0k
    SwNode& GetEndOfPostIts() const     { return *m_pEndOfPostIts; }
170
    /// Section for all footnotes.
171
399k
    SwNode& GetEndOfInserts() const     { return *m_pEndOfInserts; }
172
    /// Section for all Flys/Header/Footers.
173
2.16M
    SwNode& GetEndOfAutotext() const    { return *m_pEndOfAutotext; }
174
    /// Section for all Redlines.
175
2.35M
    SwNode& GetEndOfRedlines() const    { return *m_pEndOfRedlines; }
176
    /** This is the last EndNode of a special section. After it
177
       there is only the regular ContentSection (i.e. the BodyText). */
178
3.10M
    SwNode& GetEndOfExtras() const      { return *m_pEndOfRedlines; }
179
    /// Regular ContentSection (i.e. the BodyText).
180
6.87M
    SwNode& GetEndOfContent() const     { return *m_pEndOfContent; }
181
182
    /** Is the NodesArray the regular one of Doc? (and not the UndoNds, ...)
183
       Implementation in doc.hxx (because one needs to know Doc for it) ! */
184
    SW_DLLPUBLIC bool IsDocNodes() const;
185
186
    static sal_uInt16 GetSectionLevel(const SwNode &rIndex);
187
    void Delete(const SwNodeIndex &rPos, SwNodeOffset nNodes = SwNodeOffset(1));
188
    void Delete(const SwNode& rPos, SwNodeOffset nNodes = SwNodeOffset(1));
189
190
    bool MoveNodes( const SwNodeRange&, SwNodes& rNodes, SwNode& rPos,
191
                bool bNewFrames = true );
192
    void MoveRange( SwPaM&, SwPosition&, SwNodes& rNodes );
193
194
    void Copy_( const SwNodeRange& rRg, SwNode& rInsPos,
195
                bool bNewFrames = true ) const
196
127k
        {   CopyNodes( rRg, rInsPos, bNewFrames ); }
197
198
    void SectionUp( SwNodeRange *);
199
    void SectionDown( SwNodeRange *pRange, SwStartNodeType = SwNormalStartNode );
200
201
    static void GoStartOfSection(SwNodeIndex *);
202
    static void GoEndOfSection(SwNodeIndex *);
203
204
    SW_DLLPUBLIC static SwContentNode* GoNext(SwNodeIndex*);
205
    static SwContentNode* GoNext(SwPosition*);
206
    static SwContentNode* GoPrevious(SwNodeIndex *, bool canCrossBoundary = false);
207
    static SwContentNode* GoPrevious(SwPosition *, bool canCrossBoundary = false);
208
209
    /** Go to next content-node that is not protected or hidden
210
       (Both set FALSE ==> GoNext/GoPrevious!!!). */
211
    static SwContentNode* GoNextSection( SwNodeIndex *, bool bSkipHidden  = true,
212
                                           bool bSkipProtect = true );
213
    static SwContentNode* GoNextSection( SwPosition *, bool bSkipHidden  = true,
214
                                           bool bSkipProtect = true );
215
    // canCrossBoundary allows moving out of the current global section (fly / header / footer /
216
    // footnote / redlines / content).
217
    SW_DLLPUBLIC static SwContentNode* GoPrevSection( SwNodeIndex *, bool bSkipHidden  = true,
218
                                           bool bSkipProtect = true, bool canCrossBoundary = false );
219
    static SwContentNode* GoPrevSection( SwPosition *, bool bSkipHidden  = true,
220
                                           bool bSkipProtect = true, bool canCrossBoundary = false );
221
222
    /** Create an empty section of Start- and EndNode. It may be called
223
       only if a new section with content is to be created,
224
       e.g. at filters/Undo/... */
225
    static SwStartNode* MakeEmptySection( const SwNode& rWhere,
226
                                    SwStartNodeType = SwNormalStartNode );
227
228
    /// Implementations of "Make...Node" are in the given .cxx-files.
229
    SW_DLLPUBLIC SwTextNode *MakeTextNode( const SwNode& rWhere,
230
                            SwTextFormatColl *pColl,
231
                            bool bNewFrames = true); ///< in ndtxt.cxx
232
    SW_DLLPUBLIC SwStartNode* MakeTextSection( const SwNode & rWhere,
233
                            SwStartNodeType eSttNdTyp,
234
                            SwTextFormatColl *pColl );
235
236
    static SwGrfNode *MakeGrfNode( const SwNode& rWhere,
237
                            const OUString& rGrfName,
238
                            const OUString& rFltName,
239
                            const Graphic* pGraphic,
240
                            SwGrfFormatColl *pColl,
241
                            SwAttrSet const * pAutoAttr = nullptr );    ///< in ndgrf.cxx
242
243
    SwOLENode *MakeOLENode( const SwNode& rWhere,
244
                            const svt::EmbeddedObjectRef&,
245
                            SwGrfFormatColl *pColl ); ///< in ndole.cxx
246
    SwOLENode *MakeOLENode( const SwNode& rWhere,
247
                            const OUString &rName,
248
                            sal_Int64 nAspect,
249
                            SwGrfFormatColl *pColl,
250
                            SwAttrSet const * pAutoAttr ); ///< in ndole.cxx
251
252
    /// Array of all OutlineNodes.
253
27.6k
    const SwOutlineNodes& GetOutLineNds() const { return m_aOutlineNodes;}
254
255
    /// Update all Nodes - Rule/Format-Change.
256
    void UpdateOutlineNode(SwNode & rNd);
257
258
    /** Insert nodes for tables. If Lines is given, create the matrix
259
       from lines and boxes, else only the count of boxes.
260
261
       New parameter pAttrSet: If pAttrSet is non-null and contains an
262
       adjust item it is propagated to the table cells. If there is an
263
       adjust in pContentTextColl or pHeadlineTextColl this adjust item
264
       overrides the item in pAttrSet. */
265
266
    static SwTableNode* InsertTable( const SwNode& rNd,
267
                        sal_uInt16 nBoxes, SwTextFormatColl* pContentTextColl,
268
                        sal_uInt16 nLines, sal_uInt16 nRepeat,
269
                        SwTextFormatColl* pHeadlineTextColl,
270
                        const SwAttrSet * pAttrSet);
271
272
    /// Create balanced table from selected range.
273
    /// @param nCols  number of additional empty columns to append (tdf#167632)
274
    SwTableNode* TextToTable( const SwNodeRange& rRange, sal_Unicode cCh,
275
                                SwTableFormat* pTableFormat,
276
                                SwTableLineFormat* pLineFormat,
277
                                SwTableBoxFormat* pBoxFormat,
278
                                SwTextFormatColl* pTextColl,
279
                                SwUndoTextToTable* pUndo,
280
                                sal_uInt16 nCols = 0 );
281
282
    void ExpandRangeForTableBox(const SwNodeRange & rRange,
283
                                std::optional<SwNodeRange>& rExpandedRange);
284
285
    /// create a table from a vector of NodeRanges - API support
286
    SwTableNode* TextToTable( const TableRanges_t& rTableNodes,
287
                                SwTableFormat* pTableFormat,
288
                                SwTableLineFormat* pLineFormat,
289
                                SwTableBoxFormat* pBoxFormat );
290
291
    /// Create regular text from what was table.
292
    bool TableToText( const SwNodeRange& rRange, sal_Unicode cCh,
293
                        SwUndoTableToText* );
294
    /// Is in untbl.cxx and may be called only by Undo-object.
295
    SwTableNode* UndoTableToText( SwNodeOffset nStt, SwNodeOffset nEnd,
296
                        const SwTableToTextSaves& rSavedData );
297
298
    /** Insert a new box in the line before InsPos. Its format
299
       is taken from the following one (or from the previous one if we are
300
       at the end). In the line there must be a box already. */
301
    SW_DLLPUBLIC bool InsBoxen( SwTableNode*, SwTableLine*, SwTableBoxFormat*,
302
                        /// Formats for TextNode of box.
303
                        SwTextFormatColl*, const SfxItemSet* pAutoAttr,
304
                        sal_uInt16 nInsPos, sal_uInt16 nCnt = 1 );
305
    /** Splits a table at the base-line which contains the index.
306
       All base lines behind it are moved to a new table/ -node.
307
       If the flag bCalcNewSize is set to TRUE, the new SSize for both
308
       tables is calculated from the Maximum of the boxes, provided
309
       SSize is set "absolute" (LONG_MAX).
310
     */
311
    SwTableNode* SplitTable( SwNode& rPos, bool bAfter = true,
312
                                bool bCalcNewSize = false );
313
    void SplitFloatingTableFrame(SwTableNode & rNewTableNode,
314
        ::std::tuple<SwStartNode &, SwFrameFormat &, SwTextNode &> floatingFrame);
315
    /// Two Tables that are following one another are merged.
316
    bool MergeTable( SwNode& rPos, bool bWithPrev = true );
317
    void MergeFloatingTableFrame(SwNodeOffset nEndOfOldFlyIndex);
318
319
    /// Insert a new SwSection.
320
    SwSectionNode* InsertTextSection(SwNode& rNd,
321
                                SwSectionFormat& rSectionFormat,
322
                                SwSectionData const&,
323
                                SwTOXBase const*const pTOXBase,
324
                                SwNode const * pEndNd,
325
                                bool const bInsAtStart = true,
326
                                bool const bCreateFrames = true);
327
328
    /// Which Doc contains the nodes-array?
329
179M
            SwDoc& GetDoc()         { return m_rMyDoc; }
330
85.5M
    const   SwDoc& GetDoc() const   { return m_rMyDoc; }
331
332
    /** Search previous / next content node or table node with frames.
333
     Search is started backward with the one before rFrameNd and
334
     forward after pEnd.
335
     If no valid node is found, return nullptr. **/
336
    SwNode* FindPrvNxtFrameNode( const SwNode& rFrameNd,
337
                                const SwNode* pEnd,
338
                                SwRootFrame const* pLayout = nullptr) const;
339
340
    SwNode * DocumentSectionStartNode(SwNode * pNode) const;
341
    SwNode * DocumentSectionEndNode(SwNode * pNode) const;
342
343
    /**
344
     * Dumps the entire nodes structure to the given destination (file nodes.xml in the current directory by default)
345
     */
346
    void dumpAsXml( xmlTextWriterPtr pWriter ) const;
347
};
348
349
350
#endif
351
352
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */