update dev300-m57
[ooovba.git] / sc / source / core / data / olinetab.cxx
bloba30065e000455e37294999e91c37420467923a45
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"
48 //------------------------------------------------------------------------
50 ScOutlineEntry::ScOutlineEntry( SCCOLROW nNewStart, SCCOLROW nNewSize, BOOL bNewHidden ) :
51 nStart ( nNewStart ),
52 nSize ( nNewSize ),
53 bHidden ( bNewHidden ),
54 bVisible( TRUE )
58 ScOutlineEntry::ScOutlineEntry( const ScOutlineEntry& rEntry ) :
59 ScDataObject(),
60 nStart ( rEntry.nStart ),
61 nSize ( rEntry.nSize ),
62 bHidden ( rEntry.bHidden ),
63 bVisible( rEntry.bVisible )
67 ScDataObject* ScOutlineEntry::Clone() const
69 return new ScOutlineEntry( *this );
72 void ScOutlineEntry::Move( SCsCOLROW nDelta )
74 SCCOLROW nNewPos = nStart + nDelta;
75 if (nNewPos<0)
77 DBG_ERROR("OutlineEntry < 0");
78 nNewPos = 0;
80 nStart = nNewPos;
83 void ScOutlineEntry::SetSize( SCSIZE nNewSize )
85 if (nNewSize>0)
86 nSize = nNewSize;
87 else
89 DBG_ERROR("ScOutlineEntry Size == 0");
93 void ScOutlineEntry::SetPosSize( SCCOLROW nNewPos, SCSIZE nNewSize )
95 nStart = nNewPos;
96 SetSize( nNewSize );
99 void ScOutlineEntry::SetHidden( BOOL bNewHidden )
101 bHidden = bNewHidden;
104 void ScOutlineEntry::SetVisible( BOOL bNewVisible )
106 bVisible = bNewVisible;
109 //------------------------------------------------------------------------
111 ScOutlineCollection::ScOutlineCollection() :
112 ScSortedCollection( 4,4,FALSE )
116 inline short IntCompare( SCCOLROW nX, SCCOLROW nY )
118 if ( nX==nY ) return 0;
119 else if ( nX<nY ) return -1;
120 else return 1;
123 short ScOutlineCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
125 return IntCompare( ((ScOutlineEntry*)pKey1)->GetStart(),
126 ((ScOutlineEntry*)pKey2)->GetStart() );
129 USHORT ScOutlineCollection::FindStart( SCCOLROW nMinStart )
131 //! binaer suchen ?
133 USHORT nPos = 0;
134 USHORT nLocalCount = GetCount();
135 while ( (nPos<nLocalCount) ? (((ScOutlineEntry*)At(nPos))->GetStart() < nMinStart) : FALSE )
136 ++nPos;
138 return nPos;
141 //------------------------------------------------------------------------
143 ScOutlineArray::ScOutlineArray() :
144 nDepth( 0 )
148 ScOutlineArray::ScOutlineArray( const ScOutlineArray& rArray ) :
149 nDepth( rArray.nDepth )
151 for (USHORT nLevel=0; nLevel<nDepth; nLevel++)
153 USHORT nCount = rArray.aCollections[nLevel].GetCount();
154 for (USHORT nEntry=0; nEntry<nCount; nEntry++)
156 ScOutlineEntry* pEntry = (ScOutlineEntry*) rArray.aCollections[nLevel].At(nEntry);
157 aCollections[nLevel].Insert( new ScOutlineEntry( *pEntry ) );
162 void ScOutlineArray::FindEntry( SCCOLROW nSearchPos, USHORT& rFindLevel, USHORT& rFindIndex,
163 USHORT nMaxLevel )
165 rFindLevel = rFindIndex = 0;
167 if (nMaxLevel > nDepth)
168 nMaxLevel = nDepth;
170 for (USHORT nLevel=0; nLevel<nMaxLevel; nLevel++) //! rueckwaerts suchen ?
172 ScOutlineCollection* pCollect = &aCollections[nLevel];
173 USHORT nCount = pCollect->GetCount();
174 for (USHORT i=0; i<nCount; i++)
176 ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
177 if ( pEntry->GetStart() <= nSearchPos && pEntry->GetEnd() >= nSearchPos )
179 rFindLevel = nLevel + 1; // naechster Level (zum Einfuegen)
180 rFindIndex = i;
186 BOOL ScOutlineArray::Insert( SCCOLROW nStartCol, SCCOLROW nEndCol, BOOL& rSizeChanged,
187 BOOL bHidden, BOOL bVisible )
189 rSizeChanged = FALSE;
191 USHORT nStartLevel;
192 USHORT nStartIndex;
193 USHORT nEndLevel;
194 USHORT nEndIndex;
195 BOOL bFound = FALSE;
197 BOOL bCont;
198 USHORT nFindMax;
199 FindEntry( nStartCol, nStartLevel, nStartIndex ); // nLevel = neuer Level (alter+1) !!!
200 FindEntry( nEndCol, nEndLevel, nEndIndex );
201 nFindMax = Max(nStartLevel,nEndLevel);
204 bCont = FALSE;
206 if ( nStartLevel == nEndLevel && nStartIndex == nEndIndex && nStartLevel < SC_OL_MAXDEPTH )
207 bFound = TRUE;
209 if (!bFound)
211 if (nFindMax>0)
213 --nFindMax;
214 if (nStartLevel)
215 if ( ((ScOutlineEntry*)aCollections[nStartLevel-1].At(nStartIndex))->
216 GetStart() == nStartCol )
217 FindEntry( nStartCol, nStartLevel, nStartIndex, nFindMax );
218 if (nEndLevel)
219 if ( ((ScOutlineEntry*)aCollections[nEndLevel-1].At(nEndIndex))->
220 GetEnd() == nEndCol )
221 FindEntry( nEndCol, nEndLevel, nEndIndex, nFindMax );
222 bCont = TRUE;
226 while ( !bFound && bCont );
228 if (!bFound)
229 return FALSE;
231 USHORT nLevel = nStartLevel;
233 // untere verschieben
235 BOOL bNeedSize = FALSE;
236 for ( short nMoveLevel = nDepth-1; nMoveLevel >= (short) nLevel; nMoveLevel-- )
238 USHORT nCount = aCollections[nMoveLevel].GetCount();
239 BOOL bMoved = FALSE;
240 for ( USHORT i=0; i<nCount; i += bMoved ? 0 : 1 )
242 ScOutlineEntry* pEntry = (ScOutlineEntry*) aCollections[nMoveLevel].At(i);
243 SCCOLROW nEntryStart = pEntry->GetStart();
244 if ( nEntryStart >= nStartCol && nEntryStart <= nEndCol )
246 if (nMoveLevel >= SC_OL_MAXDEPTH - 1)
248 rSizeChanged = FALSE; // kein Platz
249 return FALSE;
251 aCollections[nMoveLevel+1].Insert( new ScOutlineEntry( *pEntry ) );
252 aCollections[nMoveLevel].AtFree( i );
253 nCount = aCollections[nMoveLevel].GetCount();
254 bMoved = TRUE;
255 if (nMoveLevel == (short) nDepth - 1)
256 bNeedSize = TRUE;
258 else
259 bMoved = FALSE;
263 if (bNeedSize)
265 ++nDepth;
266 rSizeChanged = TRUE;
269 if (nDepth <= nLevel)
271 nDepth = nLevel+1;
272 rSizeChanged = TRUE;
275 /* nicht zusammenfassen!
277 // zusammenfassen
279 USHORT nCount = aCollections[nLevel].GetCount();
280 USHORT nIndex;
281 bFound = FALSE;
282 for ( nIndex=0; nIndex<nCount && !bFound; nIndex++ )
284 if ( ((ScOutlineEntry*) aCollections[nLevel].At(nIndex))->GetEnd() + 1 == nStartCol )
286 nStartCol = ((ScOutlineEntry*) aCollections[nLevel].At(nIndex))->GetStart();
287 aCollections[nLevel].AtFree(nIndex);
288 nCount = aCollections[nLevel].GetCount(); // Daten geaendert
289 bFound = TRUE;
293 bFound = FALSE;
294 for ( nIndex=0; nIndex<nCount && !bFound; nIndex++ )
296 if ( ((ScOutlineEntry*) aCollections[nLevel].At(nIndex))->GetStart() == nEndCol + 1 )
298 nEndCol = ((ScOutlineEntry*) aCollections[nLevel].At(nIndex))->GetEnd();
299 aCollections[nLevel].AtFree(nIndex);
300 bFound = TRUE;
304 ScOutlineEntry* pNewEntry = new ScOutlineEntry( nStartCol, nEndCol+1-nStartCol, bHidden );
305 pNewEntry->SetVisible( bVisible );
306 aCollections[nLevel].Insert( pNewEntry );
308 return TRUE;
311 BOOL ScOutlineArray::FindTouchedLevel( SCCOLROW nBlockStart, SCCOLROW nBlockEnd, USHORT& rFindLevel ) const
313 BOOL bFound = FALSE;
314 rFindLevel = 0;
316 for (USHORT nLevel=0; nLevel<nDepth; nLevel++)
318 const ScOutlineCollection* pCollect = &aCollections[nLevel];
319 USHORT nCount = pCollect->GetCount();
320 for (USHORT i=0; i<nCount; i++)
322 ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
323 SCCOLROW nStart = pEntry->GetStart();
324 SCCOLROW nEnd = pEntry->GetEnd();
326 if ( ( nBlockStart>=nStart && nBlockStart<=nEnd ) ||
327 ( nBlockEnd >=nStart && nBlockEnd <=nEnd ) )
329 rFindLevel = nLevel; // wirklicher Level
330 bFound = TRUE;
335 return bFound;
338 void ScOutlineArray::RemoveSub( SCCOLROW nStartPos, SCCOLROW nEndPos, USHORT nLevel )
340 if ( nLevel >= nDepth )
341 return;
342 ScOutlineCollection* pCollect = &aCollections[nLevel];
343 USHORT nCount = pCollect->GetCount();
344 BOOL bFound = FALSE;
345 for ( USHORT i=0; i<nCount; i += ( bFound ? 0 : 1 ) )
347 bFound = FALSE;
348 ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
349 SCCOLROW nStart = pEntry->GetStart();
350 SCCOLROW nEnd = pEntry->GetEnd();
352 if ( nStart>=nStartPos && nEnd<=nEndPos )
354 RemoveSub( nStart, nEnd, nLevel+1 );
355 pCollect->AtFree(i);
356 nCount = pCollect->GetCount();
357 bFound = TRUE;
362 void ScOutlineArray::PromoteSub( SCCOLROW nStartPos, SCCOLROW nEndPos, USHORT nStartLevel )
364 if (nStartLevel==0)
366 DBG_ERROR("PromoteSub mit Level 0");
367 return;
370 for (USHORT nLevel = nStartLevel; nLevel < nDepth; nLevel++)
372 ScOutlineCollection* pCollect = &aCollections[nLevel];
373 USHORT nCount = pCollect->GetCount();
374 BOOL bFound = FALSE;
375 for ( USHORT i=0; i<nCount; i += ( bFound ? 0 : 1 ) )
377 bFound = FALSE;
378 ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
379 SCCOLROW nStart = pEntry->GetStart();
380 SCCOLROW nEnd = pEntry->GetEnd();
382 if ( nStart>=nStartPos && nEnd<=nEndPos )
384 aCollections[nLevel-1].Insert( new ScOutlineEntry( *pEntry ) );
385 pCollect->AtFree(i);
386 nCount = pCollect->GetCount();
387 bFound = TRUE;
393 BOOL ScOutlineArray::DecDepth() // nDepth auf leere Levels anpassen
395 BOOL bChanged = FALSE;
396 BOOL bCont;
399 bCont = FALSE;
400 if (nDepth)
401 if (aCollections[nDepth-1].GetCount() == 0)
403 --nDepth;
404 bChanged = TRUE;
405 bCont = TRUE;
408 while (bCont);
409 return bChanged;
412 BOOL ScOutlineArray::Remove( SCCOLROW nBlockStart, SCCOLROW nBlockEnd, BOOL& rSizeChanged )
414 USHORT nLevel;
415 FindTouchedLevel( nBlockStart, nBlockEnd, nLevel );
417 ScOutlineCollection* pCollect = &aCollections[nLevel];
418 USHORT nCount = pCollect->GetCount();
419 BOOL bFound = FALSE;
420 BOOL bAny = FALSE;
421 for ( USHORT i=0; i<nCount; i += ( bFound ? 0 : 1 ) )
423 bFound = FALSE;
424 ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
425 SCCOLROW nStart = pEntry->GetStart();
426 SCCOLROW nEnd = pEntry->GetEnd();
428 if ( nBlockStart<=nEnd && nBlockEnd>=nStart )
430 // RemoveSub( nStart, nEnd, nLevel+1 );
431 pCollect->AtFree(i);
432 PromoteSub( nStart, nEnd, nLevel+1 );
433 nCount = pCollect->GetCount();
434 i = pCollect->FindStart( nEnd+1 );
435 bFound = TRUE;
436 bAny = TRUE;
440 if (bAny) // Depth anpassen
441 if (DecDepth())
442 rSizeChanged = TRUE;
444 return bAny;
447 ScOutlineEntry* ScOutlineArray::GetEntry( USHORT nLevel, USHORT nIndex ) const
449 return (ScOutlineEntry*)((nLevel < nDepth) ? aCollections[nLevel].At(nIndex) : NULL);
452 USHORT ScOutlineArray::GetCount( USHORT nLevel ) const
454 return (nLevel < nDepth) ? aCollections[nLevel].GetCount() : 0;
457 ScOutlineEntry* ScOutlineArray::GetEntryByPos( USHORT nLevel, SCCOLROW nPos ) const
459 USHORT nCount = GetCount( nLevel );
460 ScOutlineEntry* pEntry;
462 for (USHORT nIndex = 0; nIndex < nCount; nIndex++)
464 pEntry = GetEntry( nLevel, nIndex );
465 if ((pEntry->GetStart() <= nPos) && (nPos <= pEntry->GetEnd()))
466 return pEntry;
468 return NULL;
471 BOOL ScOutlineArray::GetEntryIndex( USHORT nLevel, SCCOLROW nPos, USHORT& rnIndex ) const
473 // found entry contains passed position
474 USHORT nCount = GetCount( nLevel );
475 for ( rnIndex = 0; rnIndex < nCount; ++rnIndex )
477 const ScOutlineEntry* pEntry = GetEntry( nLevel, rnIndex );
478 if ( (pEntry->GetStart() <= nPos) && (nPos <= pEntry->GetEnd()) )
479 return TRUE;
481 return FALSE;
484 BOOL ScOutlineArray::GetEntryIndexInRange(
485 USHORT nLevel, SCCOLROW nBlockStart, SCCOLROW nBlockEnd, USHORT& rnIndex ) const
487 // found entry will be completely inside of passed range
488 USHORT nCount = GetCount( nLevel );
489 for ( rnIndex = 0; rnIndex < nCount; ++rnIndex )
491 const ScOutlineEntry* pEntry = GetEntry( nLevel, rnIndex );
492 if ( (nBlockStart <= pEntry->GetStart()) && (pEntry->GetEnd() <= nBlockEnd) )
493 return TRUE;
495 return FALSE;
498 void ScOutlineArray::SetVisibleBelow( USHORT nLevel, USHORT nEntry, BOOL bValue, BOOL bSkipHidden )
500 ScOutlineEntry* pEntry = GetEntry( nLevel, nEntry );
501 if( pEntry )
503 SCCOLROW nStart = pEntry->GetStart();
504 SCCOLROW nEnd = pEntry->GetEnd();
506 for (USHORT nSubLevel=nLevel+1; nSubLevel<nDepth; nSubLevel++)
508 USHORT i = 0;
509 pEntry = (ScOutlineEntry*) aCollections[nSubLevel].At(i);
510 while (pEntry)
512 if (pEntry->GetStart() >= nStart && pEntry->GetEnd() <= nEnd)
514 pEntry->SetVisible(bValue);
516 if (bSkipHidden)
517 if (!pEntry->IsHidden())
518 SetVisibleBelow( nSubLevel, i, bValue, TRUE );
521 ++i;
522 pEntry = (ScOutlineEntry*) aCollections[nSubLevel].At(i);
525 if (bSkipHidden)
526 nSubLevel = nDepth; // Abbruch
531 void ScOutlineArray::GetRange( SCCOLROW& rStart, SCCOLROW& rEnd ) const
533 USHORT nCount = aCollections[0].GetCount();
534 if (nCount)
536 rStart = ((ScOutlineEntry*) aCollections[0].At(0))->GetStart();
537 rEnd = ((ScOutlineEntry*) aCollections[0].At(nCount-1))->GetEnd();
539 else
540 rStart = rEnd = 0;
543 void ScOutlineArray::ExtendBlock( USHORT nLevel, SCCOLROW& rBlkStart, SCCOLROW& rBlkEnd )
545 USHORT nCount;
546 SCCOLROW nStart;
547 SCCOLROW nEnd;
548 USHORT i;
549 ScOutlineEntry* pEntry;
551 nCount = GetCount(nLevel);
552 for ( i=0; i<nCount; i++ )
554 pEntry = (ScOutlineEntry*) aCollections[nLevel].At(i);
555 nStart = pEntry->GetStart();
556 nEnd = pEntry->GetEnd();
558 if ( rBlkStart<=nEnd && rBlkEnd>=nStart )
560 if (nStart<rBlkStart) rBlkStart = nStart;
561 if (nEnd>rBlkEnd) rBlkEnd = nEnd;
566 BOOL ScOutlineArray::TestInsertSpace( SCSIZE nSize, SCCOLROW nMaxVal ) const
568 USHORT nCount = aCollections[0].GetCount();
569 if (nCount)
571 SCCOLROW nEnd = ((ScOutlineEntry*) aCollections[0].At(nCount-1))->GetEnd();
572 return ( sal::static_int_cast<SCCOLROW>(nEnd+nSize) <= nMaxVal );
575 return TRUE;
578 void ScOutlineArray::InsertSpace( SCCOLROW nStartPos, SCSIZE nSize )
580 ScSubOutlineIterator aIter( this );
581 ScOutlineEntry* pEntry;
582 while((pEntry=aIter.GetNext())!=NULL)
584 if ( pEntry->GetStart() >= nStartPos )
585 pEntry->Move(static_cast<SCsCOLROW>(nSize));
586 else
588 SCCOLROW nEnd = pEntry->GetEnd();
589 // immer erweitern, wenn innerhalb der Gruppe eingefuegt
590 // beim Einfuegen am Ende nur, wenn die Gruppe nicht ausgeblendet ist
591 if ( nEnd >= nStartPos || ( nEnd+1 >= nStartPos && !pEntry->IsHidden() ) )
593 SCSIZE nEntrySize = pEntry->GetSize();
594 nEntrySize += nSize;
595 pEntry->SetSize( nEntrySize );
601 BOOL ScOutlineArray::DeleteSpace( SCCOLROW nStartPos, SCSIZE nSize )
603 SCCOLROW nEndPos = nStartPos + nSize - 1;
604 BOOL bNeedSave = FALSE; // Original fuer Undo benoetigt?
605 BOOL bChanged = FALSE; // fuer Test auf Level
607 ScSubOutlineIterator aIter( this );
608 ScOutlineEntry* pEntry;
609 while((pEntry=aIter.GetNext())!=NULL)
611 SCCOLROW nEntryStart = pEntry->GetStart();
612 SCCOLROW nEntryEnd = pEntry->GetEnd();
613 SCSIZE nEntrySize = pEntry->GetSize();
615 if ( nEntryEnd >= nStartPos )
617 if ( nEntryStart > nEndPos ) // rechts
618 pEntry->Move(-(static_cast<SCsCOLROW>(nSize)));
619 else if ( nEntryStart < nStartPos && nEntryEnd >= nEndPos ) // aussen
620 pEntry->SetSize( nEntrySize-nSize );
621 else
623 bNeedSave = TRUE;
624 if ( nEntryStart >= nStartPos && nEntryEnd <= nEndPos ) // innen
626 aIter.DeleteLast();
627 bChanged = TRUE;
629 else if ( nEntryStart >= nStartPos ) // rechts ueber
630 pEntry->SetPosSize( nStartPos, static_cast<SCSIZE>(nEntryEnd-nEndPos) );
631 else // links ueber
632 pEntry->SetSize( static_cast<SCSIZE>(nStartPos-nEntryStart) );
637 if (bChanged)
638 DecDepth();
640 return bNeedSave;
643 BOOL ScOutlineArray::ManualAction( SCCOLROW nStartPos, SCCOLROW nEndPos,
644 BOOL bShow, const ScBitMaskCompressedArray< SCCOLROW, BYTE>& rHiddenFlags )
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
661 SCCOLROW nEnd = rHiddenFlags.GetBitStateEnd( nEntryStart,
662 CR_HIDDEN, CR_HIDDEN);
663 BOOL bAllHidden = (nEntryEnd <= nEnd && nEnd <
664 ::std::numeric_limits<SCCOLROW>::max());
666 BOOL bToggle = ( bShow != bAllHidden );
667 if ( bToggle )
669 pEntry->SetHidden( !bShow );
670 SetVisibleBelow( aIter.LastLevel(), aIter.LastEntry(), bShow, bShow );
671 bModified = TRUE;
676 return bModified;
679 void ScOutlineArray::RemoveAll()
681 for (USHORT nLevel=0; nLevel<nDepth; nLevel++)
682 aCollections[nLevel].FreeAll();
684 nDepth = 0;
687 //------------------------------------------------------------------------
689 ScOutlineTable::ScOutlineTable()
693 ScOutlineTable::ScOutlineTable( const ScOutlineTable& rOutline ) :
694 aColOutline( rOutline.aColOutline ),
695 aRowOutline( rOutline.aRowOutline )
699 BOOL ScOutlineTable::TestInsertCol( SCSIZE nSize )
701 return aColOutline.TestInsertSpace( nSize, MAXCOL );
704 void ScOutlineTable::InsertCol( SCCOL nStartCol, SCSIZE nSize )
706 aColOutline.InsertSpace( nStartCol, nSize );
709 BOOL ScOutlineTable::DeleteCol( SCCOL nStartCol, SCSIZE nSize )
711 return aColOutline.DeleteSpace( nStartCol, nSize );
714 BOOL ScOutlineTable::TestInsertRow( SCSIZE nSize )
716 return aRowOutline.TestInsertSpace( nSize, MAXROW );
719 void ScOutlineTable::InsertRow( SCROW nStartRow, SCSIZE nSize )
721 aRowOutline.InsertSpace( nStartRow, nSize );
724 BOOL ScOutlineTable::DeleteRow( SCROW nStartRow, SCSIZE nSize )
726 return aRowOutline.DeleteSpace( nStartRow, nSize );
729 //------------------------------------------------------------------------
731 ScSubOutlineIterator::ScSubOutlineIterator( ScOutlineArray* pOutlineArray ) :
732 pArray( pOutlineArray ),
733 nStart( 0 ),
734 nEnd( SCCOLROW_MAX ), // alle durchgehen
735 nSubLevel( 0 ),
736 nSubEntry( 0 )
738 nDepth = pArray->nDepth;
741 ScSubOutlineIterator::ScSubOutlineIterator( ScOutlineArray* pOutlineArray,
742 USHORT nLevel, USHORT nEntry ) :
743 pArray( pOutlineArray )
745 ScOutlineEntry* pEntry = (ScOutlineEntry*) pArray->aCollections[nLevel].At(nEntry);
746 nStart = pEntry->GetStart();
747 nEnd = pEntry->GetEnd();
748 nSubLevel = nLevel + 1;
749 nSubEntry = 0;
750 nDepth = pArray->nDepth;
753 ScOutlineEntry* ScSubOutlineIterator::GetNext()
755 ScOutlineEntry* pEntry;
756 BOOL bFound = FALSE;
759 if (nSubLevel >= nDepth)
760 return NULL;
762 pEntry = (ScOutlineEntry*) pArray->aCollections[nSubLevel].At(nSubEntry);
763 if (!pEntry)
765 nSubEntry = 0;
766 ++nSubLevel;
768 else
770 if ( pEntry->GetStart() >= nStart && pEntry->GetEnd() <= nEnd )
771 bFound = TRUE;
772 ++nSubEntry;
775 while (!bFound);
776 return pEntry; // nSubLevel gueltig, wenn pEntry != 0
779 USHORT ScSubOutlineIterator::LastLevel() const
781 return nSubLevel;
784 USHORT ScSubOutlineIterator::LastEntry() const
786 if (nSubEntry == 0)
788 DBG_ERROR("ScSubOutlineIterator::LastEntry vor GetNext");
789 return 0;
791 return nSubEntry-1;
794 void ScSubOutlineIterator::DeleteLast()
796 if (nSubLevel >= nDepth)
798 DBG_ERROR("ScSubOutlineIterator::DeleteLast nach Ende");
799 return;
801 if (nSubEntry == 0)
803 DBG_ERROR("ScSubOutlineIterator::DeleteLast vor GetNext");
804 return;
807 --nSubEntry;
808 pArray->aCollections[nSubLevel].AtFree(nSubEntry);