Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / core / data / olinetab.cxx
blob4357cd89525c1626793d081a7fd4a4472d7d1794
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 //------------------------------------------------------------------------
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::GetStart() const
48 return nStart;
51 SCSIZE ScOutlineEntry::GetSize() const
53 return nSize;
56 SCCOLROW ScOutlineEntry::GetEnd() const
58 return nStart+nSize-1;
60 bool ScOutlineEntry::IsHidden() const
62 return bHidden;
65 bool ScOutlineEntry::IsVisible() const
67 return bVisible;
70 void ScOutlineEntry::Move( SCsCOLROW nDelta )
72 SCCOLROW nNewPos = nStart + nDelta;
73 if (nNewPos<0)
75 OSL_FAIL("OutlineEntry < 0");
76 nNewPos = 0;
78 nStart = nNewPos;
81 void ScOutlineEntry::SetSize( SCSIZE nNewSize )
83 if (nNewSize>0)
84 nSize = nNewSize;
85 else
87 OSL_FAIL("ScOutlineEntry Size == 0");
91 void ScOutlineEntry::SetPosSize( SCCOLROW nNewPos, SCSIZE nNewSize )
93 nStart = nNewPos;
94 SetSize( nNewSize );
97 void ScOutlineEntry::SetHidden( bool bNewHidden )
99 bHidden = bNewHidden;
102 void ScOutlineEntry::SetVisible( bool bNewVisible )
104 bVisible = bNewVisible;
107 //------------------------------------------------------------------------
109 ScOutlineCollection::ScOutlineCollection() {}
111 size_t ScOutlineCollection::size() const
113 return maEntries.size();
116 void ScOutlineCollection::clear()
118 maEntries.clear();
121 void ScOutlineCollection::insert(ScOutlineEntry* pEntry)
123 SCCOLROW nStart = pEntry->GetStart();
124 maEntries.insert(nStart, pEntry);
127 ScOutlineCollection::iterator ScOutlineCollection::begin()
129 return maEntries.begin();
132 ScOutlineCollection::iterator ScOutlineCollection::end()
134 return maEntries.end();
137 ScOutlineCollection::const_iterator ScOutlineCollection::begin() const
139 return maEntries.begin();
142 ScOutlineCollection::const_iterator ScOutlineCollection::end() const
144 return maEntries.end();
147 void ScOutlineCollection::erase(iterator pos)
149 maEntries.erase(pos);
152 bool ScOutlineCollection::empty() const
154 return maEntries.empty();
157 ScOutlineCollection::iterator ScOutlineCollection::FindStart(SCCOLROW nMinStart)
159 return maEntries.lower_bound(nMinStart);
162 //------------------------------------------------------------------------
164 ScOutlineArray::ScOutlineArray() :
165 nDepth(0) {}
167 ScOutlineArray::ScOutlineArray( const ScOutlineArray& rArray ) :
168 nDepth( rArray.nDepth )
170 for (size_t nLevel = 0; nLevel < nDepth; ++nLevel)
172 const ScOutlineCollection& rColl = rArray.aCollections[nLevel];
173 ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
174 for (; it != itEnd; ++it)
176 const ScOutlineEntry* pEntry = it->second;
177 aCollections[nLevel].insert(new ScOutlineEntry(*pEntry));
182 void ScOutlineArray::FindEntry(
183 SCCOLROW nSearchPos, size_t& rFindLevel, size_t& rFindIndex,
184 size_t nMaxLevel )
186 rFindLevel = rFindIndex = 0;
188 if (nMaxLevel > nDepth)
189 nMaxLevel = nDepth;
191 for (size_t nLevel = 0; nLevel < nMaxLevel; ++nLevel) //! rueckwaerts suchen ?
193 ScOutlineCollection* pCollect = &aCollections[nLevel];
194 ScOutlineCollection::iterator it = pCollect->begin(), itEnd = pCollect->end();
195 for (; it != itEnd; ++it)
197 ScOutlineEntry* pEntry = it->second;
198 if (pEntry->GetStart() <= nSearchPos && pEntry->GetEnd() >= nSearchPos)
200 rFindLevel = nLevel + 1; // naechster Level (zum Einfuegen)
201 rFindIndex = std::distance(pCollect->begin(), it);
207 bool ScOutlineArray::Insert(
208 SCCOLROW nStartCol, SCCOLROW nEndCol, bool& rSizeChanged, bool bHidden, bool bVisible )
210 rSizeChanged = false;
212 size_t nStartLevel, nEndLevel, nStartIndex, nEndIndex;
213 bool bFound = false;
215 bool bCont;
216 sal_uInt16 nFindMax;
217 FindEntry( nStartCol, nStartLevel, nStartIndex ); // nLevel = neuer Level (alter+1) !!!
218 FindEntry( nEndCol, nEndLevel, nEndIndex );
219 nFindMax = std::max(nStartLevel,nEndLevel);
222 bCont = false;
224 if (nStartLevel == nEndLevel && nStartIndex == nEndIndex && nStartLevel < SC_OL_MAXDEPTH)
225 bFound = true;
227 if (!bFound)
229 if (nFindMax>0)
231 --nFindMax;
232 if (nStartLevel)
234 ScOutlineCollection::const_iterator it = aCollections[nStartLevel-1].begin();
235 std::advance(it, nStartIndex);
236 if (it->second->GetStart() == nStartCol)
237 FindEntry(nStartCol, nStartLevel, nStartIndex, nFindMax);
240 if (nEndLevel)
242 ScOutlineCollection::const_iterator it = aCollections[nEndLevel-1].begin();
243 std::advance(it, nEndIndex);
244 if (it->second->GetEnd() == nEndCol)
245 FindEntry(nEndCol, nEndLevel, nEndIndex, nFindMax);
247 bCont = true;
251 while ( !bFound && bCont );
253 if (!bFound)
254 return false;
256 size_t nLevel = nStartLevel;
258 // untere verschieben
260 bool bNeedSize = false;
261 if (nDepth > 0)
263 for (size_t nMoveLevel = nDepth-1; nMoveLevel >= nLevel; --nMoveLevel)
265 ScOutlineCollection& rColl = aCollections[nMoveLevel];
266 ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
267 while (it != itEnd)
269 ScOutlineEntry* pEntry = it->second;
270 SCCOLROW nEntryStart = pEntry->GetStart();
271 if (nEntryStart >= nStartCol && nEntryStart <= nEndCol)
273 if (nMoveLevel >= SC_OL_MAXDEPTH - 1)
275 rSizeChanged = false; // kein Platz
276 return false;
278 aCollections[nMoveLevel+1].insert(new ScOutlineEntry(*pEntry));
279 size_t nPos = std::distance(rColl.begin(), it);
280 rColl.erase(it);
281 it = rColl.begin();
282 std::advance(it, nPos);
283 itEnd = rColl.end();
284 if (nMoveLevel == nDepth - 1)
285 bNeedSize = true;
287 else
288 ++it;
290 if (nMoveLevel == 0)
291 break;
295 if (bNeedSize)
297 ++nDepth;
298 rSizeChanged = true;
301 if (nDepth <= nLevel)
303 nDepth = nLevel+1;
304 rSizeChanged = true;
307 ScOutlineEntry* pNewEntry = new ScOutlineEntry( nStartCol, nEndCol+1-nStartCol, bHidden );
308 pNewEntry->SetVisible( bVisible );
309 aCollections[nLevel].insert(pNewEntry);
311 return true;
314 size_t ScOutlineArray::GetDepth() const
316 return nDepth;
319 bool ScOutlineArray::FindTouchedLevel(
320 SCCOLROW nBlockStart, SCCOLROW nBlockEnd, size_t& rFindLevel) const
322 bool bFound = false;
323 rFindLevel = 0;
325 for (size_t nLevel = 0; nLevel < nDepth; ++nLevel)
327 const ScOutlineCollection* pCollect = &aCollections[nLevel];
328 ScOutlineCollection::const_iterator it = pCollect->begin(), itEnd = pCollect->end();
329 for (; it != itEnd; ++it)
331 const ScOutlineEntry* pEntry = it->second;
332 SCCOLROW nStart = pEntry->GetStart();
333 SCCOLROW nEnd = pEntry->GetEnd();
335 if ( ( nBlockStart>=nStart && nBlockStart<=nEnd ) ||
336 ( nBlockEnd >=nStart && nBlockEnd <=nEnd ) )
338 rFindLevel = nLevel; // wirklicher Level
339 bFound = true;
344 return bFound;
347 void ScOutlineArray::RemoveSub(SCCOLROW nStartPos, SCCOLROW nEndPos, size_t nLevel)
349 if ( nLevel >= nDepth )
350 return;
352 ScOutlineCollection& rColl = aCollections[nLevel];
354 ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
355 while (it != itEnd)
357 ScOutlineEntry* pEntry = it->second;
358 SCCOLROW nStart = pEntry->GetStart();
359 SCCOLROW nEnd = pEntry->GetEnd();
360 if (nStart >= nStartPos && nEnd <= nEndPos)
362 // Overlaps.
363 RemoveSub( nStart, nEnd, nLevel+1 );
365 // Re-calc iterator positions after the tree gets invalidated.
366 size_t nPos = std::distance(rColl.begin(), it);
367 rColl.erase(it);
368 it = rColl.begin();
369 std::advance(it, nPos);
370 itEnd = rColl.end();
372 else
373 ++it;
376 it = rColl.begin();
377 itEnd = rColl.end();
379 while (it != itEnd)
381 ScOutlineEntry* pEntry = it->second;
382 SCCOLROW nStart = pEntry->GetStart();
383 SCCOLROW nEnd = pEntry->GetEnd();
385 if (nStart >= nStartPos && nEnd <= nEndPos)
387 RemoveSub( nStart, nEnd, nLevel+1 );
389 // Re-calc iterator positions after the tree gets invalidated.
390 size_t nPos = std::distance(rColl.begin(), it);
391 rColl.erase(it);
392 it = rColl.begin();
393 std::advance(it, nPos);
394 itEnd = rColl.end();
396 else
397 ++it;
401 void ScOutlineArray::PromoteSub(SCCOLROW nStartPos, SCCOLROW nEndPos, size_t nStartLevel)
403 if (nStartLevel==0)
405 OSL_FAIL("PromoteSub mit Level 0");
406 return;
409 for (size_t nLevel = nStartLevel; nLevel < nDepth; ++nLevel)
411 ScOutlineCollection& rColl = aCollections[nLevel];
412 ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
413 while (it != itEnd)
415 ScOutlineEntry* pEntry = it->second;
416 SCCOLROW nStart = pEntry->GetStart();
417 SCCOLROW nEnd = pEntry->GetEnd();
418 if (nStart >= nStartPos && nEnd <= nEndPos)
420 aCollections[nLevel-1].insert(new ScOutlineEntry(*pEntry));
422 // Re-calc iterator positions after the tree gets invalidated.
423 size_t nPos = std::distance(rColl.begin(), it);
424 rColl.erase(it);
425 it = rColl.begin();
426 std::advance(it, nPos);
427 itEnd = rColl.end();
429 else
430 ++it;
433 it = rColl.begin();
434 itEnd = rColl.end();
436 while (it != itEnd)
438 ScOutlineEntry* pEntry = it->second;
439 SCCOLROW nStart = pEntry->GetStart();
440 SCCOLROW nEnd = pEntry->GetEnd();
441 if (nStart >= nStartPos && nEnd <= nEndPos)
443 aCollections[nLevel-1].insert(new ScOutlineEntry(*pEntry));
445 // Re-calc iterator positions after the tree gets invalidated.
446 size_t nPos = std::distance(rColl.begin(), it);
447 rColl.erase(it);
448 it = rColl.begin();
449 std::advance(it, nPos);
450 itEnd = rColl.end();
452 else
453 ++it;
458 bool ScOutlineArray::DecDepth() // nDepth auf leere Levels anpassen
460 bool bChanged = false;
461 bool bCont;
464 bCont = false;
465 if (nDepth)
467 if (aCollections[nDepth-1].empty())
469 --nDepth;
470 bChanged = true;
471 bCont = true;
475 while (bCont);
477 return bChanged;
480 bool ScOutlineArray::Remove( SCCOLROW nBlockStart, SCCOLROW nBlockEnd, bool& rSizeChanged )
482 size_t nLevel;
483 FindTouchedLevel( nBlockStart, nBlockEnd, nLevel );
485 ScOutlineCollection* pCollect = &aCollections[nLevel];
486 ScOutlineCollection::iterator it = pCollect->begin(), itEnd = pCollect->end();
487 bool bAny = false;
488 while (it != itEnd)
490 ScOutlineEntry* pEntry = it->second;
491 SCCOLROW nStart = pEntry->GetStart();
492 SCCOLROW nEnd = pEntry->GetEnd();
493 if (nBlockStart <= nEnd && nBlockEnd >= nStart)
495 // Overlaps.
496 pCollect->erase(it);
497 PromoteSub( nStart, nEnd, nLevel+1 );
498 itEnd = pCollect->end();
499 it = pCollect->FindStart( nEnd+1 );
500 bAny = true;
502 else
503 ++it;
506 if (bAny) // Depth anpassen
507 if (DecDepth())
508 rSizeChanged = true;
510 return bAny;
513 ScOutlineEntry* ScOutlineArray::GetEntry(size_t nLevel, size_t nIndex)
515 if (nLevel >= nDepth)
516 return NULL;
518 ScOutlineCollection& rColl = aCollections[nLevel];
519 if (nIndex >= rColl.size())
520 return NULL;
522 ScOutlineCollection::iterator it = rColl.begin();
523 std::advance(it, nIndex);
524 return it->second;
527 const ScOutlineEntry* ScOutlineArray::GetEntry(size_t nLevel, size_t nIndex) const
529 if (nLevel >= nDepth)
530 return NULL;
532 const ScOutlineCollection& rColl = aCollections[nLevel];
533 if (nIndex >= rColl.size())
534 return NULL;
536 ScOutlineCollection::const_iterator it = rColl.begin();
537 std::advance(it, nIndex);
538 return it->second;
541 size_t ScOutlineArray::GetCount(size_t nLevel) const
543 if (nLevel >= nDepth)
544 return 0;
546 return aCollections[nLevel].size();
549 const ScOutlineEntry* ScOutlineArray::GetEntryByPos(size_t nLevel, SCCOLROW nPos) const
551 if (nLevel >= nDepth)
552 return NULL;
554 const ScOutlineCollection& rColl = aCollections[nLevel];
555 ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
556 for (; it != itEnd; ++it)
558 const ScOutlineEntry* pEntry = it->second;
559 if (pEntry->GetStart() <= nPos && nPos <= pEntry->GetEnd())
560 return pEntry;
563 return NULL;
566 bool ScOutlineArray::GetEntryIndex(size_t nLevel, SCCOLROW nPos, size_t& rnIndex) const
568 if (nLevel >= nDepth)
569 return false;
571 // found entry contains passed position
572 const ScOutlineCollection& rColl = aCollections[nLevel];
573 ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
574 for (; it != itEnd; ++it)
576 const ScOutlineEntry* p = it->second;
577 if (p->GetStart() <= nPos && nPos <= p->GetEnd())
579 rnIndex = std::distance(rColl.begin(), it);
580 return true;
583 return false;
586 bool ScOutlineArray::GetEntryIndexInRange(
587 size_t nLevel, SCCOLROW nBlockStart, SCCOLROW nBlockEnd, size_t& rnIndex) const
589 if (nLevel >= nDepth)
590 return false;
592 // found entry will be completely inside of passed range
593 const ScOutlineCollection& rColl = aCollections[nLevel];
594 ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
595 for (; it != itEnd; ++it)
597 const ScOutlineEntry* p = it->second;
598 if (nBlockStart <= p->GetStart() && p->GetEnd() <= nBlockEnd)
600 rnIndex = std::distance(rColl.begin(), it);
601 return true;
604 return false;
607 void ScOutlineArray::SetVisibleBelow(
608 size_t nLevel, size_t nEntry, bool bValue, bool bSkipHidden)
610 const ScOutlineEntry* pEntry = GetEntry( nLevel, nEntry );
611 if (!pEntry)
612 return;
614 SCCOLROW nStart = pEntry->GetStart();
615 SCCOLROW nEnd = pEntry->GetEnd();
617 for (size_t nSubLevel = nLevel+1; nSubLevel < nDepth; ++nSubLevel)
619 ScOutlineCollection& rColl = aCollections[nSubLevel];
620 ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
621 for (; it != itEnd; ++it)
623 ScOutlineEntry* p = it->second;
624 if (p->GetStart() >= nStart && p->GetEnd() <= nEnd)
626 p->SetVisible(bValue);
627 if (bSkipHidden && !p->IsHidden())
629 size_t nPos = std::distance(rColl.begin(), it);
630 SetVisibleBelow(nSubLevel, nPos, bValue, true);
635 if (bSkipHidden)
636 nSubLevel = nDepth; // Abbruch
640 void ScOutlineArray::GetRange(SCCOLROW& rStart, SCCOLROW& rEnd) const
642 const ScOutlineCollection& rColl = aCollections[0];
643 if (!rColl.empty())
645 ScOutlineCollection::const_iterator it = rColl.begin();
646 rStart = it->second->GetStart();
647 std::advance(it, rColl.size()-1);
648 rEnd = it->second->GetEnd();
650 else
651 rStart = rEnd = 0;
654 void ScOutlineArray::ExtendBlock(size_t nLevel, SCCOLROW& rBlkStart, SCCOLROW& rBlkEnd)
656 if (nLevel >= nDepth)
657 return;
659 const ScOutlineCollection& rColl = aCollections[nLevel];
660 ScOutlineCollection::const_iterator it = rColl.begin(), itEnd = rColl.end();
661 for (; it != itEnd; ++it)
663 const ScOutlineEntry* pEntry = it->second;
664 SCCOLROW nStart = pEntry->GetStart();
665 SCCOLROW nEnd = pEntry->GetEnd();
667 if (rBlkStart <= nEnd && rBlkEnd >= nStart)
669 if (nStart < rBlkStart)
670 rBlkStart = nStart;
671 if (nEnd > rBlkEnd)
672 rBlkEnd = nEnd;
677 bool ScOutlineArray::TestInsertSpace(SCSIZE nSize, SCCOLROW nMaxVal) const
679 const ScOutlineCollection& rColl = aCollections[0];
680 if (rColl.empty())
681 return true;
683 ScOutlineCollection::const_iterator it = rColl.begin();
684 std::advance(it, rColl.size()-1);
685 SCCOLROW nEnd = it->second->GetEnd();
686 return sal::static_int_cast<SCCOLROW>(nEnd+nSize) <= nMaxVal;
689 void ScOutlineArray::InsertSpace(SCCOLROW nStartPos, SCSIZE nSize)
691 ScSubOutlineIterator aIter( this );
692 ScOutlineEntry* pEntry;
693 while ((pEntry = aIter.GetNext()) != NULL)
695 if ( pEntry->GetStart() >= nStartPos )
696 pEntry->Move(static_cast<SCsCOLROW>(nSize));
697 else
699 SCCOLROW nEnd = pEntry->GetEnd();
700 // immer erweitern, wenn innerhalb der Gruppe eingefuegt
701 // beim Einfuegen am Ende nur, wenn die Gruppe nicht ausgeblendet ist
702 if ( nEnd >= nStartPos || ( nEnd+1 >= nStartPos && !pEntry->IsHidden() ) )
704 SCSIZE nEntrySize = pEntry->GetSize();
705 nEntrySize += nSize;
706 pEntry->SetSize( nEntrySize );
712 bool ScOutlineArray::DeleteSpace(SCCOLROW nStartPos, SCSIZE nSize)
714 SCCOLROW nEndPos = nStartPos + nSize - 1;
715 sal_Bool bNeedSave = false; // Original fuer Undo benoetigt?
716 sal_Bool bChanged = false; // fuer Test auf Level
718 ScSubOutlineIterator aIter( this );
719 ScOutlineEntry* pEntry;
720 while((pEntry=aIter.GetNext())!=NULL)
722 SCCOLROW nEntryStart = pEntry->GetStart();
723 SCCOLROW nEntryEnd = pEntry->GetEnd();
724 SCSIZE nEntrySize = pEntry->GetSize();
726 if ( nEntryEnd >= nStartPos )
728 if ( nEntryStart > nEndPos ) // rechts
729 pEntry->Move(-(static_cast<SCsCOLROW>(nSize)));
730 else if ( nEntryStart < nStartPos && nEntryEnd >= nEndPos ) // aussen
731 pEntry->SetSize( nEntrySize-nSize );
732 else
734 bNeedSave = true;
735 if ( nEntryStart >= nStartPos && nEntryEnd <= nEndPos ) // innen
737 aIter.DeleteLast();
738 bChanged = true;
740 else if ( nEntryStart >= nStartPos ) // rechts ueber
741 pEntry->SetPosSize( nStartPos, static_cast<SCSIZE>(nEntryEnd-nEndPos) );
742 else // links ueber
743 pEntry->SetSize( static_cast<SCSIZE>(nStartPos-nEntryStart) );
748 if (bChanged)
749 DecDepth();
751 return bNeedSave;
754 bool ScOutlineArray::ManualAction(
755 SCCOLROW nStartPos, SCCOLROW nEndPos, bool bShow, const ScTable& rTable, bool bCol)
757 bool bModified = false;
758 ScSubOutlineIterator aIter( this );
759 ScOutlineEntry* pEntry;
760 while((pEntry=aIter.GetNext())!=NULL)
762 SCCOLROW nEntryStart = pEntry->GetStart();
763 SCCOLROW nEntryEnd = pEntry->GetEnd();
765 if (nEntryEnd>=nStartPos && nEntryStart<=nEndPos)
767 if ( pEntry->IsHidden() == bShow )
769 // #i12341# hide if all columns/rows are hidden, show if at least one
770 // is visible
771 SCCOLROW nEnd = rTable.LastHiddenColRow(nEntryStart, bCol);
772 bool bAllHidden = (nEntryEnd <= nEnd && nEnd <
773 ::std::numeric_limits<SCCOLROW>::max());
775 bool bToggle = ( bShow != bAllHidden );
776 if ( bToggle )
778 pEntry->SetHidden( !bShow );
779 SetVisibleBelow( aIter.LastLevel(), aIter.LastEntry(), bShow, bShow );
780 bModified = true;
785 return bModified;
788 void ScOutlineArray::RemoveAll()
790 for (size_t nLevel = 0; nLevel < nDepth; ++nLevel)
791 aCollections[nLevel].clear();
793 nDepth = 0;
796 //------------------------------------------------------------------------
798 ScOutlineTable::ScOutlineTable()
802 ScOutlineTable::ScOutlineTable( const ScOutlineTable& rOutline ) :
803 aColOutline( rOutline.aColOutline ),
804 aRowOutline( rOutline.aRowOutline )
808 sal_Bool ScOutlineTable::TestInsertCol( SCSIZE nSize )
810 return aColOutline.TestInsertSpace( nSize, MAXCOL );
813 void ScOutlineTable::InsertCol( SCCOL nStartCol, SCSIZE nSize )
815 aColOutline.InsertSpace( nStartCol, nSize );
818 sal_Bool ScOutlineTable::DeleteCol( SCCOL nStartCol, SCSIZE nSize )
820 return aColOutline.DeleteSpace( nStartCol, nSize );
823 sal_Bool ScOutlineTable::TestInsertRow( SCSIZE nSize )
825 return aRowOutline.TestInsertSpace( nSize, MAXROW );
828 void ScOutlineTable::InsertRow( SCROW nStartRow, SCSIZE nSize )
830 aRowOutline.InsertSpace( nStartRow, nSize );
833 sal_Bool ScOutlineTable::DeleteRow( SCROW nStartRow, SCSIZE nSize )
835 return aRowOutline.DeleteSpace( nStartRow, nSize );
838 //------------------------------------------------------------------------
840 ScSubOutlineIterator::ScSubOutlineIterator( ScOutlineArray* pOutlineArray ) :
841 pArray( pOutlineArray ),
842 nStart( 0 ),
843 nEnd( SCCOLROW_MAX ), // alle durchgehen
844 nSubLevel( 0 ),
845 nSubEntry( 0 )
847 nDepth = pArray->nDepth;
850 ScSubOutlineIterator::ScSubOutlineIterator(
851 ScOutlineArray* pOutlineArray, size_t nLevel, size_t nEntry ) :
852 pArray( pOutlineArray )
854 const ScOutlineCollection& rColl = pArray->aCollections[nLevel];
855 ScOutlineCollection::const_iterator it = rColl.begin();
856 std::advance(it, nEntry);
857 const ScOutlineEntry* pEntry = it->second;
858 nStart = pEntry->GetStart();
859 nEnd = pEntry->GetEnd();
860 nSubLevel = nLevel + 1;
861 nSubEntry = 0;
862 nDepth = pArray->nDepth;
865 ScOutlineEntry* ScSubOutlineIterator::GetNext()
867 ScOutlineEntry* pEntry = NULL;
868 bool bFound = false;
871 if (nSubLevel >= nDepth)
872 return NULL;
874 ScOutlineCollection& rColl = pArray->aCollections[nSubLevel];
875 if (nSubEntry < rColl.size())
877 ScOutlineCollection::iterator it = rColl.begin();
878 std::advance(it, nSubEntry);
879 pEntry = it->second;
881 if (pEntry->GetStart() >= nStart && pEntry->GetEnd() <= nEnd)
882 bFound = true;
884 ++nSubEntry;
886 else
888 // Go to the next sub-level.
889 nSubEntry = 0;
890 ++nSubLevel;
893 while (!bFound);
894 return pEntry; // nSubLevel gueltig, wenn pEntry != 0
897 size_t ScSubOutlineIterator::LastLevel() const
899 return nSubLevel;
902 size_t ScSubOutlineIterator::LastEntry() const
904 if (nSubEntry == 0)
906 OSL_FAIL("ScSubOutlineIterator::LastEntry before GetNext");
907 return 0;
909 return nSubEntry-1;
912 void ScSubOutlineIterator::DeleteLast()
914 if (nSubLevel >= nDepth)
916 OSL_FAIL("ScSubOutlineIterator::DeleteLast after End");
917 return;
919 if (nSubEntry == 0)
921 OSL_FAIL("ScSubOutlineIterator::DeleteLast before GetNext");
922 return;
925 --nSubEntry;
926 ScOutlineCollection& rColl = pArray->aCollections[nSubLevel];
927 OSL_ASSERT(nSubEntry < rColl.size());
928 ScOutlineCollection::iterator it = rColl.begin();
929 std::advance(it, nSubEntry);
930 rColl.erase(it);
934 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */