1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 #ifndef INCLUDED_SW_INC_DOCARY_HXX
20 #define INCLUDED_SW_INC_DOCARY_HXX
23 #include <type_traits>
24 #include <o3tl/sorted_vector.hxx>
28 #include "section.hxx"
30 #include "numrule.hxx"
40 enum class RedlineType
: sal_uInt16
;
42 /** provides some methods for generic operations on lists that contain SwFormat* subclasses. */
43 class SW_DLLPUBLIC SwFormatsBase
46 virtual size_t GetFormatCount() const = 0;
47 virtual SwFormat
* GetFormat(size_t idx
) const = 0;
48 virtual ~SwFormatsBase();
50 // default linear search implementation, some subclasses will override with a more efficient search
51 virtual SwFormat
* FindFormatByName(const OUString
& rName
) const;
52 virtual void Rename(const SwFrameFormat
&, const OUString
&) {};
54 SwFormatsBase() = default;
55 SwFormatsBase(SwFormatsBase
const &) = default;
56 SwFormatsBase(SwFormatsBase
&&) = default;
57 SwFormatsBase
& operator =(SwFormatsBase
const &) = default;
58 SwFormatsBase
& operator =(SwFormatsBase
&&) = default;
61 template<typename Value
>
62 class SwVectorModifyBase
65 typedef typename
std::vector
<Value
>::iterator iterator
;
66 typedef typename
std::vector
<Value
>::const_iterator const_iterator
;
67 typedef typename
std::vector
<Value
>::size_type size_type
;
68 typedef typename
std::vector
<Value
>::value_type value_type
;
71 enum class DestructorPolicy
{
77 typename
std::vector
<Value
> mvVals
;
78 const DestructorPolicy mPolicy
;
81 // default destructor deletes all contained elements
82 SwVectorModifyBase(DestructorPolicy policy
= DestructorPolicy::FreeElements
)
86 bool empty() const { return mvVals
.empty(); }
87 Value
const& front() const { return mvVals
.front(); }
88 size_t size() const { return mvVals
.size(); }
89 iterator
begin() { return mvVals
.begin(); }
90 const_iterator
begin() const { return mvVals
.begin(); }
91 iterator
end() { return mvVals
.end(); }
92 const_iterator
end() const { return mvVals
.end(); }
93 void clear() { mvVals
.clear(); }
94 iterator
erase(iterator aIt
) { return mvVals
.erase(aIt
); }
95 iterator
erase(iterator aFirst
, iterator aLast
) { return mvVals
.erase(aFirst
, aLast
); }
96 iterator
insert(iterator aIt
, Value
const& rVal
) { return mvVals
.insert(aIt
, rVal
); }
97 template<typename TInputIterator
>
98 void insert(iterator aIt
, TInputIterator aFirst
, TInputIterator aLast
)
100 mvVals
.insert(aIt
, aFirst
, aLast
);
102 void push_back(Value
const& rVal
) { mvVals
.push_back(rVal
); }
103 void reserve(size_type nSize
) { mvVals
.reserve(nSize
); }
104 Value
const& at(size_type nPos
) const { return mvVals
.at(nPos
); }
105 Value
const& operator[](size_type nPos
) const { return mvVals
[nPos
]; }
106 Value
& operator[](size_type nPos
) { return mvVals
[nPos
]; }
108 // free any remaining child objects based on mPolicy
109 virtual ~SwVectorModifyBase()
111 if (mPolicy
== DestructorPolicy::FreeElements
)
112 for(const_iterator it
= begin(); it
!= end(); ++it
)
116 //TODO: These functions are apparently brittle (but the copy functions are actually used by the
117 // code; the move functions will be implicitly-defined as deleted anyway) and should probably
118 // only be used with DestructorPolicy::KeepELements:
119 SwVectorModifyBase(SwVectorModifyBase
const &) = default;
120 SwVectorModifyBase(SwVectorModifyBase
&&) = default;
121 SwVectorModifyBase
& operator =(SwVectorModifyBase
const &) = default;
122 SwVectorModifyBase
& operator =(SwVectorModifyBase
&&) = default;
124 void DeleteAndDestroy(int aStartIdx
, int aEndIdx
)
126 if (aEndIdx
< aStartIdx
)
128 for (const_iterator it
= begin() + aStartIdx
;
129 it
!= begin() + aEndIdx
; ++it
)
131 erase( begin() + aStartIdx
, begin() + aEndIdx
);
134 size_t GetPos(Value
const& p
) const
136 const_iterator
const it
= std::find(begin(), end(), p
);
137 return it
== end() ? SIZE_MAX
: it
- begin();
140 /// check that given format is still alive (i.e. contained here)
141 bool IsAlive(typename
std::remove_pointer
<Value
>::type
const*const p
) const
142 { return std::find(begin(), end(), p
) != end(); }
144 static void dumpAsXml(xmlTextWriterPtr
/*pWriter*/) {};
147 template<typename Value
>
148 class SwFormatsModifyBase
: public SwVectorModifyBase
<Value
>, public SwFormatsBase
151 SwFormatsModifyBase(typename SwVectorModifyBase
<Value
>::DestructorPolicy
152 policy
= SwVectorModifyBase
<Value
>::DestructorPolicy::FreeElements
)
153 : SwVectorModifyBase
<Value
>(policy
) {}
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 size_t GetPos(const SwFormat
*p
) const
163 { return SwVectorModifyBase
<Value
>::GetPos( static_cast<Value
>( const_cast<SwFormat
*>( p
) ) ); }
165 // Override return type to reduce casting
166 virtual Value
FindFormatByName(const OUString
& rName
) const override
167 { return static_cast<Value
>(SwFormatsBase::FindFormatByName(rName
)); }
170 class SwGrfFormatColls final
: public SwFormatsModifyBase
<SwGrfFormatColl
*>
173 SwGrfFormatColls() : SwFormatsModifyBase( DestructorPolicy::KeepElements
) {}
177 /// Unsorted, undeleting SwFrameFormat vector
178 class SwFrameFormatsV final
: public SwFormatsModifyBase
<SwFrameFormat
*>
181 SwFrameFormatsV() : SwFormatsModifyBase( DestructorPolicy::KeepElements
) {}
184 class SwTextFormatColls final
: public SwFormatsModifyBase
<SwTextFormatColl
*>
187 SwTextFormatColls() : SwFormatsModifyBase( DestructorPolicy::KeepElements
) {}
188 void dumpAsXml(xmlTextWriterPtr pWriter
) const;
191 /// Array of Undo-history.
192 class SwSectionFormats final
: public SwFormatsModifyBase
<SwSectionFormat
*>
195 void dumpAsXml(xmlTextWriterPtr pWriter
) const;
198 class SwFieldTypes
: public std::vector
<std::unique_ptr
<SwFieldType
>> {
200 void dumpAsXml(xmlTextWriterPtr pWriter
) const;
203 class SwTOXTypes
: public std::vector
<std::unique_ptr
<SwTOXType
>> {};
205 class SwNumRuleTable final
: public SwVectorModifyBase
<SwNumRule
*> {
207 void dumpAsXml(xmlTextWriterPtr pWriter
) const;
210 struct CompareSwRedlineTable
212 bool operator()(SwRangeRedline
* const &lhs
, SwRangeRedline
* const &rhs
) const;
215 // Notification type for notifying about redlines to LOK clients
216 enum class RedlineNotification
{ Add
, Remove
, Modify
};
221 typedef o3tl::sorted_vector
<SwRangeRedline
*, CompareSwRedlineTable
,
222 o3tl::find_partialorder_ptrequals
> vector_type
;
223 typedef vector_type::size_type size_type
;
224 static constexpr size_type npos
= SAL_MAX_INT32
;
226 vector_type maVector
;
227 /// Sometimes we load bad data, and we need to know if we can use
228 /// fast binary search, or if we have to fall back to a linear search
229 bool m_bHasOverlappingElements
= false;
232 bool Contains(const SwRangeRedline
* p
) const { return maVector
.find(const_cast<SwRangeRedline
*>(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
; }
240 void Remove( size_type nPos
);
241 void Remove( const SwRangeRedline
* p
);
242 void DeleteAndDestroy(size_type nPos
);
243 void DeleteAndDestroyAll();
245 void dumpAsXml(xmlTextWriterPtr pWriter
) const;
247 size_type
FindNextOfSeqNo( size_type nSttPos
) const;
248 size_type
FindPrevOfSeqNo( size_type nSttPos
) const;
249 /** Search next or previous Redline with the same Seq. No.
250 Search can be restricted via Lookahead.
251 Using 0 makes search the whole array. */
252 size_type
FindNextSeqNo( sal_uInt16 nSeqNo
, size_type nSttPos
) const;
253 size_type
FindPrevSeqNo( sal_uInt16 nSeqNo
, size_type nSttPos
) const;
256 Find the redline at the given position.
258 @param tableIndex position in SwRedlineTable to start searching at, will be updated with the index of the returned
259 redline (or the next redline after the given position if not found)
260 @param next true: redline starts at position and ends after, false: redline starts before position and ends at or after
262 const SwRangeRedline
* FindAtPosition( const SwPosition
& startPosition
, size_type
& tableIndex
, bool next
= true ) const;
263 // is there a redline with the same text content from the same author (near the redline),
264 // but with the opposite type (Insert or Delete). It's used to recognize tracked text moving.
265 bool isMoved(size_type tableIndex
) const;
267 bool empty() const { return maVector
.empty(); }
268 size_type
size() const { return maVector
.size(); }
269 SwRangeRedline
* operator[]( size_type idx
) const { return maVector
[idx
]; }
270 vector_type::const_iterator
begin() const { return maVector
.begin(); }
271 vector_type::const_iterator
end() const { return maVector
.end(); }
272 void Resort() { maVector
.Resort(); }
274 // Notifies all LOK clients when redlines are added/modified/removed
275 static void LOKRedlineNotification(RedlineNotification eType
, SwRangeRedline
* pRedline
);
278 void CheckOverlapping(vector_type::const_iterator it
);
281 /// Table that holds 'extra' redlines, such as 'table row insert/delete', 'paragraph moves' etc...
282 class SwExtraRedlineTable
285 std::vector
<SwExtraRedline
*> m_aExtraRedlines
;
288 ~SwExtraRedlineTable();
290 void Insert( SwExtraRedline
* p
);
292 void DeleteAndDestroy( sal_uInt16 nPos
);
293 void DeleteAndDestroyAll();
295 void dumpAsXml(xmlTextWriterPtr pWriter
) const;
297 sal_uInt16
GetSize() const { return m_aExtraRedlines
.size(); }
298 SwExtraRedline
* GetRedline( sal_uInt16 uIndex
) const { return m_aExtraRedlines
.operator[]( uIndex
); }
300 SW_DLLPUBLIC
bool DeleteAllTableRedlines( SwDoc
& rDoc
, const SwTable
& rTable
, bool bSaveInUndo
, RedlineType nRedlineTypeToDelete
);
301 bool DeleteTableRowRedline ( SwDoc
* pDoc
, const SwTableLine
& rTableLine
, bool bSaveInUndo
, RedlineType nRedlineTypeToDelete
);
302 bool DeleteTableCellRedline( SwDoc
* pDoc
, const SwTableBox
& rTableBox
, bool bSaveInUndo
, RedlineType nRedlineTypeToDelete
);
305 typedef std::vector
<SwOLENode
*> SwOLENodes
;
307 #endif // INCLUDED_SW_INC_DOCARY_HXX
309 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */