diff options
Diffstat (limited to 'sc/source/core/data/table2.cxx')
-rw-r--r-- | sc/source/core/data/table2.cxx | 77 |
1 files changed, 64 insertions, 13 deletions
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index e3f04f95e35c..86dd93da383b 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -774,6 +774,9 @@ void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, pDestTab->pRowFlags->CopyFrom(*pRowFlags, nRow1, nRow2); // Hidden flags. + // #i116164# Collect information first, then apply the changes, + // so RowHidden doesn't rebuild the tree for each row range. + std::vector<ScShowRowsEntry> aEntries; for (SCROW i = nRow1; i <= nRow2; ++i) { SCROW nThisLastRow, nDestLastRow; @@ -786,7 +789,8 @@ void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, // the last row shouldn't exceed the upper bound the caller specified. nLastRow = nRow2; - pDestTab->SetRowHidden(i, nLastRow, bThisHidden); + //pDestTab->SetRowHidden(i, nLastRow, bThisHidden); + aEntries.push_back(ScShowRowsEntry(i, nLastRow, bThisHidden)); bool bThisHiddenChange = (bThisHidden != bDestHidden); if (bThisHiddenChange && pCharts) @@ -802,6 +806,19 @@ void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, i = nLastRow; } + std::vector<ScShowRowsEntry>::const_iterator aEnd = aEntries.end(); + std::vector<ScShowRowsEntry>::const_iterator aIter = aEntries.begin(); + if ( aIter != aEnd ) + { + pDestTab->mpHiddenRows->setInsertFromBack(true); // important for undo document + while (aIter != aEnd) + { + pDestTab->SetRowHidden(aIter->mnRow1, aIter->mnRow2, !aIter->mbShow); + ++aIter; + } + pDestTab->mpHiddenRows->setInsertFromBack(false); + } + // Filtered flags. for (SCROW i = nRow1; i <= nRow2; ++i) { @@ -2628,10 +2645,10 @@ void ScTable::DBShowRow(SCROW nRow, bool bShow) } -void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow) +void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow, bool bSetFlags) { + // #i116164# IncRecalcLevel/DecRecalcLevel is in ScTable::Query SCROW nStartRow = nRow1; - IncRecalcLevel(); InitializeNoteCaptions(); while (nStartRow <= nRow2) { @@ -2641,7 +2658,7 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow) nEndRow = nRow2; BOOL bChanged = ( bWasVis != bShow ); - if ( bChanged ) + if ( bChanged && bSetFlags ) { ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); if (pDrawLayer) @@ -2654,8 +2671,13 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow) } } - SetRowHidden(nStartRow, nEndRow, !bShow); - SetRowFiltered(nStartRow, nEndRow, !bShow); + // #i116164# Directly modify the flags only if there are drawing objects within the area. + // Otherwise, all modifications are made together in ScTable::Query, so the tree isn't constantly rebuilt. + if ( bSetFlags ) + { + SetRowHidden(nStartRow, nEndRow, !bShow); + SetRowFiltered(nStartRow, nEndRow, !bShow); + } if ( bChanged ) { @@ -2672,8 +2694,6 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow) // to be done here. if (pOutlineTable) UpdateOutlineRow( nRow1, nRow2, bShow ); - - DecRecalcLevel(); } @@ -2682,6 +2702,14 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, bool bShow) SCROW nStartRow = nRow1; IncRecalcLevel(); InitializeNoteCaptions(); + + // #i116164# if there are no drawing objects within the row range, a single HeightChanged call is enough + ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); + bool bHasObjects = pDrawLayer && pDrawLayer->HasObjectsInRows( nTab, nRow1, nRow2, false ); + long nOldHeight = 0; + if ( pDrawLayer && !bHasObjects ) + nOldHeight = static_cast<long>(GetRowHeight(nRow1, nRow2)); + while (nStartRow <= nRow2) { SCROW nEndRow = -1; @@ -2690,9 +2718,8 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, bool bShow) nEndRow = nRow2; BOOL bChanged = ( bWasVis != bShow ); - if ( bChanged ) + if ( bChanged && bHasObjects ) { - ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); if (pDrawLayer) { long nHeight = static_cast<long>(mpRowHeights->getSumValue(nStartRow, nEndRow)); @@ -2703,9 +2730,14 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, bool bShow) } } - SetRowHidden(nStartRow, nEndRow, !bShow); - if (bShow) - SetRowFiltered(nStartRow, nEndRow, false); + // #i116164# Directly modify the flags only if there are drawing objects within the area. + // Otherwise, all rows are modified together after the loop, so the tree isn't constantly rebuilt. + if ( bHasObjects ) + { + SetRowHidden(nStartRow, nEndRow, !bShow); + if (bShow) + SetRowFiltered(nStartRow, nEndRow, false); + } if ( bChanged ) { @@ -2718,6 +2750,25 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, bool bShow) nStartRow = nEndRow + 1; } + + if ( !bHasObjects ) + { + // #i116164# set the flags for the whole range at once + SetRowHidden(nRow1, nRow2, !bShow); + if (bShow) + SetRowFiltered(nRow1, nRow2, false); + + if ( pDrawLayer ) + { + // if there are no objects in the range, a single HeightChanged call is enough + long nNewHeight = 0; + if ( bShow ) + nNewHeight = static_cast<long>(GetRowHeight(nRow1, nRow2)); + if ( nNewHeight != nOldHeight ) + pDrawLayer->HeightChanged( nTab, nRow1, nNewHeight - nOldHeight ); + } + } + DecRecalcLevel(); } |