fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / core / data / olinetab.cxx
blob55f86356a187242bc1f258467d8b077ab69563b6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 #include <limits.h>
22 #include "olinetab.hxx"
23 #include "global.hxx"
24 #include "rechead.hxx"
25 #include "address.hxx"
26 #include "table.hxx"
28 #include <osl/diagnose.h>
30 ScOutlineEntry::ScOutlineEntry( SCCOLROW nNewStart, SCCOLROW nNewSize, bool bNewHidden ) :
31 nStart ( nNewStart ),
32 nSize ( nNewSize ),
33 bHidden ( bNewHidden ),
34 bVisible( true )
38 ScOutlineEntry::ScOutlineEntry( const ScOutlineEntry& rEntry ) :
39 nStart ( rEntry.nStart ),
40 nSize ( rEntry.nSize ),
41 bHidden ( rEntry.bHidden ),
42 bVisible( rEntry.bVisible )
46 SCCOLROW ScOutlineEntry::GetEnd() const
48 return nStart+nSize-1;
51 void ScOutlineEntry::Move( SCsCOLROW nDelta )
53 SCCOLROW nNewPos = nStart + nDelta;
54 if (nNewPos<0)
56 OSL_FAIL("OutlineEntry < 0");
57 nNewPos = 0;
59 nStart = nNewPos;
62 void ScOutlineEntry::SetSize( SCSIZE nNewSize )
64 if (nNewSize>0)
65 nSize = nNewSize;
66 else
68 OSL_FAIL("ScOutlineEntry Size == 0");
72 void ScOutlineEntry::SetPosSize( SCCOLROW nNewPos, SCSIZE nNewSize )
74 nStart = nNewPos;
75 SetSize( nNewSize );
78 void ScOutlineEntry::SetHidden( bool bNewHidden )
80 bHidden = bNewHidden;
83 void ScOutlineEntry::SetVisible( bool bNewVisible )
85 bVisible = bNewVisible;
88 ScOutlineCollection::ScOutlineCollection() {}
90 size_t ScOutlineCollection::size() const
92 return maEntries.size();
95 void ScOutlineCollection::clear()
97 maEntries.clear();
100 void ScOutlineCollection::insert(ScOutlineEntry* pEntry)
102 SCCOLROW nStart = pEntry->GetStart();
103 maEntries.insert(nStart, pEntry);
106 ScOutlineCollection::iterator ScOutlineCollection::begin()
108 return maEntries.begin();
111 ScOutlineCollection::iterator ScOutlineCollection::end()
113 return maEntries.end();
116 ScOutlineCollection::const_iterator ScOutlineCollection::begin() const
118 return maEntries.begin();
121 ScOutlineCollection::const_iterator ScOutlineCollection::end() const
123 return maEntries.end();
126 void ScOutlineCollection::erase(iterator pos)
128 maEntries.erase(pos);
131 bool ScOutlineCollection::empty() const
133 return maEntries.empty();
136 ScOutlineCollection::iterator ScOutlineCollection::FindStart(SCCOLROW nMinStart)
138 return maEntries.lower_bound(nMinStart);
141 ScOutlineArray::ScOutlineArray() :
142 nDepth(0) {}
144 ScOutlineArray::ScOutlineArray( const ScOutlineArray& rArray ) :
145 nDepth( rArray.nDepth )
147 for (size_t nLevel = 0; nLevel < nDepth; ++nLevel)
149 const ScOutlineCollection& rColl = rArray.aCollections[nLevel];
150 ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
151 for (; it != itEnd; ++it)
153 const ScOutlineEntry* pEntry = it->second;
154 aCollections[nLevel].insert(new ScOutlineEntry(*pEntry));
159 void ScOutlineArray::FindEntry(
160 SCCOLROW nSearchPos, size_t& rFindLevel, size_t& rFindIndex,
161 size_t nMaxLevel )
163 rFindLevel = rFindIndex = 0;
165 if (nMaxLevel > nDepth)
166 nMaxLevel = nDepth;
168 for (size_t nLevel = 0; nLevel < nMaxLevel; ++nLevel) //TODO: Search backwards?
170 ScOutlineCollection* pCollect = &aCollections[nLevel];
171 ScOutlineCollection::iterator it = pCollect->begin(), itEnd = pCollect->end();
172 for (; it != itEnd; ++it)
174 ScOutlineEntry* pEntry = it->second;
175 if (pEntry->GetStart() <= nSearchPos && pEntry->GetEnd() >= nSearchPos)
177 rFindLevel = nLevel + 1; // Next Level (for insertion)
178 rFindIndex = std::distance(pCollect->begin(), it);
184 bool ScOutlineArray::Insert(
185 SCCOLROW nStartCol, SCCOLROW nEndCol, bool& rSizeChanged, bool bHidden, bool bVisible )
187 rSizeChanged = false;
189 size_t nStartLevel, nEndLevel, nStartIndex, nEndIndex;
190 bool bFound = false;
192 bool bCont;
193 sal_uInt16 nFindMax;
194 FindEntry( nStartCol, nStartLevel, nStartIndex ); // nLevel = new Level (old+1)
195 FindEntry( nEndCol, nEndLevel, nEndIndex );
196 nFindMax = std::max(nStartLevel,nEndLevel);
199 bCont = false;
201 if (nStartLevel == nEndLevel && nStartIndex == nEndIndex && nStartLevel < SC_OL_MAXDEPTH)
202 bFound = true;
204 if (!bFound)
206 if (nFindMax>0)
208 --nFindMax;
209 if (nStartLevel)
211 ScOutlineCollection::const_iterator it = aCollections[nStartLevel-1].begin();
212 std::advance(it, nStartIndex);
213 if (it->second->GetStart() == nStartCol)
214 FindEntry(nStartCol, nStartLevel, nStartIndex, nFindMax);
217 if (nEndLevel)
219 ScOutlineCollection::const_iterator it = aCollections[nEndLevel-1].begin();
220 std::advance(it, nEndIndex);
221 if (it->second->GetEnd() == nEndCol)
222 FindEntry(nEndCol, nEndLevel, nEndIndex, nFindMax);
224 bCont = true;
228 while ( !bFound && bCont );
230 if (!bFound)
231 return false;
233 size_t nLevel = nStartLevel;
235 // Move the ones underneath
236 bool bNeedSize = false;
237 if (nDepth > 0)
239 for (size_t nMoveLevel = nDepth-1; nMoveLevel >= nLevel; --nMoveLevel)
241 ScOutlineCollection& rColl = aCollections[nMoveLevel];
242 ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
243 while (it != itEnd)
245 ScOutlineEntry* pEntry = it->second;
246 SCCOLROW nEntryStart = pEntry->GetStart();
247 if (nEntryStart >= nStartCol && nEntryStart <= nEndCol)
249 if (nMoveLevel >= SC_OL_MAXDEPTH - 1)
251 rSizeChanged = false; // No more room
252 return false;
254 aCollections[nMoveLevel+1].insert(new ScOutlineEntry(*pEntry));
255 size_t nPos = std::distance(rColl.begin(), it);
256 rColl.erase(it);
257 it = rColl.begin();
258 std::advance(it, nPos);
259 itEnd = rColl.end();
260 if (nMoveLevel == nDepth - 1)
261 bNeedSize = true;
263 else
264 ++it;
266 if (nMoveLevel == 0)
267 break;
271 if (bNeedSize)
273 ++nDepth;
274 rSizeChanged = true;
277 if (nDepth <= nLevel)
279 nDepth = nLevel+1;
280 rSizeChanged = true;
283 ScOutlineEntry* pNewEntry = new ScOutlineEntry( nStartCol, nEndCol+1-nStartCol, bHidden );
284 pNewEntry->SetVisible( bVisible );
285 aCollections[nLevel].insert(pNewEntry);
287 return true;
290 bool ScOutlineArray::FindTouchedLevel(
291 SCCOLROW nBlockStart, SCCOLROW nBlockEnd, size_t& rFindLevel) const
293 bool bFound = false;
294 rFindLevel = 0;
296 for (size_t nLevel = 0; nLevel < nDepth; ++nLevel)
298 const ScOutlineCollection* pCollect = &aCollections[nLevel];
299 ScOutlineCollection::const_iterator it = pCollect->begin(), itEnd = pCollect->end();
300 for (; it != itEnd; ++it)
302 const ScOutlineEntry* pEntry = it->second;
303 SCCOLROW nStart = pEntry->GetStart();
304 SCCOLROW nEnd = pEntry->GetEnd();
306 if ( ( nBlockStart>=nStart && nBlockStart<=nEnd ) ||
307 ( nBlockEnd >=nStart && nBlockEnd <=nEnd ) )
309 rFindLevel = nLevel; // Actual Level
310 bFound = true;
315 return bFound;
318 void ScOutlineArray::RemoveSub(SCCOLROW nStartPos, SCCOLROW nEndPos, size_t nLevel)
320 if ( nLevel >= nDepth )
321 return;
323 ScOutlineCollection& rColl = aCollections[nLevel];
325 ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
326 while (it != itEnd)
328 ScOutlineEntry* pEntry = it->second;
329 SCCOLROW nStart = pEntry->GetStart();
330 SCCOLROW nEnd = pEntry->GetEnd();
331 if (nStart >= nStartPos && nEnd <= nEndPos)
333 // Overlaps
334 RemoveSub( nStart, nEnd, nLevel+1 );
336 // Re-calc iterator positions after the tree gets invalidated
337 size_t nPos = std::distance(rColl.begin(), it);
338 rColl.erase(it);
339 it = rColl.begin();
340 std::advance(it, nPos);
341 itEnd = rColl.end();
343 else
344 ++it;
347 it = rColl.begin();
348 itEnd = rColl.end();
350 while (it != itEnd)
352 ScOutlineEntry* pEntry = it->second;
353 SCCOLROW nStart = pEntry->GetStart();
354 SCCOLROW nEnd = pEntry->GetEnd();
356 if (nStart >= nStartPos && nEnd <= nEndPos)
358 RemoveSub( nStart, nEnd, nLevel+1 );
360 // Re-calc iterator positions after the tree gets invalidated
361 size_t nPos = std::distance(rColl.begin(), it);
362 rColl.erase(it);
363 it = rColl.begin();
364 std::advance(it, nPos);
365 itEnd = rColl.end();
367 else
368 ++it;
372 void ScOutlineArray::PromoteSub(SCCOLROW nStartPos, SCCOLROW nEndPos, size_t nStartLevel)
374 if (nStartLevel==0)
376 OSL_FAIL("PromoteSub with Level 0");
377 return;
380 for (size_t nLevel = nStartLevel; nLevel < nDepth; ++nLevel)
382 ScOutlineCollection& rColl = aCollections[nLevel];
383 ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
384 while (it != itEnd)
386 ScOutlineEntry* pEntry = it->second;
387 SCCOLROW nStart = pEntry->GetStart();
388 SCCOLROW nEnd = pEntry->GetEnd();
389 if (nStart >= nStartPos && nEnd <= nEndPos)
391 aCollections[nLevel-1].insert(new ScOutlineEntry(*pEntry));
393 // Re-calc iterator positions after the tree gets invalidated
394 size_t nPos = std::distance(rColl.begin(), it);
395 rColl.erase(it);
396 it = rColl.begin();
397 std::advance(it, nPos);
398 itEnd = rColl.end();
400 else
401 ++it;
404 it = rColl.begin();
405 itEnd = rColl.end();
407 while (it != itEnd)
409 ScOutlineEntry* pEntry = it->second;
410 SCCOLROW nStart = pEntry->GetStart();
411 SCCOLROW nEnd = pEntry->GetEnd();
412 if (nStart >= nStartPos && nEnd <= nEndPos)
414 aCollections[nLevel-1].insert(new ScOutlineEntry(*pEntry));
416 // Re-calc iterator positions after the tree gets invalidated
417 size_t nPos = std::distance(rColl.begin(), it);
418 rColl.erase(it);
419 it = rColl.begin();
420 std::advance(it, nPos);
421 itEnd = rColl.end();
423 else
424 ++it;
430 * Adapt nDepth for empty Levels
432 bool ScOutlineArray::DecDepth()
434 bool bChanged = false;
435 bool bCont;
438 bCont = false;
439 if (nDepth)
441 if (aCollections[nDepth-1].empty())
443 --nDepth;
444 bChanged = true;
445 bCont = true;
449 while (bCont);
451 return bChanged;
454 bool ScOutlineArray::Remove( SCCOLROW nBlockStart, SCCOLROW nBlockEnd, bool& rSizeChanged )
456 size_t nLevel;
457 FindTouchedLevel( nBlockStart, nBlockEnd, nLevel );
459 ScOutlineCollection* pCollect = &aCollections[nLevel];
460 ScOutlineCollection::iterator it = pCollect->begin(), itEnd = pCollect->end();
461 bool bAny = false;
462 while (it != itEnd)
464 ScOutlineEntry* pEntry = it->second;
465 SCCOLROW nStart = pEntry->GetStart();
466 SCCOLROW nEnd = pEntry->GetEnd();
467 if (nBlockStart <= nEnd && nBlockEnd >= nStart)
469 // Overlaps
470 pCollect->erase(it);
471 PromoteSub( nStart, nEnd, nLevel+1 );
472 itEnd = pCollect->end();
473 it = pCollect->FindStart( nEnd+1 );
474 bAny = true;
476 else
477 ++it;
480 if (bAny) // Adapt Depth
481 if (DecDepth())
482 rSizeChanged = true;
484 return bAny;
487 ScOutlineEntry* ScOutlineArray::GetEntry(size_t nLevel, size_t nIndex)
489 if (nLevel >= nDepth)
490 return NULL;
492 ScOutlineCollection& rColl = aCollections[nLevel];
493 if (nIndex >= rColl.size())
494 return NULL;
496 ScOutlineCollection::iterator it = rColl.begin();
497 std::advance(it, nIndex);
498 return it->second;
501 const ScOutlineEntry* ScOutlineArray::GetEntry(size_t nLevel, size_t nIndex) const
503 if (nLevel >= nDepth)
504 return NULL;
506 const ScOutlineCollection& rColl = aCollections[nLevel];
507 if (nIndex >= rColl.size())
508 return NULL;
510 ScOutlineCollection::const_iterator it = rColl.begin();
511 std::advance(it, nIndex);
512 return it->second;
515 size_t ScOutlineArray::GetCount(size_t nLevel) const
517 if (nLevel >= nDepth)
518 return 0;
520 return aCollections[nLevel].size();
523 const ScOutlineEntry* ScOutlineArray::GetEntryByPos(size_t nLevel, SCCOLROW nPos) const
525 if (nLevel >= nDepth)
526 return NULL;
528 const ScOutlineCollection& rColl = aCollections[nLevel];
529 ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
530 for (; it != itEnd; ++it)
532 const ScOutlineEntry* pEntry = it->second;
533 if (pEntry->GetStart() <= nPos && nPos <= pEntry->GetEnd())
534 return pEntry;
537 return NULL;
540 bool ScOutlineArray::GetEntryIndex(size_t nLevel, SCCOLROW nPos, size_t& rnIndex) const
542 if (nLevel >= nDepth)
543 return false;
545 // Found entry contains passed position
546 const ScOutlineCollection& rColl = aCollections[nLevel];
547 ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
548 for (; it != itEnd; ++it)
550 const ScOutlineEntry* p = it->second;
551 if (p->GetStart() <= nPos && nPos <= p->GetEnd())
553 rnIndex = std::distance(rColl.begin(), it);
554 return true;
557 return false;
560 bool ScOutlineArray::GetEntryIndexInRange(
561 size_t nLevel, SCCOLROW nBlockStart, SCCOLROW nBlockEnd, size_t& rnIndex) const
563 if (nLevel >= nDepth)
564 return false;
566 // Found entry will be completely inside of passed range
567 const ScOutlineCollection& rColl = aCollections[nLevel];
568 ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
569 for (; it != itEnd; ++it)
571 const ScOutlineEntry* p = it->second;
572 if (nBlockStart <= p->GetStart() && p->GetEnd() <= nBlockEnd)
574 rnIndex = std::distance(rColl.begin(), it);
575 return true;
578 return false;
581 void ScOutlineArray::SetVisibleBelow(
582 size_t nLevel, size_t nEntry, bool bValue, bool bSkipHidden)
584 const ScOutlineEntry* pEntry = GetEntry( nLevel, nEntry );
585 if (!pEntry)
586 return;
588 SCCOLROW nStart = pEntry->GetStart();
589 SCCOLROW nEnd = pEntry->GetEnd();
591 for (size_t nSubLevel = nLevel+1; nSubLevel < nDepth; ++nSubLevel)
593 ScOutlineCollection& rColl = aCollections[nSubLevel];
594 ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
595 for (; it != itEnd; ++it)
597 ScOutlineEntry* p = it->second;
598 if (p->GetStart() >= nStart && p->GetEnd() <= nEnd)
600 p->SetVisible(bValue);
601 if (bSkipHidden && !p->IsHidden())
603 size_t nPos = std::distance(rColl.begin(), it);
604 SetVisibleBelow(nSubLevel, nPos, bValue, true);
609 if (bSkipHidden)
610 nSubLevel = nDepth; // Bail out
614 void ScOutlineArray::GetRange(SCCOLROW& rStart, SCCOLROW& rEnd) const
616 const ScOutlineCollection& rColl = aCollections[0];
617 if (!rColl.empty())
619 ScOutlineCollection::const_iterator it = rColl.begin();
620 rStart = it->second->GetStart();
621 std::advance(it, rColl.size()-1);
622 rEnd = it->second->GetEnd();
624 else
625 rStart = rEnd = 0;
628 void ScOutlineArray::ExtendBlock(size_t nLevel, SCCOLROW& rBlkStart, SCCOLROW& rBlkEnd)
630 if (nLevel >= nDepth)
631 return;
633 const ScOutlineCollection& rColl = aCollections[nLevel];
634 ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
635 for (; it != itEnd; ++it)
637 const ScOutlineEntry* pEntry = it->second;
638 SCCOLROW nStart = pEntry->GetStart();
639 SCCOLROW nEnd = pEntry->GetEnd();
641 if (rBlkStart <= nEnd && rBlkEnd >= nStart)
643 if (nStart < rBlkStart)
644 rBlkStart = nStart;
645 if (nEnd > rBlkEnd)
646 rBlkEnd = nEnd;
651 bool ScOutlineArray::TestInsertSpace(SCSIZE nSize, SCCOLROW nMaxVal) const
653 const ScOutlineCollection& rColl = aCollections[0];
654 if (rColl.empty())
655 return true;
657 ScOutlineCollection::const_iterator it = rColl.begin();
658 std::advance(it, rColl.size()-1);
659 SCCOLROW nEnd = it->second->GetEnd();
660 return sal::static_int_cast<SCCOLROW>(nEnd+nSize) <= nMaxVal;
663 void ScOutlineArray::InsertSpace(SCCOLROW nStartPos, SCSIZE nSize)
665 ScSubOutlineIterator aIter( this );
666 ScOutlineEntry* pEntry;
667 while ((pEntry = aIter.GetNext()) != NULL)
669 if ( pEntry->GetStart() >= nStartPos )
670 pEntry->Move(static_cast<SCsCOLROW>(nSize));
671 else
673 SCCOLROW nEnd = pEntry->GetEnd();
674 // Always expand if inserted within the group
675 // When inserting at the end, only if the group is not hidden
676 if ( nEnd >= nStartPos || ( nEnd+1 >= nStartPos && !pEntry->IsHidden() ) )
678 SCSIZE nEntrySize = pEntry->GetSize();
679 nEntrySize += nSize;
680 pEntry->SetSize( nEntrySize );
686 bool ScOutlineArray::DeleteSpace(SCCOLROW nStartPos, SCSIZE nSize)
688 SCCOLROW nEndPos = nStartPos + nSize - 1;
689 bool bNeedSave = false; // Do we need the original one for Undo?
690 bool bChanged = false; // For Level test
692 ScSubOutlineIterator aIter( this );
693 ScOutlineEntry* pEntry;
694 while((pEntry=aIter.GetNext())!=NULL)
696 SCCOLROW nEntryStart = pEntry->GetStart();
697 SCCOLROW nEntryEnd = pEntry->GetEnd();
698 SCSIZE nEntrySize = pEntry->GetSize();
700 if ( nEntryEnd >= nStartPos )
702 if ( nEntryStart > nEndPos ) // Right
703 pEntry->Move(-(static_cast<SCsCOLROW>(nSize)));
704 else if ( nEntryStart < nStartPos && nEntryEnd >= nEndPos ) // Outside
705 pEntry->SetSize( nEntrySize-nSize );
706 else
708 bNeedSave = true;
709 if ( nEntryStart >= nStartPos && nEntryEnd <= nEndPos ) // Inside
711 aIter.DeleteLast();
712 bChanged = true;
714 else if ( nEntryStart >= nStartPos ) // Top right
715 pEntry->SetPosSize( nStartPos, static_cast<SCSIZE>(nEntryEnd-nEndPos) );
716 else // Top left
717 pEntry->SetSize( static_cast<SCSIZE>(nStartPos-nEntryStart) );
722 if (bChanged)
723 DecDepth();
725 return bNeedSave;
728 bool ScOutlineArray::ManualAction(
729 SCCOLROW nStartPos, SCCOLROW nEndPos, bool bShow, const ScTable& rTable, bool bCol)
731 bool bModified = false;
732 ScSubOutlineIterator aIter( this );
733 ScOutlineEntry* pEntry;
734 while((pEntry=aIter.GetNext())!=NULL)
736 SCCOLROW nEntryStart = pEntry->GetStart();
737 SCCOLROW nEntryEnd = pEntry->GetEnd();
739 if (nEntryEnd>=nStartPos && nEntryStart<=nEndPos)
741 if ( pEntry->IsHidden() == bShow )
743 // #i12341# hide if all columns/rows are hidden, show if at least one
744 // is visible
745 SCCOLROW nEnd = rTable.LastHiddenColRow(nEntryStart, bCol);
746 bool bAllHidden = (nEntryEnd <= nEnd && nEnd <
747 ::std::numeric_limits<SCCOLROW>::max());
749 bool bToggle = ( bShow != bAllHidden );
750 if ( bToggle )
752 pEntry->SetHidden( !bShow );
753 SetVisibleBelow( aIter.LastLevel(), aIter.LastEntry(), bShow, bShow );
754 bModified = true;
759 return bModified;
762 void ScOutlineArray::RemoveAll()
764 for (size_t nLevel = 0; nLevel < nDepth; ++nLevel)
765 aCollections[nLevel].clear();
767 nDepth = 0;
770 ScOutlineTable::ScOutlineTable()
774 ScOutlineTable::ScOutlineTable( const ScOutlineTable& rOutline ) :
775 aColOutline( rOutline.aColOutline ),
776 aRowOutline( rOutline.aRowOutline )
780 bool ScOutlineTable::TestInsertCol( SCSIZE nSize )
782 return aColOutline.TestInsertSpace( nSize, MAXCOL );
785 void ScOutlineTable::InsertCol( SCCOL nStartCol, SCSIZE nSize )
787 aColOutline.InsertSpace( nStartCol, nSize );
790 bool ScOutlineTable::DeleteCol( SCCOL nStartCol, SCSIZE nSize )
792 return aColOutline.DeleteSpace( nStartCol, nSize );
795 bool ScOutlineTable::TestInsertRow( SCSIZE nSize )
797 return aRowOutline.TestInsertSpace( nSize, MAXROW );
800 void ScOutlineTable::InsertRow( SCROW nStartRow, SCSIZE nSize )
802 aRowOutline.InsertSpace( nStartRow, nSize );
805 bool ScOutlineTable::DeleteRow( SCROW nStartRow, SCSIZE nSize )
807 return aRowOutline.DeleteSpace( nStartRow, nSize );
810 ScSubOutlineIterator::ScSubOutlineIterator( ScOutlineArray* pOutlineArray ) :
811 pArray( pOutlineArray ),
812 nStart( 0 ),
813 nEnd( SCCOLROW_MAX ), // Iterate over all of them
814 nSubLevel( 0 ),
815 nSubEntry( 0 )
817 nDepth = pArray->nDepth;
820 ScSubOutlineIterator::ScSubOutlineIterator(
821 ScOutlineArray* pOutlineArray, size_t nLevel, size_t nEntry ) :
822 pArray( pOutlineArray )
824 const ScOutlineCollection& rColl = pArray->aCollections[nLevel];
825 ScOutlineCollection::const_iterator it = rColl.begin();
826 std::advance(it, nEntry);
827 const ScOutlineEntry* pEntry = it->second;
828 nStart = pEntry->GetStart();
829 nEnd = pEntry->GetEnd();
830 nSubLevel = nLevel + 1;
831 nSubEntry = 0;
832 nDepth = pArray->nDepth;
835 ScOutlineEntry* ScSubOutlineIterator::GetNext()
837 ScOutlineEntry* pEntry = NULL;
838 bool bFound = false;
841 if (nSubLevel >= nDepth)
842 return NULL;
844 ScOutlineCollection& rColl = pArray->aCollections[nSubLevel];
845 if (nSubEntry < rColl.size())
847 ScOutlineCollection::iterator it = rColl.begin();
848 std::advance(it, nSubEntry);
849 pEntry = it->second;
851 if (pEntry->GetStart() >= nStart && pEntry->GetEnd() <= nEnd)
852 bFound = true;
854 ++nSubEntry;
856 else
858 // Go to the next sub-level
859 nSubEntry = 0;
860 ++nSubLevel;
863 while (!bFound);
864 return pEntry; // nSubLevel valid, if pEntry != 0
867 size_t ScSubOutlineIterator::LastEntry() const
869 if (nSubEntry == 0)
871 OSL_FAIL("ScSubOutlineIterator::LastEntry before GetNext");
872 return 0;
874 return nSubEntry-1;
877 void ScSubOutlineIterator::DeleteLast()
879 if (nSubLevel >= nDepth)
881 OSL_FAIL("ScSubOutlineIterator::DeleteLast after End");
882 return;
884 if (nSubEntry == 0)
886 OSL_FAIL("ScSubOutlineIterator::DeleteLast before GetNext");
887 return;
890 --nSubEntry;
891 ScOutlineCollection& rColl = pArray->aCollections[nSubLevel];
892 OSL_ASSERT(nSubEntry < rColl.size());
893 ScOutlineCollection::iterator it = rColl.begin();
894 std::advance(it, nSubEntry);
895 rColl.erase(it);
898 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */