diff options
Diffstat (limited to 'sc/source/core/data/table2.cxx')
-rw-r--r-- | sc/source/core/data/table2.cxx | 699 |
1 files changed, 454 insertions, 245 deletions
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 69d16df7be58..9bd5b031fde5 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -56,7 +56,9 @@ #include "fillinfo.hxx" #include "bcaslot.hxx" #include "postit.hxx" +#include "sheetevents.hxx" #include "globstr.hrc" +#include "segmenttree.hxx" #include <math.h> @@ -97,6 +99,27 @@ void ScTable::StartOutlineTable() } +void ScTable::SetSheetEvents( const ScSheetEvents* pNew ) +{ + delete pSheetEvents; + if (pNew) + pSheetEvents = new ScSheetEvents(*pNew); + else + pSheetEvents = NULL; + + SetCalcNotification( FALSE ); // discard notifications before the events were set + + if (IsStreamValid()) + SetStreamValid(FALSE); +} + + +void ScTable::SetCalcNotification( BOOL bSet ) +{ + bCalcNotification = bSet; +} + + BOOL ScTable::TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCSIZE nSize ) { BOOL bTest = TRUE; @@ -117,22 +140,28 @@ void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE InitializeNoteCaptions(); if (nStartCol==0 && nEndCol==MAXCOL) { - if (pRowHeight && pRowFlags) + if (mpRowHeights && pRowFlags) { - pRowHeight->Insert( nStartRow, nSize); + mpRowHeights->insertSegment(nStartRow, nSize, false); BYTE nNewFlags = pRowFlags->Insert( nStartRow, nSize); // only copy manual size flag, clear all others if (nNewFlags && (nNewFlags != CR_MANUALSIZE)) pRowFlags->SetValue( nStartRow, nStartRow + nSize - 1, nNewFlags & CR_MANUALSIZE); } + if (pOutlineTable) pOutlineTable->InsertRow( nStartRow, nSize ); + + mpFilteredRows->insertSegment(nStartRow, nSize, true); + mpHiddenRows->insertSegment(nStartRow, nSize, true); } for (SCCOL j=nStartCol; j<=nEndCol; j++) aCol[j].InsertRow( nStartRow, nSize ); DecRecalcLevel( false ); + + InvalidatePageBreaks(); } @@ -143,15 +172,19 @@ void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE InitializeNoteCaptions(); if (nStartCol==0 && nEndCol==MAXCOL) { - if (pRowHeight && pRowFlags) - { - pRowHeight->Remove( nStartRow, nSize); + if (pRowFlags) pRowFlags->Remove( nStartRow, nSize); - } + + if (mpRowHeights) + mpRowHeights->removeSegment(nStartRow, nStartRow+nSize); + if (pOutlineTable) if (pOutlineTable->DeleteRow( nStartRow, nSize )) if (pUndoOutline) *pUndoOutline = TRUE; + + mpFilteredRows->removeSegment(nStartRow, nStartRow+nSize); + mpHiddenRows->removeSegment(nStartRow, nStartRow+nSize); } { // scope for bulk broadcast @@ -160,6 +193,8 @@ void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE aCol[j].DeleteRow( nStartRow, nSize ); } DecRecalcLevel(); + + InvalidatePageBreaks(); } @@ -195,6 +230,9 @@ void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE } if (pOutlineTable) pOutlineTable->InsertCol( nStartCol, nSize ); + + mpHiddenCols->insertSegment(nStartCol, static_cast<SCCOL>(nSize), true); + mpFilteredCols->insertSegment(nStartCol, static_cast<SCCOL>(nSize), true); } @@ -226,6 +264,8 @@ void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE } } DecRecalcLevel(); + + InvalidatePageBreaks(); } @@ -247,6 +287,10 @@ void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE if (pOutlineTable->DeleteCol( nStartCol, nSize )) if (pUndoOutline) *pUndoOutline = TRUE; + + SCCOL nRmSize = nStartCol + static_cast<SCCOL>(nSize); + mpHiddenCols->removeSegment(nStartCol, nRmSize); + mpFilteredCols->removeSegment(nStartCol, nRmSize); } @@ -268,6 +312,8 @@ void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE aCol[nStartCol + nSize + i].MoveTo(nStartRow, nEndRow, aCol[nStartCol + i]); } DecRecalcLevel(); + + InvalidatePageBreaks(); } @@ -339,20 +385,21 @@ void ScTable::CopyToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, // copy widths/heights, and only "hidden", "filtered" and "manual" flags // also for all preceding columns/rows, to have valid positions for drawing objects - if (pColFlags && pTable->pColFlags && pColWidth && pTable->pColWidth) + if (pColWidth && pTable->pColWidth) for (i=0; i<=nCol2; i++) - { - pTable->pColFlags[i] = pColFlags[i] & CR_HIDDEN; pTable->pColWidth[i] = pColWidth[i]; - } - if (pRowFlags && pTable->pRowFlags && pRowHeight && pTable->pRowHeight) + pTable->CopyColHidden(*this, 0, nCol2); + pTable->CopyColFiltered(*this, 0, nCol2); + + if (pRowFlags && pTable->pRowFlags && mpRowHeights && pTable->mpRowHeights) { - pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2, - (CR_HIDDEN | CR_FILTERED | CR_MANUALSIZE)); - pTable->pRowHeight->CopyFrom( *pRowHeight, 0, nRow2); + pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2, CR_MANUALSIZE); + pTable->CopyRowHeight(*this, 0, nRow2, 0); } + pTable->CopyRowHidden(*this, 0, nRow2); + pTable->CopyRowFiltered(*this, 0, nRow2); // ggf. Formeln durch Werte ersetzen @@ -393,10 +440,10 @@ void ScTable::CopyFromClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, for (i=nCol1; i<=nCol2; i++) pColWidth[i] = pTable->pColWidth[i-nDx]; - if (nCol1==0 && nCol2==MAXCOL && pRowHeight && pTable->pRowHeight && + if (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pTable->mpRowHeights && pRowFlags && pTable->pRowFlags) { - pRowHeight->CopyFrom( *pTable->pRowHeight, nRow1, nRow2, -nDy); + CopyRowHeight(*pTable, nRow1, nRow2, -nDy); // Must copy CR_MANUALSIZE bit too, otherwise pRowHeight doesn't make sense for (SCROW j=nRow1; j<=nRow2; j++) { @@ -631,8 +678,10 @@ void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, // Charts muessen beim Ein-/Ausblenden angepasst werden ScChartListenerCollection* pCharts = pDestTab->pDocument->GetChartListenerCollection(); + bool bFlagChange = false; + BOOL bWidth = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth); - BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && pRowHeight && pDestTab->pRowHeight); + BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pDestTab->mpRowHeights); if (bWidth||bHeight) { @@ -641,33 +690,77 @@ void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, if (bWidth) for (SCCOL i=nCol1; i<=nCol2; i++) { - BOOL bChange = pCharts && - ( pDestTab->pColFlags[i] & CR_HIDDEN ) != ( pColFlags[i] & CR_HIDDEN ); + bool bThisHidden = ColHidden(i); + bool bHiddenChange = (pDestTab->ColHidden(i) != bThisHidden); + bool bChange = bHiddenChange || (pDestTab->pColWidth[i] != pColWidth[i]); pDestTab->pColWidth[i] = pColWidth[i]; pDestTab->pColFlags[i] = pColFlags[i]; + pDestTab->SetColHidden(i, i, bThisHidden); //! Aenderungen zusammenfassen? - if (bChange) + if (bHiddenChange && pCharts) pCharts->SetRangeDirty(ScRange( i, 0, nTab, i, MAXROW, nTab )); + + if (bChange) + bFlagChange = true; } if (bHeight) { - pDestTab->pRowHeight->CopyFrom( *pRowHeight, nRow1, nRow2); - for (SCROW i=nRow1; i<=nRow2; i++) + bool bChange = pDestTab->GetRowHeight(nRow1, nRow2) != GetRowHeight(nRow1, nRow2); + + if (bChange) + bFlagChange = true; + + pDestTab->CopyRowHeight(*this, nRow1, nRow2, 0); + pDestTab->pRowFlags->CopyFrom(*pRowFlags, nRow1, nRow2); + + // Hidden flags. + for (SCROW i = nRow1; i <= nRow2; ++i) { - // TODO: might need some performance improvement, block - // operations instead of single GetValue()/SetValue() calls. - BYTE nThisRowFlags = pRowFlags->GetValue(i); - BOOL bChange = pCharts && - ( pDestTab->pRowFlags->GetValue(i) & CR_HIDDEN ) != ( nThisRowFlags & CR_HIDDEN ); - pDestTab->pRowFlags->SetValue( i, nThisRowFlags ); - //! Aenderungen zusammenfassen? - if (bChange) - pCharts->SetRangeDirty(ScRange( 0, i, nTab, MAXCOL, i, nTab )); + SCROW nThisLastRow, nDestLastRow; + bool bThisHidden = RowHidden(i, NULL, &nThisLastRow); + bool bDestHidden = pDestTab->RowHidden(i, NULL, &nDestLastRow); + + // If the segment sizes differ, we take the shorter segment of the two. + SCROW nLastRow = ::std::min(nThisLastRow, nDestLastRow); + if (nLastRow >= nRow2) + // the last row shouldn't exceed the upper bound the caller specified. + nLastRow = nRow2; + + pDestTab->SetRowHidden(i, nLastRow, bThisHidden); + + bool bThisHiddenChange = (bThisHidden != bDestHidden); + if (bThisHiddenChange && pCharts) + { + // Hidden flags differ. + pCharts->SetRangeDirty(ScRange(0, i, nTab, MAXCOL, nLastRow, nTab)); + } + + if (bThisHiddenChange) + bFlagChange = true; + + // Jump to the last row of the identical flag segment. + i = nLastRow; + } + + // Filtered flags. + for (SCROW i = nRow1; i <= nRow2; ++i) + { + SCROW nLastRow; + bool bFiltered = RowFiltered(i, NULL, &nLastRow); + if (nLastRow >= nRow2) + // the last row shouldn't exceed the upper bound the caller specified. + nLastRow = nRow2; + pDestTab->SetRowFiltered(i, nLastRow, bFiltered); + i = nLastRow; } } pDestTab->DecRecalcLevel(); } + + if (bFlagChange) + pDestTab->InvalidatePageBreaks(); + pDestTab->SetOutlineTable( pOutlineTable ); // auch nur wenn bColRowFlags } } @@ -681,7 +774,7 @@ void ScTable::UndoToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2)) { BOOL bWidth = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth); - BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && pRowHeight && pDestTab->pRowHeight); + BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pDestTab->mpRowHeights); if (bWidth||bHeight) IncRecalcLevel(); @@ -701,8 +794,8 @@ void ScTable::UndoToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, for (SCCOL i=nCol1; i<=nCol2; i++) pDestTab->pColWidth[i] = pColWidth[i]; if (bHeight) - pDestTab->pRowHeight->CopyFrom( *pRowHeight, nRow1, nRow2); - DecRecalcLevel(); + pDestTab->CopyRowHeight(*this, nRow1, nRow2, 0); + DecRecalcLevel(); } } } @@ -714,6 +807,16 @@ void ScTable::CopyUpdated( const ScTable* pPosTab, ScTable* pDestTab ) const aCol[i].CopyUpdated( pPosTab->aCol[i], pDestTab->aCol[i] ); } +void ScTable::InvalidateTableArea() +{ + bTableAreaValid = FALSE; +} + +void ScTable::InvalidatePageBreaks() +{ + mbPageBreaksValid = false; +} + void ScTable::CopyScenarioTo( ScTable* pDestTab ) const { DBG_ASSERT( bScenario, "bScenario == FALSE" ); @@ -1093,6 +1196,17 @@ void ScTable::SetRelNameDirty() } +void ScTable::SetLoadingMedium(bool bLoading) +{ + mpRowHeights->enableTreeSearch(!bLoading); + + // When loading a medium, prefer inserting row heights from the back + // position since the row heights are stored and read in ascending order + // during import. + mpRowHeights->setInsertFromBack(bLoading); +} + + void ScTable::CalcAll() { for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CalcAll(); @@ -1240,7 +1354,7 @@ BOOL ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2, SCCOL nCol, SCROW nAttrRow1, SCROW nAttrRow2, SCSIZE nArrY, - const ScPatternAttr* pPattern, const SfxItemSet* pCondSet ) const + const ScPatternAttr* pPattern, const SfxItemSet* pCondSet ) { // Rueckgabe = neues nArrY @@ -1273,7 +1387,7 @@ SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCO for ( SCROW nRow = nAttrRow1; nRow <= nAttrRow2; nRow++ ) { - if ( !(pRowFlags->GetValue(nRow) & CR_HIDDEN) ) + if (!RowHidden(nRow)) { BOOL bHitOne = TRUE; if ( nCol > nX2+1 ) @@ -1281,7 +1395,7 @@ SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCO // reicht die gedrehte Zelle bis in den sichtbaren Bereich? SCCOL nTouchedCol = nCol; - long nWidth = (long) ( pRowHeight->GetValue(nRow) * nFactor ); + long nWidth = static_cast<long>(mpRowHeights->getValue(nRow) * nFactor); DBG_ASSERT(nWidth <= 0, "Richtung falsch"); while ( nWidth < 0 && nTouchedCol > 0 ) { @@ -1307,9 +1421,9 @@ SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCO return nArrY; } -void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2 ) const +void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2 ) { - if ( !pColWidth || !pRowHeight || !pColFlags || !pRowFlags ) + if ( !pColWidth || !mpRowHeights || !pColFlags || !pRowFlags ) { DBG_ERROR( "Spalten-/Zeileninfo fehlt" ); return; @@ -1322,7 +1436,7 @@ void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCC for (SCCOL nCol=0; nCol<=MAXCOL; nCol++) { - if ( !(pColFlags[nCol] & CR_HIDDEN) ) + if (!ColHidden(nCol)) { SCSIZE nArrY = 0; ScDocAttrIterator aIter( pDocument, nTab, nCol, nY1, nCol, nY2 ); @@ -1837,36 +1951,24 @@ void ScTable::StyleSheetChanged( const SfxStyleSheetBase* pStyleSheet, BOOL bRem double nPPTX, double nPPTY, const Fraction& rZoomX, const Fraction& rZoomY ) { - BOOL* pUsed = new BOOL[MAXROWCOUNT]; - memset( pUsed, 0, sizeof(BOOL) * (MAXROWCOUNT) ); + ScFlatBoolRowSegments aUsedRows; + for (SCCOL i = 0; i <= MAXCOL; ++i) + aCol[i].FindStyleSheet(pStyleSheet, aUsedRows, bRemoved); - SCCOL nCol; - for (nCol=0; nCol<=MAXCOL; nCol++) - aCol[nCol].FindStyleSheet( pStyleSheet, pUsed, bRemoved ); - - BOOL bFound = FALSE; - SCROW nStart = 0, nEnd = 0; - for (SCROW i=0; i<=MAXROW; i++) + SCROW nRow = 0; + while (nRow <= MAXROW) { - if (pUsed[i]) - { - if (!bFound) - { - nStart = i; - bFound = TRUE; - } - nEnd = i; - } - else if (bFound) - { - SetOptimalHeight( nStart, nEnd, 0, pDev, nPPTX, nPPTY, rZoomX, rZoomY, FALSE ); - bFound = FALSE; - } - } - if (bFound) - SetOptimalHeight( nStart, nEnd, 0, pDev, nPPTX, nPPTY, rZoomX, rZoomY, FALSE ); + ScFlatBoolRowSegments::RangeData aData; + if (!aUsedRows.getRangeData(nRow, aData)) + // search failed! + return; - delete[] pUsed; + SCROW nEndRow = aData.mnRow2; + if (aData.mbValue) + SetOptimalHeight(nRow, nEndRow, 0, pDev, nPPTX, nPPTY, rZoomX, rZoomY, FALSE); + + nRow = nEndRow + 1; + } } @@ -1948,6 +2050,8 @@ void ScTable::SetColWidth( SCCOL nCol, USHORT nNewWidth ) pDrawLayer->WidthChanged( nTab, nCol, ((long) nNewWidth) - (long) pColWidth[nCol] ); pColWidth[nCol] = nNewWidth; DecRecalcLevel(); + + InvalidatePageBreaks(); } } else @@ -1959,7 +2063,7 @@ void ScTable::SetColWidth( SCCOL nCol, USHORT nNewWidth ) void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight ) { - if (VALIDROW(nRow) && pRowHeight) + if (VALIDROW(nRow) && mpRowHeights) { if (!nNewHeight) { @@ -1967,7 +2071,7 @@ void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight ) nNewHeight = ScGlobal::nStdRowHeight; } - USHORT nOldHeight = pRowHeight->GetValue(nRow); + sal_uInt16 nOldHeight = mpRowHeights->getValue(nRow); if ( nNewHeight != nOldHeight ) { IncRecalcLevel(); @@ -1975,8 +2079,10 @@ void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight ) ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); if (pDrawLayer) pDrawLayer->HeightChanged( nTab, nRow, ((long) nNewHeight) - (long) nOldHeight ); - pRowHeight->SetValue( nRow, nNewHeight); + mpRowHeights->setValue(nRow, nRow, nNewHeight); DecRecalcLevel(); + + InvalidatePageBreaks(); } } else @@ -1985,12 +2091,45 @@ void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight ) } } +namespace { + +/** + * Check if the new pixel size is different from the old size between + * specified ranges. + */ +bool lcl_pixelSizeChanged( + ScFlatUInt16RowSegments& rRowHeights, SCROW nStartRow, SCROW nEndRow, + sal_uInt16 nNewHeight, double nPPTY) +{ + long nNewPix = static_cast<long>(nNewHeight * nPPTY); + + ScFlatUInt16RowSegments::ForwardIterator aFwdIter(rRowHeights); + for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow) + { + sal_uInt16 nHeight; + if (!aFwdIter.getValue(nRow, nHeight)) + break; + + if (nHeight != nNewHeight) + { + bool bChanged = (nNewPix != static_cast<long>(nHeight * nPPTY)); + if (bChanged) + return true; + } + + // Skip ahead to the last position of the current range. + nRow = aFwdIter.getLastPos(); + } + return false; +} + +} BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeight, double /* nPPTX */, double nPPTY ) { BOOL bChanged = FALSE; - if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowHeight) + if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && mpRowHeights) { IncRecalcLevel(); InitializeNoteCaptions(); @@ -2000,8 +2139,6 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig nNewHeight = ScGlobal::nStdRowHeight; } - long nNewPix = (long) ( nNewHeight * nPPTY ); - BOOL bSingle = FALSE; // TRUE = process every row for its own ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); if (pDrawLayer) @@ -2010,24 +2147,17 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig if (bSingle) { - size_t nIndex; - SCROW nRegionEndRow; - USHORT nOldHeight = pRowHeight->GetValue( nStartRow, nIndex, nRegionEndRow); - if (nNewHeight == nOldHeight && nEndRow <= nRegionEndRow) + ScFlatUInt16RowSegments::RangeData aData; + mpRowHeights->getRangeData(nStartRow, aData); + if (nNewHeight == aData.mnValue && nEndRow <= aData.mnRow2) bSingle = FALSE; // no difference in this range } if (bSingle) { if (nEndRow-nStartRow < 20) { - // Whether new pixel size will differ from old pixel size in any row. - ScCompressedArrayIterator< SCROW, USHORT> aIter( *pRowHeight, - nStartRow, nEndRow); - do - { - if (*aIter != nNewHeight) - bChanged = (nNewPix != (long) (*aIter * nPPTY)); - } while (!bChanged && aIter.NextRange()); + if (!bChanged) + bChanged = lcl_pixelSizeChanged(*mpRowHeights, nStartRow, nEndRow, nNewHeight, nPPTY); /* #i94028# #i94991# If drawing objects are involved, each row has to be changed for its own, because each call to @@ -2039,12 +2169,12 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig for( SCROW nRow = nStartRow; nRow <= nEndRow ; ++nRow ) { pDrawLayer->HeightChanged( nTab, nRow, - ((long) nNewHeight) - ((long) pRowHeight->GetValue( nRow ))); - pRowHeight->SetValue( nRow, nNewHeight ); + static_cast<long>(nNewHeight) - static_cast<long>(mpRowHeights->getValue(nRow))); + mpRowHeights->setValue(nRow, nRow, nNewHeight); } } else - pRowHeight->SetValue( nStartRow, nEndRow, nNewHeight); + mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight); } else { @@ -2059,23 +2189,22 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig { if (pDrawLayer) { - unsigned long nOldHeights = pRowHeight->SumValues( nStartRow, nEndRow); + unsigned long nOldHeights = GetRowHeight(nStartRow, nEndRow); // FIXME: should we test for overflows? long nHeightDif = (long) (unsigned long) nNewHeight * (nEndRow - nStartRow + 1) - nOldHeights; pDrawLayer->HeightChanged( nTab, nEndRow, nHeightDif ); } - // Whether new pixel size will differ from old pixel size in any row. - ScCompressedArrayIterator< SCROW, USHORT> aIter( *pRowHeight, - nStartRow, nEndRow); - do - { - if (*aIter != nNewHeight) - bChanged = (nNewPix != (long) (*aIter * nPPTY)); - } while (!bChanged && aIter.NextRange()); - pRowHeight->SetValue( nStartRow, nEndRow, nNewHeight); + + if (!bChanged) + bChanged = lcl_pixelSizeChanged(*mpRowHeights, nStartRow, nEndRow, nNewHeight, nPPTY); + + mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight); } DecRecalcLevel(); + + if (bChanged) + InvalidatePageBreaks(); } else { @@ -2085,6 +2214,16 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig return bChanged; } +void ScTable::SetRowHeightOnly( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeight ) +{ + if (!ValidRow(nStartRow) || !ValidRow(nEndRow) || !mpRowHeights) + return; + + if (!nNewHeight) + nNewHeight = ScGlobal::nStdRowHeight; + + mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight); +} void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual ) { @@ -2102,13 +2241,13 @@ void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual ) } -USHORT ScTable::GetColWidth( SCCOL nCol ) const +USHORT ScTable::GetColWidth( SCCOL nCol ) { DBG_ASSERT(VALIDCOL(nCol),"Falsche Spaltennummer"); if (VALIDCOL(nCol) && pColFlags && pColWidth) { - if ( pColFlags[nCol] & CR_HIDDEN ) + if (ColHidden(nCol)) return 0; else return pColWidth[nCol]; @@ -2129,7 +2268,7 @@ USHORT ScTable::GetOriginalWidth( SCCOL nCol ) const // immer die eingest } -USHORT ScTable::GetCommonWidth( SCCOL nEndCol ) const +USHORT ScTable::GetCommonWidth( SCCOL nEndCol ) { // get the width that is used in the largest continuous column range (up to nEndCol) @@ -2141,24 +2280,24 @@ USHORT ScTable::GetCommonWidth( SCCOL nEndCol ) const USHORT nMaxWidth = 0; USHORT nMaxCount = 0; - USHORT nRangeStart = 0; + SCCOL nRangeStart = 0; while ( nRangeStart <= nEndCol ) { // skip hidden columns - while ( nRangeStart <= nEndCol && (pColFlags[nRangeStart] & CR_HIDDEN) ) + while ( nRangeStart <= nEndCol && ColHidden(nRangeStart) ) ++nRangeStart; if ( nRangeStart <= nEndCol ) { USHORT nThisCount = 0; USHORT nThisWidth = pColWidth[nRangeStart]; - USHORT nRangeEnd = nRangeStart; + SCCOL nRangeEnd = nRangeStart; while ( nRangeEnd <= nEndCol && pColWidth[nRangeEnd] == nThisWidth ) { ++nThisCount; ++nRangeEnd; // skip hidden columns - while ( nRangeEnd <= nEndCol && (pColFlags[nRangeEnd] & CR_HIDDEN) ) + while ( nRangeEnd <= nEndCol && ColHidden(nRangeEnd) ) ++nRangeEnd; } @@ -2176,44 +2315,80 @@ USHORT ScTable::GetCommonWidth( SCCOL nEndCol ) const } -USHORT ScTable::GetRowHeight( SCROW nRow ) const +USHORT ScTable::GetRowHeight( SCROW nRow, SCROW* pStartRow, SCROW* pEndRow, bool bHiddenAsZero ) { DBG_ASSERT(VALIDROW(nRow),"Falsche Zeilennummer"); - if (VALIDROW(nRow) && pRowFlags && pRowHeight) + if (VALIDROW(nRow) && mpRowHeights) { - if ( pRowFlags->GetValue(nRow) & CR_HIDDEN ) + if (bHiddenAsZero && RowHidden(nRow)) return 0; else - return pRowHeight->GetValue(nRow); + { + ScFlatUInt16RowSegments::RangeData aData; + if (!mpRowHeights->getRangeData(nRow, aData)) + // TODO: What should we return in case the search fails? + return 0; + + if (pStartRow) + *pStartRow = aData.mnRow1; + if (pEndRow) + *pEndRow = aData.mnRow2; + return aData.mnValue; + } } else return (USHORT) ScGlobal::nStdRowHeight; } -ULONG ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow ) const +ULONG ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow ) { DBG_ASSERT(VALIDROW(nStartRow) && VALIDROW(nEndRow),"Falsche Zeilennummer"); - if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowFlags && pRowHeight) + if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && mpRowHeights) { - return pRowFlags->SumCoupledArrayForCondition( nStartRow, nEndRow, - CR_HIDDEN, 0, *pRowHeight); + ULONG nHeight = 0; + SCROW nRow = nStartRow; + while (nRow <= nEndRow) + { + SCROW nLastRow = -1; + if (!RowHidden(nRow, nLastRow)) + { + if (nLastRow > nEndRow) + nLastRow = nEndRow; + nHeight += mpRowHeights->getSumValue(nRow, nLastRow); + } + nRow = nLastRow + 1; + } + return nHeight; } else return (ULONG) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight); } -ULONG ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale ) const +ULONG ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale ) { DBG_ASSERT(VALIDROW(nStartRow) && VALIDROW(nEndRow),"Falsche Zeilennummer"); - if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowFlags && pRowHeight) + if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && mpRowHeights) { - return pRowFlags->SumScaledCoupledArrayForCondition( nStartRow, - nEndRow, CR_HIDDEN, 0, *pRowHeight, fScale); + ULONG nHeight = 0; + SCROW nRow = nStartRow; + while (nRow <= nEndRow) + { + SCROW nLastRow = -1; + if (!RowHidden(nRow, nLastRow)) + { + if (nLastRow > nEndRow) + nLastRow = nEndRow; + sal_uInt32 nThisHeight = mpRowHeights->getSumValue(nRow, nLastRow); + nHeight += static_cast<ULONG>(nThisHeight * fScale); + } + nRow = nLastRow + 1; + } + return nHeight; } else return (ULONG) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight * fScale); @@ -2224,8 +2399,8 @@ USHORT ScTable::GetOriginalHeight( SCROW nRow ) const // non-0 even if hid { DBG_ASSERT(VALIDROW(nRow),"wrong row number"); - if (VALIDROW(nRow) && pRowHeight) - return pRowHeight->GetValue(nRow); + if (VALIDROW(nRow) && mpRowHeights) + return mpRowHeights->getValue(nRow); else return (USHORT) ScGlobal::nStdRowHeight; } @@ -2234,28 +2409,26 @@ USHORT ScTable::GetOriginalHeight( SCROW nRow ) const // non-0 even if hid // Spalten-/Zeilen-Flags -SCROW ScTable::GetHiddenRowCount( SCROW nRow ) const +SCROW ScTable::GetHiddenRowCount( SCROW nRow ) { - SCROW nEndRow = nRow; - if ( pRowFlags ) - { - nEndRow = pRowFlags->GetBitStateEnd( nRow, CR_HIDDEN, CR_HIDDEN); - if (ValidRow(nEndRow)) - ++nEndRow; - else - nEndRow = nRow; - } - return nEndRow - nRow; + if (!ValidRow(nRow)) + return 0; + + SCROW nLastRow = -1; + if (!RowHidden(nRow, nLastRow) || !ValidRow(nLastRow)) + return 0; + + return nLastRow - nRow + 1; } //! ShowRows / DBShowRows zusammenfassen -void ScTable::ShowCol(SCCOL nCol, BOOL bShow) +void ScTable::ShowCol(SCCOL nCol, bool bShow) { - if (VALIDCOL(nCol) && pColFlags) + if (VALIDCOL(nCol)) { - BOOL bWasVis = ( pColFlags[nCol] & CR_HIDDEN ) == 0; + bool bWasVis = !ColHidden(nCol); if (bWasVis != bShow) { IncRecalcLevel(); @@ -2269,11 +2442,8 @@ void ScTable::ShowCol(SCCOL nCol, BOOL bShow) pDrawLayer->WidthChanged( nTab, nCol, -(long) pColWidth[nCol] ); } - if (bShow) - pColFlags[nCol] &= ~CR_HIDDEN; - else - pColFlags[nCol] |= CR_HIDDEN; - DecRecalcLevel(); + SetColHidden(nCol, nCol, !bShow); + DecRecalcLevel(); ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection(); if ( pCharts ) @@ -2287,12 +2457,11 @@ void ScTable::ShowCol(SCCOL nCol, BOOL bShow) } -void ScTable::ShowRow(SCROW nRow, BOOL bShow) +void ScTable::ShowRow(SCROW nRow, bool bShow) { if (VALIDROW(nRow) && pRowFlags) { - BYTE nFlags = pRowFlags->GetValue(nRow); - BOOL bWasVis = ( nFlags & CR_HIDDEN ) == 0; + bool bWasVis = !RowHidden(nRow); if (bWasVis != bShow) { IncRecalcLevel(); @@ -2301,20 +2470,23 @@ void ScTable::ShowRow(SCROW nRow, BOOL bShow) if (pDrawLayer) { if (bShow) - pDrawLayer->HeightChanged( nTab, nRow, (long) pRowHeight->GetValue(nRow) ); + pDrawLayer->HeightChanged( + nTab, nRow, static_cast<long>(mpRowHeights->getValue(nRow))); else - pDrawLayer->HeightChanged( nTab, nRow, -(long) pRowHeight->GetValue(nRow) ); + pDrawLayer->HeightChanged( + nTab, nRow, -static_cast<long>(mpRowHeights->getValue(nRow))); } + SetRowHidden(nRow, nRow, !bShow); if (bShow) - pRowFlags->SetValue( nRow, nFlags & ~(CR_HIDDEN | CR_FILTERED)); - else - pRowFlags->SetValue( nRow, nFlags | CR_HIDDEN); - DecRecalcLevel(); + SetRowFiltered(nRow, nRow, false); + DecRecalcLevel(); ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection(); if ( pCharts ) pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, MAXCOL, nRow, nTab )); + + InvalidatePageBreaks(); } } else @@ -2324,12 +2496,11 @@ void ScTable::ShowRow(SCROW nRow, BOOL bShow) } -void ScTable::DBShowRow(SCROW nRow, BOOL bShow) +void ScTable::DBShowRow(SCROW nRow, bool bShow) { if (VALIDROW(nRow) && pRowFlags) { - BYTE nFlags = pRowFlags->GetValue(nRow); - BOOL bWasVis = ( nFlags & CR_HIDDEN ) == 0; + bool bWasVis = !RowHidden(nRow); IncRecalcLevel(); InitializeNoteCaptions(); if (bWasVis != bShow) @@ -2338,18 +2509,18 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow) if (pDrawLayer) { if (bShow) - pDrawLayer->HeightChanged( nTab, nRow, (long) pRowHeight->GetValue(nRow) ); + pDrawLayer->HeightChanged( + nTab, nRow, static_cast<long>(mpRowHeights->getValue(nRow))); else - pDrawLayer->HeightChanged( nTab, nRow, -(long) pRowHeight->GetValue(nRow) ); + pDrawLayer->HeightChanged( + nTab, nRow, -static_cast<long>(mpRowHeights->getValue(nRow))); } } // Filter-Flag immer setzen, auch wenn Hidden unveraendert - if (bShow) - pRowFlags->SetValue( nRow, nFlags & ~(CR_HIDDEN | CR_FILTERED)); - else - pRowFlags->SetValue( nRow, nFlags | (CR_HIDDEN | CR_FILTERED)); - DecRecalcLevel(); + SetRowHidden(nRow, nRow, !bShow); + SetRowFiltered(nRow, nRow, !bShow); + DecRecalcLevel(); if (bWasVis != bShow) { @@ -2359,6 +2530,8 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow) if (pOutlineTable) UpdateOutlineRow( nRow, nRow, bShow ); + + InvalidatePageBreaks(); } } else @@ -2368,26 +2541,25 @@ 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) { SCROW nStartRow = nRow1; IncRecalcLevel(); InitializeNoteCaptions(); while (nStartRow <= nRow2) { - BYTE nOldFlag = pRowFlags->GetValue(nStartRow) & CR_HIDDEN; - SCROW nEndRow = pRowFlags->GetBitStateEnd( nStartRow, CR_HIDDEN, nOldFlag); + SCROW nEndRow = -1; + bool bWasVis = !RowHidden(nStartRow, nEndRow); if (nEndRow > nRow2) nEndRow = nRow2; - BOOL bWasVis = ( nOldFlag == 0 ); BOOL bChanged = ( bWasVis != bShow ); if ( bChanged ) { ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); if (pDrawLayer) { - long nHeight = (long) pRowHeight->SumValues( nStartRow, nEndRow); + long nHeight = static_cast<long>(mpRowHeights->getSumValue(nStartRow, nEndRow)); if (bShow) pDrawLayer->HeightChanged( nTab, nStartRow, nHeight ); else @@ -2395,10 +2567,8 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow) } } - if (bShow) - pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~(CR_HIDDEN | CR_FILTERED)) ); - else - pRowFlags->OrValue( nStartRow, nEndRow, (CR_HIDDEN | CR_FILTERED)); + SetRowHidden(nStartRow, nEndRow, !bShow); + SetRowFiltered(nStartRow, nEndRow, !bShow); if ( bChanged ) { @@ -2420,26 +2590,25 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow) } -void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow) +void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, bool bShow) { SCROW nStartRow = nRow1; IncRecalcLevel(); InitializeNoteCaptions(); while (nStartRow <= nRow2) { - BYTE nOldFlag = pRowFlags->GetValue(nStartRow) & CR_HIDDEN; - SCROW nEndRow = pRowFlags->GetBitStateEnd( nStartRow, CR_HIDDEN, nOldFlag); + SCROW nEndRow = -1; + bool bWasVis = !RowHidden(nStartRow, nEndRow); if (nEndRow > nRow2) nEndRow = nRow2; - BOOL bWasVis = ( nOldFlag == 0 ); BOOL bChanged = ( bWasVis != bShow ); if ( bChanged ) { ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); if (pDrawLayer) { - long nHeight = (long) pRowHeight->SumValues( nStartRow, nEndRow); + long nHeight = static_cast<long>(mpRowHeights->getSumValue(nStartRow, nEndRow)); if (bShow) pDrawLayer->HeightChanged( nTab, nStartRow, nHeight ); else @@ -2447,16 +2616,17 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow) } } + SetRowHidden(nStartRow, nEndRow, !bShow); if (bShow) - pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~(CR_HIDDEN | CR_FILTERED)) ); - else - pRowFlags->OrValue( nStartRow, nEndRow, CR_HIDDEN); + SetRowFiltered(nStartRow, nEndRow, false); if ( bChanged ) { ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection(); if ( pCharts ) pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab )); + + InvalidatePageBreaks(); } nStartRow = nEndRow + 1; @@ -2465,16 +2635,6 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow) } -BOOL ScTable::IsFiltered(SCROW nRow) const -{ - if (VALIDROW(nRow) && pRowFlags) - return ( pRowFlags->GetValue(nRow) & CR_FILTERED ) != 0; - - DBG_ERROR("Falsche Zeilennummer oder keine Flags"); - return FALSE; -} - - void ScTable::SetColFlags( SCCOL nCol, BYTE nNewFlags ) { if (VALIDCOL(nCol) && pColFlags) @@ -2528,11 +2688,32 @@ BYTE ScTable::GetRowFlags( SCROW nRow ) const SCROW ScTable::GetLastFlaggedRow() const { - if ( !pRowFlags ) - return 0; + SCROW nLastFound = 0; + if (pRowFlags) + { + SCROW nRow = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(CR_ALL) ); + if (ValidRow(nRow)) + nLastFound = nRow; + } + + if (!maRowManualBreaks.empty()) + nLastFound = ::std::max(nLastFound, *maRowManualBreaks.rbegin()); + + if (mpHiddenRows) + { + SCROW nRow = mpHiddenRows->findLastNotOf(false); + if (ValidRow(nRow)) + nLastFound = ::std::max(nLastFound, nRow); + } + + if (mpFilteredRows) + { + SCROW nRow = mpFilteredRows->findLastNotOf(false); + if (ValidRow(nRow)) + nLastFound = ::std::max(nLastFound, nRow); + } - SCROW nLastFound = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) ); - return ValidRow(nLastFound) ? nLastFound : 0; + return nLastFound; } @@ -2543,7 +2724,7 @@ SCCOL ScTable::GetLastChangedCol() const SCCOL nLastFound = 0; for (SCCOL nCol = 1; nCol <= MAXCOL; nCol++) - if ((pColFlags[nCol] & ~CR_PAGEBREAK) || (pColWidth[nCol] != STD_COL_WIDTH)) + if ((pColFlags[nCol] & CR_ALL) || (pColWidth[nCol] != STD_COL_WIDTH)) nLastFound = nCol; return nLastFound; @@ -2555,11 +2736,12 @@ SCROW ScTable::GetLastChangedRow() const if ( !pRowFlags ) return 0; - SCROW nLastFlags = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) ); - if (!ValidRow(nLastFlags)) - nLastFlags = 0; + SCROW nLastFlags = GetLastFlaggedRow(); - SCROW nLastHeight = pRowHeight->GetLastUnequalAccess( 0, ScGlobal::nStdRowHeight); + // Find the last row position where the height is NOT the standard row + // height. + // KOHEI: Test this to make sure it does what it's supposed to. + SCROW nLastHeight = mpRowHeights->findLastNotOf(ScGlobal::nStdRowHeight); if (!ValidRow(nLastHeight)) nLastHeight = 0; @@ -2572,7 +2754,7 @@ BOOL ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, BOOL bShow ) if (pOutlineTable && pColFlags) { ScBitMaskCompressedArray< SCCOLROW, BYTE> aArray( MAXCOL, pColFlags, MAXCOLCOUNT); - return pOutlineTable->GetColArray()->ManualAction( nStartCol, nEndCol, bShow, aArray ); + return pOutlineTable->GetColArray()->ManualAction( nStartCol, nEndCol, bShow, *this, true ); } else return FALSE; @@ -2582,7 +2764,7 @@ BOOL ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, BOOL bShow ) BOOL ScTable::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, BOOL bShow ) { if (pOutlineTable && pRowFlags) - return pOutlineTable->GetRowArray()->ManualAction( nStartRow, nEndRow, bShow, *pRowFlags ); + return pOutlineTable->GetRowArray()->ManualAction( nStartRow, nEndRow, bShow, *this, false ); else return FALSE; } @@ -2590,54 +2772,58 @@ BOOL ScTable::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, BOOL bShow ) void ScTable::ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 ) { - if (pColFlags) - { - while ( rX1>0 ? (pColFlags[rX1-1] & CR_HIDDEN) : FALSE ) - --rX1; - while ( rX2<MAXCOL ? (pColFlags[rX2+1] & CR_HIDDEN) : FALSE ) - ++rX2; - } - if (pRowFlags) + // Column-wise expansion + + while (rX1 > 0 && ColHidden(rX1-1)) + --rX1; + + while (rX2 < MAXCOL && ColHidden(rX2+1)) + ++rX2; + + // Row-wise expansion + + if (rY1 > 0) { - if (rY1 > 0) + ScFlatBoolRowSegments::RangeData aData; + if (mpHiddenRows->getRangeData(rY1-1, aData) && aData.mbValue) { - SCROW nStartRow = pRowFlags->GetBitStateStart( rY1-1, CR_HIDDEN, CR_HIDDEN); + SCROW nStartRow = aData.mnRow1; if (ValidRow(nStartRow)) rY1 = nStartRow; } - if (rY2 < MAXROW) - { - SCROW nEndRow = pRowFlags->GetBitStateEnd( rY2+1, CR_HIDDEN, CR_HIDDEN); - if (ValidRow(nEndRow)) - rY2 = nEndRow; - } + } + if (rY2 < MAXROW) + { + SCROW nEndRow = -1; + if (RowHidden(rY2+1, nEndRow) && ValidRow(nEndRow)) + rY2 = nEndRow; } } void ScTable::StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 ) { - if (pColFlags) - { - while ( rX2>rX1 && (pColFlags[rX2] & CR_HIDDEN) ) - --rX2; - while ( rX2>rX1 && (pColFlags[rX1] & CR_HIDDEN) ) - ++rX1; - } - if (pRowFlags) + while ( rX2>rX1 && ColHidden(rX2) ) + --rX2; + while ( rX2>rX1 && ColHidden(rX1) ) + ++rX1; + + if (rY1 < rY2) { - if (rY1 < rY2) + ScFlatBoolRowSegments::RangeData aData; + if (mpHiddenRows->getRangeData(rY2, aData) && aData.mbValue) { - SCROW nStartRow = pRowFlags->GetBitStateStart( rY2, CR_HIDDEN, CR_HIDDEN); + SCROW nStartRow = aData.mnRow1; if (ValidRow(nStartRow) && nStartRow >= rY1) rY2 = nStartRow; } - if (rY1 < rY2) - { - SCROW nEndRow = pRowFlags->GetBitStateEnd( rY1, CR_HIDDEN, CR_HIDDEN); - if (ValidRow(nEndRow) && nEndRow <= rY2) - rY1 = nEndRow; - } + } + + if (rY1 < rY2) + { + SCROW nEndRow = -1; + if (RowHidden(rY1, nEndRow) && ValidRow(nEndRow) && nEndRow <= rY2) + rY1 = nEndRow; } } @@ -2799,16 +2985,16 @@ BOOL ScTable::RefVisible(ScFormulaCell* pCell) if (pCell->HasOneReference(aRef)) { - if (aRef.aStart.Col()==aRef.aEnd.Col() && aRef.aStart.Tab()==aRef.aEnd.Tab() && pRowFlags) + if (aRef.aStart.Col()==aRef.aEnd.Col() && aRef.aStart.Tab()==aRef.aEnd.Tab()) { - // while ((value & CR_FILTERED) == CR_FILTERED) - // most times will be faster than - // while ((value & CR_FILTERED) == 0) - SCROW nEndRow = pRowFlags->GetBitStateEnd( aRef.aStart.Row(), - CR_FILTERED, CR_FILTERED); + SCROW nEndRow; + if (!RowFiltered(aRef.aStart.Row(), NULL, &nEndRow)) + // row not filtered. + nEndRow = ::std::numeric_limits<SCROW>::max(); + if (!ValidRow(nEndRow) || nEndRow < aRef.aEnd.Row()) return TRUE; // at least partly visible - return FALSE; // completely unvisible + return FALSE; // completely invisible } } @@ -2850,18 +3036,17 @@ void ScTable::SetDrawPageSize(bool bResetStreamValid, bool bUpdateNoteCaptionPos } -ULONG ScTable::GetRowOffset( SCROW nRow ) const +ULONG ScTable::GetRowOffset( SCROW nRow ) { ULONG n = 0; - if ( pRowFlags && pRowHeight ) + if ( mpHiddenRows && mpRowHeights ) { if (nRow == 0) return 0; else if (nRow == 1) return GetRowHeight(0); - n = pRowFlags->SumCoupledArrayForCondition( 0, nRow-1, CR_HIDDEN, 0, - *pRowHeight); + n = GetTotalRowHeight(0, nRow-1); #ifdef DBG_UTIL if (n == ::std::numeric_limits<unsigned long>::max()) DBG_ERRORFILE("ScTable::GetRowOffset: row heights overflow"); @@ -2874,18 +3059,42 @@ ULONG ScTable::GetRowOffset( SCROW nRow ) const return n; } +SCROW ScTable::GetRowForHeight(ULONG nHeight) +{ + sal_uInt32 nSum = 0; + + ScFlatBoolRowSegments::RangeData aData; + for (SCROW nRow = 0; nRow <= MAXROW; ++nRow) + { + if (!mpHiddenRows->getRangeData(nRow, aData)) + break; + + if (aData.mbValue) + { + nRow = aData.mnRow2; + continue; + } + + sal_uInt32 nNew = mpRowHeights->getValue(nRow); + nSum += nNew; + if (nSum > nHeight) + { + return nRow < MAXROW ? nRow + 1 : MAXROW; + } + } + return -1; +} + -ULONG ScTable::GetColOffset( SCCOL nCol ) const +ULONG ScTable::GetColOffset( SCCOL nCol ) { ULONG n = 0; - if ( pColFlags && pColWidth ) + if ( pColWidth ) { SCCOL i; - BYTE* pFlags = pColFlags; - USHORT* pWidth = pColWidth; - for( i = 0; i < nCol; i++, pFlags++, pWidth++ ) - if( !( *pFlags & CR_HIDDEN ) ) - n += *pWidth; + for( i = 0; i < nCol; i++ ) + if (!ColHidden(i)) + n += pColWidth[i]; } else { |