1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <olinetab.hxx>
21 #include <address.hxx>
24 #include <osl/diagnose.h>
26 ScOutlineEntry::ScOutlineEntry( SCCOLROW nNewStart
, SCCOLROW nNewSize
, bool bNewHidden
) :
29 bHidden ( bNewHidden
),
34 ScOutlineEntry::ScOutlineEntry( const ScOutlineEntry
& rEntry
) :
35 nStart ( rEntry
.nStart
),
36 nSize ( rEntry
.nSize
),
37 bHidden ( rEntry
.bHidden
),
38 bVisible( rEntry
.bVisible
)
42 SCCOLROW
ScOutlineEntry::GetEnd() const
44 return nStart
+nSize
-1;
47 void ScOutlineEntry::Move( SCCOLROW nDelta
)
49 SCCOLROW nNewPos
= nStart
+ nDelta
;
52 OSL_FAIL("OutlineEntry < 0");
58 void ScOutlineEntry::SetSize( SCSIZE nNewSize
)
64 OSL_FAIL("ScOutlineEntry Size == 0");
68 void ScOutlineEntry::SetPosSize( SCCOLROW nNewPos
, SCSIZE nNewSize
)
74 void ScOutlineEntry::SetHidden( bool bNewHidden
)
79 void ScOutlineEntry::SetVisible( bool bNewVisible
)
81 bVisible
= bNewVisible
;
84 OString
ScOutlineEntry::dumpAsString() const
86 const char* const pSep
= ":";
87 return OString::number(nStart
) + pSep
+ OString::number(nSize
) +
88 pSep
+ (bHidden
? "1" : "0") + pSep
+ (bVisible
? "1" : "0");
91 ScOutlineCollection::ScOutlineCollection() {}
93 size_t ScOutlineCollection::size() const
95 return m_Entries
.size();
98 void ScOutlineCollection::clear()
103 void ScOutlineCollection::insert(ScOutlineEntry
const& rEntry
)
105 SCCOLROW nStart
= rEntry
.GetStart();
106 m_Entries
.insert(std::make_pair(nStart
, rEntry
));
109 ScOutlineCollection::iterator
ScOutlineCollection::begin()
111 return m_Entries
.begin();
114 ScOutlineCollection::iterator
ScOutlineCollection::end()
116 return m_Entries
.end();
119 ScOutlineCollection::const_iterator
ScOutlineCollection::begin() const
121 return m_Entries
.begin();
124 ScOutlineCollection::const_iterator
ScOutlineCollection::end() const
126 return m_Entries
.end();
129 ScOutlineCollection::iterator
ScOutlineCollection::erase(const iterator
& pos
)
131 return m_Entries
.erase(pos
);
134 bool ScOutlineCollection::empty() const
136 return m_Entries
.empty();
139 ScOutlineCollection::iterator
ScOutlineCollection::FindStart(SCCOLROW nMinStart
)
141 return m_Entries
.lower_bound(nMinStart
);
144 OString
ScOutlineCollection::dumpAsString() const
147 const char* const pGroupEntrySep
= ",";
148 for (const auto& rKeyValuePair
: m_Entries
)
149 aOutput
+= rKeyValuePair
.second
.dumpAsString() + pGroupEntrySep
;
154 ScOutlineArray::ScOutlineArray() :
157 ScOutlineArray::ScOutlineArray( const ScOutlineArray
& rArray
) :
158 nDepth( rArray
.nDepth
)
160 for (size_t nLevel
= 0; nLevel
< nDepth
; ++nLevel
)
162 const ScOutlineCollection
& rColl
= rArray
.aCollections
[nLevel
];
163 for (const auto& rEntry
: rColl
)
165 const ScOutlineEntry
*const pEntry
= &rEntry
.second
;
166 aCollections
[nLevel
].insert(*pEntry
);
171 void ScOutlineArray::FindEntry(
172 SCCOLROW nSearchPos
, size_t& rFindLevel
, size_t& rFindIndex
,
175 rFindLevel
= rFindIndex
= 0;
177 if (nMaxLevel
> nDepth
)
180 for (size_t nLevel
= 0; nLevel
< nMaxLevel
; ++nLevel
) //TODO: Search backwards?
182 ScOutlineCollection
* pCollect
= &aCollections
[nLevel
];
184 for (auto& rEntry
: *pCollect
)
186 ScOutlineEntry
*const pEntry
= &rEntry
.second
;
187 if (pEntry
->GetStart() <= nSearchPos
&& pEntry
->GetEnd() >= nSearchPos
)
189 rFindLevel
= nLevel
+ 1; // Next Level (for insertion)
197 bool ScOutlineArray::Insert(
198 SCCOLROW nStartCol
, SCCOLROW nEndCol
, bool& rSizeChanged
, bool bHidden
)
200 rSizeChanged
= false;
202 size_t nStartLevel
, nEndLevel
, nStartIndex
, nEndIndex
;
207 FindEntry( nStartCol
, nStartLevel
, nStartIndex
); // nLevel = new Level (old+1)
208 FindEntry( nEndCol
, nEndLevel
, nEndIndex
);
209 nFindMax
= std::max(nStartLevel
,nEndLevel
);
214 if (nStartLevel
== nEndLevel
&& nStartIndex
== nEndIndex
&& nStartLevel
< SC_OL_MAXDEPTH
)
217 if (!bFound
&& nFindMax
>0)
222 ScOutlineCollection::const_iterator it
= aCollections
[nStartLevel
-1].begin();
223 std::advance(it
, nStartIndex
);
224 if (it
->second
.GetStart() == nStartCol
)
225 FindEntry(nStartCol
, nStartLevel
, nStartIndex
, nFindMax
);
230 ScOutlineCollection::const_iterator it
= aCollections
[nEndLevel
-1].begin();
231 std::advance(it
, nEndIndex
);
232 if (it
->second
.GetEnd() == nEndCol
)
233 FindEntry(nEndCol
, nEndLevel
, nEndIndex
, nFindMax
);
238 while ( !bFound
&& bCont
);
243 size_t nLevel
= nStartLevel
;
245 // Move the ones underneath
246 bool bNeedSize
= false;
249 for (size_t nMoveLevel
= nDepth
-1; nMoveLevel
>= nLevel
; --nMoveLevel
)
251 ScOutlineCollection
& rColl
= aCollections
[nMoveLevel
];
252 ScOutlineCollection::iterator it
= rColl
.begin(), itEnd
= rColl
.end();
255 ScOutlineEntry
*const pEntry
= &it
->second
;
256 SCCOLROW nEntryStart
= pEntry
->GetStart();
257 if (nEntryStart
>= nStartCol
&& nEntryStart
<= nEndCol
)
259 if (nMoveLevel
>= SC_OL_MAXDEPTH
- 1)
261 rSizeChanged
= false; // No more room
264 aCollections
[nMoveLevel
+1].insert(*pEntry
);
265 it
= rColl
.erase(it
);
266 if (nMoveLevel
== nDepth
- 1)
283 if (nDepth
<= nLevel
)
289 ScOutlineEntry
aNewEntry(nStartCol
, nEndCol
+1-nStartCol
, bHidden
);
290 aNewEntry
.SetVisible( true );
291 aCollections
[nLevel
].insert(aNewEntry
);
296 bool ScOutlineArray::FindTouchedLevel(
297 SCCOLROW nBlockStart
, SCCOLROW nBlockEnd
, size_t& rFindLevel
) const
302 for (size_t nLevel
= 0; nLevel
< nDepth
; ++nLevel
)
304 const ScOutlineCollection
* pCollect
= &aCollections
[nLevel
];
305 for (const auto& rEntry
: *pCollect
)
307 const ScOutlineEntry
*const pEntry
= &rEntry
.second
;
308 SCCOLROW nStart
= pEntry
->GetStart();
309 SCCOLROW nEnd
= pEntry
->GetEnd();
311 if ( ( nBlockStart
>=nStart
&& nBlockStart
<=nEnd
) ||
312 ( nBlockEnd
>=nStart
&& nBlockEnd
<=nEnd
) )
314 rFindLevel
= nLevel
; // Actual Level
323 void ScOutlineArray::PromoteSub(SCCOLROW nStartPos
, SCCOLROW nEndPos
, size_t nStartLevel
)
327 OSL_FAIL("PromoteSub with Level 0");
331 for (size_t nLevel
= nStartLevel
; nLevel
< nDepth
; ++nLevel
)
333 ScOutlineCollection
& rColl
= aCollections
[nLevel
];
334 ScOutlineCollection::iterator it
= rColl
.begin(), itEnd
= rColl
.end();
337 ScOutlineEntry
*const pEntry
= &it
->second
;
338 SCCOLROW nStart
= pEntry
->GetStart();
339 SCCOLROW nEnd
= pEntry
->GetEnd();
340 if (nStart
>= nStartPos
&& nEnd
<= nEndPos
)
342 aCollections
[nLevel
-1].insert(*pEntry
);
344 it
= rColl
.erase(it
);
355 ScOutlineEntry
*const pEntry
= &it
->second
;
356 SCCOLROW nStart
= pEntry
->GetStart();
357 SCCOLROW nEnd
= pEntry
->GetEnd();
358 if (nStart
>= nStartPos
&& nEnd
<= nEndPos
)
360 aCollections
[nLevel
-1].insert(*pEntry
);
362 it
= rColl
.erase(it
);
371 * Adapt nDepth for empty Levels
373 bool ScOutlineArray::DecDepth()
375 bool bChanged
= false;
382 if (aCollections
[nDepth
-1].empty())
395 bool ScOutlineArray::Remove( SCCOLROW nBlockStart
, SCCOLROW nBlockEnd
, bool& rSizeChanged
)
398 FindTouchedLevel( nBlockStart
, nBlockEnd
, nLevel
);
400 ScOutlineCollection
* pCollect
= &aCollections
[nLevel
];
401 ScOutlineCollection::iterator it
= pCollect
->begin(), itEnd
= pCollect
->end();
405 ScOutlineEntry
*const pEntry
= &it
->second
;
406 SCCOLROW nStart
= pEntry
->GetStart();
407 SCCOLROW nEnd
= pEntry
->GetEnd();
408 if (nBlockStart
<= nEnd
&& nBlockEnd
>= nStart
)
412 PromoteSub( nStart
, nEnd
, nLevel
+1 );
413 itEnd
= pCollect
->end();
414 it
= pCollect
->FindStart( nEnd
+1 );
421 if (bAny
) // Adapt Depth
428 ScOutlineEntry
* ScOutlineArray::GetEntry(size_t nLevel
, size_t nIndex
)
430 if (nLevel
>= nDepth
)
433 ScOutlineCollection
& rColl
= aCollections
[nLevel
];
434 if (nIndex
>= rColl
.size())
437 ScOutlineCollection::iterator it
= rColl
.begin();
438 std::advance(it
, nIndex
);
442 const ScOutlineEntry
* ScOutlineArray::GetEntry(size_t nLevel
, size_t nIndex
) const
444 if (nLevel
>= nDepth
)
447 const ScOutlineCollection
& rColl
= aCollections
[nLevel
];
448 if (nIndex
>= rColl
.size())
451 ScOutlineCollection::const_iterator it
= rColl
.begin();
452 std::advance(it
, nIndex
);
456 size_t ScOutlineArray::GetCount(size_t nLevel
) const
458 if (nLevel
>= nDepth
)
461 return aCollections
[nLevel
].size();
464 const ScOutlineEntry
* ScOutlineArray::GetEntryByPos(size_t nLevel
, SCCOLROW nPos
) const
466 if (nLevel
>= nDepth
)
469 const ScOutlineCollection
& rColl
= aCollections
[nLevel
];
470 ScOutlineCollection::const_iterator it
= std::find_if(rColl
.begin(), rColl
.end(),
471 [&nPos
](const auto& rEntry
) {
472 const ScOutlineEntry
*const pEntry
= &rEntry
.second
;
473 return pEntry
->GetStart() <= nPos
&& nPos
<= pEntry
->GetEnd();
475 if (it
!= rColl
.end())
481 bool ScOutlineArray::GetEntryIndex(size_t nLevel
, SCCOLROW nPos
, size_t& rnIndex
) const
483 if (nLevel
>= nDepth
)
486 // Found entry contains passed position
487 const ScOutlineCollection
& rColl
= aCollections
[nLevel
];
488 ScOutlineCollection::const_iterator it
= std::find_if(rColl
.begin(), rColl
.end(),
489 [&nPos
](const auto& rEntry
) {
490 const ScOutlineEntry
*const p
= &rEntry
.second
;
491 return p
->GetStart() <= nPos
&& nPos
<= p
->GetEnd();
493 if (it
!= rColl
.end())
495 rnIndex
= std::distance(rColl
.begin(), it
);
501 bool ScOutlineArray::GetEntryIndexInRange(
502 size_t nLevel
, SCCOLROW nBlockStart
, SCCOLROW nBlockEnd
, size_t& rnIndex
) const
504 if (nLevel
>= nDepth
)
507 // Found entry will be completely inside of passed range
508 const ScOutlineCollection
& rColl
= aCollections
[nLevel
];
509 ScOutlineCollection::const_iterator it
= std::find_if(rColl
.begin(), rColl
.end(),
510 [&nBlockStart
, &nBlockEnd
](const auto& rEntry
) {
511 const ScOutlineEntry
*const p
= &rEntry
.second
;
512 return nBlockStart
<= p
->GetStart() && p
->GetEnd() <= nBlockEnd
;
514 if (it
!= rColl
.end())
516 rnIndex
= std::distance(rColl
.begin(), it
);
522 void ScOutlineArray::SetVisibleBelow(
523 size_t nLevel
, size_t nEntry
, bool bValue
, bool bSkipHidden
)
525 const ScOutlineEntry
* pEntry
= GetEntry( nLevel
, nEntry
);
529 SCCOLROW nStart
= pEntry
->GetStart();
530 SCCOLROW nEnd
= pEntry
->GetEnd();
532 for (size_t nSubLevel
= nLevel
+1; nSubLevel
< nDepth
; ++nSubLevel
)
534 ScOutlineCollection
& rColl
= aCollections
[nSubLevel
];
536 for (auto& rEntry
: rColl
)
538 ScOutlineEntry
*const p
= &rEntry
.second
;
539 if (p
->GetStart() >= nStart
&& p
->GetEnd() <= nEnd
)
541 p
->SetVisible(bValue
);
542 if (bSkipHidden
&& !p
->IsHidden())
544 SetVisibleBelow(nSubLevel
, nPos
, bValue
, true);
551 nSubLevel
= nDepth
; // Bail out
555 void ScOutlineArray::GetRange(SCCOLROW
& rStart
, SCCOLROW
& rEnd
) const
557 const ScOutlineCollection
& rColl
= aCollections
[0];
560 ScOutlineCollection::const_iterator it
= rColl
.begin();
561 rStart
= it
->second
.GetStart();
562 std::advance(it
, rColl
.size()-1);
563 rEnd
= it
->second
.GetEnd();
569 void ScOutlineArray::ExtendBlock(size_t nLevel
, SCCOLROW
& rBlkStart
, SCCOLROW
& rBlkEnd
)
571 if (nLevel
>= nDepth
)
574 const ScOutlineCollection
& rColl
= aCollections
[nLevel
];
575 for (const auto& rEntry
: rColl
)
577 const ScOutlineEntry
*const pEntry
= &rEntry
.second
;
578 SCCOLROW nStart
= pEntry
->GetStart();
579 SCCOLROW nEnd
= pEntry
->GetEnd();
581 if (rBlkStart
<= nEnd
&& rBlkEnd
>= nStart
)
583 if (nStart
< rBlkStart
)
591 bool ScOutlineArray::TestInsertSpace(SCSIZE nSize
, SCCOLROW nMaxVal
) const
593 const ScOutlineCollection
& rColl
= aCollections
[0];
597 ScOutlineCollection::const_iterator it
= rColl
.begin();
598 std::advance(it
, rColl
.size()-1);
599 SCCOLROW nEnd
= it
->second
.GetEnd();
600 return sal::static_int_cast
<SCCOLROW
>(nEnd
+nSize
) <= nMaxVal
;
603 void ScOutlineArray::InsertSpace(SCCOLROW nStartPos
, SCSIZE nSize
)
605 ScSubOutlineIterator
aIter( this );
606 ScOutlineEntry
* pEntry
;
607 while ((pEntry
= aIter
.GetNext()) != nullptr)
609 if ( pEntry
->GetStart() >= nStartPos
)
610 pEntry
->Move(static_cast<SCCOLROW
>(nSize
));
613 SCCOLROW nEnd
= pEntry
->GetEnd();
614 // Always expand if inserted within the group
615 // When inserting at the end, only if the group is not hidden
616 if ( nEnd
>= nStartPos
|| ( nEnd
+1 >= nStartPos
&& !pEntry
->IsHidden() ) )
618 SCSIZE nEntrySize
= pEntry
->GetSize();
620 pEntry
->SetSize( nEntrySize
);
626 bool ScOutlineArray::DeleteSpace(SCCOLROW nStartPos
, SCSIZE nSize
)
628 SCCOLROW nEndPos
= nStartPos
+ nSize
- 1;
629 bool bNeedSave
= false; // Do we need the original one for Undo?
630 bool bChanged
= false; // For Level test
632 ScSubOutlineIterator
aIter( this );
633 ScOutlineEntry
* pEntry
;
634 while((pEntry
=aIter
.GetNext())!=nullptr)
636 SCCOLROW nEntryStart
= pEntry
->GetStart();
637 SCCOLROW nEntryEnd
= pEntry
->GetEnd();
638 SCSIZE nEntrySize
= pEntry
->GetSize();
640 if ( nEntryEnd
>= nStartPos
)
642 if ( nEntryStart
> nEndPos
) // Right
643 pEntry
->Move(-static_cast<SCCOLROW
>(nSize
));
644 else if ( nEntryStart
< nStartPos
&& nEntryEnd
>= nEndPos
) // Outside
645 pEntry
->SetSize( nEntrySize
-nSize
);
649 if ( nEntryStart
>= nStartPos
&& nEntryEnd
<= nEndPos
) // Inside
654 else if ( nEntryStart
>= nStartPos
) // Top right
655 pEntry
->SetPosSize( nStartPos
, static_cast<SCSIZE
>(nEntryEnd
-nEndPos
) );
657 pEntry
->SetSize( static_cast<SCSIZE
>(nStartPos
-nEntryStart
) );
668 bool ScOutlineArray::ManualAction(
669 SCCOLROW nStartPos
, SCCOLROW nEndPos
, bool bShow
, const ScTable
& rTable
, bool bCol
)
671 bool bModified
= false;
672 ScSubOutlineIterator
aIter( this );
673 ScOutlineEntry
* pEntry
;
674 while((pEntry
=aIter
.GetNext())!=nullptr)
676 SCCOLROW nEntryStart
= pEntry
->GetStart();
677 SCCOLROW nEntryEnd
= pEntry
->GetEnd();
679 if (nEntryEnd
>=nStartPos
&& nEntryStart
<=nEndPos
)
681 if ( pEntry
->IsHidden() == bShow
)
683 // #i12341# hide if all columns/rows are hidden, show if at least one
685 SCCOLROW nEnd
= rTable
.LastHiddenColRow(nEntryStart
, bCol
);
686 bool bAllHidden
= (nEntryEnd
<= nEnd
&& nEnd
<
687 ::std::numeric_limits
<SCCOLROW
>::max());
689 bool bToggle
= ( bShow
!= bAllHidden
);
692 pEntry
->SetHidden( !bShow
);
693 SetVisibleBelow( aIter
.LastLevel(), aIter
.LastEntry(), bShow
, bShow
);
702 void ScOutlineArray::RemoveAll()
704 for (size_t nLevel
= 0; nLevel
< nDepth
; ++nLevel
)
705 aCollections
[nLevel
].clear();
710 void ScOutlineArray::finalizeImport(const ScTable
& rTable
)
712 ScSubOutlineIterator
aIter( this );
713 ScOutlineEntry
* pEntry
;
714 while((pEntry
=aIter
.GetNext())!=nullptr)
717 if (!pEntry
->IsHidden())
720 SCCOLROW nEntryStart
= pEntry
->GetStart();
721 SCCOLROW nEntryEnd
= pEntry
->GetEnd();
722 SCCOLROW nEnd
= rTable
.LastHiddenColRow(nEntryStart
, false/*bCol*/);
723 bool bAllHidden
= (nEntryEnd
<= nEnd
&& nEnd
<
724 ::std::numeric_limits
<SCCOLROW
>::max());
726 pEntry
->SetHidden(bAllHidden
);
727 SetVisibleBelow(aIter
.LastLevel(), aIter
.LastEntry(), !bAllHidden
, !bAllHidden
);
731 OString
ScOutlineArray::dumpAsString() const
734 const char* const pLevelSep
= " ";
735 for (const auto& rCollection
: aCollections
)
737 if (rCollection
.empty())
739 aOutput
+= rCollection
.dumpAsString() + pLevelSep
;
745 ScOutlineTable::ScOutlineTable()
749 ScOutlineTable::ScOutlineTable( const ScOutlineTable
& rOutline
) :
750 aColOutline( rOutline
.aColOutline
),
751 aRowOutline( rOutline
.aRowOutline
)
755 bool ScOutlineTable::TestInsertCol( SCSIZE nSize
)
757 return aColOutline
.TestInsertSpace( nSize
, MAXCOL
);
760 void ScOutlineTable::InsertCol( SCCOL nStartCol
, SCSIZE nSize
)
762 aColOutline
.InsertSpace( nStartCol
, nSize
);
765 bool ScOutlineTable::DeleteCol( SCCOL nStartCol
, SCSIZE nSize
)
767 return aColOutline
.DeleteSpace( nStartCol
, nSize
);
770 bool ScOutlineTable::TestInsertRow( SCSIZE nSize
)
772 return aRowOutline
.TestInsertSpace( nSize
, MAXROW
);
775 void ScOutlineTable::InsertRow( SCROW nStartRow
, SCSIZE nSize
)
777 aRowOutline
.InsertSpace( nStartRow
, nSize
);
780 bool ScOutlineTable::DeleteRow( SCROW nStartRow
, SCSIZE nSize
)
782 return aRowOutline
.DeleteSpace( nStartRow
, nSize
);
785 ScSubOutlineIterator::ScSubOutlineIterator( ScOutlineArray
* pOutlineArray
) :
786 pArray( pOutlineArray
),
788 nEnd( SCCOLROW_MAX
), // Iterate over all of them
792 nDepth
= pArray
->nDepth
;
795 ScSubOutlineIterator::ScSubOutlineIterator(
796 ScOutlineArray
* pOutlineArray
, size_t nLevel
, size_t nEntry
) :
797 pArray( pOutlineArray
)
799 const ScOutlineCollection
& rColl
= pArray
->aCollections
[nLevel
];
800 ScOutlineCollection::const_iterator it
= rColl
.begin();
801 std::advance(it
, nEntry
);
802 const ScOutlineEntry
* pEntry
= &it
->second
;
803 nStart
= pEntry
->GetStart();
804 nEnd
= pEntry
->GetEnd();
805 nSubLevel
= nLevel
+ 1;
807 nDepth
= pArray
->nDepth
;
810 ScOutlineEntry
* ScSubOutlineIterator::GetNext()
812 ScOutlineEntry
* pEntry
= nullptr;
816 if (nSubLevel
>= nDepth
)
819 ScOutlineCollection
& rColl
= pArray
->aCollections
[nSubLevel
];
820 if (nSubEntry
< rColl
.size())
822 ScOutlineCollection::iterator it
= rColl
.begin();
823 std::advance(it
, nSubEntry
);
824 pEntry
= &it
->second
;
826 if (pEntry
->GetStart() >= nStart
&& pEntry
->GetEnd() <= nEnd
)
833 // Go to the next sub-level
839 return pEntry
; // nSubLevel valid, if pEntry != 0
842 size_t ScSubOutlineIterator::LastEntry() const
846 OSL_FAIL("ScSubOutlineIterator::LastEntry before GetNext");
852 void ScSubOutlineIterator::DeleteLast()
854 if (nSubLevel
>= nDepth
)
856 OSL_FAIL("ScSubOutlineIterator::DeleteLast after End");
861 OSL_FAIL("ScSubOutlineIterator::DeleteLast before GetNext");
866 ScOutlineCollection
& rColl
= pArray
->aCollections
[nSubLevel
];
867 assert(nSubEntry
< rColl
.size());
868 ScOutlineCollection::iterator it
= rColl
.begin();
869 std::advance(it
, nSubEntry
);
873 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */