1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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>
41 // INCLUDE ---------------------------------------------------------------
43 #include "olinetab.hxx"
45 #include "rechead.hxx"
46 #include "address.hxx"
49 //------------------------------------------------------------------------
51 ScOutlineEntry::ScOutlineEntry( SCCOLROW nNewStart
, SCCOLROW nNewSize
, BOOL bNewHidden
) :
54 bHidden ( bNewHidden
),
59 ScOutlineEntry::ScOutlineEntry( const ScOutlineEntry
& rEntry
) :
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
;
78 DBG_ERROR("OutlineEntry < 0");
84 void ScOutlineEntry::SetSize( SCSIZE nNewSize
)
90 DBG_ERROR("ScOutlineEntry Size == 0");
94 void ScOutlineEntry::SetPosSize( SCCOLROW nNewPos
, SCSIZE 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;
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
)
135 USHORT nLocalCount
= GetCount();
136 while ( (nPos
<nLocalCount
) ? (((ScOutlineEntry
*)At(nPos
))->GetStart() < nMinStart
) : FALSE
)
142 //------------------------------------------------------------------------
144 ScOutlineArray::ScOutlineArray() :
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
,
166 rFindLevel
= rFindIndex
= 0;
168 if (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)
187 BOOL
ScOutlineArray::Insert( SCCOLROW nStartCol
, SCCOLROW nEndCol
, BOOL
& rSizeChanged
,
188 BOOL bHidden
, BOOL bVisible
)
190 rSizeChanged
= FALSE
;
200 FindEntry( nStartCol
, nStartLevel
, nStartIndex
); // nLevel = neuer Level (alter+1) !!!
201 FindEntry( nEndCol
, nEndLevel
, nEndIndex
);
202 nFindMax
= Max(nStartLevel
,nEndLevel
);
207 if ( nStartLevel
== nEndLevel
&& nStartIndex
== nEndIndex
&& nStartLevel
< SC_OL_MAXDEPTH
)
216 if ( ((ScOutlineEntry
*)aCollections
[nStartLevel
-1].At(nStartIndex
))->
217 GetStart() == nStartCol
)
218 FindEntry( nStartCol
, nStartLevel
, nStartIndex
, nFindMax
);
220 if ( ((ScOutlineEntry
*)aCollections
[nEndLevel
-1].At(nEndIndex
))->
221 GetEnd() == nEndCol
)
222 FindEntry( nEndCol
, nEndLevel
, nEndIndex
, nFindMax
);
227 while ( !bFound
&& bCont
);
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();
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
252 aCollections
[nMoveLevel
+1].Insert( new ScOutlineEntry( *pEntry
) );
253 aCollections
[nMoveLevel
].AtFree( i
);
254 nCount
= aCollections
[nMoveLevel
].GetCount();
256 if (nMoveLevel
== (short) nDepth
- 1)
270 if (nDepth
<= nLevel
)
276 /* nicht zusammenfassen!
280 USHORT nCount = aCollections[nLevel].GetCount();
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
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);
305 ScOutlineEntry
* pNewEntry
= new ScOutlineEntry( nStartCol
, nEndCol
+1-nStartCol
, bHidden
);
306 pNewEntry
->SetVisible( bVisible
);
307 aCollections
[nLevel
].Insert( pNewEntry
);
312 BOOL
ScOutlineArray::FindTouchedLevel( SCCOLROW nBlockStart
, SCCOLROW nBlockEnd
, USHORT
& rFindLevel
) const
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
339 void ScOutlineArray::RemoveSub( SCCOLROW nStartPos
, SCCOLROW nEndPos
, USHORT nLevel
)
341 if ( nLevel
>= nDepth
)
343 ScOutlineCollection
* pCollect
= &aCollections
[nLevel
];
344 USHORT nCount
= pCollect
->GetCount();
346 for ( USHORT i
=0; i
<nCount
; i
+= ( bFound
? 0 : 1 ) )
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 );
357 nCount
= pCollect
->GetCount();
363 void ScOutlineArray::PromoteSub( SCCOLROW nStartPos
, SCCOLROW nEndPos
, USHORT nStartLevel
)
367 DBG_ERROR("PromoteSub mit Level 0");
371 for (USHORT nLevel
= nStartLevel
; nLevel
< nDepth
; nLevel
++)
373 ScOutlineCollection
* pCollect
= &aCollections
[nLevel
];
374 USHORT nCount
= pCollect
->GetCount();
376 for ( USHORT i
=0; i
<nCount
; i
+= ( bFound
? 0 : 1 ) )
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
) );
387 nCount
= pCollect
->GetCount();
394 BOOL
ScOutlineArray::DecDepth() // nDepth auf leere Levels anpassen
396 BOOL bChanged
= FALSE
;
402 if (aCollections
[nDepth
-1].GetCount() == 0)
413 BOOL
ScOutlineArray::Remove( SCCOLROW nBlockStart
, SCCOLROW nBlockEnd
, BOOL
& rSizeChanged
)
416 FindTouchedLevel( nBlockStart
, nBlockEnd
, nLevel
);
418 ScOutlineCollection
* pCollect
= &aCollections
[nLevel
];
419 USHORT nCount
= pCollect
->GetCount();
422 for ( USHORT i
=0; i
<nCount
; i
+= ( bFound
? 0 : 1 ) )
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 );
433 PromoteSub( nStart
, nEnd
, nLevel
+1 );
434 nCount
= pCollect
->GetCount();
435 i
= pCollect
->FindStart( nEnd
+1 );
441 if (bAny
) // Depth anpassen
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()))
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()) )
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
) )
499 void ScOutlineArray::SetVisibleBelow( USHORT nLevel
, USHORT nEntry
, BOOL bValue
, BOOL bSkipHidden
)
501 ScOutlineEntry
* pEntry
= GetEntry( nLevel
, nEntry
);
504 SCCOLROW nStart
= pEntry
->GetStart();
505 SCCOLROW nEnd
= pEntry
->GetEnd();
507 for (USHORT nSubLevel
=nLevel
+1; nSubLevel
<nDepth
; nSubLevel
++)
510 pEntry
= (ScOutlineEntry
*) aCollections
[nSubLevel
].At(i
);
513 if (pEntry
->GetStart() >= nStart
&& pEntry
->GetEnd() <= nEnd
)
515 pEntry
->SetVisible(bValue
);
518 if (!pEntry
->IsHidden())
519 SetVisibleBelow( nSubLevel
, i
, bValue
, TRUE
);
523 pEntry
= (ScOutlineEntry
*) aCollections
[nSubLevel
].At(i
);
527 nSubLevel
= nDepth
; // Abbruch
532 void ScOutlineArray::GetRange( SCCOLROW
& rStart
, SCCOLROW
& rEnd
) const
534 USHORT nCount
= aCollections
[0].GetCount();
537 rStart
= ((ScOutlineEntry
*) aCollections
[0].At(0))->GetStart();
538 rEnd
= ((ScOutlineEntry
*) aCollections
[0].At(nCount
-1))->GetEnd();
544 void ScOutlineArray::ExtendBlock( USHORT nLevel
, SCCOLROW
& rBlkStart
, SCCOLROW
& rBlkEnd
)
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();
572 SCCOLROW nEnd
= ((ScOutlineEntry
*) aCollections
[0].At(nCount
-1))->GetEnd();
573 return ( sal::static_int_cast
<SCCOLROW
>(nEnd
+nSize
) <= nMaxVal
);
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
));
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();
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
);
625 if ( nEntryStart
>= nStartPos
&& nEntryEnd
<= nEndPos
) // innen
630 else if ( nEntryStart
>= nStartPos
) // rechts ueber
631 pEntry
->SetPosSize( nStartPos
, static_cast<SCSIZE
>(nEntryEnd
-nEndPos
) );
633 pEntry
->SetSize( static_cast<SCSIZE
>(nStartPos
-nEntryStart
) );
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
660 SCCOLROW nEnd
= rTable
.LastHiddenColRow(nEntryStart
, bCol
);
661 BOOL bAllHidden
= (nEntryEnd
<= nEnd
&& nEnd
<
662 ::std::numeric_limits
<SCCOLROW
>::max());
664 BOOL bToggle
= ( bShow
!= bAllHidden
);
667 pEntry
->SetHidden( !bShow
);
668 SetVisibleBelow( aIter
.LastLevel(), aIter
.LastEntry(), bShow
, bShow
);
677 void ScOutlineArray::RemoveAll()
679 for (USHORT nLevel
=0; nLevel
<nDepth
; nLevel
++)
680 aCollections
[nLevel
].FreeAll();
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
),
732 nEnd( SCCOLROW_MAX
), // alle durchgehen
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;
748 nDepth
= pArray
->nDepth
;
751 ScOutlineEntry
* ScSubOutlineIterator::GetNext()
753 ScOutlineEntry
* pEntry
;
757 if (nSubLevel
>= nDepth
)
760 pEntry
= (ScOutlineEntry
*) pArray
->aCollections
[nSubLevel
].At(nSubEntry
);
768 if ( pEntry
->GetStart() >= nStart
&& pEntry
->GetEnd() <= nEnd
)
774 return pEntry
; // nSubLevel gueltig, wenn pEntry != 0
777 USHORT
ScSubOutlineIterator::LastLevel() const
782 USHORT
ScSubOutlineIterator::LastEntry() const
786 DBG_ERROR("ScSubOutlineIterator::LastEntry vor GetNext");
792 void ScSubOutlineIterator::DeleteLast()
794 if (nSubLevel
>= nDepth
)
796 DBG_ERROR("ScSubOutlineIterator::DeleteLast nach Ende");
801 DBG_ERROR("ScSubOutlineIterator::DeleteLast vor GetNext");
806 pArray
->aCollections
[nSubLevel
].AtFree(nSubEntry
);