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 <limits.h>
30 : :
31 : : #include "olinetab.hxx"
32 : : #include "global.hxx"
33 : : #include "rechead.hxx"
34 : : #include "address.hxx"
35 : : #include "table.hxx"
36 : :
37 : : //------------------------------------------------------------------------
38 : :
39 : 10 : ScOutlineEntry::ScOutlineEntry( SCCOLROW nNewStart, SCCOLROW nNewSize, bool bNewHidden ) :
40 : : nStart ( nNewStart ),
41 : : nSize ( nNewSize ),
42 : : bHidden ( bNewHidden ),
43 : 10 : bVisible( true )
44 : : {
45 : 10 : }
46 : :
47 : 28 : ScOutlineEntry::ScOutlineEntry( const ScOutlineEntry& rEntry ) :
48 : : nStart ( rEntry.nStart ),
49 : : nSize ( rEntry.nSize ),
50 : : bHidden ( rEntry.bHidden ),
51 : 28 : bVisible( rEntry.bVisible )
52 : : {
53 : 28 : }
54 : :
55 : 74 : SCCOLROW ScOutlineEntry::GetStart() const
56 : : {
57 : 74 : return nStart;
58 : : }
59 : :
60 : 0 : SCSIZE ScOutlineEntry::GetSize() const
61 : : {
62 : 0 : return nSize;
63 : : }
64 : :
65 : 26 : SCCOLROW ScOutlineEntry::GetEnd() const
66 : : {
67 : 26 : return nStart+nSize-1;
68 : : }
69 : 10 : bool ScOutlineEntry::IsHidden() const
70 : : {
71 : 10 : return bHidden;
72 : : }
73 : :
74 : 10 : bool ScOutlineEntry::IsVisible() const
75 : : {
76 : 10 : return bVisible;
77 : : }
78 : :
79 : 0 : void ScOutlineEntry::Move( SCsCOLROW nDelta )
80 : : {
81 : 0 : SCCOLROW nNewPos = nStart + nDelta;
82 [ # # ]: 0 : if (nNewPos<0)
83 : : {
84 : : OSL_FAIL("OutlineEntry < 0");
85 : 0 : nNewPos = 0;
86 : : }
87 : 0 : nStart = nNewPos;
88 : 0 : }
89 : :
90 : 0 : void ScOutlineEntry::SetSize( SCSIZE nNewSize )
91 : : {
92 [ # # ]: 0 : if (nNewSize>0)
93 : 0 : nSize = nNewSize;
94 : : else
95 : : {
96 : : OSL_FAIL("ScOutlineEntry Size == 0");
97 : : }
98 : 0 : }
99 : :
100 : 0 : void ScOutlineEntry::SetPosSize( SCCOLROW nNewPos, SCSIZE nNewSize )
101 : : {
102 : 0 : nStart = nNewPos;
103 : 0 : SetSize( nNewSize );
104 : 0 : }
105 : :
106 : 0 : void ScOutlineEntry::SetHidden( bool bNewHidden )
107 : : {
108 : 0 : bHidden = bNewHidden;
109 : 0 : }
110 : :
111 : 10 : void ScOutlineEntry::SetVisible( bool bNewVisible )
112 : : {
113 : 10 : bVisible = bNewVisible;
114 : 10 : }
115 : :
116 : : //------------------------------------------------------------------------
117 : :
118 : 9086 : ScOutlineCollection::ScOutlineCollection() {}
119 : :
120 : : inline short IntCompare( SCCOLROW nX, SCCOLROW nY )
121 : : {
122 : : if ( nX==nY ) return 0;
123 : : else if ( nX<nY ) return -1;
124 : : else return 1;
125 : : }
126 : :
127 : 28 : size_t ScOutlineCollection::size() const
128 : : {
129 : 28 : return maEntries.size();
130 : : }
131 : :
132 : 4 : void ScOutlineCollection::clear()
133 : : {
134 : 4 : maEntries.clear();
135 : 4 : }
136 : :
137 : 38 : void ScOutlineCollection::insert(ScOutlineEntry* pEntry)
138 : : {
139 : 38 : SCCOLROW nStart = pEntry->GetStart();
140 [ + - ]: 38 : maEntries.insert(nStart, pEntry);
141 : 38 : }
142 : :
143 : 19 : ScOutlineCollection::iterator ScOutlineCollection::begin()
144 : : {
145 : 19 : return maEntries.begin();
146 : : }
147 : :
148 : 12 : ScOutlineCollection::iterator ScOutlineCollection::end()
149 : : {
150 : 12 : return maEntries.end();
151 : : }
152 : :
153 : 44 : ScOutlineCollection::const_iterator ScOutlineCollection::begin() const
154 : : {
155 : 44 : return maEntries.begin();
156 : : }
157 : :
158 : 20 : ScOutlineCollection::const_iterator ScOutlineCollection::end() const
159 : : {
160 : 20 : return maEntries.end();
161 : : }
162 : :
163 : 3 : void ScOutlineCollection::erase(iterator pos)
164 : : {
165 : 3 : maEntries.erase(pos);
166 : 3 : }
167 : :
168 : 4 : bool ScOutlineCollection::empty() const
169 : : {
170 : 4 : return maEntries.empty();
171 : : }
172 : :
173 : 0 : ScOutlineCollection::iterator ScOutlineCollection::FindStart(SCCOLROW nMinStart)
174 : : {
175 : 0 : return maEntries.lower_bound(nMinStart);
176 : : }
177 : :
178 : : //------------------------------------------------------------------------
179 : :
180 : 538 : ScOutlineArray::ScOutlineArray() :
181 [ + - ][ + + ]: 4304 : nDepth(0) {}
[ # # # # ]
182 : :
183 : 760 : ScOutlineArray::ScOutlineArray( const ScOutlineArray& rArray ) :
184 [ + - ][ + + : 6080 : nDepth( rArray.nDepth )
# # # # ]
185 : : {
186 [ + + ]: 780 : for (size_t nLevel = 0; nLevel < nDepth; ++nLevel)
187 : : {
188 : 20 : const ScOutlineCollection& rColl = rArray.aCollections[nLevel];
189 [ + - ][ + - ]: 20 : ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
190 [ + - ][ + - ]: 45 : for (; it != itEnd; ++it)
[ + + ]
191 : : {
192 [ + - ]: 25 : const ScOutlineEntry* pEntry = it->second;
193 [ + - ][ + - ]: 25 : aCollections[nLevel].insert(new ScOutlineEntry(*pEntry));
194 : : }
195 : : }
196 [ # # # # ]: 760 : }
197 : :
198 : 22 : void ScOutlineArray::FindEntry(
199 : : SCCOLROW nSearchPos, size_t& rFindLevel, size_t& rFindIndex,
200 : : size_t nMaxLevel )
201 : : {
202 : 22 : rFindLevel = rFindIndex = 0;
203 : :
204 [ + + ]: 22 : if (nMaxLevel > nDepth)
205 : 20 : nMaxLevel = nDepth;
206 : :
207 [ + + ]: 28 : for (size_t nLevel = 0; nLevel < nMaxLevel; ++nLevel) //! rueckwaerts suchen ?
208 : : {
209 : 6 : ScOutlineCollection* pCollect = &aCollections[nLevel];
210 [ + - ][ + - ]: 6 : ScOutlineCollection::iterator it = pCollect->begin(), itEnd = pCollect->end();
211 [ + - ][ + - ]: 14 : for (; it != itEnd; ++it)
[ + + ]
212 : : {
213 [ + - ]: 8 : ScOutlineEntry* pEntry = it->second;
214 [ + - ][ + + ]: 8 : if (pEntry->GetStart() <= nSearchPos && pEntry->GetEnd() >= nSearchPos)
[ + + ][ + + ]
215 : : {
216 : 2 : rFindLevel = nLevel + 1; // naechster Level (zum Einfuegen)
217 [ + - ][ + - ]: 2 : rFindIndex = std::distance(pCollect->begin(), it);
218 : : }
219 : : }
220 : : }
221 : 22 : }
222 : :
223 : 10 : bool ScOutlineArray::Insert(
224 : : SCCOLROW nStartCol, SCCOLROW nEndCol, bool& rSizeChanged, bool bHidden, bool bVisible )
225 : : {
226 : 10 : rSizeChanged = false;
227 : :
228 : : size_t nStartLevel, nEndLevel, nStartIndex, nEndIndex;
229 : 10 : bool bFound = false;
230 : :
231 : : bool bCont;
232 : : sal_uInt16 nFindMax;
233 [ + - ]: 10 : FindEntry( nStartCol, nStartLevel, nStartIndex ); // nLevel = neuer Level (alter+1) !!!
234 [ + - ]: 10 : FindEntry( nEndCol, nEndLevel, nEndIndex );
235 : 10 : nFindMax = Max(nStartLevel,nEndLevel);
236 [ + + ][ + - ]: 12 : do
[ + + ]
237 : : {
238 : 12 : bCont = false;
239 : :
240 [ + + ][ + - ]: 12 : if (nStartLevel == nEndLevel && nStartIndex == nEndIndex && nStartLevel < SC_OL_MAXDEPTH)
[ + - ]
241 : 10 : bFound = true;
242 : :
243 [ + + ]: 12 : if (!bFound)
244 : : {
245 [ + - ]: 2 : if (nFindMax>0)
246 : : {
247 : 2 : --nFindMax;
248 [ + - ]: 2 : if (nStartLevel)
249 : : {
250 [ + - ][ + - ]: 2 : ScOutlineCollection::const_iterator it = aCollections[nStartLevel-1].begin();
251 [ + - ]: 2 : std::advance(it, nStartIndex);
252 [ + - ][ + - ]: 2 : if (it->second->GetStart() == nStartCol)
253 [ + - ]: 2 : FindEntry(nStartCol, nStartLevel, nStartIndex, nFindMax);
254 : : }
255 : :
256 [ - + ]: 2 : if (nEndLevel)
257 : : {
258 [ # # ][ # # ]: 0 : ScOutlineCollection::const_iterator it = aCollections[nEndLevel-1].begin();
259 [ # # ]: 0 : std::advance(it, nEndIndex);
260 [ # # ][ # # ]: 0 : if (it->second->GetEnd() == nEndCol)
[ # # ]
261 [ # # ]: 0 : FindEntry(nEndCol, nEndLevel, nEndIndex, nFindMax);
262 : : }
263 : 2 : bCont = true;
264 : : }
265 : : }
266 : : }
267 : 12 : while ( !bFound && bCont );
268 : :
269 [ - + ]: 10 : if (!bFound)
270 : 0 : return false;
271 : :
272 : 10 : size_t nLevel = nStartLevel;
273 : :
274 : : // untere verschieben
275 : :
276 : 10 : bool bNeedSize = false;
277 [ + + ]: 10 : if (nDepth > 0)
278 : : {
279 [ + - ]: 6 : for (size_t nMoveLevel = nDepth-1; nMoveLevel >= nLevel; --nMoveLevel)
280 : : {
281 : 3 : ScOutlineCollection& rColl = aCollections[nMoveLevel];
282 [ + - ][ + - ]: 3 : ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
283 [ + - ][ + + ]: 7 : while (it != itEnd)
284 : : {
285 [ + - ]: 4 : ScOutlineEntry* pEntry = it->second;
286 : 4 : SCCOLROW nEntryStart = pEntry->GetStart();
287 [ + - ][ + + ]: 4 : if (nEntryStart >= nStartCol && nEntryStart <= nEndCol)
288 : : {
289 [ - + ]: 3 : if (nMoveLevel >= SC_OL_MAXDEPTH - 1)
290 : : {
291 : 0 : rSizeChanged = false; // kein Platz
292 : 0 : return false;
293 : : }
294 [ + - ][ + - ]: 3 : aCollections[nMoveLevel+1].insert(new ScOutlineEntry(*pEntry));
295 [ + - ][ + - ]: 3 : size_t nPos = std::distance(rColl.begin(), it);
296 [ + - ]: 3 : rColl.erase(it);
297 [ + - ]: 3 : it = rColl.begin();
298 [ + - ]: 3 : std::advance(it, nPos);
299 [ + - ]: 3 : itEnd = rColl.end();
300 [ + - ]: 3 : if (nMoveLevel == nDepth - 1)
301 : 3 : bNeedSize = true;
302 : : }
303 : : else
304 [ + - ]: 1 : ++it;
305 : : }
306 [ - + ]: 3 : if (nMoveLevel == 0)
307 : : break;
308 : : }
309 : : }
310 : :
311 [ + + ]: 10 : if (bNeedSize)
312 : : {
313 : 2 : ++nDepth;
314 : 2 : rSizeChanged = true;
315 : : }
316 : :
317 [ + + ]: 10 : if (nDepth <= nLevel)
318 : : {
319 : 7 : nDepth = nLevel+1;
320 : 7 : rSizeChanged = true;
321 : : }
322 : :
323 [ + - ]: 10 : ScOutlineEntry* pNewEntry = new ScOutlineEntry( nStartCol, nEndCol+1-nStartCol, bHidden );
324 : 10 : pNewEntry->SetVisible( bVisible );
325 [ + - ]: 10 : aCollections[nLevel].insert(pNewEntry);
326 : :
327 : 10 : return true;
328 : : }
329 : :
330 : 966 : size_t ScOutlineArray::GetDepth() const
331 : : {
332 : 966 : return nDepth;
333 : : }
334 : :
335 : 0 : bool ScOutlineArray::FindTouchedLevel(
336 : : SCCOLROW nBlockStart, SCCOLROW nBlockEnd, size_t& rFindLevel) const
337 : : {
338 : 0 : bool bFound = false;
339 : 0 : rFindLevel = 0;
340 : :
341 [ # # ]: 0 : for (size_t nLevel = 0; nLevel < nDepth; ++nLevel)
342 : : {
343 : 0 : const ScOutlineCollection* pCollect = &aCollections[nLevel];
344 [ # # ][ # # ]: 0 : ScOutlineCollection::const_iterator it = pCollect->begin(), itEnd = pCollect->end();
345 [ # # ][ # # ]: 0 : for (; it != itEnd; ++it)
[ # # ]
346 : : {
347 [ # # ]: 0 : const ScOutlineEntry* pEntry = it->second;
348 : 0 : SCCOLROW nStart = pEntry->GetStart();
349 [ # # ]: 0 : SCCOLROW nEnd = pEntry->GetEnd();
350 : :
351 [ # # ][ # # ]: 0 : if ( ( nBlockStart>=nStart && nBlockStart<=nEnd ) ||
[ # # ][ # # ]
352 : : ( nBlockEnd >=nStart && nBlockEnd <=nEnd ) )
353 : : {
354 : 0 : rFindLevel = nLevel; // wirklicher Level
355 : 0 : bFound = true;
356 : : }
357 : : }
358 : : }
359 : :
360 : 0 : return bFound;
361 : : }
362 : :
363 : 0 : void ScOutlineArray::RemoveSub(SCCOLROW nStartPos, SCCOLROW nEndPos, size_t nLevel)
364 : : {
365 [ # # ]: 0 : if ( nLevel >= nDepth )
366 : 0 : return;
367 : :
368 : 0 : ScOutlineCollection& rColl = aCollections[nLevel];
369 : :
370 [ # # ][ # # ]: 0 : ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
371 [ # # ][ # # ]: 0 : while (it != itEnd)
372 : : {
373 [ # # ]: 0 : ScOutlineEntry* pEntry = it->second;
374 : 0 : SCCOLROW nStart = pEntry->GetStart();
375 [ # # ]: 0 : SCCOLROW nEnd = pEntry->GetEnd();
376 [ # # ][ # # ]: 0 : if (nStart >= nStartPos && nEnd <= nEndPos)
377 : : {
378 : : // Overlaps.
379 [ # # ]: 0 : RemoveSub( nStart, nEnd, nLevel+1 );
380 : :
381 : : // Re-calc iterator positions after the tree gets invalidated.
382 [ # # ][ # # ]: 0 : size_t nPos = std::distance(rColl.begin(), it);
383 [ # # ]: 0 : rColl.erase(it);
384 [ # # ]: 0 : it = rColl.begin();
385 [ # # ]: 0 : std::advance(it, nPos);
386 [ # # ]: 0 : itEnd = rColl.end();
387 : : }
388 : : else
389 [ # # ]: 0 : ++it;
390 : : }
391 : :
392 [ # # ]: 0 : it = rColl.begin();
393 [ # # ]: 0 : itEnd = rColl.end();
394 : :
395 [ # # ][ # # ]: 0 : while (it != itEnd)
396 : : {
397 [ # # ]: 0 : ScOutlineEntry* pEntry = it->second;
398 : 0 : SCCOLROW nStart = pEntry->GetStart();
399 [ # # ]: 0 : SCCOLROW nEnd = pEntry->GetEnd();
400 : :
401 [ # # ][ # # ]: 0 : if (nStart >= nStartPos && nEnd <= nEndPos)
402 : : {
403 [ # # ]: 0 : RemoveSub( nStart, nEnd, nLevel+1 );
404 : :
405 : : // Re-calc iterator positions after the tree gets invalidated.
406 [ # # ][ # # ]: 0 : size_t nPos = std::distance(rColl.begin(), it);
407 [ # # ]: 0 : rColl.erase(it);
408 [ # # ]: 0 : it = rColl.begin();
409 [ # # ]: 0 : std::advance(it, nPos);
410 [ # # ]: 0 : itEnd = rColl.end();
411 : : }
412 : : else
413 [ # # ]: 0 : ++it;
414 : : }
415 : : }
416 : :
417 : 0 : void ScOutlineArray::PromoteSub(SCCOLROW nStartPos, SCCOLROW nEndPos, size_t nStartLevel)
418 : : {
419 [ # # ]: 0 : if (nStartLevel==0)
420 : : {
421 : : OSL_FAIL("PromoteSub mit Level 0");
422 : 0 : return;
423 : : }
424 : :
425 [ # # ]: 0 : for (size_t nLevel = nStartLevel; nLevel < nDepth; ++nLevel)
426 : : {
427 : 0 : ScOutlineCollection& rColl = aCollections[nLevel];
428 [ # # ][ # # ]: 0 : ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
429 [ # # ][ # # ]: 0 : while (it != itEnd)
430 : : {
431 [ # # ]: 0 : ScOutlineEntry* pEntry = it->second;
432 : 0 : SCCOLROW nStart = pEntry->GetStart();
433 [ # # ]: 0 : SCCOLROW nEnd = pEntry->GetEnd();
434 [ # # ][ # # ]: 0 : if (nStart >= nStartPos && nEnd <= nEndPos)
435 : : {
436 [ # # ][ # # ]: 0 : aCollections[nLevel-1].insert(new ScOutlineEntry(*pEntry));
437 : :
438 : : // Re-calc iterator positions after the tree gets invalidated.
439 [ # # ][ # # ]: 0 : size_t nPos = std::distance(rColl.begin(), it);
440 [ # # ]: 0 : rColl.erase(it);
441 [ # # ]: 0 : it = rColl.begin();
442 [ # # ]: 0 : std::advance(it, nPos);
443 [ # # ]: 0 : itEnd = rColl.end();
444 : : }
445 : : else
446 [ # # ]: 0 : ++it;
447 : : }
448 : :
449 [ # # ]: 0 : it = rColl.begin();
450 [ # # ]: 0 : itEnd = rColl.end();
451 : :
452 [ # # ][ # # ]: 0 : while (it != itEnd)
453 : : {
454 [ # # ]: 0 : ScOutlineEntry* pEntry = it->second;
455 : 0 : SCCOLROW nStart = pEntry->GetStart();
456 [ # # ]: 0 : SCCOLROW nEnd = pEntry->GetEnd();
457 [ # # ][ # # ]: 0 : if (nStart >= nStartPos && nEnd <= nEndPos)
458 : : {
459 [ # # ][ # # ]: 0 : aCollections[nLevel-1].insert(new ScOutlineEntry(*pEntry));
460 : :
461 : : // Re-calc iterator positions after the tree gets invalidated.
462 [ # # ][ # # ]: 0 : size_t nPos = std::distance(rColl.begin(), it);
463 [ # # ]: 0 : rColl.erase(it);
464 [ # # ]: 0 : it = rColl.begin();
465 [ # # ]: 0 : std::advance(it, nPos);
466 [ # # ]: 0 : itEnd = rColl.end();
467 : : }
468 : : else
469 [ # # ]: 0 : ++it;
470 : : }
471 : : }
472 : : }
473 : :
474 : 0 : bool ScOutlineArray::DecDepth() // nDepth auf leere Levels anpassen
475 : : {
476 : 0 : bool bChanged = false;
477 : : bool bCont;
478 [ # # ]: 0 : do
479 : : {
480 : 0 : bCont = false;
481 [ # # ]: 0 : if (nDepth)
482 : : {
483 [ # # ]: 0 : if (aCollections[nDepth-1].empty())
484 : : {
485 : 0 : --nDepth;
486 : 0 : bChanged = true;
487 : 0 : bCont = true;
488 : : }
489 : : }
490 : : }
491 : : while (bCont);
492 : :
493 : 0 : return bChanged;
494 : : }
495 : :
496 : 0 : bool ScOutlineArray::Remove( SCCOLROW nBlockStart, SCCOLROW nBlockEnd, bool& rSizeChanged )
497 : : {
498 : : size_t nLevel;
499 [ # # ]: 0 : FindTouchedLevel( nBlockStart, nBlockEnd, nLevel );
500 : :
501 : 0 : ScOutlineCollection* pCollect = &aCollections[nLevel];
502 [ # # ][ # # ]: 0 : ScOutlineCollection::iterator it = pCollect->begin(), itEnd = pCollect->end();
503 : 0 : bool bAny = false;
504 [ # # ][ # # ]: 0 : while (it != itEnd)
505 : : {
506 [ # # ]: 0 : ScOutlineEntry* pEntry = it->second;
507 : 0 : SCCOLROW nStart = pEntry->GetStart();
508 [ # # ]: 0 : SCCOLROW nEnd = pEntry->GetEnd();
509 [ # # ][ # # ]: 0 : if (nBlockStart <= nEnd && nBlockEnd >= nStart)
510 : : {
511 : : // Overlaps.
512 [ # # ]: 0 : pCollect->erase(it);
513 [ # # ]: 0 : PromoteSub( nStart, nEnd, nLevel+1 );
514 [ # # ]: 0 : itEnd = pCollect->end();
515 [ # # ]: 0 : it = pCollect->FindStart( nEnd+1 );
516 : 0 : bAny = true;
517 : : }
518 : : else
519 [ # # ]: 0 : ++it;
520 : : }
521 : :
522 [ # # ]: 0 : if (bAny) // Depth anpassen
523 [ # # ][ # # ]: 0 : if (DecDepth())
524 : 0 : rSizeChanged = true;
525 : :
526 : 0 : return bAny;
527 : : }
528 : :
529 : 0 : ScOutlineEntry* ScOutlineArray::GetEntry(size_t nLevel, size_t nIndex)
530 : : {
531 [ # # ]: 0 : if (nLevel >= nDepth)
532 : 0 : return NULL;
533 : :
534 : 0 : ScOutlineCollection& rColl = aCollections[nLevel];
535 [ # # ][ # # ]: 0 : if (nIndex >= rColl.size())
536 : 0 : return NULL;
537 : :
538 [ # # ]: 0 : ScOutlineCollection::iterator it = rColl.begin();
539 [ # # ]: 0 : std::advance(it, nIndex);
540 [ # # ]: 0 : return it->second;
541 : : }
542 : :
543 : 22 : const ScOutlineEntry* ScOutlineArray::GetEntry(size_t nLevel, size_t nIndex) const
544 : : {
545 [ - + ]: 22 : if (nLevel >= nDepth)
546 : 0 : return NULL;
547 : :
548 : 22 : const ScOutlineCollection& rColl = aCollections[nLevel];
549 [ + - ][ - + ]: 22 : if (nIndex >= rColl.size())
550 : 0 : return NULL;
551 : :
552 [ + - ]: 22 : ScOutlineCollection::const_iterator it = rColl.begin();
553 [ + - ]: 22 : std::advance(it, nIndex);
554 [ + - ]: 22 : return it->second;
555 : : }
556 : :
557 : 4 : size_t ScOutlineArray::GetCount(size_t nLevel) const
558 : : {
559 [ - + ]: 4 : if (nLevel >= nDepth)
560 : 0 : return 0;
561 : :
562 : 4 : return aCollections[nLevel].size();
563 : : }
564 : :
565 : 0 : const ScOutlineEntry* ScOutlineArray::GetEntryByPos(size_t nLevel, SCCOLROW nPos) const
566 : : {
567 [ # # ]: 0 : if (nLevel >= nDepth)
568 : 0 : return NULL;
569 : :
570 : 0 : const ScOutlineCollection& rColl = aCollections[nLevel];
571 [ # # ][ # # ]: 0 : ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
572 [ # # ][ # # ]: 0 : for (; it != itEnd; ++it)
[ # # ]
573 : : {
574 [ # # ]: 0 : const ScOutlineEntry* pEntry = it->second;
575 [ # # ][ # # ]: 0 : if (pEntry->GetStart() <= nPos && nPos <= pEntry->GetEnd())
[ # # ][ # # ]
576 : 0 : return pEntry;
577 : : }
578 : :
579 : 0 : return NULL;
580 : : }
581 : :
582 : 0 : bool ScOutlineArray::GetEntryIndex(size_t nLevel, SCCOLROW nPos, size_t& rnIndex) const
583 : : {
584 [ # # ]: 0 : if (nLevel >= nDepth)
585 : 0 : return false;
586 : :
587 : : // found entry contains passed position
588 : 0 : const ScOutlineCollection& rColl = aCollections[nLevel];
589 [ # # ][ # # ]: 0 : ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
590 [ # # ][ # # ]: 0 : for (; it != itEnd; ++it)
[ # # ]
591 : : {
592 [ # # ]: 0 : const ScOutlineEntry* p = it->second;
593 [ # # ][ # # ]: 0 : if (p->GetStart() <= nPos && nPos <= p->GetEnd())
[ # # ][ # # ]
594 : : {
595 [ # # ][ # # ]: 0 : rnIndex = std::distance(rColl.begin(), it);
596 : 0 : return true;
597 : : }
598 : : }
599 : 0 : return false;
600 : : }
601 : :
602 : 0 : bool ScOutlineArray::GetEntryIndexInRange(
603 : : size_t nLevel, SCCOLROW nBlockStart, SCCOLROW nBlockEnd, size_t& rnIndex) const
604 : : {
605 [ # # ]: 0 : if (nLevel >= nDepth)
606 : 0 : return false;
607 : :
608 : : // found entry will be completely inside of passed range
609 : 0 : const ScOutlineCollection& rColl = aCollections[nLevel];
610 [ # # ][ # # ]: 0 : ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
611 [ # # ][ # # ]: 0 : for (; it != itEnd; ++it)
[ # # ]
612 : : {
613 [ # # ]: 0 : const ScOutlineEntry* p = it->second;
614 [ # # ][ # # ]: 0 : if (nBlockStart <= p->GetStart() && p->GetEnd() <= nBlockEnd)
[ # # ][ # # ]
615 : : {
616 [ # # ][ # # ]: 0 : rnIndex = std::distance(rColl.begin(), it);
617 : 0 : return true;
618 : : }
619 : : }
620 : 0 : return false;
621 : : }
622 : :
623 : 0 : void ScOutlineArray::SetVisibleBelow(
624 : : size_t nLevel, size_t nEntry, bool bValue, bool bSkipHidden)
625 : : {
626 : 0 : const ScOutlineEntry* pEntry = GetEntry( nLevel, nEntry );
627 [ # # ]: 0 : if (!pEntry)
628 : 0 : return;
629 : :
630 : 0 : SCCOLROW nStart = pEntry->GetStart();
631 : 0 : SCCOLROW nEnd = pEntry->GetEnd();
632 : :
633 [ # # ]: 0 : for (size_t nSubLevel = nLevel+1; nSubLevel < nDepth; ++nSubLevel)
634 : : {
635 : 0 : ScOutlineCollection& rColl = aCollections[nSubLevel];
636 [ # # ][ # # ]: 0 : ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
637 [ # # ][ # # ]: 0 : for (; it != itEnd; ++it)
[ # # ]
638 : : {
639 [ # # ]: 0 : ScOutlineEntry* p = it->second;
640 [ # # ][ # # ]: 0 : if (p->GetStart() >= nStart && p->GetEnd() <= nEnd)
[ # # ][ # # ]
641 : : {
642 : 0 : p->SetVisible(bValue);
643 [ # # ][ # # ]: 0 : if (bSkipHidden && !p->IsHidden())
[ # # ][ # # ]
644 : : {
645 [ # # ][ # # ]: 0 : size_t nPos = std::distance(rColl.begin(), it);
646 [ # # ]: 0 : SetVisibleBelow(nSubLevel, nPos, bValue, true);
647 : : }
648 : : }
649 : : }
650 : :
651 [ # # ]: 0 : if (bSkipHidden)
652 : 0 : nSubLevel = nDepth; // Abbruch
653 : : }
654 : : }
655 : :
656 : 4 : void ScOutlineArray::GetRange(SCCOLROW& rStart, SCCOLROW& rEnd) const
657 : : {
658 : 4 : const ScOutlineCollection& rColl = aCollections[0];
659 [ + + ]: 4 : if (!rColl.empty())
660 : : {
661 [ + - ]: 2 : ScOutlineCollection::const_iterator it = rColl.begin();
662 [ + - ]: 2 : rStart = it->second->GetStart();
663 [ + - ][ + - ]: 2 : std::advance(it, rColl.size()-1);
664 [ + - ][ + - ]: 2 : rEnd = it->second->GetEnd();
665 : : }
666 : : else
667 : 2 : rStart = rEnd = 0;
668 : 4 : }
669 : :
670 : 0 : void ScOutlineArray::ExtendBlock(size_t nLevel, SCCOLROW& rBlkStart, SCCOLROW& rBlkEnd)
671 : : {
672 [ # # ]: 0 : if (nLevel >= nDepth)
673 : 0 : return;
674 : :
675 : 0 : const ScOutlineCollection& rColl = aCollections[nLevel];
676 [ # # ][ # # ]: 0 : ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
677 [ # # ][ # # ]: 0 : for (; it != itEnd; ++it)
[ # # ]
678 : : {
679 [ # # ]: 0 : const ScOutlineEntry* pEntry = it->second;
680 : 0 : SCCOLROW nStart = pEntry->GetStart();
681 [ # # ]: 0 : SCCOLROW nEnd = pEntry->GetEnd();
682 : :
683 [ # # ][ # # ]: 0 : if (rBlkStart <= nEnd && rBlkEnd >= nStart)
684 : : {
685 [ # # ]: 0 : if (nStart < rBlkStart)
686 : 0 : rBlkStart = nStart;
687 [ # # ]: 0 : if (nEnd > rBlkEnd)
688 : 0 : rBlkEnd = nEnd;
689 : : }
690 : : }
691 : : }
692 : :
693 : 0 : bool ScOutlineArray::TestInsertSpace(SCSIZE nSize, SCCOLROW nMaxVal) const
694 : : {
695 : 0 : const ScOutlineCollection& rColl = aCollections[0];
696 [ # # ][ # # ]: 0 : if (rColl.empty())
697 : 0 : return true;
698 : :
699 [ # # ]: 0 : ScOutlineCollection::const_iterator it = rColl.begin();
700 [ # # ][ # # ]: 0 : std::advance(it, rColl.size()-1);
701 [ # # ][ # # ]: 0 : SCCOLROW nEnd = it->second->GetEnd();
702 : 0 : return sal::static_int_cast<SCCOLROW>(nEnd+nSize) <= nMaxVal;
703 : : }
704 : :
705 : 0 : void ScOutlineArray::InsertSpace(SCCOLROW nStartPos, SCSIZE nSize)
706 : : {
707 : 0 : ScSubOutlineIterator aIter( this );
708 : : ScOutlineEntry* pEntry;
709 [ # # ][ # # ]: 0 : while ((pEntry = aIter.GetNext()) != NULL)
710 : : {
711 [ # # ]: 0 : if ( pEntry->GetStart() >= nStartPos )
712 : 0 : pEntry->Move(static_cast<SCsCOLROW>(nSize));
713 : : else
714 : : {
715 [ # # ]: 0 : SCCOLROW nEnd = pEntry->GetEnd();
716 : : // immer erweitern, wenn innerhalb der Gruppe eingefuegt
717 : : // beim Einfuegen am Ende nur, wenn die Gruppe nicht ausgeblendet ist
718 [ # # ][ # # ]: 0 : if ( nEnd >= nStartPos || ( nEnd+1 >= nStartPos && !pEntry->IsHidden() ) )
[ # # ][ # # ]
[ # # ]
719 : : {
720 : 0 : SCSIZE nEntrySize = pEntry->GetSize();
721 : 0 : nEntrySize += nSize;
722 : 0 : pEntry->SetSize( nEntrySize );
723 : : }
724 : : }
725 : : }
726 : 0 : }
727 : :
728 : 3 : bool ScOutlineArray::DeleteSpace(SCCOLROW nStartPos, SCSIZE nSize)
729 : : {
730 : 3 : SCCOLROW nEndPos = nStartPos + nSize - 1;
731 : 3 : sal_Bool bNeedSave = false; // Original fuer Undo benoetigt?
732 : 3 : sal_Bool bChanged = false; // fuer Test auf Level
733 : :
734 : 3 : ScSubOutlineIterator aIter( this );
735 : : ScOutlineEntry* pEntry;
736 [ + - ][ - + ]: 3 : while((pEntry=aIter.GetNext())!=NULL)
737 : : {
738 : 0 : SCCOLROW nEntryStart = pEntry->GetStart();
739 [ # # ]: 0 : SCCOLROW nEntryEnd = pEntry->GetEnd();
740 : 0 : SCSIZE nEntrySize = pEntry->GetSize();
741 : :
742 [ # # ]: 0 : if ( nEntryEnd >= nStartPos )
743 : : {
744 [ # # ]: 0 : if ( nEntryStart > nEndPos ) // rechts
745 : 0 : pEntry->Move(-(static_cast<SCsCOLROW>(nSize)));
746 [ # # ][ # # ]: 0 : else if ( nEntryStart < nStartPos && nEntryEnd >= nEndPos ) // aussen
747 : 0 : pEntry->SetSize( nEntrySize-nSize );
748 : : else
749 : : {
750 : 0 : bNeedSave = true;
751 [ # # ][ # # ]: 0 : if ( nEntryStart >= nStartPos && nEntryEnd <= nEndPos ) // innen
752 : : {
753 [ # # ]: 0 : aIter.DeleteLast();
754 : 0 : bChanged = true;
755 : : }
756 [ # # ]: 0 : else if ( nEntryStart >= nStartPos ) // rechts ueber
757 : 0 : pEntry->SetPosSize( nStartPos, static_cast<SCSIZE>(nEntryEnd-nEndPos) );
758 : : else // links ueber
759 : 0 : pEntry->SetSize( static_cast<SCSIZE>(nStartPos-nEntryStart) );
760 : : }
761 : : }
762 : : }
763 : :
764 [ - + ]: 3 : if (bChanged)
765 [ # # ]: 0 : DecDepth();
766 : :
767 : 3 : return bNeedSave;
768 : : }
769 : :
770 : 0 : bool ScOutlineArray::ManualAction(
771 : : SCCOLROW nStartPos, SCCOLROW nEndPos, bool bShow, const ScTable& rTable, bool bCol)
772 : : {
773 : 0 : bool bModified = false;
774 : 0 : ScSubOutlineIterator aIter( this );
775 : : ScOutlineEntry* pEntry;
776 [ # # ][ # # ]: 0 : while((pEntry=aIter.GetNext())!=NULL)
777 : : {
778 : 0 : SCCOLROW nEntryStart = pEntry->GetStart();
779 [ # # ]: 0 : SCCOLROW nEntryEnd = pEntry->GetEnd();
780 : :
781 [ # # ][ # # ]: 0 : if (nEntryEnd>=nStartPos && nEntryStart<=nEndPos)
782 : : {
783 [ # # ][ # # ]: 0 : if ( pEntry->IsHidden() == bShow )
784 : : {
785 : : // #i12341# hide if all columns/rows are hidden, show if at least one
786 : : // is visible
787 [ # # ]: 0 : SCCOLROW nEnd = rTable.LastHiddenColRow(nEntryStart, bCol);
788 : : bool bAllHidden = (nEntryEnd <= nEnd && nEnd <
789 [ # # ][ # # ]: 0 : ::std::numeric_limits<SCCOLROW>::max());
790 : :
791 : 0 : bool bToggle = ( bShow != bAllHidden );
792 [ # # ]: 0 : if ( bToggle )
793 : : {
794 : 0 : pEntry->SetHidden( !bShow );
795 [ # # ]: 0 : SetVisibleBelow( aIter.LastLevel(), aIter.LastEntry(), bShow, bShow );
796 : 0 : bModified = true;
797 : : }
798 : : }
799 : : }
800 : : }
801 : 0 : return bModified;
802 : : }
803 : :
804 : 2 : void ScOutlineArray::RemoveAll()
805 : : {
806 [ + + ]: 6 : for (size_t nLevel = 0; nLevel < nDepth; ++nLevel)
807 : 4 : aCollections[nLevel].clear();
808 : :
809 : 2 : nDepth = 0;
810 : 2 : }
811 : :
812 : : //------------------------------------------------------------------------
813 : :
814 [ + - ]: 269 : ScOutlineTable::ScOutlineTable()
815 : : {
816 : 269 : }
817 : :
818 : 380 : ScOutlineTable::ScOutlineTable( const ScOutlineTable& rOutline ) :
819 : : aColOutline( rOutline.aColOutline ),
820 [ + - ]: 380 : aRowOutline( rOutline.aRowOutline )
821 : : {
822 : 380 : }
823 : :
824 : 0 : sal_Bool ScOutlineTable::TestInsertCol( SCSIZE nSize )
825 : : {
826 : 0 : return aColOutline.TestInsertSpace( nSize, MAXCOL );
827 : : }
828 : :
829 : 0 : void ScOutlineTable::InsertCol( SCCOL nStartCol, SCSIZE nSize )
830 : : {
831 : 0 : aColOutline.InsertSpace( nStartCol, nSize );
832 : 0 : }
833 : :
834 : 0 : sal_Bool ScOutlineTable::DeleteCol( SCCOL nStartCol, SCSIZE nSize )
835 : : {
836 : 0 : return aColOutline.DeleteSpace( nStartCol, nSize );
837 : : }
838 : :
839 : 0 : sal_Bool ScOutlineTable::TestInsertRow( SCSIZE nSize )
840 : : {
841 : 0 : return aRowOutline.TestInsertSpace( nSize, MAXROW );
842 : : }
843 : :
844 : 0 : void ScOutlineTable::InsertRow( SCROW nStartRow, SCSIZE nSize )
845 : : {
846 : 0 : aRowOutline.InsertSpace( nStartRow, nSize );
847 : 0 : }
848 : :
849 : 3 : sal_Bool ScOutlineTable::DeleteRow( SCROW nStartRow, SCSIZE nSize )
850 : : {
851 : 3 : return aRowOutline.DeleteSpace( nStartRow, nSize );
852 : : }
853 : :
854 : : //------------------------------------------------------------------------
855 : :
856 : 3 : ScSubOutlineIterator::ScSubOutlineIterator( ScOutlineArray* pOutlineArray ) :
857 : : pArray( pOutlineArray ),
858 : : nStart( 0 ),
859 : : nEnd( SCCOLROW_MAX ), // alle durchgehen
860 : : nSubLevel( 0 ),
861 : 3 : nSubEntry( 0 )
862 : : {
863 : 3 : nDepth = pArray->nDepth;
864 : 3 : }
865 : :
866 : 0 : ScSubOutlineIterator::ScSubOutlineIterator(
867 : : ScOutlineArray* pOutlineArray, size_t nLevel, size_t nEntry ) :
868 : 0 : pArray( pOutlineArray )
869 : : {
870 : 0 : const ScOutlineCollection& rColl = pArray->aCollections[nLevel];
871 [ # # ]: 0 : ScOutlineCollection::const_iterator it = rColl.begin();
872 [ # # ]: 0 : std::advance(it, nEntry);
873 [ # # ]: 0 : const ScOutlineEntry* pEntry = it->second;
874 : 0 : nStart = pEntry->GetStart();
875 [ # # ]: 0 : nEnd = pEntry->GetEnd();
876 : 0 : nSubLevel = nLevel + 1;
877 : 0 : nSubEntry = 0;
878 : 0 : nDepth = pArray->nDepth;
879 : 0 : }
880 : :
881 : 3 : ScOutlineEntry* ScSubOutlineIterator::GetNext()
882 : : {
883 : 3 : ScOutlineEntry* pEntry = NULL;
884 : 3 : bool bFound = false;
885 [ # # ]: 0 : do
886 : : {
887 [ + - ]: 3 : if (nSubLevel >= nDepth)
888 : 3 : return NULL;
889 : :
890 : 0 : ScOutlineCollection& rColl = pArray->aCollections[nSubLevel];
891 [ # # ]: 0 : if (nSubEntry < rColl.size())
892 : : {
893 [ # # ]: 0 : ScOutlineCollection::iterator it = rColl.begin();
894 [ # # ]: 0 : std::advance(it, nSubEntry);
895 [ # # ]: 0 : pEntry = it->second;
896 : :
897 [ # # ][ # # ]: 0 : if (pEntry->GetStart() >= nStart && pEntry->GetEnd() <= nEnd)
[ # # ][ # # ]
898 : 0 : bFound = true;
899 : :
900 : 0 : ++nSubEntry;
901 : : }
902 : : else
903 : : {
904 : : // Go to the next sub-level.
905 : 0 : nSubEntry = 0;
906 : 0 : ++nSubLevel;
907 : : }
908 : : }
909 : 0 : while (!bFound);
910 : 3 : return pEntry; // nSubLevel gueltig, wenn pEntry != 0
911 : : }
912 : :
913 : 0 : size_t ScSubOutlineIterator::LastLevel() const
914 : : {
915 : 0 : return nSubLevel;
916 : : }
917 : :
918 : 0 : size_t ScSubOutlineIterator::LastEntry() const
919 : : {
920 [ # # ]: 0 : if (nSubEntry == 0)
921 : : {
922 : : OSL_FAIL("ScSubOutlineIterator::LastEntry vor GetNext");
923 : 0 : return 0;
924 : : }
925 : 0 : return nSubEntry-1;
926 : : }
927 : :
928 : 0 : void ScSubOutlineIterator::DeleteLast()
929 : : {
930 [ # # ]: 0 : if (nSubLevel >= nDepth)
931 : : {
932 : : OSL_FAIL("ScSubOutlineIterator::DeleteLast nach Ende");
933 : : return;
934 : : }
935 [ # # ]: 0 : if (nSubEntry == 0)
936 : : {
937 : : OSL_FAIL("ScSubOutlineIterator::DeleteLast vor GetNext");
938 : : return;
939 : : }
940 : :
941 : 0 : --nSubEntry;
942 : 0 : ScOutlineCollection& rColl = pArray->aCollections[nSubLevel];
943 : : OSL_ASSERT(nSubEntry < rColl.size());
944 [ # # ]: 0 : ScOutlineCollection::iterator it = rColl.begin();
945 [ # # ]: 0 : std::advance(it, nSubEntry);
946 [ # # ]: 0 : rColl.erase(it);
947 : : }
948 : :
949 : :
950 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|