1*b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*b3f79822SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*b3f79822SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*b3f79822SAndrew Rist * distributed with this work for additional information
6*b3f79822SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*b3f79822SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*b3f79822SAndrew Rist * "License"); you may not use this file except in compliance
9*b3f79822SAndrew Rist * with the License. You may obtain a copy of the License at
10*b3f79822SAndrew Rist *
11*b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*b3f79822SAndrew Rist *
13*b3f79822SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*b3f79822SAndrew Rist * software distributed under the License is distributed on an
15*b3f79822SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b3f79822SAndrew Rist * KIND, either express or implied. See the License for the
17*b3f79822SAndrew Rist * specific language governing permissions and limitations
18*b3f79822SAndrew Rist * under the License.
19*b3f79822SAndrew Rist *
20*b3f79822SAndrew Rist *************************************************************/
21*b3f79822SAndrew Rist
22*b3f79822SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir
28cdf0e10cSrcweir
29cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
30cdf0e10cSrcweir
31cdf0e10cSrcweir #include <tools/debug.hxx>
32cdf0e10cSrcweir
33cdf0e10cSrcweir #include "markarr.hxx"
34cdf0e10cSrcweir #include "global.hxx"
35cdf0e10cSrcweir #include "address.hxx"
36cdf0e10cSrcweir
37cdf0e10cSrcweir // STATIC DATA -----------------------------------------------------------
38cdf0e10cSrcweir
39cdf0e10cSrcweir //------------------------------------------------------------------------
40cdf0e10cSrcweir
ScMarkArray()41cdf0e10cSrcweir ScMarkArray::ScMarkArray() :
42cdf0e10cSrcweir nCount( 0 ),
43cdf0e10cSrcweir nLimit( 0 ),
44cdf0e10cSrcweir pData( NULL )
45cdf0e10cSrcweir {
46cdf0e10cSrcweir // special case "no marks" with pData = NULL
47cdf0e10cSrcweir }
48cdf0e10cSrcweir
49cdf0e10cSrcweir //------------------------------------------------------------------------
50cdf0e10cSrcweir
~ScMarkArray()51cdf0e10cSrcweir ScMarkArray::~ScMarkArray()
52cdf0e10cSrcweir {
53cdf0e10cSrcweir delete[] pData;
54cdf0e10cSrcweir }
55cdf0e10cSrcweir
56cdf0e10cSrcweir //------------------------------------------------------------------------
57cdf0e10cSrcweir
Reset(sal_Bool bMarked)58cdf0e10cSrcweir void ScMarkArray::Reset( sal_Bool bMarked )
59cdf0e10cSrcweir {
60cdf0e10cSrcweir // always create pData here
61cdf0e10cSrcweir // (or have separate method to ensure pData)
62cdf0e10cSrcweir
63cdf0e10cSrcweir delete[] pData;
64cdf0e10cSrcweir
65cdf0e10cSrcweir nCount = nLimit = 1;
66cdf0e10cSrcweir pData = new ScMarkEntry[1];
67cdf0e10cSrcweir pData[0].nRow = MAXROW;
68cdf0e10cSrcweir pData[0].bMarked = bMarked;
69cdf0e10cSrcweir }
70cdf0e10cSrcweir
71cdf0e10cSrcweir //------------------------------------------------------------------------
72cdf0e10cSrcweir
Search(SCROW nRow,SCSIZE & nIndex) const73cdf0e10cSrcweir sal_Bool ScMarkArray::Search( SCROW nRow, SCSIZE& nIndex ) const
74cdf0e10cSrcweir {
75cdf0e10cSrcweir long nLo = 0;
76cdf0e10cSrcweir long nHi = static_cast<long>(nCount) - 1;
77cdf0e10cSrcweir long nStartRow = 0;
78cdf0e10cSrcweir long nEndRow = 0;
79cdf0e10cSrcweir long i = 0;
80cdf0e10cSrcweir sal_Bool bFound = (nCount == 1);
81cdf0e10cSrcweir if (pData)
82cdf0e10cSrcweir {
83cdf0e10cSrcweir while ( !bFound && nLo <= nHi )
84cdf0e10cSrcweir {
85cdf0e10cSrcweir i = (nLo + nHi) / 2;
86cdf0e10cSrcweir if (i > 0)
87cdf0e10cSrcweir nStartRow = (long) pData[i - 1].nRow;
88cdf0e10cSrcweir else
89cdf0e10cSrcweir nStartRow = -1;
90cdf0e10cSrcweir nEndRow = (long) pData[i].nRow;
91cdf0e10cSrcweir if (nEndRow < (long) nRow)
92cdf0e10cSrcweir nLo = ++i;
93cdf0e10cSrcweir else
94cdf0e10cSrcweir if (nStartRow >= (long) nRow)
95cdf0e10cSrcweir nHi = --i;
96cdf0e10cSrcweir else
97cdf0e10cSrcweir bFound = sal_True;
98cdf0e10cSrcweir }
99cdf0e10cSrcweir }
100cdf0e10cSrcweir else
101cdf0e10cSrcweir bFound = sal_False;
102cdf0e10cSrcweir
103cdf0e10cSrcweir if (bFound)
104cdf0e10cSrcweir nIndex=(SCSIZE)i;
105cdf0e10cSrcweir else
106cdf0e10cSrcweir nIndex=0;
107cdf0e10cSrcweir return bFound;
108cdf0e10cSrcweir }
109cdf0e10cSrcweir
GetMark(SCROW nRow) const110cdf0e10cSrcweir sal_Bool ScMarkArray::GetMark( SCROW nRow ) const
111cdf0e10cSrcweir {
112cdf0e10cSrcweir SCSIZE i;
113cdf0e10cSrcweir if (Search( nRow, i ))
114cdf0e10cSrcweir return pData[i].bMarked;
115cdf0e10cSrcweir else
116cdf0e10cSrcweir return sal_False;
117cdf0e10cSrcweir
118cdf0e10cSrcweir }
119cdf0e10cSrcweir
120cdf0e10cSrcweir //------------------------------------------------------------------------
121cdf0e10cSrcweir
SetMarkArea(SCROW nStartRow,SCROW nEndRow,sal_Bool bMarked)122cdf0e10cSrcweir void ScMarkArray::SetMarkArea( SCROW nStartRow, SCROW nEndRow, sal_Bool bMarked )
123cdf0e10cSrcweir {
124cdf0e10cSrcweir if (ValidRow(nStartRow) && ValidRow(nEndRow))
125cdf0e10cSrcweir {
126cdf0e10cSrcweir if ((nStartRow == 0) && (nEndRow == MAXROW))
127cdf0e10cSrcweir {
128cdf0e10cSrcweir Reset(bMarked);
129cdf0e10cSrcweir }
130cdf0e10cSrcweir else
131cdf0e10cSrcweir {
132cdf0e10cSrcweir if (!pData)
133cdf0e10cSrcweir Reset(sal_False); // create pData for further processing - could use special case handling!
134cdf0e10cSrcweir
135cdf0e10cSrcweir SCSIZE nNeeded = nCount + 2;
136cdf0e10cSrcweir if ( nLimit < nNeeded )
137cdf0e10cSrcweir {
138cdf0e10cSrcweir nLimit += SC_MARKARRAY_DELTA;
139cdf0e10cSrcweir if ( nLimit < nNeeded )
140cdf0e10cSrcweir nLimit = nNeeded;
141cdf0e10cSrcweir ScMarkEntry* pNewData = new ScMarkEntry[nLimit];
142cdf0e10cSrcweir memcpy( pNewData, pData, nCount*sizeof(ScMarkEntry) );
143cdf0e10cSrcweir delete[] pData;
144cdf0e10cSrcweir pData = pNewData;
145cdf0e10cSrcweir }
146cdf0e10cSrcweir
147cdf0e10cSrcweir SCSIZE ni; // number of entries in beginning
148cdf0e10cSrcweir SCSIZE nInsert; // insert position (MAXROW+1 := no insert)
149cdf0e10cSrcweir sal_Bool bCombined = sal_False;
150cdf0e10cSrcweir sal_Bool bSplit = sal_False;
151cdf0e10cSrcweir if ( nStartRow > 0 )
152cdf0e10cSrcweir {
153cdf0e10cSrcweir // skip beginning
154cdf0e10cSrcweir SCSIZE nIndex;
155cdf0e10cSrcweir Search( nStartRow, nIndex );
156cdf0e10cSrcweir ni = nIndex;
157cdf0e10cSrcweir
158cdf0e10cSrcweir nInsert = MAXROWCOUNT;
159cdf0e10cSrcweir if ( pData[ni].bMarked != bMarked )
160cdf0e10cSrcweir {
161cdf0e10cSrcweir if ( ni == 0 || (pData[ni-1].nRow < nStartRow - 1) )
162cdf0e10cSrcweir { // may be a split or a simple insert or just a shrink,
163cdf0e10cSrcweir // row adjustment is done further down
164cdf0e10cSrcweir if ( pData[ni].nRow > nEndRow )
165cdf0e10cSrcweir bSplit = sal_True;
166cdf0e10cSrcweir ni++;
167cdf0e10cSrcweir nInsert = ni;
168cdf0e10cSrcweir }
169cdf0e10cSrcweir else if ( ni > 0 && pData[ni-1].nRow == nStartRow - 1 )
170cdf0e10cSrcweir nInsert = ni;
171cdf0e10cSrcweir }
172cdf0e10cSrcweir if ( ni > 0 && pData[ni-1].bMarked == bMarked )
173cdf0e10cSrcweir { // combine
174cdf0e10cSrcweir pData[ni-1].nRow = nEndRow;
175cdf0e10cSrcweir nInsert = MAXROWCOUNT;
176cdf0e10cSrcweir bCombined = sal_True;
177cdf0e10cSrcweir }
178cdf0e10cSrcweir }
179cdf0e10cSrcweir else
180cdf0e10cSrcweir {
181cdf0e10cSrcweir nInsert = 0;
182cdf0e10cSrcweir ni = 0;
183cdf0e10cSrcweir }
184cdf0e10cSrcweir
185cdf0e10cSrcweir SCSIZE nj = ni; // stop position of range to replace
186cdf0e10cSrcweir while ( nj < nCount && pData[nj].nRow <= nEndRow )
187cdf0e10cSrcweir nj++;
188cdf0e10cSrcweir if ( !bSplit )
189cdf0e10cSrcweir {
190cdf0e10cSrcweir if ( nj < nCount && pData[nj].bMarked == bMarked )
191cdf0e10cSrcweir { // combine
192cdf0e10cSrcweir if ( ni > 0 )
193cdf0e10cSrcweir {
194cdf0e10cSrcweir if ( pData[ni-1].bMarked == bMarked )
195cdf0e10cSrcweir { // adjacent entries
196cdf0e10cSrcweir pData[ni-1].nRow = pData[nj].nRow;
197cdf0e10cSrcweir nj++;
198cdf0e10cSrcweir }
199cdf0e10cSrcweir else if ( ni == nInsert )
200cdf0e10cSrcweir pData[ni-1].nRow = nStartRow - 1; // shrink
201cdf0e10cSrcweir }
202cdf0e10cSrcweir nInsert = MAXROWCOUNT;
203cdf0e10cSrcweir bCombined = sal_True;
204cdf0e10cSrcweir }
205cdf0e10cSrcweir else if ( ni > 0 && ni == nInsert )
206cdf0e10cSrcweir pData[ni-1].nRow = nStartRow - 1; // shrink
207cdf0e10cSrcweir }
208cdf0e10cSrcweir if ( ni < nj )
209cdf0e10cSrcweir { // remove middle entries
210cdf0e10cSrcweir if ( !bCombined )
211cdf0e10cSrcweir { // replace one entry
212cdf0e10cSrcweir pData[ni].nRow = nEndRow;
213cdf0e10cSrcweir pData[ni].bMarked = bMarked;
214cdf0e10cSrcweir ni++;
215cdf0e10cSrcweir nInsert = MAXROWCOUNT;
216cdf0e10cSrcweir }
217cdf0e10cSrcweir if ( ni < nj )
218cdf0e10cSrcweir { // remove entries
219cdf0e10cSrcweir memmove( pData + ni, pData + nj, (nCount - nj) * sizeof(ScMarkEntry) );
220cdf0e10cSrcweir nCount -= nj - ni;
221cdf0e10cSrcweir }
222cdf0e10cSrcweir }
223cdf0e10cSrcweir
224cdf0e10cSrcweir if ( nInsert < sal::static_int_cast<SCSIZE>(MAXROWCOUNT) )
225cdf0e10cSrcweir { // insert or append new entry
226cdf0e10cSrcweir if ( nInsert <= nCount )
227cdf0e10cSrcweir {
228cdf0e10cSrcweir if ( !bSplit )
229cdf0e10cSrcweir memmove( pData + nInsert + 1, pData + nInsert,
230cdf0e10cSrcweir (nCount - nInsert) * sizeof(ScMarkEntry) );
231cdf0e10cSrcweir else
232cdf0e10cSrcweir {
233cdf0e10cSrcweir memmove( pData + nInsert + 2, pData + nInsert,
234cdf0e10cSrcweir (nCount - nInsert) * sizeof(ScMarkEntry) );
235cdf0e10cSrcweir pData[nInsert+1] = pData[nInsert-1];
236cdf0e10cSrcweir nCount++;
237cdf0e10cSrcweir }
238cdf0e10cSrcweir }
239cdf0e10cSrcweir if ( nInsert )
240cdf0e10cSrcweir pData[nInsert-1].nRow = nStartRow - 1;
241cdf0e10cSrcweir pData[nInsert].nRow = nEndRow;
242cdf0e10cSrcweir pData[nInsert].bMarked = bMarked;
243cdf0e10cSrcweir nCount++;
244cdf0e10cSrcweir }
245cdf0e10cSrcweir }
246cdf0e10cSrcweir }
247cdf0e10cSrcweir // InfoBox(0, String(nCount) + String(" Eintraege") ).Execute();
248cdf0e10cSrcweir }
249cdf0e10cSrcweir
250cdf0e10cSrcweir //UNUSED2009-05 void ScMarkArray::DeleteArea(SCROW nStartRow, SCROW nEndRow)
251cdf0e10cSrcweir //UNUSED2009-05 {
252cdf0e10cSrcweir //UNUSED2009-05 SetMarkArea(nStartRow, nEndRow, sal_False);
253cdf0e10cSrcweir //UNUSED2009-05 }
254cdf0e10cSrcweir
IsAllMarked(SCROW nStartRow,SCROW nEndRow) const255cdf0e10cSrcweir sal_Bool ScMarkArray::IsAllMarked( SCROW nStartRow, SCROW nEndRow ) const
256cdf0e10cSrcweir {
257cdf0e10cSrcweir SCSIZE nStartIndex;
258cdf0e10cSrcweir SCSIZE nEndIndex;
259cdf0e10cSrcweir
260cdf0e10cSrcweir if (Search( nStartRow, nStartIndex ))
261cdf0e10cSrcweir if (pData[nStartIndex].bMarked)
262cdf0e10cSrcweir if (Search( nEndRow, nEndIndex ))
263cdf0e10cSrcweir if (nEndIndex==nStartIndex)
264cdf0e10cSrcweir return sal_True;
265cdf0e10cSrcweir
266cdf0e10cSrcweir return sal_False;
267cdf0e10cSrcweir }
268cdf0e10cSrcweir
HasOneMark(SCROW & rStartRow,SCROW & rEndRow) const269cdf0e10cSrcweir sal_Bool ScMarkArray::HasOneMark( SCROW& rStartRow, SCROW& rEndRow ) const
270cdf0e10cSrcweir {
271cdf0e10cSrcweir sal_Bool bRet = sal_False;
272cdf0e10cSrcweir if ( nCount == 1 )
273cdf0e10cSrcweir {
274cdf0e10cSrcweir if ( pData[0].bMarked )
275cdf0e10cSrcweir {
276cdf0e10cSrcweir rStartRow = 0;
277cdf0e10cSrcweir rEndRow = MAXROW;
278cdf0e10cSrcweir bRet = sal_True;
279cdf0e10cSrcweir }
280cdf0e10cSrcweir }
281cdf0e10cSrcweir else if ( nCount == 2 )
282cdf0e10cSrcweir {
283cdf0e10cSrcweir if ( pData[0].bMarked )
284cdf0e10cSrcweir {
285cdf0e10cSrcweir rStartRow = 0;
286cdf0e10cSrcweir rEndRow = pData[0].nRow;
287cdf0e10cSrcweir }
288cdf0e10cSrcweir else
289cdf0e10cSrcweir {
290cdf0e10cSrcweir rStartRow = pData[0].nRow + 1;
291cdf0e10cSrcweir rEndRow = MAXROW;
292cdf0e10cSrcweir }
293cdf0e10cSrcweir bRet = sal_True;
294cdf0e10cSrcweir }
295cdf0e10cSrcweir else if ( nCount == 3 )
296cdf0e10cSrcweir {
297cdf0e10cSrcweir if ( pData[1].bMarked )
298cdf0e10cSrcweir {
299cdf0e10cSrcweir rStartRow = pData[0].nRow + 1;
300cdf0e10cSrcweir rEndRow = pData[1].nRow;
301cdf0e10cSrcweir bRet = sal_True;
302cdf0e10cSrcweir }
303cdf0e10cSrcweir }
304cdf0e10cSrcweir return bRet;
305cdf0e10cSrcweir }
306cdf0e10cSrcweir
CopyMarksTo(ScMarkArray & rDestMarkArray) const307cdf0e10cSrcweir void ScMarkArray::CopyMarksTo( ScMarkArray& rDestMarkArray ) const
308cdf0e10cSrcweir {
309cdf0e10cSrcweir delete[] rDestMarkArray.pData;
310cdf0e10cSrcweir
311cdf0e10cSrcweir if (pData)
312cdf0e10cSrcweir {
313cdf0e10cSrcweir rDestMarkArray.pData = new ScMarkEntry[nCount];
314cdf0e10cSrcweir memmove( rDestMarkArray.pData, pData, nCount * sizeof(ScMarkEntry) );
315cdf0e10cSrcweir }
316cdf0e10cSrcweir else
317cdf0e10cSrcweir rDestMarkArray.pData = NULL;
318cdf0e10cSrcweir
319cdf0e10cSrcweir rDestMarkArray.nCount = rDestMarkArray.nLimit = nCount;
320cdf0e10cSrcweir }
321cdf0e10cSrcweir
GetNextMarked(SCsROW nRow,sal_Bool bUp) const322cdf0e10cSrcweir SCsROW ScMarkArray::GetNextMarked( SCsROW nRow, sal_Bool bUp ) const
323cdf0e10cSrcweir {
324cdf0e10cSrcweir if (!pData)
325cdf0e10cSrcweir const_cast<ScMarkArray*>(this)->Reset(sal_False); // create pData for further processing
326cdf0e10cSrcweir
327cdf0e10cSrcweir SCsROW nRet = nRow;
328cdf0e10cSrcweir if (VALIDROW(nRow))
329cdf0e10cSrcweir {
330cdf0e10cSrcweir SCSIZE nIndex;
331cdf0e10cSrcweir Search(nRow, nIndex);
332cdf0e10cSrcweir if (!pData[nIndex].bMarked)
333cdf0e10cSrcweir {
334cdf0e10cSrcweir if (bUp)
335cdf0e10cSrcweir {
336cdf0e10cSrcweir if (nIndex>0)
337cdf0e10cSrcweir nRet = pData[nIndex-1].nRow;
338cdf0e10cSrcweir else
339cdf0e10cSrcweir nRet = -1;
340cdf0e10cSrcweir }
341cdf0e10cSrcweir else
342cdf0e10cSrcweir nRet = pData[nIndex].nRow + 1;
343cdf0e10cSrcweir }
344cdf0e10cSrcweir }
345cdf0e10cSrcweir return nRet;
346cdf0e10cSrcweir }
347cdf0e10cSrcweir
GetMarkEnd(SCROW nRow,sal_Bool bUp) const348cdf0e10cSrcweir SCROW ScMarkArray::GetMarkEnd( SCROW nRow, sal_Bool bUp ) const
349cdf0e10cSrcweir {
350cdf0e10cSrcweir if (!pData)
351cdf0e10cSrcweir const_cast<ScMarkArray*>(this)->Reset(sal_False); // create pData for further processing
352cdf0e10cSrcweir
353cdf0e10cSrcweir SCROW nRet;
354cdf0e10cSrcweir SCSIZE nIndex;
355cdf0e10cSrcweir Search(nRow, nIndex);
356cdf0e10cSrcweir DBG_ASSERT( pData[nIndex].bMarked, "GetMarkEnd ohne bMarked" );
357cdf0e10cSrcweir if (bUp)
358cdf0e10cSrcweir {
359cdf0e10cSrcweir if (nIndex>0)
360cdf0e10cSrcweir nRet = pData[nIndex-1].nRow + 1;
361cdf0e10cSrcweir else
362cdf0e10cSrcweir nRet = 0;
363cdf0e10cSrcweir }
364cdf0e10cSrcweir else
365cdf0e10cSrcweir nRet = pData[nIndex].nRow;
366cdf0e10cSrcweir
367cdf0e10cSrcweir return nRet;
368cdf0e10cSrcweir }
369cdf0e10cSrcweir
370cdf0e10cSrcweir //
371cdf0e10cSrcweir // -------------- Iterator ----------------------------------------------
372cdf0e10cSrcweir //
373cdf0e10cSrcweir
ScMarkArrayIter(const ScMarkArray * pNewArray)374cdf0e10cSrcweir ScMarkArrayIter::ScMarkArrayIter( const ScMarkArray* pNewArray ) :
375cdf0e10cSrcweir pArray( pNewArray ),
376cdf0e10cSrcweir nPos( 0 )
377cdf0e10cSrcweir {
378cdf0e10cSrcweir }
379cdf0e10cSrcweir
~ScMarkArrayIter()380cdf0e10cSrcweir ScMarkArrayIter::~ScMarkArrayIter()
381cdf0e10cSrcweir {
382cdf0e10cSrcweir }
383cdf0e10cSrcweir
Next(SCROW & rTop,SCROW & rBottom)384cdf0e10cSrcweir sal_Bool ScMarkArrayIter::Next( SCROW& rTop, SCROW& rBottom )
385cdf0e10cSrcweir {
386cdf0e10cSrcweir if ( nPos >= pArray->nCount )
387cdf0e10cSrcweir return sal_False;
388cdf0e10cSrcweir while (!pArray->pData[nPos].bMarked)
389cdf0e10cSrcweir {
390cdf0e10cSrcweir ++nPos;
391cdf0e10cSrcweir if ( nPos >= pArray->nCount )
392cdf0e10cSrcweir return sal_False;
393cdf0e10cSrcweir }
394cdf0e10cSrcweir rBottom = pArray->pData[nPos].nRow;
395cdf0e10cSrcweir if (nPos==0)
396cdf0e10cSrcweir rTop = 0;
397cdf0e10cSrcweir else
398cdf0e10cSrcweir rTop = pArray->pData[nPos-1].nRow + 1;
399cdf0e10cSrcweir ++nPos;
400cdf0e10cSrcweir return sal_True;
401cdf0e10cSrcweir }
402cdf0e10cSrcweir
403cdf0e10cSrcweir
404cdf0e10cSrcweir
405cdf0e10cSrcweir
406cdf0e10cSrcweir
407