LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / sc / inc / attarray.hxx
blob8681187965604ed652d506f9485a787d1b0c6f78
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 .
20 #pragma once
22 #include "global.hxx"
23 #include "attrib.hxx"
24 #include "document.hxx"
25 #include "patattr.hxx"
27 #include <algorithm>
28 #include <memory>
29 #include <optional>
31 #include <svl/itemset.hxx>
33 class ScDocument;
34 class ScEditDataArray;
35 class ScMarkArray;
36 class ScStyleSheet;
37 class ScFlatBoolRowSegments;
39 class SfxItemPoolCache;
40 class SfxStyleSheetBase;
41 class SvxBoxItem;
42 class SvxBoxInfoItem;
44 namespace editeng { class SvxBorderLine; }
46 #define SC_LINE_EMPTY 0
47 #define SC_LINE_SET 1
48 #define SC_LINE_DONTCARE 2
50 #define SC_ATTRARRAY_DELTA 4
52 #define DEBUG_SC_TESTATTRARRAY 0
54 struct ScLineFlags
56 sal_uInt8 nLeft;
57 sal_uInt8 nRight;
58 sal_uInt8 nTop;
59 sal_uInt8 nBottom;
60 sal_uInt8 nHori;
61 sal_uInt8 nVert;
63 ScLineFlags() : nLeft(SC_LINE_EMPTY),nRight(SC_LINE_EMPTY),nTop(SC_LINE_EMPTY),
64 nBottom(SC_LINE_EMPTY),nHori(SC_LINE_EMPTY),nVert(SC_LINE_EMPTY) {}
67 struct ScMergePatternState
69 std::optional<SfxItemSet> pItemSet;
70 const ScPatternAttr* pOld1; ///< existing objects, temporary
71 const ScPatternAttr* pOld2;
73 bool mbValidPatternId;
74 sal_uInt64 mnPatternId;
76 ScMergePatternState() : pOld1(nullptr), pOld2(nullptr),
77 mbValidPatternId(true), mnPatternId(0) {}
80 // we store an array of these where the pattern applies to all rows up till nEndRow
81 struct ScAttrEntry
83 SCROW nEndRow;
84 const ScPatternAttr* pPattern;
85 bool operator==( const ScAttrEntry& other ) const
87 return nEndRow == other.nEndRow && pPattern == other.pPattern;
91 class ScAttrArray
93 private:
94 SCCOL nCol;
95 SCTAB nTab;
96 ScDocument& rDocument;
98 std::vector<ScAttrEntry> mvData;
100 friend class ScDocument; // for FillInfo
101 friend class ScDocumentIterator;
102 friend class ScAttrIterator;
103 friend class ScHorizontalAttrIterator;
105 bool ApplyFrame( const SvxBoxItem& rLineOuter, const SvxBoxInfoItem* pLineInner,
106 SCROW nStartRow, SCROW nEndRow,
107 bool bLeft, SCCOL nDistRight, bool bTop, SCROW nDistBottom );
109 void RemoveCellCharAttribs( SCROW nStartRow, SCROW nEndRow,
110 const ScPatternAttr* pPattern, ScEditDataArray* pDataArray );
111 void SetDefaultIfNotInit( SCSIZE nNeeded = 1 );
112 bool HasAttrib_Impl(const ScPatternAttr* pPattern, HasAttrFlags nMask, SCROW nRow1, SCROW nRow2, SCSIZE i) const;
114 ScAttrArray(const ScAttrArray&) = delete;
115 ScAttrArray& operator=(const ScAttrArray&) = delete;
117 public:
118 ScAttrArray( SCCOL nNewCol, SCTAB nNewTab, ScDocument& rDoc, ScAttrArray* pNextColAttrArray );
119 ~ScAttrArray();
121 ScDocument& GetDoc() { return rDocument; }
122 const ScDocument& GetDoc() const { return rDocument; }
123 void SetTab(SCTAB nNewTab) { nTab = nNewTab; }
124 void SetCol(SCCOL nNewCol) { nCol = nNewCol; }
125 #if DEBUG_SC_TESTATTRARRAY
126 void TestData() const;
127 #endif
128 void Reset( const ScPatternAttr* pPattern);
129 bool Concat(SCSIZE nPos);
131 const ScPatternAttr* GetPattern( SCROW nRow ) const;
133 /** Returns if you search for attributes at nRow the range from rStartRow
134 to rEndRow where that attribute combination (ScPatternAttr) is applied.
135 The next ScPatternAttr different from this one starts at rEndRow+1
136 (if that is <= MAXROW).
138 const ScPatternAttr* GetPatternRange( SCROW& rStartRow, SCROW& rEndRow, SCROW nRow ) const;
140 void MergePatternArea( SCROW nStartRow, SCROW nEndRow, ScMergePatternState& rState, bool bDeep ) const;
142 void MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner, ScLineFlags& rFlags,
143 SCROW nStartRow, SCROW nEndRow, bool bLeft, SCCOL nDistRight ) const;
144 void ApplyBlockFrame(const SvxBoxItem& rLineOuter, const SvxBoxInfoItem* pLineInner,
145 SCROW nStartRow, SCROW nEndRow, bool bLeft, SCCOL nDistRight);
147 void SetPattern( SCROW nRow, const ScPatternAttr* pPattern, bool bPutToPool = false )
148 { SetPatternAreaImpl(nRow, nRow, pPattern, bPutToPool, nullptr, /*bPassingOwnership*/false); }
149 const ScPatternAttr* SetPattern( SCROW nRow, std::unique_ptr<ScPatternAttr> pPattern, bool bPutToPool = false )
150 { return SetPatternAreaImpl(nRow, nRow, pPattern.release(), bPutToPool, nullptr, /*bPassingOwnership*/true); }
151 void SetPatternArea( SCROW nStartRow, SCROW nEndRow, std::unique_ptr<ScPatternAttr> pPattern,
152 bool bPutToPool = false, ScEditDataArray* pDataArray = nullptr)
153 { SetPatternAreaImpl(nStartRow, nEndRow, pPattern.release(), bPutToPool, pDataArray, /*bPassingOwnership*/true); }
154 void SetPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr* pPattern,
155 bool bPutToPool = false, ScEditDataArray* pDataArray = nullptr)
156 { SetPatternAreaImpl(nStartRow, nEndRow, pPattern, bPutToPool, pDataArray, /*bPassingOwnership*/false); }
157 void ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, const ScStyleSheet& rStyle );
158 void ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, SfxItemPoolCache* pCache,
159 ScEditDataArray* pDataArray = nullptr, bool* const pIsChanged = nullptr );
160 void SetAttrEntries(std::vector<ScAttrEntry> && vNewData);
161 void ApplyLineStyleArea( SCROW nStartRow, SCROW nEndRow,
162 const ::editeng::SvxBorderLine* pLine, bool bColorOnly );
164 void AddCondFormat( SCROW nStartRow, SCROW nEndRow, sal_uInt32 nIndex );
165 /// if nIndex == 0, remove all conditional format data
166 void RemoveCondFormat( SCROW nStartRow, SCROW nEndRow, sal_uInt32 nIndex );
168 void ClearItems( SCROW nStartRow, SCROW nEndRow, const sal_uInt16* pWhich );
169 void ChangeIndent( SCROW nStartRow, SCROW nEndRow, bool bIncrement );
171 /// Including current, may return -1
172 SCROW GetNextUnprotected( SCROW nRow, bool bUp ) const;
174 /// May return -1 if not found
175 SCROW SearchStyle(
176 SCROW nRow, const ScStyleSheet* pSearchStyle, bool bUp,
177 const ScMarkArray* pMarkArray = nullptr) const;
179 bool SearchStyleRange(
180 SCROW& rRow, SCROW& rEndRow, const ScStyleSheet* pSearchStyle, bool bUp,
181 const ScMarkArray* pMarkArray = nullptr) const;
183 bool ApplyFlags( SCROW nStartRow, SCROW nEndRow, ScMF nFlags );
184 bool RemoveFlags( SCROW nStartRow, SCROW nEndRow, ScMF nFlags );
186 bool Search( SCROW nRow, SCSIZE& nIndex ) const;
188 bool HasAttrib( SCROW nRow1, SCROW nRow2, HasAttrFlags nMask ) const;
189 bool HasAttrib( SCROW nRow, HasAttrFlags nMask, SCROW* nStartRow = nullptr, SCROW* nEndRow = nullptr ) const;
190 bool IsMerged( SCROW nRow ) const;
191 bool ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow,
192 SCCOL& rPaintCol, SCROW& rPaintRow,
193 bool bRefresh );
194 void RemoveAreaMerge( SCROW nStartRow, SCROW nEndRow );
196 void FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBoolRowSegments& rUsedRows, bool bReset );
197 bool IsStyleSheetUsed( const ScStyleSheet& rStyle ) const;
199 void SetPatternAreaSafe( SCROW nStartRow, SCROW nEndRow,
200 const ScPatternAttr* pWantedPattern, bool bDefault );
201 void CopyAreaSafe( SCROW nStartRow, SCROW nEndRow, tools::Long nDy, ScAttrArray& rAttrArray );
203 bool IsEmpty() const;
205 bool GetFirstVisibleAttr( SCROW& rFirstRow ) const;
206 bool GetLastVisibleAttr( SCROW& rLastRow, SCROW nLastData ) const;
207 bool HasVisibleAttrIn( SCROW nStartRow, SCROW nEndRow ) const;
208 bool IsVisibleEqual( const ScAttrArray& rOther,
209 SCROW nStartRow, SCROW nEndRow ) const;
210 bool IsAllEqual( const ScAttrArray& rOther, SCROW nStartRow, SCROW nEndRow ) const;
212 bool TestInsertCol( SCROW nStartRow, SCROW nEndRow) const;
213 bool TestInsertRow( SCSIZE nSize ) const;
214 void InsertRow( SCROW nStartRow, SCSIZE nSize );
215 void DeleteRow( SCROW nStartRow, SCSIZE nSize );
216 void DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex );
217 void DeleteArea( SCROW nStartRow, SCROW nEndRow );
218 void MoveTo( SCROW nStartRow, SCROW nEndRow, ScAttrArray& rAttrArray );
219 void CopyArea(
220 SCROW nStartRow, SCROW nEndRow, tools::Long nDy, ScAttrArray& rAttrArray, ScMF nStripFlags = ScMF::NONE) const;
222 void DeleteHardAttr( SCROW nStartRow, SCROW nEndRow );
224 /* i123909: Pre-calculate needed memory, and pre-reserve enough memory */
225 bool Reserve( SCSIZE nReserve );
226 SCSIZE Count() const { return mvData.size(); }
227 SCSIZE Count( SCROW nRow1, SCROW nRow2 ) const;
229 private:
230 const ScPatternAttr* SetPatternAreaImpl( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr* pPattern,
231 bool bPutToPool = false, ScEditDataArray* pDataArray = nullptr,
232 bool bPassingPatternOwnership = false );
235 // Iterator for attributes
237 class ScAttrIterator
239 const ScAttrArray* pArray;
240 const ScPatternAttr* pDefPattern;
241 SCSIZE nPos;
242 SCROW nRow;
243 SCROW nEndRow;
244 public:
245 inline ScAttrIterator( const ScAttrArray* pNewArray, SCROW nStart, SCROW nEnd, const ScPatternAttr* pDefaultPattern );
246 inline const ScPatternAttr* Next( SCROW& rTop, SCROW& rBottom );
247 inline const ScPatternAttr* Resync( SCROW nRow, SCROW& rTop, SCROW& rBottom );
248 SCROW GetNextRow() const { return nRow; }
251 inline ScAttrIterator::ScAttrIterator( const ScAttrArray* pNewArray, SCROW nStart, SCROW nEnd, const ScPatternAttr* pDefaultPattern ) :
252 pArray( pNewArray ),
253 pDefPattern( pDefaultPattern ),
254 nRow( nStart ),
255 nEndRow( nEnd )
257 if ( pArray->Count() )
259 if ( nStart > 0 )
260 pArray->Search( nStart, nPos );
261 else
262 nPos = 0;
264 else
265 nPos = 0;
268 inline const ScPatternAttr* ScAttrIterator::Next( SCROW& rTop, SCROW& rBottom )
270 const ScPatternAttr* pRet;
271 if ( !pArray->Count() )
273 if ( !nPos )
275 ++nPos;
276 if ( nRow > pArray->GetDoc().MaxRow())
277 return nullptr;
278 rTop = nRow;
279 rBottom = std::min( nEndRow, pArray->GetDoc().MaxRow());
280 nRow = rBottom + 1;
281 return pDefPattern;
283 return nullptr;
286 if ( nPos < pArray->Count() && nRow <= nEndRow )
288 rTop = nRow;
289 rBottom = std::min( pArray->mvData[nPos].nEndRow, nEndRow );
290 pRet = pArray->mvData[nPos].pPattern;
291 nRow = rBottom + 1;
292 ++nPos;
294 else
295 pRet = nullptr;
296 return pRet;
299 inline const ScPatternAttr* ScAttrIterator::Resync( SCROW nRowP, SCROW& rTop, SCROW& rBottom )
301 nRow = nRowP;
302 if ( !pArray->Count() )
304 nPos = 0;
305 return Next( rTop, rBottom );
307 // Chances are high that the pattern changed on nRowP introduced a span
308 // starting right there. Assume that Next() was called so nPos already
309 // advanced. Another high chance is that the change extended a previous or
310 // next pattern. In all these cases we don't need to search.
311 if (3 <= nPos && nPos <= pArray->Count() && pArray->mvData[nPos-3].nEndRow < nRowP &&
312 nRowP <= pArray->mvData[nPos-2].nEndRow)
313 nPos -= 2;
314 else if (2 <= nPos && nPos <= pArray->Count() && pArray->mvData[nPos-2].nEndRow < nRowP &&
315 nRowP <= pArray->mvData[nPos-1].nEndRow)
316 --nPos;
317 else if (pArray->Count() > 0 && nRowP <= pArray->mvData[0].nEndRow)
318 nPos = 0;
319 else
320 pArray->Search( nRowP, nPos );
321 return Next( rTop, rBottom);
324 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */