Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "markarr.hxx"
30 : : #include "global.hxx"
31 : : #include "address.hxx"
32 : :
33 : : // STATIC DATA -----------------------------------------------------------
34 : :
35 : : //------------------------------------------------------------------------
36 : :
37 : 673792 : ScMarkArray::ScMarkArray() :
38 : : nCount( 0 ),
39 : : nLimit( 0 ),
40 : 673792 : pData( NULL )
41 : : {
42 : : // special case "no marks" with pData = NULL
43 : 673792 : }
44 : :
45 : : //------------------------------------------------------------------------
46 : :
47 : 671744 : ScMarkArray::~ScMarkArray()
48 : : {
49 [ + + ]: 671744 : delete[] pData;
50 : 671744 : }
51 : :
52 : : //------------------------------------------------------------------------
53 : :
54 : 11684 : void ScMarkArray::Reset( sal_Bool bMarked )
55 : : {
56 : : // always create pData here
57 : : // (or have separate method to ensure pData)
58 : :
59 [ + + ]: 11684 : delete[] pData;
60 : :
61 : 11684 : nCount = nLimit = 1;
62 : 11684 : pData = new ScMarkEntry[1];
63 : 11684 : pData[0].nRow = MAXROW;
64 : 11684 : pData[0].bMarked = bMarked;
65 : 11684 : }
66 : :
67 : : //------------------------------------------------------------------------
68 : :
69 : 8818 : sal_Bool ScMarkArray::Search( SCROW nRow, SCSIZE& nIndex ) const
70 : : {
71 : 8818 : long nHi = static_cast<long>(nCount) - 1;
72 : 8818 : long i = 0;
73 : 8818 : sal_Bool bFound = (nCount == 1);
74 [ + + ]: 8818 : if (pData)
75 : : {
76 : 8607 : long nLo = 0;
77 : 8607 : long nStartRow = 0;
78 [ + + ][ + - ]: 20167 : while ( !bFound && nLo <= nHi )
[ + + ]
79 : : {
80 : 11560 : i = (nLo + nHi) / 2;
81 [ + + ]: 11560 : if (i > 0)
82 : 7939 : nStartRow = (long) pData[i - 1].nRow;
83 : : else
84 : 3621 : nStartRow = -1;
85 : 11560 : long nEndRow = (long) pData[i].nRow;
86 [ + + ]: 11560 : if (nEndRow < (long) nRow)
87 : 5751 : nLo = ++i;
88 : : else
89 [ + + ]: 5809 : if (nStartRow >= (long) nRow)
90 : 90 : nHi = --i;
91 : : else
92 : 5719 : bFound = sal_True;
93 : : }
94 : : }
95 : : else
96 : 211 : bFound = false;
97 : :
98 [ + + ]: 8818 : if (bFound)
99 : 8607 : nIndex=(SCSIZE)i;
100 : : else
101 : 211 : nIndex=0;
102 : 8818 : return bFound;
103 : : }
104 : :
105 : 1036 : sal_Bool ScMarkArray::GetMark( SCROW nRow ) const
106 : : {
107 : : SCSIZE i;
108 [ + + ]: 1036 : if (Search( nRow, i ))
109 : 915 : return pData[i].bMarked;
110 : : else
111 : 1036 : return false;
112 : :
113 : : }
114 : :
115 : : //------------------------------------------------------------------------
116 : :
117 : 16962 : void ScMarkArray::SetMarkArea( SCROW nStartRow, SCROW nEndRow, sal_Bool bMarked )
118 : : {
119 [ + - ][ + - ]: 16962 : if (ValidRow(nStartRow) && ValidRow(nEndRow))
[ + - ]
120 : : {
121 [ + + ][ + + ]: 16962 : if ((nStartRow == 0) && (nEndRow == MAXROW))
122 : : {
123 : 8192 : Reset(bMarked);
124 : : }
125 : : else
126 : : {
127 [ + + ]: 8770 : if (!pData)
128 : 3490 : Reset(false); // create pData for further processing - could use special case handling!
129 : :
130 : 8770 : SCSIZE nNeeded = nCount + 2;
131 [ + + ]: 8770 : if ( nLimit < nNeeded )
132 : : {
133 : 3928 : nLimit += SC_MARKARRAY_DELTA;
134 [ - + ]: 3928 : if ( nLimit < nNeeded )
135 : 0 : nLimit = nNeeded;
136 : 3928 : ScMarkEntry* pNewData = new ScMarkEntry[nLimit];
137 : 3928 : memcpy( pNewData, pData, nCount*sizeof(ScMarkEntry) );
138 [ + - ]: 3928 : delete[] pData;
139 : 3928 : pData = pNewData;
140 : : }
141 : :
142 : : SCSIZE ni; // number of entries in beginning
143 : : SCSIZE nInsert; // insert position (MAXROW+1 := no insert)
144 : 8770 : sal_Bool bCombined = false;
145 : 8770 : sal_Bool bSplit = false;
146 [ + + ]: 8770 : if ( nStartRow > 0 )
147 : : {
148 : : // skip beginning
149 : : SCSIZE nIndex;
150 : 5489 : Search( nStartRow, nIndex );
151 : 5489 : ni = nIndex;
152 : :
153 : 5489 : nInsert = MAXROWCOUNT;
154 [ + + ]: 5489 : if ( pData[ni].bMarked != bMarked )
155 : : {
156 [ + + ][ + + ]: 5424 : if ( ni == 0 || (pData[ni-1].nRow < nStartRow - 1) )
157 : : { // may be a split or a simple insert or just a shrink,
158 : : // row adjustment is done further down
159 [ + - ]: 1720 : if ( pData[ni].nRow > nEndRow )
160 : 1720 : bSplit = sal_True;
161 : 1720 : ni++;
162 : 1720 : nInsert = ni;
163 : : }
164 [ + - ][ + - ]: 3704 : else if ( ni > 0 && pData[ni-1].nRow == nStartRow - 1 )
165 : 5424 : nInsert = ni;
166 : : }
167 [ + - ][ + + ]: 5489 : if ( ni > 0 && pData[ni-1].bMarked == bMarked )
168 : : { // combine
169 : 3704 : pData[ni-1].nRow = nEndRow;
170 : 3704 : nInsert = MAXROWCOUNT;
171 : 5489 : bCombined = sal_True;
172 : : }
173 : : }
174 : : else
175 : : {
176 : 3281 : nInsert = 0;
177 : 3281 : ni = 0;
178 : : }
179 : :
180 : 8770 : SCSIZE nj = ni; // stop position of range to replace
181 [ + + ][ + + ]: 9478 : while ( nj < nCount && pData[nj].nRow <= nEndRow )
[ + + ]
182 : 708 : nj++;
183 [ + + ]: 8770 : if ( !bSplit )
184 : : {
185 [ + - ][ + + ]: 7050 : if ( nj < nCount && pData[nj].bMarked == bMarked )
186 : : { // combine
187 [ + + ]: 1082 : if ( ni > 0 )
188 : : {
189 [ + + ]: 52 : if ( pData[ni-1].bMarked == bMarked )
190 : : { // adjacent entries
191 : 42 : pData[ni-1].nRow = pData[nj].nRow;
192 : 42 : nj++;
193 : : }
194 [ - + ]: 10 : else if ( ni == nInsert )
195 : 0 : pData[ni-1].nRow = nStartRow - 1; // shrink
196 : : }
197 : 1082 : nInsert = MAXROWCOUNT;
198 : 1082 : bCombined = sal_True;
199 : : }
200 [ + + ][ - + ]: 5968 : else if ( ni > 0 && ni == nInsert )
201 : 7050 : pData[ni-1].nRow = nStartRow - 1; // shrink
202 : : }
203 [ + + ]: 8770 : if ( ni < nj )
204 : : { // remove middle entries
205 [ + + ]: 708 : if ( !bCombined )
206 : : { // replace one entry
207 : 654 : pData[ni].nRow = nEndRow;
208 : 654 : pData[ni].bMarked = bMarked;
209 : 654 : ni++;
210 : 654 : nInsert = MAXROWCOUNT;
211 : : }
212 [ + + ]: 708 : if ( ni < nj )
213 : : { // remove entries
214 : 54 : memmove( pData + ni, pData + nj, (nCount - nj) * sizeof(ScMarkEntry) );
215 : 54 : nCount -= nj - ni;
216 : : }
217 : : }
218 : :
219 [ + + ]: 8770 : if ( nInsert < sal::static_int_cast<SCSIZE>(MAXROWCOUNT) )
220 : : { // insert or append new entry
221 [ + - ]: 3372 : if ( nInsert <= nCount )
222 : : {
223 [ + + ]: 3372 : if ( !bSplit )
224 : 1652 : memmove( pData + nInsert + 1, pData + nInsert,
225 : 1652 : (nCount - nInsert) * sizeof(ScMarkEntry) );
226 : : else
227 : : {
228 : 1720 : memmove( pData + nInsert + 2, pData + nInsert,
229 : 3440 : (nCount - nInsert) * sizeof(ScMarkEntry) );
230 : 1720 : pData[nInsert+1] = pData[nInsert-1];
231 : 1720 : nCount++;
232 : : }
233 : : }
234 [ + + ]: 3372 : if ( nInsert )
235 : 1720 : pData[nInsert-1].nRow = nStartRow - 1;
236 : 3372 : pData[nInsert].nRow = nEndRow;
237 : 3372 : pData[nInsert].bMarked = bMarked;
238 : 16962 : nCount++;
239 : : }
240 : : }
241 : : }
242 : 16962 : }
243 : :
244 : 36 : sal_Bool ScMarkArray::IsAllMarked( SCROW nStartRow, SCROW nEndRow ) const
245 : : {
246 : : SCSIZE nStartIndex;
247 : : SCSIZE nEndIndex;
248 : :
249 [ + - ]: 36 : if (Search( nStartRow, nStartIndex ))
250 [ + - ]: 36 : if (pData[nStartIndex].bMarked)
251 [ + - ]: 36 : if (Search( nEndRow, nEndIndex ))
252 [ + - ]: 36 : if (nEndIndex==nStartIndex)
253 : 36 : return sal_True;
254 : :
255 : 36 : return false;
256 : : }
257 : :
258 : 456 : sal_Bool ScMarkArray::HasOneMark( SCROW& rStartRow, SCROW& rEndRow ) const
259 : : {
260 : 456 : sal_Bool bRet = false;
261 [ - + ]: 456 : if ( nCount == 1 )
262 : : {
263 [ # # ]: 0 : if ( pData[0].bMarked )
264 : : {
265 : 0 : rStartRow = 0;
266 : 0 : rEndRow = MAXROW;
267 : 0 : bRet = sal_True;
268 : : }
269 : : }
270 [ + + ]: 456 : else if ( nCount == 2 )
271 : : {
272 [ + - ]: 424 : if ( pData[0].bMarked )
273 : : {
274 : 424 : rStartRow = 0;
275 : 424 : rEndRow = pData[0].nRow;
276 : : }
277 : : else
278 : : {
279 : 0 : rStartRow = pData[0].nRow + 1;
280 : 0 : rEndRow = MAXROW;
281 : : }
282 : 424 : bRet = sal_True;
283 : : }
284 [ + - ]: 32 : else if ( nCount == 3 )
285 : : {
286 [ + - ]: 32 : if ( pData[1].bMarked )
287 : : {
288 : 32 : rStartRow = pData[0].nRow + 1;
289 : 32 : rEndRow = pData[1].nRow;
290 : 32 : bRet = sal_True;
291 : : }
292 : : }
293 : 456 : return bRet;
294 : : }
295 : :
296 : 165888 : void ScMarkArray::CopyMarksTo( ScMarkArray& rDestMarkArray ) const
297 : : {
298 [ - + ]: 165888 : delete[] rDestMarkArray.pData;
299 : :
300 [ + + ]: 165888 : if (pData)
301 : : {
302 : 1999 : rDestMarkArray.pData = new ScMarkEntry[nCount];
303 : 1999 : memmove( rDestMarkArray.pData, pData, nCount * sizeof(ScMarkEntry) );
304 : : }
305 : : else
306 : 163889 : rDestMarkArray.pData = NULL;
307 : :
308 : 165888 : rDestMarkArray.nCount = rDestMarkArray.nLimit = nCount;
309 : 165888 : }
310 : :
311 : 1029 : SCsROW ScMarkArray::GetNextMarked( SCsROW nRow, sal_Bool bUp ) const
312 : : {
313 [ + + ]: 1029 : if (!pData)
314 : 2 : const_cast<ScMarkArray*>(this)->Reset(false); // create pData for further processing
315 : :
316 : 1029 : SCsROW nRet = nRow;
317 [ + - ]: 1029 : if (VALIDROW(nRow))
318 : : {
319 : : SCSIZE nIndex;
320 : 1029 : Search(nRow, nIndex);
321 [ + + ]: 1029 : if (!pData[nIndex].bMarked)
322 : : {
323 [ - + ]: 2 : if (bUp)
324 : : {
325 [ # # ]: 0 : if (nIndex>0)
326 : 0 : nRet = pData[nIndex-1].nRow;
327 : : else
328 : 0 : nRet = -1;
329 : : }
330 : : else
331 : 1029 : nRet = pData[nIndex].nRow + 1;
332 : : }
333 : : }
334 : 1029 : return nRet;
335 : : }
336 : :
337 : 1027 : SCROW ScMarkArray::GetMarkEnd( SCROW nRow, sal_Bool bUp ) const
338 : : {
339 [ - + ]: 1027 : if (!pData)
340 [ # # ]: 0 : const_cast<ScMarkArray*>(this)->Reset(false); // create pData for further processing
341 : :
342 : : SCROW nRet;
343 : : SCSIZE nIndex;
344 : 1027 : Search(nRow, nIndex);
345 : : OSL_ENSURE( pData[nIndex].bMarked, "GetMarkEnd ohne bMarked" );
346 [ - + ]: 1027 : if (bUp)
347 : : {
348 [ # # ]: 0 : if (nIndex>0)
349 : 0 : nRet = pData[nIndex-1].nRow + 1;
350 : : else
351 : 0 : nRet = 0;
352 : : }
353 : : else
354 : 1027 : nRet = pData[nIndex].nRow;
355 : :
356 : 1027 : return nRet;
357 : : }
358 : :
359 : : //
360 : : // -------------- Iterator ----------------------------------------------
361 : : //
362 : :
363 : 543583 : ScMarkArrayIter::ScMarkArrayIter( const ScMarkArray* pNewArray ) :
364 : : pArray( pNewArray ),
365 : 543583 : nPos( 0 )
366 : : {
367 : 543583 : }
368 : :
369 : 543583 : ScMarkArrayIter::~ScMarkArrayIter()
370 : : {
371 : 543583 : }
372 : :
373 : 551047 : sal_Bool ScMarkArrayIter::Next( SCROW& rTop, SCROW& rBottom )
374 : : {
375 [ + + ]: 551047 : if ( nPos >= pArray->nCount )
376 : 539037 : return false;
377 [ + + ]: 15574 : while (!pArray->pData[nPos].bMarked)
378 : : {
379 : 7790 : ++nPos;
380 [ + + ]: 7790 : if ( nPos >= pArray->nCount )
381 : 4226 : return false;
382 : : }
383 : 7784 : rBottom = pArray->pData[nPos].nRow;
384 [ + + ]: 7784 : if (nPos==0)
385 : 4220 : rTop = 0;
386 : : else
387 : 3564 : rTop = pArray->pData[nPos-1].nRow + 1;
388 : 7784 : ++nPos;
389 : 551047 : return sal_True;
390 : : }
391 : :
392 : :
393 : :
394 : :
395 : :
396 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|