Update ooo320-m1
[ooovba.git] / sc / source / core / data / olinetab.cxx
blobcc4f7f6702c28166ae2166511beb2287db5ffbdb
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: olinetab.cxx,v $
10 * $Revision: 1.10.32.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 // System - Includes -----------------------------------------------------
38 #include <tools/debug.hxx>
39 #include <limits.h>
41 // INCLUDE ---------------------------------------------------------------
43 #include "olinetab.hxx"
44 #include "global.hxx"
45 #include "rechead.hxx"
46 #include "address.hxx"
47 #include "table.hxx"
49 //------------------------------------------------------------------------
51 ScOutlineEntry::ScOutlineEntry( SCCOLROW nNewStart, SCCOLROW nNewSize, BOOL bNewHidden ) :
52 nStart ( nNewStart ),
53 nSize ( nNewSize ),
54 bHidden ( bNewHidden ),
55 bVisible( TRUE )
59 ScOutlineEntry::ScOutlineEntry( const ScOutlineEntry& rEntry ) :
60 ScDataObject(),
61 nStart ( rEntry.nStart ),
62 nSize ( rEntry.nSize ),
63 bHidden ( rEntry.bHidden ),
64 bVisible( rEntry.bVisible )
68 ScDataObject* ScOutlineEntry::Clone() const
70 return new ScOutlineEntry( *this );
73 void ScOutlineEntry::Move( SCsCOLROW nDelta )
75 SCCOLROW nNewPos = nStart + nDelta;
76 if (nNewPos<0)
78 DBG_ERROR("OutlineEntry < 0");
79 nNewPos = 0;
81 nStart = nNewPos;
84 void ScOutlineEntry::SetSize( SCSIZE nNewSize )
86 if (nNewSize>0)
87 nSize = nNewSize;
88 else
90 DBG_ERROR("ScOutlineEntry Size == 0");
94 void ScOutlineEntry::SetPosSize( SCCOLROW nNewPos, SCSIZE nNewSize )
96 nStart = nNewPos;
97 SetSize( nNewSize );
100 void ScOutlineEntry::SetHidden( BOOL bNewHidden )
102 bHidden = bNewHidden;
105 void ScOutlineEntry::SetVisible( BOOL bNewVisible )
107 bVisible = bNewVisible;
110 //------------------------------------------------------------------------
112 ScOutlineCollection::ScOutlineCollection() :
113 ScSortedCollection( 4,4,FALSE )
117 inline short IntCompare( SCCOLROW nX, SCCOLROW nY )
119 if ( nX==nY ) return 0;
120 else if ( nX<nY ) return -1;
121 else return 1;
124 short ScOutlineCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
126 return IntCompare( ((ScOutlineEntry*)pKey1)->GetStart(),
127 ((ScOutlineEntry*)pKey2)->GetStart() );
130 USHORT ScOutlineCollection::FindStart( SCCOLROW nMinStart )
132 //! binaer suchen ?
134 USHORT nPos = 0;
135 USHORT nLocalCount = GetCount();
136 while ( (nPos<nLocalCount) ? (((ScOutlineEntry*)At(nPos))->GetStart() < nMinStart) : FALSE )
137 ++nPos;
139 return nPos;
142 //------------------------------------------------------------------------
144 ScOutlineArray::ScOutlineArray() :
145 nDepth( 0 )
149 ScOutlineArray::ScOutlineArray( const ScOutlineArray& rArray ) :
150 nDepth( rArray.nDepth )
152 for (USHORT nLevel=0; nLevel<nDepth; nLevel++)
154 USHORT nCount = rArray.aCollections[nLevel].GetCount();
155 for (USHORT nEntry=0; nEntry<nCount; nEntry++)
157 ScOutlineEntry* pEntry = (ScOutlineEntry*) rArray.aCollections[nLevel].At(nEntry);
158 aCollections[nLevel].Insert( new ScOutlineEntry( *pEntry ) );
163 void ScOutlineArray::FindEntry( SCCOLROW nSearchPos, USHORT& rFindLevel, USHORT& rFindIndex,
164 USHORT nMaxLevel )
166 rFindLevel = rFindIndex = 0;
168 if (nMaxLevel > nDepth)
169 nMaxLevel = nDepth;
171 for (USHORT nLevel=0; nLevel<nMaxLevel; nLevel++) //! rueckwaerts suchen ?
173 ScOutlineCollection* pCollect = &aCollections[nLevel];
174 USHORT nCount = pCollect->GetCount();
175 for (USHORT i=0; i<nCount; i++)
177 ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
178 if ( pEntry->GetStart() <= nSearchPos && pEntry->GetEnd() >= nSearchPos )
180 rFindLevel = nLevel + 1; // naechster Level (zum Einfuegen)
181 rFindIndex = i;
187 BOOL ScOutlineArray::Insert( SCCOLROW nStartCol, SCCOLROW nEndCol, BOOL& rSizeChanged,
188 BOOL bHidden, BOOL bVisible )
190 rSizeChanged = FALSE;
192 USHORT nStartLevel;
193 USHORT nStartIndex;
194 USHORT nEndLevel;
195 USHORT nEndIndex;
196 BOOL bFound = FALSE;
198 BOOL bCont;
199 USHORT nFindMax;
200 FindEntry( nStartCol, nStartLevel, nStartIndex ); // nLevel = neuer Level (alter+1) !!!
201 FindEntry( nEndCol, nEndLevel, nEndIndex );
202 nFindMax = Max(nStartLevel,nEndLevel);
205 bCont = FALSE;
207 if ( nStartLevel == nEndLevel && nStartIndex == nEndIndex && nStartLevel < SC_OL_MAXDEPTH )
208 bFound = TRUE;
210 if (!bFound)
212 if (nFindMax>0)
214 --nFindMax;
215 if (nStartLevel)
216 if ( ((ScOutlineEntry*)aCollections[nStartLevel-1].At(nStartIndex))->
217 GetStart() == nStartCol )
218 FindEntry( nStartCol, nStartLevel, nStartIndex, nFindMax );
219 if (nEndLevel)
220 if ( ((ScOutlineEntry*)aCollections[nEndLevel-1].At(nEndIndex))->
221 GetEnd() == nEndCol )
222 FindEntry( nEndCol, nEndLevel, nEndIndex, nFindMax );
223 bCont = TRUE;
227 while ( !bFound && bCont );
229 if (!bFound)
230 return FALSE;
232 USHORT nLevel = nStartLevel;
234 // untere verschieben
236 BOOL bNeedSize = FALSE;
237 for ( short nMoveLevel = nDepth-1; nMoveLevel >= (short) nLevel; nMoveLevel-- )
239 USHORT nCount = aCollections[nMoveLevel].GetCount();
240 BOOL bMoved = FALSE;
241 for ( USHORT i=0; i<nCount; i += bMoved ? 0 : 1 )
243 ScOutlineEntry* pEntry = (ScOutlineEntry*) aCollections[nMoveLevel].At(i);
244 SCCOLROW nEntryStart = pEntry->GetStart();
245 if ( nEntryStart >= nStartCol && nEntryStart <= nEndCol )
247 if (nMoveLevel >= SC_OL_MAXDEPTH - 1)
249 rSizeChanged = FALSE; // kein Platz
250 return FALSE;
252 aCollections[nMoveLevel+1].Insert( new ScOutlineEntry( *pEntry ) );
253 aCollections[nMoveLevel].AtFree( i );
254 nCount = aCollections[nMoveLevel].GetCount();
255 bMoved = TRUE;
256 if (nMoveLevel == (short) nDepth - 1)
257 bNeedSize = TRUE;
259 else
260 bMoved = FALSE;
264 if (bNeedSize)
266 ++nDepth;
267 rSizeChanged = TRUE;
270 if (nDepth <= nLevel)
272 nDepth = nLevel+1;
273 rSizeChanged = TRUE;
276 /* nicht zusammenfassen!
278 // zusammenfassen
280 USHORT nCount = aCollections[nLevel].GetCount();
281 USHORT nIndex;
282 bFound = FALSE;
283 for ( nIndex=0; nIndex<nCount && !bFound; nIndex++ )
285 if ( ((ScOutlineEntry*) aCollections[nLevel].At(nIndex))->GetEnd() + 1 == nStartCol )
287 nStartCol = ((ScOutlineEntry*) aCollections[nLevel].At(nIndex))->GetStart();
288 aCollections[nLevel].AtFree(nIndex);
289 nCount = aCollections[nLevel].GetCount(); // Daten geaendert
290 bFound = TRUE;
294 bFound = FALSE;
295 for ( nIndex=0; nIndex<nCount && !bFound; nIndex++ )
297 if ( ((ScOutlineEntry*) aCollections[nLevel].At(nIndex))->GetStart() == nEndCol + 1 )
299 nEndCol = ((ScOutlineEntry*) aCollections[nLevel].At(nIndex))->GetEnd();
300 aCollections[nLevel].AtFree(nIndex);
301 bFound = TRUE;
305 ScOutlineEntry* pNewEntry = new ScOutlineEntry( nStartCol, nEndCol+1-nStartCol, bHidden );
306 pNewEntry->SetVisible( bVisible );
307 aCollections[nLevel].Insert( pNewEntry );
309 return TRUE;
312 BOOL ScOutlineArray::FindTouchedLevel( SCCOLROW nBlockStart, SCCOLROW nBlockEnd, USHORT& rFindLevel ) const
314 BOOL bFound = FALSE;
315 rFindLevel = 0;
317 for (USHORT nLevel=0; nLevel<nDepth; nLevel++)
319 const ScOutlineCollection* pCollect = &aCollections[nLevel];
320 USHORT nCount = pCollect->GetCount();
321 for (USHORT i=0; i<nCount; i++)
323 ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
324 SCCOLROW nStart = pEntry->GetStart();
325 SCCOLROW nEnd = pEntry->GetEnd();
327 if ( ( nBlockStart>=nStart && nBlockStart<=nEnd ) ||
328 ( nBlockEnd >=nStart && nBlockEnd <=nEnd ) )
330 rFindLevel = nLevel; // wirklicher Level
331 bFound = TRUE;
336 return bFound;
339 void ScOutlineArray::RemoveSub( SCCOLROW nStartPos, SCCOLROW nEndPos, USHORT nLevel )
341 if ( nLevel >= nDepth )
342 return;
343 ScOutlineCollection* pCollect = &aCollections[nLevel];
344 USHORT nCount = pCollect->GetCount();
345 BOOL bFound = FALSE;
346 for ( USHORT i=0; i<nCount; i += ( bFound ? 0 : 1 ) )
348 bFound = FALSE;
349 ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
350 SCCOLROW nStart = pEntry->GetStart();
351 SCCOLROW nEnd = pEntry->GetEnd();
353 if ( nStart>=nStartPos && nEnd<=nEndPos )
355 RemoveSub( nStart, nEnd, nLevel+1 );
356 pCollect->AtFree(i);
357 nCount = pCollect->GetCount();
358 bFound = TRUE;
363 void ScOutlineArray::PromoteSub( SCCOLROW nStartPos, SCCOLROW nEndPos, USHORT nStartLevel )
365 if (nStartLevel==0)
367 DBG_ERROR("PromoteSub mit Level 0");
368 return;
371 for (USHORT nLevel = nStartLevel; nLevel < nDepth; nLevel++)
373 ScOutlineCollection* pCollect = &aCollections[nLevel];
374 USHORT nCount = pCollect->GetCount();
375 BOOL bFound = FALSE;
376 for ( USHORT i=0; i<nCount; i += ( bFound ? 0 : 1 ) )
378 bFound = FALSE;
379 ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
380 SCCOLROW nStart = pEntry->GetStart();
381 SCCOLROW nEnd = pEntry->GetEnd();
383 if ( nStart>=nStartPos && nEnd<=nEndPos )
385 aCollections[nLevel-1].Insert( new ScOutlineEntry( *pEntry ) );
386 pCollect->AtFree(i);
387 nCount = pCollect->GetCount();
388 bFound = TRUE;
394 BOOL ScOutlineArray::DecDepth() // nDepth auf leere Levels anpassen
396 BOOL bChanged = FALSE;
397 BOOL bCont;
400 bCont = FALSE;
401 if (nDepth)
402 if (aCollections[nDepth-1].GetCount() == 0)
404 --nDepth;
405 bChanged = TRUE;
406 bCont = TRUE;
409 while (bCont);
410 return bChanged;
413 BOOL ScOutlineArray::Remove( SCCOLROW nBlockStart, SCCOLROW nBlockEnd, BOOL& rSizeChanged )
415 USHORT nLevel;
416 FindTouchedLevel( nBlockStart, nBlockEnd, nLevel );
418 ScOutlineCollection* pCollect = &aCollections[nLevel];
419 USHORT nCount = pCollect->GetCount();
420 BOOL bFound = FALSE;
421 BOOL bAny = FALSE;
422 for ( USHORT i=0; i<nCount; i += ( bFound ? 0 : 1 ) )
424 bFound = FALSE;
425 ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
426 SCCOLROW nStart = pEntry->GetStart();
427 SCCOLROW nEnd = pEntry->GetEnd();
429 if ( nBlockStart<=nEnd && nBlockEnd>=nStart )
431 // RemoveSub( nStart, nEnd, nLevel+1 );
432 pCollect->AtFree(i);
433 PromoteSub( nStart, nEnd, nLevel+1 );
434 nCount = pCollect->GetCount();
435 i = pCollect->FindStart( nEnd+1 );
436 bFound = TRUE;
437 bAny = TRUE;
441 if (bAny) // Depth anpassen
442 if (DecDepth())
443 rSizeChanged = TRUE;
445 return bAny;
448 ScOutlineEntry* ScOutlineArray::GetEntry( USHORT nLevel, USHORT nIndex ) const
450 return (ScOutlineEntry*)((nLevel < nDepth) ? aCollections[nLevel].At(nIndex) : NULL);
453 USHORT ScOutlineArray::GetCount( USHORT nLevel ) const
455 return (nLevel < nDepth) ? aCollections[nLevel].GetCount() : 0;
458 ScOutlineEntry* ScOutlineArray::GetEntryByPos( USHORT nLevel, SCCOLROW nPos ) const
460 USHORT nCount = GetCount( nLevel );
461 ScOutlineEntry* pEntry;
463 for (USHORT nIndex = 0; nIndex < nCount; nIndex++)
465 pEntry = GetEntry( nLevel, nIndex );
466 if ((pEntry->GetStart() <= nPos) && (nPos <= pEntry->GetEnd()))
467 return pEntry;
469 return NULL;
472 BOOL ScOutlineArray::GetEntryIndex( USHORT nLevel, SCCOLROW nPos, USHORT& rnIndex ) const
474 // found entry contains passed position
475 USHORT nCount = GetCount( nLevel );
476 for ( rnIndex = 0; rnIndex < nCount; ++rnIndex )
478 const ScOutlineEntry* pEntry = GetEntry( nLevel, rnIndex );
479 if ( (pEntry->GetStart() <= nPos) && (nPos <= pEntry->GetEnd()) )
480 return TRUE;
482 return FALSE;
485 BOOL ScOutlineArray::GetEntryIndexInRange(
486 USHORT nLevel, SCCOLROW nBlockStart, SCCOLROW nBlockEnd, USHORT& rnIndex ) const
488 // found entry will be completely inside of passed range
489 USHORT nCount = GetCount( nLevel );
490 for ( rnIndex = 0; rnIndex < nCount; ++rnIndex )
492 const ScOutlineEntry* pEntry = GetEntry( nLevel, rnIndex );
493 if ( (nBlockStart <= pEntry->GetStart()) && (pEntry->GetEnd() <= nBlockEnd) )
494 return TRUE;
496 return FALSE;
499 void ScOutlineArray::SetVisibleBelow( USHORT nLevel, USHORT nEntry, BOOL bValue, BOOL bSkipHidden )
501 ScOutlineEntry* pEntry = GetEntry( nLevel, nEntry );
502 if( pEntry )
504 SCCOLROW nStart = pEntry->GetStart();
505 SCCOLROW nEnd = pEntry->GetEnd();
507 for (USHORT nSubLevel=nLevel+1; nSubLevel<nDepth; nSubLevel++)
509 USHORT i = 0;
510 pEntry = (ScOutlineEntry*) aCollections[nSubLevel].At(i);
511 while (pEntry)
513 if (pEntry->GetStart() >= nStart && pEntry->GetEnd() <= nEnd)
515 pEntry->SetVisible(bValue);
517 if (bSkipHidden)
518 if (!pEntry->IsHidden())
519 SetVisibleBelow( nSubLevel, i, bValue, TRUE );
522 ++i;
523 pEntry = (ScOutlineEntry*) aCollections[nSubLevel].At(i);
526 if (bSkipHidden)
527 nSubLevel = nDepth; // Abbruch
532 void ScOutlineArray::GetRange( SCCOLROW& rStart, SCCOLROW& rEnd ) const
534 USHORT nCount = aCollections[0].GetCount();
535 if (nCount)
537 rStart = ((ScOutlineEntry*) aCollections[0].At(0))->GetStart();
538 rEnd = ((ScOutlineEntry*) aCollections[0].At(nCount-1))->GetEnd();
540 else
541 rStart = rEnd = 0;
544 void ScOutlineArray::ExtendBlock( USHORT nLevel, SCCOLROW& rBlkStart, SCCOLROW& rBlkEnd )
546 USHORT nCount;
547 SCCOLROW nStart;
548 SCCOLROW nEnd;
549 USHORT i;
550 ScOutlineEntry* pEntry;
552 nCount = GetCount(nLevel);
553 for ( i=0; i<nCount; i++ )
555 pEntry = (ScOutlineEntry*) aCollections[nLevel].At(i);
556 nStart = pEntry->GetStart();
557 nEnd = pEntry->GetEnd();
559 if ( rBlkStart<=nEnd && rBlkEnd>=nStart )
561 if (nStart<rBlkStart) rBlkStart = nStart;
562 if (nEnd>rBlkEnd) rBlkEnd = nEnd;
567 BOOL ScOutlineArray::TestInsertSpace( SCSIZE nSize, SCCOLROW nMaxVal ) const
569 USHORT nCount = aCollections[0].GetCount();
570 if (nCount)
572 SCCOLROW nEnd = ((ScOutlineEntry*) aCollections[0].At(nCount-1))->GetEnd();
573 return ( sal::static_int_cast<SCCOLROW>(nEnd+nSize) <= nMaxVal );
576 return TRUE;
579 void ScOutlineArray::InsertSpace( SCCOLROW nStartPos, SCSIZE nSize )
581 ScSubOutlineIterator aIter( this );
582 ScOutlineEntry* pEntry;
583 while((pEntry=aIter.GetNext())!=NULL)
585 if ( pEntry->GetStart() >= nStartPos )
586 pEntry->Move(static_cast<SCsCOLROW>(nSize));
587 else
589 SCCOLROW nEnd = pEntry->GetEnd();
590 // immer erweitern, wenn innerhalb der Gruppe eingefuegt
591 // beim Einfuegen am Ende nur, wenn die Gruppe nicht ausgeblendet ist
592 if ( nEnd >= nStartPos || ( nEnd+1 >= nStartPos && !pEntry->IsHidden() ) )
594 SCSIZE nEntrySize = pEntry->GetSize();
595 nEntrySize += nSize;
596 pEntry->SetSize( nEntrySize );
602 BOOL ScOutlineArray::DeleteSpace( SCCOLROW nStartPos, SCSIZE nSize )
604 SCCOLROW nEndPos = nStartPos + nSize - 1;
605 BOOL bNeedSave = FALSE; // Original fuer Undo benoetigt?
606 BOOL bChanged = FALSE; // fuer Test auf Level
608 ScSubOutlineIterator aIter( this );
609 ScOutlineEntry* pEntry;
610 while((pEntry=aIter.GetNext())!=NULL)
612 SCCOLROW nEntryStart = pEntry->GetStart();
613 SCCOLROW nEntryEnd = pEntry->GetEnd();
614 SCSIZE nEntrySize = pEntry->GetSize();
616 if ( nEntryEnd >= nStartPos )
618 if ( nEntryStart > nEndPos ) // rechts
619 pEntry->Move(-(static_cast<SCsCOLROW>(nSize)));
620 else if ( nEntryStart < nStartPos && nEntryEnd >= nEndPos ) // aussen
621 pEntry->SetSize( nEntrySize-nSize );
622 else
624 bNeedSave = TRUE;
625 if ( nEntryStart >= nStartPos && nEntryEnd <= nEndPos ) // innen
627 aIter.DeleteLast();
628 bChanged = TRUE;
630 else if ( nEntryStart >= nStartPos ) // rechts ueber
631 pEntry->SetPosSize( nStartPos, static_cast<SCSIZE>(nEntryEnd-nEndPos) );
632 else // links ueber
633 pEntry->SetSize( static_cast<SCSIZE>(nStartPos-nEntryStart) );
638 if (bChanged)
639 DecDepth();
641 return bNeedSave;
644 bool ScOutlineArray::ManualAction( SCCOLROW nStartPos, SCCOLROW nEndPos, bool bShow, ScTable& rTable, bool bCol )
646 BOOL bModified = FALSE;
647 ScSubOutlineIterator aIter( this );
648 ScOutlineEntry* pEntry;
649 while((pEntry=aIter.GetNext())!=NULL)
651 SCCOLROW nEntryStart = pEntry->GetStart();
652 SCCOLROW nEntryEnd = pEntry->GetEnd();
654 if (nEntryEnd>=nStartPos && nEntryStart<=nEndPos)
656 if ( pEntry->IsHidden() == bShow )
658 // #i12341# hide if all columns/rows are hidden, show if at least one
659 // is visible
660 SCCOLROW nEnd = rTable.LastHiddenColRow(nEntryStart, bCol);
661 BOOL bAllHidden = (nEntryEnd <= nEnd && nEnd <
662 ::std::numeric_limits<SCCOLROW>::max());
664 BOOL bToggle = ( bShow != bAllHidden );
665 if ( bToggle )
667 pEntry->SetHidden( !bShow );
668 SetVisibleBelow( aIter.LastLevel(), aIter.LastEntry(), bShow, bShow );
669 bModified = TRUE;
674 return bModified;
677 void ScOutlineArray::RemoveAll()
679 for (USHORT nLevel=0; nLevel<nDepth; nLevel++)
680 aCollections[nLevel].FreeAll();
682 nDepth = 0;
685 //------------------------------------------------------------------------
687 ScOutlineTable::ScOutlineTable()
691 ScOutlineTable::ScOutlineTable( const ScOutlineTable& rOutline ) :
692 aColOutline( rOutline.aColOutline ),
693 aRowOutline( rOutline.aRowOutline )
697 BOOL ScOutlineTable::TestInsertCol( SCSIZE nSize )
699 return aColOutline.TestInsertSpace( nSize, MAXCOL );
702 void ScOutlineTable::InsertCol( SCCOL nStartCol, SCSIZE nSize )
704 aColOutline.InsertSpace( nStartCol, nSize );
707 BOOL ScOutlineTable::DeleteCol( SCCOL nStartCol, SCSIZE nSize )
709 return aColOutline.DeleteSpace( nStartCol, nSize );
712 BOOL ScOutlineTable::TestInsertRow( SCSIZE nSize )
714 return aRowOutline.TestInsertSpace( nSize, MAXROW );
717 void ScOutlineTable::InsertRow( SCROW nStartRow, SCSIZE nSize )
719 aRowOutline.InsertSpace( nStartRow, nSize );
722 BOOL ScOutlineTable::DeleteRow( SCROW nStartRow, SCSIZE nSize )
724 return aRowOutline.DeleteSpace( nStartRow, nSize );
727 //------------------------------------------------------------------------
729 ScSubOutlineIterator::ScSubOutlineIterator( ScOutlineArray* pOutlineArray ) :
730 pArray( pOutlineArray ),
731 nStart( 0 ),
732 nEnd( SCCOLROW_MAX ), // alle durchgehen
733 nSubLevel( 0 ),
734 nSubEntry( 0 )
736 nDepth = pArray->nDepth;
739 ScSubOutlineIterator::ScSubOutlineIterator( ScOutlineArray* pOutlineArray,
740 USHORT nLevel, USHORT nEntry ) :
741 pArray( pOutlineArray )
743 ScOutlineEntry* pEntry = (ScOutlineEntry*) pArray->aCollections[nLevel].At(nEntry);
744 nStart = pEntry->GetStart();
745 nEnd = pEntry->GetEnd();
746 nSubLevel = nLevel + 1;
747 nSubEntry = 0;
748 nDepth = pArray->nDepth;
751 ScOutlineEntry* ScSubOutlineIterator::GetNext()
753 ScOutlineEntry* pEntry;
754 BOOL bFound = FALSE;
757 if (nSubLevel >= nDepth)
758 return NULL;
760 pEntry = (ScOutlineEntry*) pArray->aCollections[nSubLevel].At(nSubEntry);
761 if (!pEntry)
763 nSubEntry = 0;
764 ++nSubLevel;
766 else
768 if ( pEntry->GetStart() >= nStart && pEntry->GetEnd() <= nEnd )
769 bFound = TRUE;
770 ++nSubEntry;
773 while (!bFound);
774 return pEntry; // nSubLevel gueltig, wenn pEntry != 0
777 USHORT ScSubOutlineIterator::LastLevel() const
779 return nSubLevel;
782 USHORT ScSubOutlineIterator::LastEntry() const
784 if (nSubEntry == 0)
786 DBG_ERROR("ScSubOutlineIterator::LastEntry vor GetNext");
787 return 0;
789 return nSubEntry-1;
792 void ScSubOutlineIterator::DeleteLast()
794 if (nSubLevel >= nDepth)
796 DBG_ERROR("ScSubOutlineIterator::DeleteLast nach Ende");
797 return;
799 if (nSubEntry == 0)
801 DBG_ERROR("ScSubOutlineIterator::DeleteLast vor GetNext");
802 return;
805 --nSubEntry;
806 pArray->aCollections[nSubLevel].AtFree(nSubEntry);