blob: 13d412df652f3fe5248379164326ef8f14dd5fd2 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
// INCLUDE ---------------------------------------------------------------
#include <vcl/sound.hxx>
#include <sfx2/bindings.hxx>
#include "olinefun.hxx"
#include "docsh.hxx"
#include "olinetab.hxx"
#include "undodat.hxx"
#include "globstr.hrc"
#include "sc.hrc"
//========================================================================
void lcl_InvalidateOutliner( SfxBindings* pBindings )
{
if ( pBindings )
{
pBindings->Invalidate( SID_OUTLINE_SHOW );
pBindings->Invalidate( SID_OUTLINE_HIDE );
pBindings->Invalidate( SID_OUTLINE_REMOVE );
pBindings->Invalidate( SID_STATUS_SUM ); // wegen ein-/ausblenden
pBindings->Invalidate( SID_ATTR_SIZE );
}
}
//------------------------------------------------------------------------
//! PaintWidthHeight zur DocShell verschieben?
void lcl_PaintWidthHeight( ScDocShell& rDocShell, SCTAB nTab,
sal_Bool bColumns, SCCOLROW nStart, SCCOLROW nEnd )
{
ScDocument* pDoc = rDocShell.GetDocument();
sal_uInt16 nParts = PAINT_GRID;
SCCOL nStartCol = 0;
SCROW nStartRow = 0;
SCCOL nEndCol = MAXCOL; // fuer Test auf Merge
SCROW nEndRow = MAXROW;
if ( bColumns )
{
nParts |= PAINT_TOP;
nStartCol = static_cast<SCCOL>(nStart);
nEndCol = static_cast<SCCOL>(nEnd);
}
else
{
nParts |= PAINT_LEFT;
nStartRow = nStart;
nEndRow = nEnd;
}
if (pDoc->HasAttrib( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
HASATTR_MERGED | HASATTR_OVERLAPPED ))
{
nStartCol = 0;
nStartRow = 0;
}
rDocShell.PostPaint( nStartCol,nStartRow,nTab, MAXCOL,MAXROW,nTab, nParts );
}
//------------------------------------------------------------------------
sal_Bool ScOutlineDocFunc::MakeOutline( const ScRange& rRange, sal_Bool bColumns, sal_Bool bRecord, sal_Bool bApi )
{
sal_Bool bSuccess = sal_False;
SCCOL nStartCol = rRange.aStart.Col();
SCROW nStartRow = rRange.aStart.Row();
SCCOL nEndCol = rRange.aEnd.Col();
SCROW nEndRow = rRange.aEnd.Row();
SCTAB nTab = rRange.aStart.Tab();
ScDocument* pDoc = rDocShell.GetDocument();
ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab, sal_True );
ScOutlineTable* pUndoTab = NULL;
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = sal_False;
if (bRecord)
pUndoTab = new ScOutlineTable( *pTable );
ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
sal_Bool bRes;
sal_Bool bSize = sal_False;
if ( bColumns )
bRes = pArray->Insert( nStartCol, nEndCol, bSize );
else
bRes = pArray->Insert( nStartRow, nEndRow, bSize );
if ( bRes )
{
if (bRecord)
{
rDocShell.GetUndoManager()->AddUndoAction(
new ScUndoMakeOutline( &rDocShell,
nStartCol,nStartRow,nTab,nEndCol,nEndRow,nTab,
pUndoTab, bColumns, sal_True ) );
}
if (pDoc->IsStreamValid(nTab))
pDoc->SetStreamValid(nTab, sal_False);
sal_uInt16 nParts = 0; // Datenbereich nicht geaendert
if ( bColumns )
nParts |= PAINT_TOP;
else
nParts |= PAINT_LEFT;
if ( bSize )
nParts |= PAINT_SIZE;
rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, nParts );
rDocShell.SetDocumentModified();
lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
bSuccess = sal_True;
}
else
{
if (!bApi)
rDocShell.ErrorMessage(STR_MSSG_MAKEOUTLINE_0); // "Gruppierung nicht moeglich"
delete pUndoTab;
}
return bSuccess;
}
sal_Bool ScOutlineDocFunc::RemoveOutline( const ScRange& rRange, sal_Bool bColumns, sal_Bool bRecord, sal_Bool bApi )
{
sal_Bool bDone = sal_False;
SCCOL nStartCol = rRange.aStart.Col();
SCROW nStartRow = rRange.aStart.Row();
SCCOL nEndCol = rRange.aEnd.Col();
SCROW nEndRow = rRange.aEnd.Row();
SCTAB nTab = rRange.aStart.Tab();
ScDocument* pDoc = rDocShell.GetDocument();
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = sal_False;
ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
if (pTable)
{
ScOutlineTable* pUndoTab = NULL;
if (bRecord)
pUndoTab = new ScOutlineTable( *pTable );
ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
sal_Bool bRes;
sal_Bool bSize = sal_False;
if ( bColumns )
bRes = pArray->Remove( nStartCol, nEndCol, bSize );
else
bRes = pArray->Remove( nStartRow, nEndRow, bSize );
if ( bRes )
{
if (bRecord)
{
rDocShell.GetUndoManager()->AddUndoAction(
new ScUndoMakeOutline( &rDocShell,
nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
pUndoTab, bColumns, sal_False ) );
}
if (pDoc->IsStreamValid(nTab))
pDoc->SetStreamValid(nTab, sal_False);
sal_uInt16 nParts = 0; // Datenbereich nicht geaendert
if ( bColumns )
nParts |= PAINT_TOP;
else
nParts |= PAINT_LEFT;
if ( bSize )
nParts |= PAINT_SIZE;
rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, nParts );
rDocShell.SetDocumentModified();
bDone = sal_True;
lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
// es wird nicht wieder eingeblendet -> kein UpdatePageBreaks
}
else
delete pUndoTab;
}
if (!bDone && !bApi)
rDocShell.ErrorMessage(STR_MSSG_REMOVEOUTLINE_0); // "Aufheben nicht moeglich"
return bDone;
}
sal_Bool ScOutlineDocFunc::RemoveAllOutlines( SCTAB nTab, sal_Bool bRecord, sal_Bool bApi )
{
sal_Bool bSuccess = sal_False;
ScDocument* pDoc = rDocShell.GetDocument();
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = sal_False;
ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
if (pTable)
{
if (bRecord)
{
SCCOLROW nCol1, nCol2, nRow1, nRow2;
pTable->GetColArray()->GetRange( nCol1, nCol2 );
pTable->GetRowArray()->GetRange( nRow1, nRow2 );
SCCOL nStartCol = static_cast<SCCOL>(nCol1);
SCROW nStartRow = nRow1;
SCCOL nEndCol = static_cast<SCCOL>(nCol2);
SCROW nEndRow = nRow2;
ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
pDoc->CopyToDocument( nStartCol, 0, nTab, nEndCol, MAXROW, nTab, IDF_NONE, sal_False, pUndoDoc );
pDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, sal_False, pUndoDoc );
ScOutlineTable* pUndoTab = new ScOutlineTable( *pTable );
rDocShell.GetUndoManager()->AddUndoAction(
new ScUndoRemoveAllOutlines( &rDocShell,
nStartCol, nStartRow, nTab,
nEndCol, nEndRow, nTab,
pUndoDoc, pUndoTab ) );
}
SelectLevel( nTab, sal_True, pTable->GetColArray()->GetDepth(), sal_False, sal_False, bApi );
SelectLevel( nTab, sal_False, pTable->GetRowArray()->GetDepth(), sal_False, sal_False, bApi );
pDoc->SetOutlineTable( nTab, NULL );
pDoc->UpdatePageBreaks( nTab );
if (pDoc->IsStreamValid(nTab))
pDoc->SetStreamValid(nTab, sal_False);
rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab,
PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE );
rDocShell.SetDocumentModified();
lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
bSuccess = sal_True;
}
else if (!bApi)
Sound::Beep();
return bSuccess;
}
//------------------------------------------------------------------------
sal_Bool ScOutlineDocFunc::AutoOutline( const ScRange& rRange, sal_Bool bRecord, sal_Bool bApi )
{
SCCOL nStartCol = rRange.aStart.Col();
SCROW nStartRow = rRange.aStart.Row();
SCCOL nEndCol = rRange.aEnd.Col();
SCROW nEndRow = rRange.aEnd.Row();
SCTAB nTab = rRange.aStart.Tab();
ScDocument* pDoc = rDocShell.GetDocument();
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = sal_False;
ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
ScDocument* pUndoDoc = NULL;
ScOutlineTable* pUndoTab = NULL;
if ( pTable )
{
if ( bRecord )
{
pUndoTab = new ScOutlineTable( *pTable );
SCCOLROW nCol1, nCol2, nRow1, nRow2;
pTable->GetColArray()->GetRange( nCol1, nCol2 );
pTable->GetRowArray()->GetRange( nRow1, nRow2 );
SCCOL nOutStartCol = static_cast<SCCOL>(nCol1);;
SCROW nOutStartRow = nRow1;
SCCOL nOutEndCol = static_cast<SCCOL>(nCol2);;
SCROW nOutEndRow = nRow2;
pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
pDoc->CopyToDocument( nOutStartCol, 0, nTab, nOutEndCol, MAXROW, nTab, IDF_NONE, sal_False, pUndoDoc );
pDoc->CopyToDocument( 0, nOutStartRow, nTab, MAXCOL, nOutEndRow, nTab, IDF_NONE, sal_False, pUndoDoc );
}
// einblenden
SelectLevel( nTab, sal_True, pTable->GetColArray()->GetDepth(), sal_False, sal_False, bApi );
SelectLevel( nTab, sal_False, pTable->GetRowArray()->GetDepth(), sal_False, sal_False, bApi );
pDoc->SetOutlineTable( nTab, NULL );
}
pDoc->DoAutoOutline( nStartCol,nStartRow, nEndCol,nEndRow, nTab );
if (bRecord)
{
rDocShell.GetUndoManager()->AddUndoAction(
new ScUndoAutoOutline( &rDocShell,
nStartCol, nStartRow, nTab,
nEndCol, nEndRow, nTab,
pUndoDoc, pUndoTab ) );
}
if (pDoc->IsStreamValid(nTab))
pDoc->SetStreamValid(nTab, sal_False);
rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_LEFT | PAINT_TOP | PAINT_SIZE );
rDocShell.SetDocumentModified();
lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
return sal_True;
}
//------------------------------------------------------------------------
sal_Bool ScOutlineDocFunc::SelectLevel( SCTAB nTab, sal_Bool bColumns, sal_uInt16 nLevel,
sal_Bool bRecord, sal_Bool bPaint, sal_Bool /* bApi */ )
{
ScDocument* pDoc = rDocShell.GetDocument();
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = sal_False;
ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); // ist schon da
if (!pTable)
return sal_False;
ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
if (!pArray)
return sal_False;
SCCOLROW nStart, nEnd;
pArray->GetRange( nStart, nEnd );
if ( bRecord )
{
ScOutlineTable* pUndoTab = new ScOutlineTable( *pTable );
ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
if (bColumns)
{
pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_False );
pDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, sal_False,
pUndoDoc );
}
else
{
pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, sal_True );
pDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, sal_False, pUndoDoc );
}
rDocShell.GetUndoManager()->AddUndoAction(
new ScUndoOutlineLevel( &rDocShell,
nStart, nEnd, nTab, //! start und end berechnen
pUndoDoc, pUndoTab,
bColumns, nLevel ) );
}
pDoc->IncSizeRecalcLevel( nTab );
ScSubOutlineIterator aIter( pArray ); // alle Eintraege
ScOutlineEntry* pEntry;
while ((pEntry=aIter.GetNext()) != NULL)
{
sal_uInt16 nThisLevel = aIter.LastLevel();
sal_Bool bShow = (nThisLevel < nLevel);
if (bShow) // einblenden
{
pEntry->SetHidden( sal_False );
pEntry->SetVisible( sal_True );
}
else if ( nThisLevel == nLevel ) // ausblenden
{
pEntry->SetHidden( sal_True );
pEntry->SetVisible( sal_True );
}
else // verdeckt
{
pEntry->SetVisible( sal_False );
}
SCCOLROW nThisStart = pEntry->GetStart();
SCCOLROW nThisEnd = pEntry->GetEnd();
for (SCCOLROW i=nThisStart; i<=nThisEnd; i++)
{
if ( bColumns )
pDoc->ShowCol( static_cast<SCCOL>(i), nTab, bShow );
else
{
// show several rows together, don't show filtered rows
SCROW nFilterEnd = i;
bool bFiltered = pDoc->RowFiltered( i, nTab, NULL, &nFilterEnd );
nFilterEnd = std::min( nThisEnd, nFilterEnd );
if ( !bShow || !bFiltered )
pDoc->ShowRows( i, nFilterEnd, nTab, bShow );
i = nFilterEnd;
}
}
}
pDoc->DecSizeRecalcLevel( nTab );
pDoc->UpdatePageBreaks( nTab );
if (bPaint)
lcl_PaintWidthHeight( rDocShell, nTab, bColumns, nStart, nEnd );
rDocShell.SetDocumentModified();
lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
return sal_True;
}
//------------------------------------------------------------------------
sal_Bool ScOutlineDocFunc::ShowMarkedOutlines( const ScRange& rRange, sal_Bool bRecord, sal_Bool bApi )
{
sal_Bool bDone = sal_False;
SCCOL nStartCol = rRange.aStart.Col();
SCROW nStartRow = rRange.aStart.Row();
SCCOL nEndCol = rRange.aEnd.Col();
SCROW nEndRow = rRange.aEnd.Row();
SCTAB nTab = rRange.aStart.Tab();
ScDocument* pDoc = rDocShell.GetDocument();
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = sal_False;
ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
if (pTable)
{
ScOutlineArray* pArray;
ScOutlineEntry* pEntry;
SCCOLROW nStart;
SCCOLROW nEnd;
SCCOLROW nMin;
SCCOLROW nMax;
SCCOLROW i;
if ( bRecord )
{
ScOutlineTable* pUndoTab = new ScOutlineTable( *pTable );
ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
pDoc->CopyToDocument( nStartCol, 0, nTab, nEndCol, MAXROW, nTab, IDF_NONE, sal_False, pUndoDoc );
pDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, sal_False, pUndoDoc );
rDocShell.GetUndoManager()->AddUndoAction(
new ScUndoOutlineBlock( &rDocShell,
nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
pUndoDoc, pUndoTab, sal_True ) );
}
pDoc->IncSizeRecalcLevel( nTab );
// Spalten
nMin=MAXCOL;
nMax=0;
pArray = pTable->GetColArray();
ScSubOutlineIterator aColIter( pArray );
while ((pEntry=aColIter.GetNext()) != NULL)
{
nStart = pEntry->GetStart();
nEnd = pEntry->GetEnd();
if ( nStart>=nStartCol && nEnd<=nEndCol )
{
pEntry->SetHidden( sal_False );
pEntry->SetVisible( sal_True );
if (nStart<nMin) nMin=nStart;
if (nEnd>nMax) nMax=nEnd;
}
}
for ( i=nMin; i<=nMax; i++ )
pDoc->ShowCol( static_cast<SCCOL>(i), nTab, sal_True );
// Zeilen
nMin=MAXROW;
nMax=0;
pArray = pTable->GetRowArray();
ScSubOutlineIterator aRowIter( pArray );
while ((pEntry=aRowIter.GetNext()) != NULL)
{
nStart = pEntry->GetStart();
nEnd = pEntry->GetEnd();
if ( nStart>=nStartRow && nEnd<=nEndRow )
{
pEntry->SetHidden( sal_False );
pEntry->SetVisible( sal_True );
if (nStart<nMin) nMin=nStart;
if (nEnd>nMax) nMax=nEnd;
}
}
for ( i=nMin; i<=nMax; i++ )
{
// show several rows together, don't show filtered rows
SCROW nFilterEnd = i;
bool bFiltered = pDoc->RowFiltered( i, nTab, NULL, &nFilterEnd );
nFilterEnd = std::min( nMax, nFilterEnd );
if ( !bFiltered )
pDoc->ShowRows( i, nFilterEnd, nTab, sal_True );
i = nFilterEnd;
}
pDoc->DecSizeRecalcLevel( nTab );
pDoc->UpdatePageBreaks( nTab );
rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_LEFT | PAINT_TOP );
rDocShell.SetDocumentModified();
bDone = sal_True;
lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
}
if (!bDone && !bApi)
Sound::Beep();
return bDone;
}
sal_Bool ScOutlineDocFunc::HideMarkedOutlines( const ScRange& rRange, sal_Bool bRecord, sal_Bool bApi )
{
sal_Bool bDone = sal_False;
SCCOL nStartCol = rRange.aStart.Col();
SCROW nStartRow = rRange.aStart.Row();
SCCOL nEndCol = rRange.aEnd.Col();
SCROW nEndRow = rRange.aEnd.Row();
SCTAB nTab = rRange.aStart.Tab();
ScDocument* pDoc = rDocShell.GetDocument();
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = sal_False;
ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
if (pTable)
{
ScOutlineEntry* pEntry;
sal_uInt16 nColLevel;
sal_uInt16 nRowLevel;
sal_uInt16 nCount;
SCCOLROW nStart;
SCCOLROW nEnd;
sal_uInt16 i;
SCCOLROW nEffStartCol = nStartCol;
SCCOLROW nEffEndCol = nEndCol;
ScOutlineArray* pColArray = pTable->GetColArray();
pColArray->FindTouchedLevel( nStartCol, nEndCol, nColLevel );
pColArray->ExtendBlock( nColLevel, nEffStartCol, nEffEndCol );
SCCOLROW nEffStartRow = nStartRow;
SCCOLROW nEffEndRow = nEndRow;
ScOutlineArray* pRowArray = pTable->GetRowArray();
pRowArray->FindTouchedLevel( nStartRow, nEndRow, nRowLevel );
pRowArray->ExtendBlock( nRowLevel, nEffStartRow, nEffEndRow );
if ( bRecord )
{
ScOutlineTable* pUndoTab = new ScOutlineTable( *pTable );
ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
pDoc->CopyToDocument( static_cast<SCCOL>(nEffStartCol), 0, nTab,
static_cast<SCCOL>(nEffEndCol), MAXROW, nTab, IDF_NONE,
sal_False, pUndoDoc );
pDoc->CopyToDocument( 0, nEffStartRow, nTab, MAXCOL, nEffEndRow, nTab, IDF_NONE, sal_False, pUndoDoc );
rDocShell.GetUndoManager()->AddUndoAction(
new ScUndoOutlineBlock( &rDocShell,
nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
pUndoDoc, pUndoTab, sal_False ) );
}
pDoc->IncSizeRecalcLevel( nTab );
// Spalten
nCount = pColArray->GetCount(nColLevel);
for ( i=0; i<nCount; i++ )
{
pEntry = pColArray->GetEntry(nColLevel,i);
nStart = pEntry->GetStart();
nEnd = pEntry->GetEnd();
if ( static_cast<SCCOLROW>(nStartCol)<=nEnd && static_cast<SCCOLROW>(nEndCol)>=nStart )
HideOutline( nTab, sal_True, nColLevel, i, sal_False, sal_False, bApi );
}
// Zeilen
nCount = pRowArray->GetCount(nRowLevel);
for ( i=0; i<nCount; i++ )
{
pEntry = pRowArray->GetEntry(nRowLevel,i);
nStart = pEntry->GetStart();
nEnd = pEntry->GetEnd();
if ( nStartRow<=nEnd && nEndRow>=nStart )
HideOutline( nTab, sal_False, nRowLevel, i, sal_False, sal_False, bApi );
}
pDoc->DecSizeRecalcLevel( nTab );
pDoc->UpdatePageBreaks( nTab );
rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_LEFT | PAINT_TOP );
rDocShell.SetDocumentModified();
bDone = sal_True;
lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
}
if (!bDone && !bApi)
Sound::Beep();
return bDone;
}
//------------------------------------------------------------------------
sal_Bool ScOutlineDocFunc::ShowOutline( SCTAB nTab, sal_Bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry,
sal_Bool bRecord, sal_Bool bPaint, sal_Bool /* bApi */ )
{
ScDocument* pDoc = rDocShell.GetDocument();
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = sal_False;
ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
ScOutlineEntry* pEntry = pArray->GetEntry( nLevel, nEntry );
SCCOLROW nStart = pEntry->GetStart();
SCCOLROW nEnd = pEntry->GetEnd();
if ( bRecord )
{
ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
if (bColumns)
{
pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_False );
pDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, sal_False,
pUndoDoc );
}
else
{
pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, sal_True );
pDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, sal_False, pUndoDoc );
}
rDocShell.GetUndoManager()->AddUndoAction(
new ScUndoDoOutline( &rDocShell,
nStart, nEnd, nTab, pUndoDoc, //! start und end berechnen
bColumns, nLevel, nEntry, sal_True ) );
}
//! HideCursor();
pDoc->IncSizeRecalcLevel( nTab );
pEntry->SetHidden(sal_False);
SCCOLROW i;
for ( i = nStart; i <= nEnd; i++ )
{
if ( bColumns )
pDoc->ShowCol( static_cast<SCCOL>(i), nTab, sal_True );
else
{
// show several rows together, don't show filtered rows
SCROW nFilterEnd = i;
bool bFiltered = pDoc->RowFiltered( i, nTab, NULL, &nFilterEnd );
nFilterEnd = std::min( nEnd, nFilterEnd );
if ( !bFiltered )
pDoc->ShowRows( i, nFilterEnd, nTab, sal_True );
i = nFilterEnd;
}
}
ScSubOutlineIterator aIter( pArray, nLevel, nEntry );
while ((pEntry=aIter.GetNext()) != NULL)
{
if ( pEntry->IsHidden() )
{
SCCOLROW nSubStart = pEntry->GetStart();
SCCOLROW nSubEnd = pEntry->GetEnd();
if ( bColumns )
for ( i = nSubStart; i <= nSubEnd; i++ )
pDoc->ShowCol( static_cast<SCCOL>(i), nTab, sal_False );
else
pDoc->ShowRows( nSubStart, nSubEnd, nTab, sal_False );
}
}
pArray->SetVisibleBelow( nLevel, nEntry, sal_True, sal_True );
pDoc->DecSizeRecalcLevel( nTab );
pDoc->InvalidatePageBreaks(nTab);
pDoc->UpdatePageBreaks( nTab );
if (bPaint)
lcl_PaintWidthHeight( rDocShell, nTab, bColumns, nStart, nEnd );
//! ShowCursor();
rDocShell.SetDocumentModified();
//! if (bPaint)
//! UpdateScrollBars();
lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
return sal_True; //! immer ???
}
sal_Bool ScOutlineDocFunc::HideOutline( SCTAB nTab, sal_Bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry,
sal_Bool bRecord, sal_Bool bPaint, sal_Bool /* bApi */ )
{
ScDocument* pDoc = rDocShell.GetDocument();
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = sal_False;
ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
ScOutlineEntry* pEntry = pArray->GetEntry( nLevel, nEntry );
SCCOLROW nStart = pEntry->GetStart();
SCCOLROW nEnd = pEntry->GetEnd();
if ( bRecord )
{
ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
if (bColumns)
{
pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_False );
pDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, sal_False,
pUndoDoc );
}
else
{
pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, sal_True );
pDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, sal_False, pUndoDoc );
}
rDocShell.GetUndoManager()->AddUndoAction(
new ScUndoDoOutline( &rDocShell,
nStart, nEnd, nTab, pUndoDoc,
bColumns, nLevel, nEntry, sal_False ) );
}
//! HideCursor();
pDoc->IncSizeRecalcLevel( nTab );
pEntry->SetHidden(sal_True);
SCCOLROW i;
if ( bColumns )
for ( i = nStart; i <= nEnd; i++ )
pDoc->ShowCol( static_cast<SCCOL>(i), nTab, sal_False );
else
pDoc->ShowRows( nStart, nEnd, nTab, sal_False );
pArray->SetVisibleBelow( nLevel, nEntry, sal_False );
pDoc->DecSizeRecalcLevel( nTab );
pDoc->InvalidatePageBreaks(nTab);
pDoc->UpdatePageBreaks( nTab );
if (bPaint)
lcl_PaintWidthHeight( rDocShell, nTab, bColumns, nStart, nEnd );
//! ShowCursor();
rDocShell.SetDocumentModified();
//! if (bPaint)
//! UpdateScrollBars();
lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
return sal_True; //! immer ???
}