Update git submodules
[LibreOffice.git] / sw / inc / docary.hxx
blobdc8d0941dc04dc0adfea40d31e78dd903c13f5ff
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #pragma once
21 #include <vector>
22 #include <type_traits>
23 #include <o3tl/sorted_vector.hxx>
25 #include "fmtcol.hxx"
26 #include "frmfmt.hxx"
27 #include "section.hxx"
28 #include "tox.hxx"
29 #include "numrule.hxx"
30 #include "fldbas.hxx"
31 #include "pam.hxx"
33 class SwRangeRedline;
34 class SwExtraRedline;
35 class SwOLENode;
36 class SwTable;
37 class SwTableLine;
38 class SwTableBox;
39 enum class RedlineType : sal_uInt16;
41 /** provides some methods for generic operations on lists that contain SwFormat* subclasses. */
42 class SW_DLLPUBLIC SwFormatsBase
44 public:
45 virtual size_t GetFormatCount() const = 0;
46 virtual SwFormat* GetFormat(size_t idx) const = 0;
47 virtual ~SwFormatsBase();
49 // default linear search implementation, some subclasses will override with a more efficient search
50 virtual SwFormat* FindFormatByName(const OUString& rName) const;
51 virtual void Rename(const SwFrameFormat&, const OUString&) {};
53 SwFormatsBase() = default;
54 SwFormatsBase(SwFormatsBase const &) = default;
55 SwFormatsBase(SwFormatsBase &&) = default;
56 SwFormatsBase & operator =(SwFormatsBase const &) = default;
57 SwFormatsBase & operator =(SwFormatsBase &&) = default;
60 template<typename Value>
61 class SwVectorModifyBase
63 public:
64 typedef typename std::vector<Value>::iterator iterator;
65 typedef typename std::vector<Value>::const_iterator const_iterator;
66 typedef typename std::vector<Value>::size_type size_type;
67 typedef typename std::vector<Value>::value_type value_type;
69 protected:
70 enum class DestructorPolicy {
71 KeepElements,
72 FreeElements,
75 private:
76 typename std::vector<Value> mvVals;
77 const DestructorPolicy mPolicy;
79 protected:
80 // default destructor deletes all contained elements
81 SwVectorModifyBase(DestructorPolicy policy = DestructorPolicy::FreeElements)
82 : mPolicy(policy) {}
84 public:
85 bool empty() const { return mvVals.empty(); }
86 Value const& front() const { return mvVals.front(); }
87 size_t size() const { return mvVals.size(); }
88 iterator begin() { return mvVals.begin(); }
89 const_iterator begin() const { return mvVals.begin(); }
90 iterator end() { return mvVals.end(); }
91 const_iterator end() const { return mvVals.end(); }
92 void clear() { mvVals.clear(); }
93 iterator erase(iterator aIt) { return mvVals.erase(aIt); }
94 iterator erase(iterator aFirst, iterator aLast) { return mvVals.erase(aFirst, aLast); }
95 iterator insert(iterator aIt, Value const& rVal) { return mvVals.insert(aIt, rVal); }
96 template<typename TInputIterator>
97 void insert(iterator aIt, TInputIterator aFirst, TInputIterator aLast)
99 mvVals.insert(aIt, aFirst, aLast);
101 void push_back(Value const& rVal) { mvVals.push_back(rVal); }
102 void reserve(size_type nSize) { mvVals.reserve(nSize); }
103 Value const& at(size_type nPos) const { return mvVals.at(nPos); }
104 Value const& operator[](size_type nPos) const { return mvVals[nPos]; }
105 Value& operator[](size_type nPos) { return mvVals[nPos]; }
107 // free any remaining child objects based on mPolicy
108 virtual ~SwVectorModifyBase()
110 if (mPolicy == DestructorPolicy::FreeElements)
111 for(const_iterator it = begin(); it != end(); ++it)
112 delete *it;
115 //TODO: These functions are apparently brittle (but the copy functions are actually used by the
116 // code; the move functions will be implicitly-defined as deleted anyway) and should probably
117 // only be used with DestructorPolicy::KeepELements:
118 SwVectorModifyBase(SwVectorModifyBase const &) = default;
119 SwVectorModifyBase(SwVectorModifyBase &&) = default;
120 SwVectorModifyBase & operator =(SwVectorModifyBase const &) = default;
121 SwVectorModifyBase & operator =(SwVectorModifyBase &&) = default;
123 void DeleteAndDestroy(int aStartIdx, int aEndIdx)
125 if (aEndIdx < aStartIdx)
126 return;
127 for (const_iterator it = begin() + aStartIdx;
128 it != begin() + aEndIdx; ++it)
129 delete *it;
130 erase( begin() + aStartIdx, begin() + aEndIdx);
133 size_t GetPos(typename std::remove_pointer_t<Value> const* const p) const
135 const_iterator const it = std::find(begin(), end(), p);
136 return it == end() ? SIZE_MAX : it - begin();
139 /// check that given format is still alive (i.e. contained here)
140 bool IsAlive(typename std::remove_pointer<Value>::type const*const p) const
141 { return std::find(begin(), end(), p) != end(); }
143 static void dumpAsXml(xmlTextWriterPtr /*pWriter*/) {};
146 /// Provides a generic container for Writer styles: paragraph, graphic, section, etc styles.
147 template<typename Value>
148 class SwFormatsModifyBase : public SwVectorModifyBase<Value>, public SwFormatsBase
150 protected:
151 SwFormatsModifyBase(typename SwVectorModifyBase<Value>::DestructorPolicy
152 policy = SwVectorModifyBase<Value>::DestructorPolicy::FreeElements)
153 : SwVectorModifyBase<Value>(policy) {}
155 public:
156 virtual size_t GetFormatCount() const override
157 { return SwVectorModifyBase<Value>::size(); }
159 virtual Value GetFormat(size_t idx) const override
160 { return SwVectorModifyBase<Value>::operator[](idx); }
162 // Override return type to reduce casting
163 virtual Value FindFormatByName(const OUString& rName) const override
164 { return static_cast<Value>(SwFormatsBase::FindFormatByName(rName)); }
167 class SwGrfFormatColls final : public SwFormatsModifyBase<SwGrfFormatColl*>
169 public:
170 SwGrfFormatColls() : SwFormatsModifyBase( DestructorPolicy::KeepElements ) {}
174 /// Unsorted, undeleting SwFrameFormat vector
175 class SwFrameFormatsV final : public SwFormatsModifyBase<SwFrameFormat*>
177 public:
178 SwFrameFormatsV() : SwFormatsModifyBase( DestructorPolicy::KeepElements ) {}
181 /// Container of paragraph styles.
182 class SwTextFormatColls final : public SwFormatsModifyBase<SwTextFormatColl*>
184 public:
185 SwTextFormatColls() : SwFormatsModifyBase( DestructorPolicy::KeepElements ) {}
186 void dumpAsXml(xmlTextWriterPtr pWriter) const;
189 /// Array of Undo-history.
190 class SwSectionFormats final : public SwFormatsModifyBase<SwSectionFormat*>
192 public:
193 void dumpAsXml(xmlTextWriterPtr pWriter) const;
196 class SwFieldTypes : public std::vector<std::unique_ptr<SwFieldType>> {
197 public:
198 void dumpAsXml(xmlTextWriterPtr pWriter) const;
201 class SwTOXTypes : public std::vector<std::unique_ptr<SwTOXType>> {};
203 class SwNumRuleTable final : public SwVectorModifyBase<SwNumRule*> {
204 public:
205 void dumpAsXml(xmlTextWriterPtr pWriter) const;
208 struct CompareSwRedlineTable
210 bool operator()(const SwRangeRedline* lhs, const SwRangeRedline* rhs) const;
213 // Notification type for notifying about redlines to LOK clients
214 enum class RedlineNotification { Add, Remove, Modify };
216 class SwRedlineTable
218 public:
219 typedef o3tl::sorted_vector<SwRangeRedline*, CompareSwRedlineTable,
220 o3tl::find_partialorder_ptrequals> vector_type;
221 typedef vector_type::size_type size_type;
222 static constexpr size_type npos = SAL_MAX_INT32;
223 private:
224 vector_type maVector;
225 /// Sometimes we load bad data, and we need to know if we can use
226 /// fast binary search, or if we have to fall back to a linear search
227 bool m_bHasOverlappingElements = false;
228 mutable sal_uInt32 m_nMaxMovedID = 1; //every move-redline pair get a unique ID, so they can find each other.
229 mutable const SwRangeRedline* mpMaxEndPos = nullptr; // the redline with the maximum end pos
230 public:
231 ~SwRedlineTable();
232 bool Contains(const SwRangeRedline* p) const { return maVector.find(p) != maVector.end(); }
233 size_type GetPos(const SwRangeRedline* p) const;
235 bool Insert(SwRangeRedline*& p);
236 bool Insert(SwRangeRedline*& p, size_type& rInsPos);
237 bool InsertWithValidRanges(SwRangeRedline*& p, size_type* pInsPos = nullptr);
238 bool HasOverlappingElements() const { return m_bHasOverlappingElements; }
239 const SwPosition& GetMaxEndPos() const;
241 void Remove( size_type nPos );
242 void Remove( const SwRangeRedline* p );
243 void DeleteAndDestroy(size_type nPos);
244 void DeleteAndDestroyAll();
246 void dumpAsXml(xmlTextWriterPtr pWriter) const;
248 size_type FindNextOfSeqNo( size_type nSttPos ) const;
249 size_type FindPrevOfSeqNo( size_type nSttPos ) const;
250 /** Search next or previous Redline with the same Seq. No.
251 Search can be restricted via Lookahead.
252 Using 0 makes search the whole array. */
253 size_type FindNextSeqNo( sal_uInt16 nSeqNo, size_type nSttPos ) const;
254 size_type FindPrevSeqNo( sal_uInt16 nSeqNo, size_type nSttPos ) const;
257 Find the redline at the given position.
259 @param tableIndex position in SwRedlineTable to start searching at, will be updated with the index of the returned
260 redline (or the next redline after the given position if not found)
261 @param next true: redline starts at position and ends after, false: redline starts before position and ends at or after
263 const SwRangeRedline* FindAtPosition( const SwPosition& startPosition, size_type& tableIndex, bool next = true ) const;
264 // is there a redline with the same text content from the same author (near the redline),
265 // but with the opposite type (Insert or Delete). It's used to recognize tracked text moving.
266 bool isMoved(size_type tableIndex) const;
267 bool isMovedImpl(size_type tableIndex, bool bTryCombined) const;
268 sal_uInt32 getNewMovedID() const { return ++m_nMaxMovedID; }
269 void setMovedIDIfNeeded(sal_uInt32 nMax);
270 void getConnectedArea(size_type nPosOrigin, size_type& rPosStart, size_type& rPosEnd,
271 bool bCheckChilds) const;
272 OUString getTextOfArea(size_type rPosStart, size_type rPosEnd) const;
275 bool empty() const { return maVector.empty(); }
276 size_type size() const { return maVector.size(); }
277 SwRangeRedline* operator[]( size_type idx ) const { return maVector[idx]; }
278 vector_type::const_iterator begin() const { return maVector.begin(); }
279 vector_type::const_iterator end() const { return maVector.end(); }
280 void Resort() { maVector.Resort(); mpMaxEndPos = nullptr; }
282 // Notifies all LOK clients when redlines are added/modified/removed
283 static void LOKRedlineNotification(RedlineNotification eType, SwRangeRedline* pRedline);
285 private:
286 void CheckOverlapping(vector_type::const_iterator it);
289 /// Table that holds 'extra' redlines, such as 'table row insert/delete', 'paragraph moves' etc...
290 class SwExtraRedlineTable
292 private:
293 std::vector<SwExtraRedline*> m_aExtraRedlines;
295 public:
296 ~SwExtraRedlineTable();
298 void Insert( SwExtraRedline* p );
300 void DeleteAndDestroy( sal_uInt16 nPos);
301 void DeleteAndDestroyAll();
303 void dumpAsXml(xmlTextWriterPtr pWriter) const;
305 sal_uInt16 GetSize() const { return m_aExtraRedlines.size(); }
306 SwExtraRedline* GetRedline( sal_uInt16 uIndex ) const { return m_aExtraRedlines.operator[]( uIndex ); }
308 SW_DLLPUBLIC bool DeleteAllTableRedlines( SwDoc& rDoc, const SwTable& rTable, bool bSaveInUndo, RedlineType nRedlineTypeToDelete );
309 bool DeleteTableRowRedline ( SwDoc* pDoc, const SwTableLine& rTableLine, bool bSaveInUndo, RedlineType nRedlineTypeToDelete );
310 bool DeleteTableCellRedline( SwDoc* pDoc, const SwTableBox& rTableBox, bool bSaveInUndo, RedlineType nRedlineTypeToDelete );
313 typedef std::vector<SwOLENode*> SwOLENodes;
315 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */