Line data Source code
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_SC_INC_ATTARRAY_HXX
21 : #define INCLUDED_SC_INC_ATTARRAY_HXX
22 :
23 : #include "global.hxx"
24 : #include "attrib.hxx"
25 : #include <algorithm>
26 :
27 : class ScDocument;
28 : class ScEditDataArray;
29 : class ScMarkArray;
30 : class ScPatternAttr;
31 : class ScStyleSheet;
32 : class ScFlatBoolRowSegments;
33 :
34 : class SfxItemPoolCache;
35 : class SfxStyleSheetBase;
36 : class SvxBoxItem;
37 : class SvxBoxInfoItem;
38 :
39 : namespace editeng { class SvxBorderLine; }
40 :
41 : #define SC_LINE_EMPTY 0
42 : #define SC_LINE_SET 1
43 : #define SC_LINE_DONTCARE 2
44 :
45 : #define SC_ATTRARRAY_DELTA 4
46 :
47 : struct ScLineFlags
48 : {
49 : sal_uInt8 nLeft;
50 : sal_uInt8 nRight;
51 : sal_uInt8 nTop;
52 : sal_uInt8 nBottom;
53 : sal_uInt8 nHori;
54 : sal_uInt8 nVert;
55 :
56 60 : ScLineFlags() : nLeft(SC_LINE_EMPTY),nRight(SC_LINE_EMPTY),nTop(SC_LINE_EMPTY),
57 60 : nBottom(SC_LINE_EMPTY),nHori(SC_LINE_EMPTY),nVert(SC_LINE_EMPTY) {}
58 : };
59 :
60 : struct ScMergePatternState
61 : {
62 : SfxItemSet* pItemSet; ///< allocated in MergePatternArea, used for resulting ScPatternAttr
63 : const ScPatternAttr* pOld1; ///< existing objects, temporary
64 : const ScPatternAttr* pOld2;
65 :
66 17060 : ScMergePatternState() : pItemSet(NULL), pOld1(NULL), pOld2(NULL) {}
67 : };
68 :
69 : struct ScAttrEntry
70 : {
71 : SCROW nRow;
72 : const ScPatternAttr* pPattern;
73 : };
74 :
75 : class ScAttrArray
76 : {
77 : private:
78 : SCCOL nCol;
79 : SCTAB nTab;
80 : ScDocument* pDocument;
81 :
82 : SCSIZE nCount;
83 : SCSIZE nLimit;
84 : ScAttrEntry* pData;
85 :
86 : friend class ScDocument; // for FillInfo
87 : friend class ScDocumentIterator;
88 : friend class ScAttrIterator;
89 : friend class ScHorizontalAttrIterator;
90 :
91 : bool ApplyFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
92 : SCROW nStartRow, SCROW nEndRow,
93 : bool bLeft, SCCOL nDistRight, bool bTop, SCROW nDistBottom );
94 :
95 : void RemoveCellCharAttribs( SCROW nStartRow, SCROW nEndRow,
96 : const ScPatternAttr* pPattern, ScEditDataArray* pDataArray );
97 :
98 : ScAttrArray(const ScAttrArray&) SAL_DELETED_FUNCTION;
99 : ScAttrArray& operator=(const ScAttrArray&) SAL_DELETED_FUNCTION;
100 :
101 : public:
102 : ScAttrArray( SCCOL nNewCol, SCTAB nNewTab, ScDocument* pDoc );
103 : ~ScAttrArray();
104 :
105 243712 : void SetTab(SCTAB nNewTab) { nTab = nNewTab; }
106 161300 : void SetCol(SCCOL nNewCol) { nCol = nNewCol; }
107 : #if OSL_DEBUG_LEVEL > 1
108 : void TestData() const;
109 : #endif
110 : void Reset( const ScPatternAttr* pPattern);
111 : bool Concat(SCSIZE nPos);
112 :
113 : const ScPatternAttr* GetPattern( SCROW nRow ) const;
114 : const ScPatternAttr* GetPatternRange( SCROW& rStartRow, SCROW& rEndRow, SCROW nRow ) const;
115 : void MergePatternArea( SCROW nStartRow, SCROW nEndRow, ScMergePatternState& rState, bool bDeep ) const;
116 :
117 : void MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner, ScLineFlags& rFlags,
118 : SCROW nStartRow, SCROW nEndRow, bool bLeft, SCCOL nDistRight ) const;
119 : void ApplyBlockFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
120 : SCROW nStartRow, SCROW nEndRow, bool bLeft, SCCOL nDistRight );
121 :
122 : void SetPattern( SCROW nRow, const ScPatternAttr* pPattern, bool bPutToPool = false );
123 : void SetPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr* pPattern,
124 : bool bPutToPool = false, ScEditDataArray* pDataArray = NULL );
125 : void ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, ScStyleSheet* pStyle );
126 : void ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, SfxItemPoolCache* pCache,
127 : ScEditDataArray* pDataArray = NULL );
128 : bool SetAttrEntries(ScAttrEntry* pNewData, SCSIZE nSize);
129 : void ApplyLineStyleArea( SCROW nStartRow, SCROW nEndRow,
130 : const ::editeng::SvxBorderLine* pLine, bool bColorOnly );
131 :
132 : void AddCondFormat( SCROW nStartRow, SCROW nEndRow, sal_uInt32 nIndex );
133 : /// if nIndex == 0, remove all conditional format data
134 : void RemoveCondFormat( SCROW nStartRow, SCROW nEndRow, sal_uInt32 nIndex );
135 :
136 : void ClearItems( SCROW nStartRow, SCROW nEndRow, const sal_uInt16* pWhich );
137 : void ChangeIndent( SCROW nStartRow, SCROW nEndRow, bool bIncrement );
138 :
139 : /// Including current, may return -1
140 : SCsROW GetNextUnprotected( SCsROW nRow, bool bUp ) const;
141 :
142 : /// May return -1 if not found
143 : SCsROW SearchStyle(
144 : SCsROW nRow, const ScStyleSheet* pSearchStyle, bool bUp,
145 : const ScMarkArray* pMarkArray = NULL) const;
146 :
147 : bool SearchStyleRange(
148 : SCsROW& rRow, SCsROW& rEndRow, const ScStyleSheet* pSearchStyle, bool bUp,
149 : const ScMarkArray* pMarkArray = NULL) const;
150 :
151 : bool ApplyFlags( SCROW nStartRow, SCROW nEndRow, sal_Int16 nFlags );
152 : bool RemoveFlags( SCROW nStartRow, SCROW nEndRow, sal_Int16 nFlags );
153 :
154 : bool Search( SCROW nRow, SCSIZE& nIndex ) const;
155 :
156 : bool HasAttrib( SCROW nRow1, SCROW nRow2, sal_uInt16 nMask ) const;
157 : bool IsMerged( SCROW nRow ) const;
158 : bool ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow,
159 : SCCOL& rPaintCol, SCROW& rPaintRow,
160 : bool bRefresh );
161 : bool RemoveAreaMerge( SCROW nStartRow, SCROW nEndRow );
162 :
163 : void FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBoolRowSegments& rUsedRows, bool bReset );
164 : bool IsStyleSheetUsed( const ScStyleSheet& rStyle, bool bGatherAllStyles ) const;
165 :
166 : void DeleteAreaSafe(SCROW nStartRow, SCROW nEndRow);
167 : void SetPatternAreaSafe( SCROW nStartRow, SCROW nEndRow,
168 : const ScPatternAttr* pWantedPattern, bool bDefault );
169 : void CopyAreaSafe( SCROW nStartRow, SCROW nEndRow, long nDy, ScAttrArray& rAttrArray );
170 :
171 : bool IsEmpty() const;
172 :
173 : bool GetFirstVisibleAttr( SCROW& rFirstRow ) const;
174 : bool GetLastVisibleAttr( SCROW& rLastRow, SCROW nLastData, bool bFullFormattedArea = false ) const;
175 : bool HasVisibleAttrIn( SCROW nStartRow, SCROW nEndRow ) const;
176 : bool IsVisibleEqual( const ScAttrArray& rOther,
177 : SCROW nStartRow, SCROW nEndRow ) const;
178 : bool IsAllEqual( const ScAttrArray& rOther, SCROW nStartRow, SCROW nEndRow ) const;
179 :
180 : bool TestInsertCol( SCROW nStartRow, SCROW nEndRow) const;
181 : bool TestInsertRow( SCSIZE nSize ) const;
182 : void InsertRow( SCROW nStartRow, SCSIZE nSize );
183 : void DeleteRow( SCROW nStartRow, SCSIZE nSize );
184 : void DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex );
185 : void DeleteArea( SCROW nStartRow, SCROW nEndRow );
186 : void MoveTo( SCROW nStartRow, SCROW nEndRow, ScAttrArray& rAttrArray );
187 : void CopyArea(
188 : SCROW nStartRow, SCROW nEndRow, long nDy, ScAttrArray& rAttrArray, sal_Int16 nStripFlags = 0) const;
189 :
190 : void DeleteHardAttr( SCROW nStartRow, SCROW nEndRow );
191 :
192 : /* i123909: Pre-calculate needed memory, and pre-reserve enough memory */
193 : bool Reserve( SCSIZE nReserve );
194 0 : SCSIZE Count() const { return nCount; }
195 : SCSIZE Count( SCROW nRow1, SCROW nRow2 ) const;
196 : };
197 :
198 : // Iterator for attributes
199 :
200 : class ScAttrIterator
201 : {
202 : const ScAttrArray* pArray;
203 : SCSIZE nPos;
204 : SCROW nRow;
205 : SCROW nEndRow;
206 : public:
207 : inline ScAttrIterator( const ScAttrArray* pNewArray, SCROW nStart, SCROW nEnd );
208 : inline const ScPatternAttr* Next( SCROW& rTop, SCROW& rBottom );
209 : inline const ScPatternAttr* Resync( SCROW nRow, SCROW& rTop, SCROW& rBottom );
210 0 : SCROW GetNextRow() const { return nRow; }
211 : };
212 :
213 1440529 : inline ScAttrIterator::ScAttrIterator( const ScAttrArray* pNewArray, SCROW nStart, SCROW nEnd ) :
214 : pArray( pNewArray ),
215 : nRow( nStart ),
216 1440529 : nEndRow( nEnd )
217 : {
218 1440529 : if ( nStart > 0 )
219 449716 : pArray->Search( nStart, nPos );
220 : else
221 990813 : nPos = 0;
222 1440529 : }
223 :
224 2883159 : inline const ScPatternAttr* ScAttrIterator::Next( SCROW& rTop, SCROW& rBottom )
225 : {
226 : const ScPatternAttr* pRet;
227 2883159 : if ( nPos < pArray->nCount && nRow <= nEndRow )
228 : {
229 1446790 : rTop = nRow;
230 1446790 : rBottom = std::min( pArray->pData[nPos].nRow, nEndRow );
231 1446790 : pRet = pArray->pData[nPos].pPattern;
232 1446790 : nRow = rBottom + 1;
233 1446790 : ++nPos;
234 : }
235 : else
236 1436369 : pRet = NULL;
237 2883159 : return pRet;
238 : }
239 :
240 0 : inline const ScPatternAttr* ScAttrIterator::Resync( SCROW nRowP, SCROW& rTop, SCROW& rBottom )
241 : {
242 0 : nRow = nRowP;
243 : // Chances are high that the pattern changed on nRowP introduced a span
244 : // starting right there. Assume that Next() was called so nPos already
245 : // advanced. Another high chance is that the change extended a previous or
246 : // next pattern. In all these cases we don't need to search.
247 0 : if (3 <= nPos && nPos <= pArray->nCount && pArray->pData[nPos-3].nRow < nRowP &&
248 0 : nRowP <= pArray->pData[nPos-2].nRow)
249 0 : nPos -= 2;
250 0 : else if (2 <= nPos && nPos <= pArray->nCount && pArray->pData[nPos-2].nRow < nRowP &&
251 0 : nRowP <= pArray->pData[nPos-1].nRow)
252 0 : --nPos;
253 0 : else if (pArray->nCount > 0 && nRowP <= pArray->pData[0].nRow)
254 0 : nPos = 0;
255 : else
256 0 : pArray->Search( nRowP, nPos );
257 0 : return Next( rTop, rBottom);
258 : }
259 :
260 : #endif
261 :
262 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|