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