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 .
20 #ifndef INCLUDED_SC_INC_ATTARRAY_HXX
21 #define INCLUDED_SC_INC_ATTARRAY_HXX
25 #include "patattr.hxx"
30 #include <svl/itemset.hxx>
33 class ScEditDataArray
;
36 class ScFlatBoolRowSegments
;
38 class SfxItemPoolCache
;
39 class SfxStyleSheetBase
;
43 namespace editeng
{ class SvxBorderLine
; }
45 #define SC_LINE_EMPTY 0
47 #define SC_LINE_DONTCARE 2
49 #define SC_ATTRARRAY_DELTA 4
51 #define DEBUG_SC_TESTATTRARRAY 0
62 ScLineFlags() : nLeft(SC_LINE_EMPTY
),nRight(SC_LINE_EMPTY
),nTop(SC_LINE_EMPTY
),
63 nBottom(SC_LINE_EMPTY
),nHori(SC_LINE_EMPTY
),nVert(SC_LINE_EMPTY
) {}
66 struct ScMergePatternState
68 std::unique_ptr
<SfxItemSet
> pItemSet
;
69 const ScPatternAttr
* pOld1
; ///< existing objects, temporary
70 const ScPatternAttr
* pOld2
;
72 bool mbValidPatternId
;
73 sal_uInt64 mnPatternId
;
75 ScMergePatternState() : pOld1(nullptr), pOld2(nullptr),
76 mbValidPatternId(true), mnPatternId(0) {}
79 // we store an array of these where the pattern applies to all rows up till nEndRow
83 const ScPatternAttr
* pPattern
;
91 ScDocument
* const pDocument
;
93 std::vector
<ScAttrEntry
> mvData
;
95 friend class ScDocument
; // for FillInfo
96 friend class ScDocumentIterator
;
97 friend class ScAttrIterator
;
98 friend class ScHorizontalAttrIterator
;
100 bool ApplyFrame( const SvxBoxItem
* pLineOuter
, const SvxBoxInfoItem
* pLineInner
,
101 SCROW nStartRow
, SCROW nEndRow
,
102 bool bLeft
, SCCOL nDistRight
, bool bTop
, SCROW nDistBottom
);
104 void RemoveCellCharAttribs( SCROW nStartRow
, SCROW nEndRow
,
105 const ScPatternAttr
* pPattern
, ScEditDataArray
* pDataArray
);
106 void SetDefaultIfNotInit( SCSIZE nNeeded
= 1 );
107 bool HasAttrib_Impl(const ScPatternAttr
* pPattern
, HasAttrFlags nMask
, SCROW nRow1
, SCROW nRow2
, SCSIZE i
) const;
109 ScAttrArray(const ScAttrArray
&) = delete;
110 ScAttrArray
& operator=(const ScAttrArray
&) = delete;
113 ScAttrArray( SCCOL nNewCol
, SCTAB nNewTab
, ScDocument
* pDoc
, ScAttrArray
* pNextColAttrArray
);
116 ScDocument
* GetDoc() { return pDocument
; }
117 void SetTab(SCTAB nNewTab
) { nTab
= nNewTab
; }
118 void SetCol(SCCOL nNewCol
) { nCol
= nNewCol
; }
119 #if DEBUG_SC_TESTATTRARRAY
120 void TestData() const;
122 void Reset( const ScPatternAttr
* pPattern
);
123 bool Concat(SCSIZE nPos
);
125 const ScPatternAttr
* GetPattern( SCROW nRow
) const;
127 /** Returns if you search for attributes at nRow the range from rStartRow
128 to rEndRow where that attribute combination (ScPatternAttr) is applied.
129 The next ScPatternAttr different from this one starts at rEndRow+1
130 (if that is <= MAXROW).
132 const ScPatternAttr
* GetPatternRange( SCROW
& rStartRow
, SCROW
& rEndRow
, SCROW nRow
) const;
134 void MergePatternArea( SCROW nStartRow
, SCROW nEndRow
, ScMergePatternState
& rState
, bool bDeep
) const;
136 void MergeBlockFrame( SvxBoxItem
* pLineOuter
, SvxBoxInfoItem
* pLineInner
, ScLineFlags
& rFlags
,
137 SCROW nStartRow
, SCROW nEndRow
, bool bLeft
, SCCOL nDistRight
) const;
138 void ApplyBlockFrame(const SvxBoxItem
& rLineOuter
, const SvxBoxInfoItem
* pLineInner
,
139 SCROW nStartRow
, SCROW nEndRow
, bool bLeft
, SCCOL nDistRight
);
141 void SetPattern( SCROW nRow
, const ScPatternAttr
* pPattern
, bool bPutToPool
= false )
142 { SetPatternAreaImpl(nRow
, nRow
, pPattern
, bPutToPool
, nullptr, /*bPassingOwnership*/false); }
143 const ScPatternAttr
* SetPattern( SCROW nRow
, std::unique_ptr
<ScPatternAttr
> pPattern
, bool bPutToPool
= false )
144 { return SetPatternAreaImpl(nRow
, nRow
, pPattern
.release(), bPutToPool
, nullptr, /*bPassingOwnership*/true); }
145 void SetPatternArea( SCROW nStartRow
, SCROW nEndRow
, std::unique_ptr
<ScPatternAttr
> pPattern
,
146 bool bPutToPool
= false, ScEditDataArray
* pDataArray
= nullptr)
147 { SetPatternAreaImpl(nStartRow
, nEndRow
, pPattern
.release(), bPutToPool
, pDataArray
, /*bPassingOwnership*/true); }
148 void SetPatternArea( SCROW nStartRow
, SCROW nEndRow
, const ScPatternAttr
* pPattern
,
149 bool bPutToPool
= false, ScEditDataArray
* pDataArray
= nullptr)
150 { SetPatternAreaImpl(nStartRow
, nEndRow
, pPattern
, bPutToPool
, pDataArray
, /*bPassingOwnership*/false); }
151 void ApplyStyleArea( SCROW nStartRow
, SCROW nEndRow
, const ScStyleSheet
& rStyle
);
152 void ApplyCacheArea( SCROW nStartRow
, SCROW nEndRow
, SfxItemPoolCache
* pCache
,
153 ScEditDataArray
* pDataArray
= nullptr, bool* const pIsChanged
= nullptr );
154 void SetAttrEntries(std::vector
<ScAttrEntry
> && vNewData
);
155 void ApplyLineStyleArea( SCROW nStartRow
, SCROW nEndRow
,
156 const ::editeng::SvxBorderLine
* pLine
, bool bColorOnly
);
158 void AddCondFormat( SCROW nStartRow
, SCROW nEndRow
, sal_uInt32 nIndex
);
159 /// if nIndex == 0, remove all conditional format data
160 void RemoveCondFormat( SCROW nStartRow
, SCROW nEndRow
, sal_uInt32 nIndex
);
162 void ClearItems( SCROW nStartRow
, SCROW nEndRow
, const sal_uInt16
* pWhich
);
163 void ChangeIndent( SCROW nStartRow
, SCROW nEndRow
, bool bIncrement
);
165 /// Including current, may return -1
166 SCROW
GetNextUnprotected( SCROW nRow
, bool bUp
) const;
168 /// May return -1 if not found
170 SCROW nRow
, const ScStyleSheet
* pSearchStyle
, bool bUp
,
171 const ScMarkArray
* pMarkArray
= nullptr) const;
173 bool SearchStyleRange(
174 SCROW
& rRow
, SCROW
& rEndRow
, const ScStyleSheet
* pSearchStyle
, bool bUp
,
175 const ScMarkArray
* pMarkArray
= nullptr) const;
177 bool ApplyFlags( SCROW nStartRow
, SCROW nEndRow
, ScMF nFlags
);
178 bool RemoveFlags( SCROW nStartRow
, SCROW nEndRow
, ScMF nFlags
);
180 bool Search( SCROW nRow
, SCSIZE
& nIndex
) const;
182 bool HasAttrib( SCROW nRow1
, SCROW nRow2
, HasAttrFlags nMask
) const;
183 bool IsMerged( SCROW nRow
) const;
184 bool ExtendMerge( SCCOL nThisCol
, SCROW nStartRow
, SCROW nEndRow
,
185 SCCOL
& rPaintCol
, SCROW
& rPaintRow
,
187 void RemoveAreaMerge( SCROW nStartRow
, SCROW nEndRow
);
189 void FindStyleSheet( const SfxStyleSheetBase
* pStyleSheet
, ScFlatBoolRowSegments
& rUsedRows
, bool bReset
);
190 bool IsStyleSheetUsed( const ScStyleSheet
& rStyle
) const;
192 void SetPatternAreaSafe( SCROW nStartRow
, SCROW nEndRow
,
193 const ScPatternAttr
* pWantedPattern
, bool bDefault
);
194 void CopyAreaSafe( SCROW nStartRow
, SCROW nEndRow
, long nDy
, ScAttrArray
& rAttrArray
);
196 bool IsEmpty() const;
198 bool GetFirstVisibleAttr( SCROW
& rFirstRow
) const;
199 bool GetLastVisibleAttr( SCROW
& rLastRow
, SCROW nLastData
) const;
200 bool HasVisibleAttrIn( SCROW nStartRow
, SCROW nEndRow
) const;
201 bool IsVisibleEqual( const ScAttrArray
& rOther
,
202 SCROW nStartRow
, SCROW nEndRow
) const;
203 bool IsAllEqual( const ScAttrArray
& rOther
, SCROW nStartRow
, SCROW nEndRow
) const;
205 bool TestInsertCol( SCROW nStartRow
, SCROW nEndRow
) const;
206 bool TestInsertRow( SCSIZE nSize
) const;
207 void InsertRow( SCROW nStartRow
, SCSIZE nSize
);
208 void DeleteRow( SCROW nStartRow
, SCSIZE nSize
);
209 void DeleteRange( SCSIZE nStartIndex
, SCSIZE nEndIndex
);
210 void DeleteArea( SCROW nStartRow
, SCROW nEndRow
);
211 void MoveTo( SCROW nStartRow
, SCROW nEndRow
, ScAttrArray
& rAttrArray
);
213 SCROW nStartRow
, SCROW nEndRow
, long nDy
, ScAttrArray
& rAttrArray
, ScMF nStripFlags
= ScMF::NONE
) const;
215 void DeleteHardAttr( SCROW nStartRow
, SCROW nEndRow
);
217 /* i123909: Pre-calculate needed memory, and pre-reserve enough memory */
218 bool Reserve( SCSIZE nReserve
);
219 SCSIZE
Count() const { return mvData
.size(); }
220 SCSIZE
Count( SCROW nRow1
, SCROW nRow2
) const;
223 const ScPatternAttr
* SetPatternAreaImpl( SCROW nStartRow
, SCROW nEndRow
, const ScPatternAttr
* pPattern
,
224 bool bPutToPool
= false, ScEditDataArray
* pDataArray
= nullptr,
225 bool bPassingPatternOwnership
= false );
228 // Iterator for attributes
232 const ScAttrArray
* pArray
;
233 const ScPatternAttr
* pDefPattern
;
238 inline ScAttrIterator( const ScAttrArray
* pNewArray
, SCROW nStart
, SCROW nEnd
, const ScPatternAttr
* pDefaultPattern
);
239 inline const ScPatternAttr
* Next( SCROW
& rTop
, SCROW
& rBottom
);
240 inline const ScPatternAttr
* Resync( SCROW nRow
, SCROW
& rTop
, SCROW
& rBottom
);
241 SCROW
GetNextRow() const { return nRow
; }
244 inline ScAttrIterator::ScAttrIterator( const ScAttrArray
* pNewArray
, SCROW nStart
, SCROW nEnd
, const ScPatternAttr
* pDefaultPattern
) :
246 pDefPattern( pDefaultPattern
),
250 if ( pArray
->Count() )
253 pArray
->Search( nStart
, nPos
);
261 inline const ScPatternAttr
* ScAttrIterator::Next( SCROW
& rTop
, SCROW
& rBottom
)
263 const ScPatternAttr
* pRet
;
264 if ( !pArray
->Count() )
272 rBottom
= std::min( nEndRow
, MAXROW
);
279 if ( nPos
< pArray
->Count() && nRow
<= nEndRow
)
282 rBottom
= std::min( pArray
->mvData
[nPos
].nEndRow
, nEndRow
);
283 pRet
= pArray
->mvData
[nPos
].pPattern
;
292 inline const ScPatternAttr
* ScAttrIterator::Resync( SCROW nRowP
, SCROW
& rTop
, SCROW
& rBottom
)
295 if ( !pArray
->Count() )
298 return Next( rTop
, rBottom
);
300 // Chances are high that the pattern changed on nRowP introduced a span
301 // starting right there. Assume that Next() was called so nPos already
302 // advanced. Another high chance is that the change extended a previous or
303 // next pattern. In all these cases we don't need to search.
304 if (3 <= nPos
&& nPos
<= pArray
->Count() && pArray
->mvData
[nPos
-3].nEndRow
< nRowP
&&
305 nRowP
<= pArray
->mvData
[nPos
-2].nEndRow
)
307 else if (2 <= nPos
&& nPos
<= pArray
->Count() && pArray
->mvData
[nPos
-2].nEndRow
< nRowP
&&
308 nRowP
<= pArray
->mvData
[nPos
-1].nEndRow
)
310 else if (pArray
->Count() > 0 && nRowP
<= pArray
->mvData
[0].nEndRow
)
313 pArray
->Search( nRowP
, nPos
);
314 return Next( rTop
, rBottom
);
319 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */