summaryrefslogtreecommitdiff
path: root/sc/source/core/data/olinetab.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core/data/olinetab.cxx')
-rw-r--r--sc/source/core/data/olinetab.cxx778
1 files changed, 778 insertions, 0 deletions
diff --git a/sc/source/core/data/olinetab.cxx b/sc/source/core/data/olinetab.cxx
new file mode 100644
index 000000000000..c7a2b0cec0f7
--- /dev/null
+++ b/sc/source/core/data/olinetab.cxx
@@ -0,0 +1,778 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// System - Includes -----------------------------------------------------
+
+
+
+#include <tools/debug.hxx>
+#include <limits.h>
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "olinetab.hxx"
+#include "global.hxx"
+#include "rechead.hxx"
+#include "address.hxx"
+#include "table.hxx"
+
+//------------------------------------------------------------------------
+
+ScOutlineEntry::ScOutlineEntry( SCCOLROW nNewStart, SCCOLROW nNewSize, bool bNewHidden ) :
+ nStart ( nNewStart ),
+ nSize ( nNewSize ),
+ bHidden ( bNewHidden ),
+ bVisible( TRUE )
+{
+}
+
+ScOutlineEntry::ScOutlineEntry( const ScOutlineEntry& rEntry ) :
+ ScDataObject(),
+ nStart ( rEntry.nStart ),
+ nSize ( rEntry.nSize ),
+ bHidden ( rEntry.bHidden ),
+ bVisible( rEntry.bVisible )
+{
+}
+
+ScDataObject* ScOutlineEntry::Clone() const
+{
+ return new ScOutlineEntry( *this );
+}
+
+void ScOutlineEntry::Move( SCsCOLROW nDelta )
+{
+ SCCOLROW nNewPos = nStart + nDelta;
+ if (nNewPos<0)
+ {
+ DBG_ERROR("OutlineEntry < 0");
+ nNewPos = 0;
+ }
+ nStart = nNewPos;
+}
+
+void ScOutlineEntry::SetSize( SCSIZE nNewSize )
+{
+ if (nNewSize>0)
+ nSize = nNewSize;
+ else
+ {
+ DBG_ERROR("ScOutlineEntry Size == 0");
+ }
+}
+
+void ScOutlineEntry::SetPosSize( SCCOLROW nNewPos, SCSIZE nNewSize )
+{
+ nStart = nNewPos;
+ SetSize( nNewSize );
+}
+
+void ScOutlineEntry::SetHidden( bool bNewHidden )
+{
+ bHidden = bNewHidden;
+}
+
+void ScOutlineEntry::SetVisible( bool bNewVisible )
+{
+ bVisible = bNewVisible;
+}
+
+//------------------------------------------------------------------------
+
+ScOutlineCollection::ScOutlineCollection() :
+ ScSortedCollection( 4,4,FALSE )
+{
+}
+
+inline short IntCompare( SCCOLROW nX, SCCOLROW nY )
+{
+ if ( nX==nY ) return 0;
+ else if ( nX<nY ) return -1;
+ else return 1;
+}
+
+short ScOutlineCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
+{
+ return IntCompare( ((ScOutlineEntry*)pKey1)->GetStart(),
+ ((ScOutlineEntry*)pKey2)->GetStart() );
+}
+
+USHORT ScOutlineCollection::FindStart( SCCOLROW nMinStart )
+{
+ //! binaer suchen ?
+
+ USHORT nPos = 0;
+ USHORT nLocalCount = GetCount();
+ while ( (nPos<nLocalCount) ? (((ScOutlineEntry*)At(nPos))->GetStart() < nMinStart) : FALSE )
+ ++nPos;
+
+ return nPos;
+}
+
+//------------------------------------------------------------------------
+
+ScOutlineArray::ScOutlineArray() :
+ nDepth( 0 )
+{
+}
+
+ScOutlineArray::ScOutlineArray( const ScOutlineArray& rArray ) :
+ nDepth( rArray.nDepth )
+{
+ for (USHORT nLevel=0; nLevel<nDepth; nLevel++)
+ {
+ USHORT nCount = rArray.aCollections[nLevel].GetCount();
+ for (USHORT nEntry=0; nEntry<nCount; nEntry++)
+ {
+ ScOutlineEntry* pEntry = (ScOutlineEntry*) rArray.aCollections[nLevel].At(nEntry);
+ aCollections[nLevel].Insert( new ScOutlineEntry( *pEntry ) );
+ }
+ }
+}
+
+void ScOutlineArray::FindEntry( SCCOLROW nSearchPos, USHORT& rFindLevel, USHORT& rFindIndex,
+ USHORT nMaxLevel )
+{
+ rFindLevel = rFindIndex = 0;
+
+ if (nMaxLevel > nDepth)
+ nMaxLevel = nDepth;
+
+ for (USHORT nLevel=0; nLevel<nMaxLevel; nLevel++) //! rueckwaerts suchen ?
+ {
+ ScOutlineCollection* pCollect = &aCollections[nLevel];
+ USHORT nCount = pCollect->GetCount();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
+ if ( pEntry->GetStart() <= nSearchPos && pEntry->GetEnd() >= nSearchPos )
+ {
+ rFindLevel = nLevel + 1; // naechster Level (zum Einfuegen)
+ rFindIndex = i;
+ }
+ }
+ }
+}
+
+BOOL ScOutlineArray::Insert( SCCOLROW nStartCol, SCCOLROW nEndCol, BOOL& rSizeChanged,
+ BOOL bHidden, BOOL bVisible )
+{
+ rSizeChanged = FALSE;
+
+ USHORT nStartLevel;
+ USHORT nStartIndex;
+ USHORT nEndLevel;
+ USHORT nEndIndex;
+ BOOL bFound = FALSE;
+
+ BOOL bCont;
+ USHORT nFindMax;
+ FindEntry( nStartCol, nStartLevel, nStartIndex ); // nLevel = neuer Level (alter+1) !!!
+ FindEntry( nEndCol, nEndLevel, nEndIndex );
+ nFindMax = Max(nStartLevel,nEndLevel);
+ do
+ {
+ bCont = FALSE;
+
+ if ( nStartLevel == nEndLevel && nStartIndex == nEndIndex && nStartLevel < SC_OL_MAXDEPTH )
+ bFound = TRUE;
+
+ if (!bFound)
+ {
+ if (nFindMax>0)
+ {
+ --nFindMax;
+ if (nStartLevel)
+ if ( ((ScOutlineEntry*)aCollections[nStartLevel-1].At(nStartIndex))->
+ GetStart() == nStartCol )
+ FindEntry( nStartCol, nStartLevel, nStartIndex, nFindMax );
+ if (nEndLevel)
+ if ( ((ScOutlineEntry*)aCollections[nEndLevel-1].At(nEndIndex))->
+ GetEnd() == nEndCol )
+ FindEntry( nEndCol, nEndLevel, nEndIndex, nFindMax );
+ bCont = TRUE;
+ }
+ }
+ }
+ while ( !bFound && bCont );
+
+ if (!bFound)
+ return FALSE;
+
+ USHORT nLevel = nStartLevel;
+
+ // untere verschieben
+
+ BOOL bNeedSize = FALSE;
+ for ( short nMoveLevel = nDepth-1; nMoveLevel >= (short) nLevel; nMoveLevel-- )
+ {
+ USHORT nCount = aCollections[nMoveLevel].GetCount();
+ BOOL bMoved = FALSE;
+ for ( USHORT i=0; i<nCount; i += bMoved ? 0 : 1 )
+ {
+ ScOutlineEntry* pEntry = (ScOutlineEntry*) aCollections[nMoveLevel].At(i);
+ SCCOLROW nEntryStart = pEntry->GetStart();
+ if ( nEntryStart >= nStartCol && nEntryStart <= nEndCol )
+ {
+ if (nMoveLevel >= SC_OL_MAXDEPTH - 1)
+ {
+ rSizeChanged = FALSE; // kein Platz
+ return FALSE;
+ }
+ aCollections[nMoveLevel+1].Insert( new ScOutlineEntry( *pEntry ) );
+ aCollections[nMoveLevel].AtFree( i );
+ nCount = aCollections[nMoveLevel].GetCount();
+ bMoved = TRUE;
+ if (nMoveLevel == (short) nDepth - 1)
+ bNeedSize = TRUE;
+ }
+ else
+ bMoved = FALSE;
+ }
+ }
+
+ if (bNeedSize)
+ {
+ ++nDepth;
+ rSizeChanged = TRUE;
+ }
+
+ if (nDepth <= nLevel)
+ {
+ nDepth = nLevel+1;
+ rSizeChanged = TRUE;
+ }
+
+ ScOutlineEntry* pNewEntry = new ScOutlineEntry( nStartCol, nEndCol+1-nStartCol, bHidden );
+ pNewEntry->SetVisible( bVisible );
+ aCollections[nLevel].Insert( pNewEntry );
+
+ return TRUE;
+}
+
+BOOL ScOutlineArray::FindTouchedLevel( SCCOLROW nBlockStart, SCCOLROW nBlockEnd, USHORT& rFindLevel ) const
+{
+ BOOL bFound = FALSE;
+ rFindLevel = 0;
+
+ for (USHORT nLevel=0; nLevel<nDepth; nLevel++)
+ {
+ const ScOutlineCollection* pCollect = &aCollections[nLevel];
+ USHORT nCount = pCollect->GetCount();
+ for (USHORT i=0; i<nCount; i++)
+ {
+ ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ if ( ( nBlockStart>=nStart && nBlockStart<=nEnd ) ||
+ ( nBlockEnd >=nStart && nBlockEnd <=nEnd ) )
+ {
+ rFindLevel = nLevel; // wirklicher Level
+ bFound = TRUE;
+ }
+ }
+ }
+
+ return bFound;
+}
+
+void ScOutlineArray::RemoveSub( SCCOLROW nStartPos, SCCOLROW nEndPos, USHORT nLevel )
+{
+ if ( nLevel >= nDepth )
+ return;
+ ScOutlineCollection* pCollect = &aCollections[nLevel];
+ USHORT nCount = pCollect->GetCount();
+ BOOL bFound = FALSE;
+ for ( USHORT i=0; i<nCount; i += ( bFound ? 0 : 1 ) )
+ {
+ bFound = FALSE;
+ ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ if ( nStart>=nStartPos && nEnd<=nEndPos )
+ {
+ RemoveSub( nStart, nEnd, nLevel+1 );
+ pCollect->AtFree(i);
+ nCount = pCollect->GetCount();
+ bFound = TRUE;
+ }
+ }
+}
+
+void ScOutlineArray::PromoteSub( SCCOLROW nStartPos, SCCOLROW nEndPos, USHORT nStartLevel )
+{
+ if (nStartLevel==0)
+ {
+ DBG_ERROR("PromoteSub mit Level 0");
+ return;
+ }
+
+ for (USHORT nLevel = nStartLevel; nLevel < nDepth; nLevel++)
+ {
+ ScOutlineCollection* pCollect = &aCollections[nLevel];
+ USHORT nCount = pCollect->GetCount();
+ BOOL bFound = FALSE;
+ for ( USHORT i=0; i<nCount; i += ( bFound ? 0 : 1 ) )
+ {
+ bFound = FALSE;
+ ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ if ( nStart>=nStartPos && nEnd<=nEndPos )
+ {
+ aCollections[nLevel-1].Insert( new ScOutlineEntry( *pEntry ) );
+ pCollect->AtFree(i);
+ nCount = pCollect->GetCount();
+ bFound = TRUE;
+ }
+ }
+ }
+}
+
+BOOL ScOutlineArray::DecDepth() // nDepth auf leere Levels anpassen
+{
+ BOOL bChanged = FALSE;
+ BOOL bCont;
+ do
+ {
+ bCont = FALSE;
+ if (nDepth)
+ if (aCollections[nDepth-1].GetCount() == 0)
+ {
+ --nDepth;
+ bChanged = TRUE;
+ bCont = TRUE;
+ }
+ }
+ while (bCont);
+ return bChanged;
+}
+
+BOOL ScOutlineArray::Remove( SCCOLROW nBlockStart, SCCOLROW nBlockEnd, BOOL& rSizeChanged )
+{
+ USHORT nLevel;
+ FindTouchedLevel( nBlockStart, nBlockEnd, nLevel );
+
+ ScOutlineCollection* pCollect = &aCollections[nLevel];
+ USHORT nCount = pCollect->GetCount();
+ BOOL bFound = FALSE;
+ BOOL bAny = FALSE;
+ for ( USHORT i=0; i<nCount; i += ( bFound ? 0 : 1 ) )
+ {
+ bFound = FALSE;
+ ScOutlineEntry* pEntry = (ScOutlineEntry*) pCollect->At(i);
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ if ( nBlockStart<=nEnd && nBlockEnd>=nStart )
+ {
+ pCollect->AtFree(i);
+ PromoteSub( nStart, nEnd, nLevel+1 );
+ nCount = pCollect->GetCount();
+ i = pCollect->FindStart( nEnd+1 );
+ bFound = TRUE;
+ bAny = TRUE;
+ }
+ }
+
+ if (bAny) // Depth anpassen
+ if (DecDepth())
+ rSizeChanged = TRUE;
+
+ return bAny;
+}
+
+ScOutlineEntry* ScOutlineArray::GetEntry( USHORT nLevel, USHORT nIndex ) const
+{
+ return (ScOutlineEntry*)((nLevel < nDepth) ? aCollections[nLevel].At(nIndex) : NULL);
+}
+
+USHORT ScOutlineArray::GetCount( USHORT nLevel ) const
+{
+ return (nLevel < nDepth) ? aCollections[nLevel].GetCount() : 0;
+}
+
+ScOutlineEntry* ScOutlineArray::GetEntryByPos( USHORT nLevel, SCCOLROW nPos ) const
+{
+ USHORT nCount = GetCount( nLevel );
+ ScOutlineEntry* pEntry;
+
+ for (USHORT nIndex = 0; nIndex < nCount; nIndex++)
+ {
+ pEntry = GetEntry( nLevel, nIndex );
+ if ((pEntry->GetStart() <= nPos) && (nPos <= pEntry->GetEnd()))
+ return pEntry;
+ }
+ return NULL;
+}
+
+BOOL ScOutlineArray::GetEntryIndex( USHORT nLevel, SCCOLROW nPos, USHORT& rnIndex ) const
+{
+ // found entry contains passed position
+ USHORT nCount = GetCount( nLevel );
+ for ( rnIndex = 0; rnIndex < nCount; ++rnIndex )
+ {
+ const ScOutlineEntry* pEntry = GetEntry( nLevel, rnIndex );
+ if ( (pEntry->GetStart() <= nPos) && (nPos <= pEntry->GetEnd()) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL ScOutlineArray::GetEntryIndexInRange(
+ USHORT nLevel, SCCOLROW nBlockStart, SCCOLROW nBlockEnd, USHORT& rnIndex ) const
+{
+ // found entry will be completely inside of passed range
+ USHORT nCount = GetCount( nLevel );
+ for ( rnIndex = 0; rnIndex < nCount; ++rnIndex )
+ {
+ const ScOutlineEntry* pEntry = GetEntry( nLevel, rnIndex );
+ if ( (nBlockStart <= pEntry->GetStart()) && (pEntry->GetEnd() <= nBlockEnd) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void ScOutlineArray::SetVisibleBelow( USHORT nLevel, USHORT nEntry, BOOL bValue, BOOL bSkipHidden )
+{
+ ScOutlineEntry* pEntry = GetEntry( nLevel, nEntry );
+ if( pEntry )
+ {
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ for (USHORT nSubLevel=nLevel+1; nSubLevel<nDepth; nSubLevel++)
+ {
+ USHORT i = 0;
+ pEntry = (ScOutlineEntry*) aCollections[nSubLevel].At(i);
+ while (pEntry)
+ {
+ if (pEntry->GetStart() >= nStart && pEntry->GetEnd() <= nEnd)
+ {
+ pEntry->SetVisible(bValue);
+
+ if (bSkipHidden)
+ if (!pEntry->IsHidden())
+ SetVisibleBelow( nSubLevel, i, bValue, TRUE );
+ }
+
+ ++i;
+ pEntry = (ScOutlineEntry*) aCollections[nSubLevel].At(i);
+ }
+
+ if (bSkipHidden)
+ nSubLevel = nDepth; // Abbruch
+ }
+ }
+}
+
+void ScOutlineArray::GetRange( SCCOLROW& rStart, SCCOLROW& rEnd ) const
+{
+ USHORT nCount = aCollections[0].GetCount();
+ if (nCount)
+ {
+ rStart = ((ScOutlineEntry*) aCollections[0].At(0))->GetStart();
+ rEnd = ((ScOutlineEntry*) aCollections[0].At(nCount-1))->GetEnd();
+ }
+ else
+ rStart = rEnd = 0;
+}
+
+void ScOutlineArray::ExtendBlock( USHORT nLevel, SCCOLROW& rBlkStart, SCCOLROW& rBlkEnd )
+{
+ USHORT nCount;
+ SCCOLROW nStart;
+ SCCOLROW nEnd;
+ USHORT i;
+ ScOutlineEntry* pEntry;
+
+ nCount = GetCount(nLevel);
+ for ( i=0; i<nCount; i++ )
+ {
+ pEntry = (ScOutlineEntry*) aCollections[nLevel].At(i);
+ nStart = pEntry->GetStart();
+ nEnd = pEntry->GetEnd();
+
+ if ( rBlkStart<=nEnd && rBlkEnd>=nStart )
+ {
+ if (nStart<rBlkStart) rBlkStart = nStart;
+ if (nEnd>rBlkEnd) rBlkEnd = nEnd;
+ }
+ }
+}
+
+BOOL ScOutlineArray::TestInsertSpace( SCSIZE nSize, SCCOLROW nMaxVal ) const
+{
+ USHORT nCount = aCollections[0].GetCount();
+ if (nCount)
+ {
+ SCCOLROW nEnd = ((ScOutlineEntry*) aCollections[0].At(nCount-1))->GetEnd();
+ return ( sal::static_int_cast<SCCOLROW>(nEnd+nSize) <= nMaxVal );
+ }
+
+ return TRUE;
+}
+
+void ScOutlineArray::InsertSpace( SCCOLROW nStartPos, SCSIZE nSize )
+{
+ ScSubOutlineIterator aIter( this );
+ ScOutlineEntry* pEntry;
+ while((pEntry=aIter.GetNext())!=NULL)
+ {
+ if ( pEntry->GetStart() >= nStartPos )
+ pEntry->Move(static_cast<SCsCOLROW>(nSize));
+ else
+ {
+ SCCOLROW nEnd = pEntry->GetEnd();
+ // immer erweitern, wenn innerhalb der Gruppe eingefuegt
+ // beim Einfuegen am Ende nur, wenn die Gruppe nicht ausgeblendet ist
+ if ( nEnd >= nStartPos || ( nEnd+1 >= nStartPos && !pEntry->IsHidden() ) )
+ {
+ SCSIZE nEntrySize = pEntry->GetSize();
+ nEntrySize += nSize;
+ pEntry->SetSize( nEntrySize );
+ }
+ }
+ }
+}
+
+BOOL ScOutlineArray::DeleteSpace( SCCOLROW nStartPos, SCSIZE nSize )
+{
+ SCCOLROW nEndPos = nStartPos + nSize - 1;
+ BOOL bNeedSave = FALSE; // Original fuer Undo benoetigt?
+ BOOL bChanged = FALSE; // fuer Test auf Level
+
+ ScSubOutlineIterator aIter( this );
+ ScOutlineEntry* pEntry;
+ while((pEntry=aIter.GetNext())!=NULL)
+ {
+ SCCOLROW nEntryStart = pEntry->GetStart();
+ SCCOLROW nEntryEnd = pEntry->GetEnd();
+ SCSIZE nEntrySize = pEntry->GetSize();
+
+ if ( nEntryEnd >= nStartPos )
+ {
+ if ( nEntryStart > nEndPos ) // rechts
+ pEntry->Move(-(static_cast<SCsCOLROW>(nSize)));
+ else if ( nEntryStart < nStartPos && nEntryEnd >= nEndPos ) // aussen
+ pEntry->SetSize( nEntrySize-nSize );
+ else
+ {
+ bNeedSave = TRUE;
+ if ( nEntryStart >= nStartPos && nEntryEnd <= nEndPos ) // innen
+ {
+ aIter.DeleteLast();
+ bChanged = TRUE;
+ }
+ else if ( nEntryStart >= nStartPos ) // rechts ueber
+ pEntry->SetPosSize( nStartPos, static_cast<SCSIZE>(nEntryEnd-nEndPos) );
+ else // links ueber
+ pEntry->SetSize( static_cast<SCSIZE>(nStartPos-nEntryStart) );
+ }
+ }
+ }
+
+ if (bChanged)
+ DecDepth();
+
+ return bNeedSave;
+}
+
+bool ScOutlineArray::ManualAction( SCCOLROW nStartPos, SCCOLROW nEndPos, bool bShow, ScTable& rTable, bool bCol )
+{
+ bool bModified = false;
+ ScSubOutlineIterator aIter( this );
+ ScOutlineEntry* pEntry;
+ while((pEntry=aIter.GetNext())!=NULL)
+ {
+ SCCOLROW nEntryStart = pEntry->GetStart();
+ SCCOLROW nEntryEnd = pEntry->GetEnd();
+
+ if (nEntryEnd>=nStartPos && nEntryStart<=nEndPos)
+ {
+ if ( pEntry->IsHidden() == bShow )
+ {
+ // #i12341# hide if all columns/rows are hidden, show if at least one
+ // is visible
+ SCCOLROW nEnd = rTable.LastHiddenColRow(nEntryStart, bCol);
+ bool bAllHidden = (nEntryEnd <= nEnd && nEnd <
+ ::std::numeric_limits<SCCOLROW>::max());
+
+ bool bToggle = ( bShow != bAllHidden );
+ if ( bToggle )
+ {
+ pEntry->SetHidden( !bShow );
+ SetVisibleBelow( aIter.LastLevel(), aIter.LastEntry(), bShow, bShow );
+ bModified = true;
+ }
+ }
+ }
+ }
+ return bModified;
+}
+
+void ScOutlineArray::RemoveAll()
+{
+ for (USHORT nLevel=0; nLevel<nDepth; nLevel++)
+ aCollections[nLevel].FreeAll();
+
+ nDepth = 0;
+}
+
+//------------------------------------------------------------------------
+
+ScOutlineTable::ScOutlineTable()
+{
+}
+
+ScOutlineTable::ScOutlineTable( const ScOutlineTable& rOutline ) :
+ aColOutline( rOutline.aColOutline ),
+ aRowOutline( rOutline.aRowOutline )
+{
+}
+
+BOOL ScOutlineTable::TestInsertCol( SCSIZE nSize )
+{
+ return aColOutline.TestInsertSpace( nSize, MAXCOL );
+}
+
+void ScOutlineTable::InsertCol( SCCOL nStartCol, SCSIZE nSize )
+{
+ aColOutline.InsertSpace( nStartCol, nSize );
+}
+
+BOOL ScOutlineTable::DeleteCol( SCCOL nStartCol, SCSIZE nSize )
+{
+ return aColOutline.DeleteSpace( nStartCol, nSize );
+}
+
+BOOL ScOutlineTable::TestInsertRow( SCSIZE nSize )
+{
+ return aRowOutline.TestInsertSpace( nSize, MAXROW );
+}
+
+void ScOutlineTable::InsertRow( SCROW nStartRow, SCSIZE nSize )
+{
+ aRowOutline.InsertSpace( nStartRow, nSize );
+}
+
+BOOL ScOutlineTable::DeleteRow( SCROW nStartRow, SCSIZE nSize )
+{
+ return aRowOutline.DeleteSpace( nStartRow, nSize );
+}
+
+//------------------------------------------------------------------------
+
+ScSubOutlineIterator::ScSubOutlineIterator( ScOutlineArray* pOutlineArray ) :
+ pArray( pOutlineArray ),
+ nStart( 0 ),
+ nEnd( SCCOLROW_MAX ), // alle durchgehen
+ nSubLevel( 0 ),
+ nSubEntry( 0 )
+{
+ nDepth = pArray->nDepth;
+}
+
+ScSubOutlineIterator::ScSubOutlineIterator( ScOutlineArray* pOutlineArray,
+ USHORT nLevel, USHORT nEntry ) :
+ pArray( pOutlineArray )
+{
+ ScOutlineEntry* pEntry = (ScOutlineEntry*) pArray->aCollections[nLevel].At(nEntry);
+ nStart = pEntry->GetStart();
+ nEnd = pEntry->GetEnd();
+ nSubLevel = nLevel + 1;
+ nSubEntry = 0;
+ nDepth = pArray->nDepth;
+}
+
+ScOutlineEntry* ScSubOutlineIterator::GetNext()
+{
+ ScOutlineEntry* pEntry;
+ BOOL bFound = FALSE;
+ do
+ {
+ if (nSubLevel >= nDepth)
+ return NULL;
+
+ pEntry = (ScOutlineEntry*) pArray->aCollections[nSubLevel].At(nSubEntry);
+ if (!pEntry)
+ {
+ nSubEntry = 0;
+ ++nSubLevel;
+ }
+ else
+ {
+ if ( pEntry->GetStart() >= nStart && pEntry->GetEnd() <= nEnd )
+ bFound = TRUE;
+ ++nSubEntry;
+ }
+ }
+ while (!bFound);
+ return pEntry; // nSubLevel gueltig, wenn pEntry != 0
+}
+
+USHORT ScSubOutlineIterator::LastLevel() const
+{
+ return nSubLevel;
+}
+
+USHORT ScSubOutlineIterator::LastEntry() const
+{
+ if (nSubEntry == 0)
+ {
+ DBG_ERROR("ScSubOutlineIterator::LastEntry vor GetNext");
+ return 0;
+ }
+ return nSubEntry-1;
+}
+
+void ScSubOutlineIterator::DeleteLast()
+{
+ if (nSubLevel >= nDepth)
+ {
+ DBG_ERROR("ScSubOutlineIterator::DeleteLast nach Ende");
+ return;
+ }
+ if (nSubEntry == 0)
+ {
+ DBG_ERROR("ScSubOutlineIterator::DeleteLast vor GetNext");
+ return;
+ }
+
+ --nSubEntry;
+ pArray->aCollections[nSubLevel].AtFree(nSubEntry);
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */