summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke [er] <erAck@sun.com>2010-07-16 15:58:36 +0200
committerEike Rathke [er] <erAck@sun.com>2010-07-16 15:58:36 +0200
commit98cdf3324314ebf7ee69605af2a8fc28be092528 (patch)
treed65a24b2527fbfa240a7bf5323fd3f929876a6ed
parentd5d147219645771f745d46db17d6fd2c31347aae (diff)
calc56: #i113139# various performance improvements for 1MB rows, especially with large hidden segments
-rw-r--r--sc/inc/document.hxx1
-rw-r--r--sc/inc/table.hxx46
-rw-r--r--sc/source/core/data/documen3.cxx83
-rw-r--r--sc/source/core/data/document.cxx54
-rw-r--r--sc/source/core/data/fillinfo.cxx20
-rw-r--r--sc/source/core/data/markdata.cxx60
-rw-r--r--sc/source/core/data/table2.cxx38
-rw-r--r--sc/source/core/data/table5.cxx52
-rw-r--r--sc/source/filter/xml/XMLStylesExportHelper.cxx27
-rw-r--r--sc/source/filter/xml/XMLStylesExportHelper.hxx1
-rw-r--r--sc/source/filter/xml/xmlexprt.cxx7
-rw-r--r--sc/source/ui/inc/viewdata.hxx18
-rw-r--r--sc/source/ui/undo/undoblk.cxx2
-rw-r--r--sc/source/ui/view/gridwin4.cxx12
-rw-r--r--sc/source/ui/view/output.cxx14
-rw-r--r--sc/source/ui/view/viewdata.cxx161
16 files changed, 398 insertions, 198 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index f7ae5e63f165..304a9d1df0f7 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1276,6 +1276,7 @@ public:
SC_DLLPUBLIC USHORT GetColWidth( SCCOL nCol, SCTAB nTab ) const;
SC_DLLPUBLIC USHORT GetRowHeight( SCROW nRow, SCTAB nTab, bool bHiddenAsZero = true ) const;
+ SC_DLLPUBLIC USHORT GetRowHeight( SCROW nRow, SCTAB nTab, SCROW* pStartRow, SCROW* pEndRow, bool bHiddenAsZero = true ) const;
SC_DLLPUBLIC ULONG GetRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab ) const;
SCROW GetRowForHeight( SCTAB nTab, ULONG nHeight ) const;
ULONG GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, double fScale ) const;
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 78e5875b6879..5f42a2f37247 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -628,12 +628,12 @@ public:
// nPPT fuer Test auf Veraenderung
void SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual );
- USHORT GetColWidth( SCCOL nCol );
- SC_DLLPUBLIC USHORT GetRowHeight( SCROW nRow, SCROW* pStartRow = NULL, SCROW* pEndRow = NULL, bool bHiddenAsZero = true );
- ULONG GetRowHeight( SCROW nStartRow, SCROW nEndRow );
- ULONG GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale );
- ULONG GetColOffset( SCCOL nCol );
- ULONG GetRowOffset( SCROW nRow );
+ USHORT GetColWidth( SCCOL nCol ) const;
+ SC_DLLPUBLIC USHORT GetRowHeight( SCROW nRow, SCROW* pStartRow = NULL, SCROW* pEndRow = NULL, bool bHiddenAsZero = true ) const;
+ ULONG GetRowHeight( SCROW nStartRow, SCROW nEndRow ) const;
+ ULONG GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale ) const;
+ ULONG GetColOffset( SCCOL nCol ) const;
+ ULONG GetRowOffset( SCROW nRow ) const;
/**
* Get the last row such that the height of row 0 to the end row is as
@@ -643,7 +643,7 @@ public:
*
* @return SCROW last row of the range within specified height.
*/
- SCROW GetRowForHeight(ULONG nHeight);
+ SCROW GetRowForHeight(ULONG nHeight) const;
USHORT GetOriginalWidth( SCCOL nCol ) const;
USHORT GetOriginalHeight( SCROW nRow ) const;
@@ -711,33 +711,33 @@ public:
::com::sun::star::uno::Sequence<
::com::sun::star::sheet::TablePageBreakData> GetRowBreakData() const;
- bool RowHidden(SCROW nRow, SCROW* pFirstRow = NULL, SCROW* pLastRow = NULL);
- bool RowHidden(SCROW nRow, SCROW& rLastRow);
- bool HasHiddenRows(SCROW nStartRow, SCROW nEndRow);
- bool ColHidden(SCCOL nCol, SCCOL& rLastCol);
- bool ColHidden(SCCOL nCol, SCCOL* pFirstCol = NULL, SCCOL* pLastCol = NULL);
+ bool RowHidden(SCROW nRow, SCROW* pFirstRow = NULL, SCROW* pLastRow = NULL) const;
+ bool RowHidden(SCROW nRow, SCROW& rLastRow) const;
+ bool HasHiddenRows(SCROW nStartRow, SCROW nEndRow) const;
+ bool ColHidden(SCCOL nCol, SCCOL& rLastCol) const;
+ bool ColHidden(SCCOL nCol, SCCOL* pFirstCol = NULL, SCCOL* pLastCol = NULL) const;
void SetRowHidden(SCROW nStartRow, SCROW nEndRow, bool bHidden);
void SetColHidden(SCCOL nStartCol, SCCOL nEndCol, bool bHidden);
void CopyColHidden(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol);
void CopyRowHidden(ScTable& rTable, SCROW nStartRow, SCROW nEndRow);
void CopyRowHeight(ScTable& rSrcTable, SCROW nStartRow, SCROW nEndRow, SCROW nSrcOffset);
- SCROW FirstVisibleRow(SCROW nStartRow, SCROW nEndRow);
- SCROW LastVisibleRow(SCROW nStartRow, SCROW nEndRow);
- SCROW CountVisibleRows(SCROW nStartRow, SCROW nEndRow);
- sal_uInt32 GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow);
+ SCROW FirstVisibleRow(SCROW nStartRow, SCROW nEndRow) const;
+ SCROW LastVisibleRow(SCROW nStartRow, SCROW nEndRow) const;
+ SCROW CountVisibleRows(SCROW nStartRow, SCROW nEndRow) const;
+ sal_uInt32 GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow) const;
- SCCOLROW LastHiddenColRow(SCCOLROW nPos, bool bCol);
+ SCCOLROW LastHiddenColRow(SCCOLROW nPos, bool bCol) const;
- bool RowFiltered(SCROW nRow, SCROW* pFirstRow = NULL, SCROW* pLastRow = NULL);
- bool ColFiltered(SCCOL nCol, SCCOL* pFirstCol = NULL, SCCOL* pLastCol = NULL);
- bool HasFilteredRows(SCROW nStartRow, SCROW nEndRow);
+ bool RowFiltered(SCROW nRow, SCROW* pFirstRow = NULL, SCROW* pLastRow = NULL) const;
+ bool ColFiltered(SCCOL nCol, SCCOL* pFirstCol = NULL, SCCOL* pLastCol = NULL) const;
+ bool HasFilteredRows(SCROW nStartRow, SCROW nEndRow) const;
void CopyColFiltered(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol);
void CopyRowFiltered(ScTable& rTable, SCROW nStartRow, SCROW nEndRow);
void SetRowFiltered(SCROW nStartRow, SCROW nEndRow, bool bFiltered);
void SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, bool bFiltered);
- SCROW FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow);
- SCROW LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow);
- SCROW CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow);
+ SCROW FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow) const;
+ SCROW LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow) const;
+ SCROW CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow) const;
void SyncColRowFlags();
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 1861988d78aa..29f59352695d 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -1546,6 +1546,48 @@ void ScDocument::ResetEmbedded()
aEmbedRange = ScRange();
}
+
+/** Similar to ScViewData::AddPixelsWhile(), but add height twips and only
+ while result is less than nStopTwips.
+ */
+void lcl_AddTwipsWhile( long & rTwips, long nStopTwips, SCROW & rPosY, SCROW nEndRow, const ScTable * pTable )
+{
+ SCROW nRow = rPosY;
+ bool bStop = false;
+ while (rTwips < nStopTwips && nRow <= nEndRow && !bStop)
+ {
+ SCROW nHeightEndRow;
+ USHORT nHeight = pTable->GetRowHeight( nRow, NULL, &nHeightEndRow);
+ if (nHeightEndRow > nEndRow)
+ nHeightEndRow = nEndRow;
+ if (!nHeight)
+ nRow = nHeightEndRow + 1;
+ else
+ {
+ SCROW nRows = nHeightEndRow - nRow + 1;
+ sal_Int64 nAdd = static_cast<sal_Int64>(nHeight) * nRows;
+ if (nAdd + rTwips >= nStopTwips)
+ {
+ sal_Int64 nDiff = nAdd + rTwips - nStopTwips;
+ nRows -= nDiff / nHeight;
+ nAdd = nHeight * nRows;
+ // We're looking for a value that satisfies loop condition.
+ if (nAdd + rTwips >= nStopTwips)
+ {
+ --nRows;
+ nAdd -= nHeight;
+ }
+ bStop = true;
+ }
+ rTwips += static_cast<long>(nAdd);
+ nRow += nRows;
+ }
+ }
+ if (nRow > rPosY)
+ --nRow;
+ rPosY = nRow;
+}
+
ScRange ScDocument::GetRange( SCTAB nTab, const Rectangle& rMMRect )
{
ScTable* pTable = pTab[nTab];
@@ -1602,43 +1644,18 @@ ScRange ScDocument::GetRange( SCTAB nTab, const Rectangle& rMMRect )
nTwips = (long) (aPosRect.Top() / HMM_PER_TWIPS);
SCROW nY1 = 0;
- bEnd = FALSE;
- for (SCROW i = nY1; i <= MAXROW && !bEnd; ++i)
- {
- if (pTable->RowHidden(i))
- continue;
-
- nY1 = i;
- nAdd = static_cast<long>(pTable->GetRowHeight(i));
- if (nSize+nAdd <= nTwips+1 && nY1<MAXROW)
- {
- nSize += nAdd;
- ++nY1;
- }
- else
- bEnd = TRUE;
- }
- if (!bEnd)
- nY1 = MAXROW; // all hidden down to the bottom
+ // Was if(nSize+nAdd<=nTwips+1) inside loop => if(nSize+nAdd<nTwips+2)
+ lcl_AddTwipsWhile( nSize, nTwips+2, nY1, MAXROW, pTable);
+ if (nY1 < MAXROW)
+ ++nY1; // original loop ended on last evaluated +1 unless that was MAXROW
nTwips = (long) (aPosRect.Bottom() / HMM_PER_TWIPS);
SCROW nY2 = nY1;
- bEnd = FALSE;
- for (SCROW i = nY2; i <= MAXROW && !bEnd; ++i)
- {
- nY2 = i;
- nAdd = static_cast<long>(pTable->GetRowHeight(i));
- if (nSize+nAdd < nTwips && nY2<MAXROW)
- {
- nSize += nAdd;
- ++nY2;
- }
- else
- bEnd = TRUE;
- }
- if (!bEnd)
- nY2 = MAXROW; // all hidden down to the bottom
+ // Was if(nSize+nAdd<nTwips) inside loop => if(nSize+nAdd<nTwips)
+ lcl_AddTwipsWhile( nSize, nTwips, nY2, MAXROW, pTable);
+ if (nY2 < MAXROW)
+ ++nY2; // original loop ended on last evaluated +1 unless that was MAXROW
return ScRange( nX1,nY1,nTab, nX2,nY2,nTab );
}
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index eee87317c258..a4f8833f6caa 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3174,7 +3174,16 @@ USHORT ScDocument::GetRowHeight( SCROW nRow, SCTAB nTab, bool bHiddenAsZero ) co
{
if ( ValidTab(nTab) && pTab[nTab] )
return pTab[nTab]->GetRowHeight( nRow, NULL, NULL, bHiddenAsZero );
- DBG_ERROR("Falsche Tabellennummer");
+ DBG_ERROR("Wrong sheet number");
+ return 0;
+}
+
+
+USHORT ScDocument::GetRowHeight( SCROW nRow, SCTAB nTab, SCROW* pStartRow, SCROW* pEndRow, bool bHiddenAsZero ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetRowHeight( nRow, pStartRow, pEndRow, bHiddenAsZero );
+ DBG_ERROR("Wrong sheet number");
return 0;
}
@@ -3697,24 +3706,35 @@ SCCOL ScDocument::GetNextDifferentChangedCol( SCTAB nTab, SCCOL nStart) const
SCROW ScDocument::GetNextDifferentChangedRow( SCTAB nTab, SCROW nStart, bool bCareManualSize) const
{
- if ( ValidTab(nTab) && pTab[nTab] && pTab[nTab]->GetRowFlagsArray() && pTab[nTab]->mpRowHeights )
- {
- BYTE nStartFlags = pTab[nTab]->GetRowFlags(nStart);
- USHORT nStartHeight = pTab[nTab]->GetOriginalHeight(nStart);
- for (SCROW nRow = nStart + 1; nRow <= MAXROW; nRow++)
+ const ScBitMaskCompressedArray< SCROW, BYTE> * pRowFlagsArray;
+ if ( ValidTab(nTab) && pTab[nTab] && ((pRowFlagsArray = pTab[nTab]->GetRowFlagsArray()) != NULL) &&
+ pTab[nTab]->mpRowHeights && pTab[nTab]->mpHiddenRows )
+ {
+ size_t nIndex; // ignored
+ SCROW nFlagsEndRow;
+ SCROW nHiddenEndRow;
+ SCROW nHeightEndRow;
+ BYTE nFlags;
+ bool bHidden;
+ USHORT nHeight;
+ BYTE nStartFlags = nFlags = pRowFlagsArray->GetValue( nStart, nIndex, nFlagsEndRow);
+ bool bStartHidden = bHidden = pTab[nTab]->RowHidden( nStart, NULL, &nHiddenEndRow);
+ USHORT nStartHeight = nHeight = pTab[nTab]->GetRowHeight( nStart, NULL, &nHeightEndRow, false);
+ SCROW nRow;
+ while ((nRow = std::min( nHiddenEndRow, std::min( nFlagsEndRow, nHeightEndRow)) + 1) <= MAXROW)
{
- size_t nIndex; // ignored
- SCROW nFlagsEndRow;
- SCROW nHeightEndRow;
- BYTE nFlags = pTab[nTab]->GetRowFlagsArray()->GetValue( nRow, nIndex, nFlagsEndRow );
- USHORT nHeight = pTab[nTab]->GetRowHeight(nRow, NULL, &nHeightEndRow);
- if (((nStartFlags & CR_MANUALBREAK) != (nFlags & CR_MANUALBREAK)) ||
- ((nStartFlags & CR_MANUALSIZE) != (nFlags & CR_MANUALSIZE)) ||
- (bCareManualSize && (nStartFlags & CR_MANUALSIZE) && (nStartHeight != nHeight)) ||
- (!bCareManualSize && ((nStartHeight != nHeight))))
+ if (nFlagsEndRow < nRow)
+ nFlags = pRowFlagsArray->GetValue( nRow, nIndex, nFlagsEndRow);
+ if (nHiddenEndRow < nRow)
+ bHidden = pTab[nTab]->RowHidden( nRow, NULL, &nHiddenEndRow);
+ if (nHeightEndRow < nRow)
+ nHeight = pTab[nTab]->GetRowHeight( nRow, NULL, &nHeightEndRow, false);
+ if ( ((nStartFlags & CR_MANUALBREAK) != (nFlags & CR_MANUALBREAK)) ||
+ ((nStartFlags & CR_MANUALSIZE) != (nFlags & CR_MANUALSIZE)) ||
+ (bStartHidden != bHidden) ||
+ (bCareManualSize && (nStartFlags & CR_MANUALSIZE) && (nStartHeight != nHeight)) ||
+ (!bCareManualSize && ((nStartHeight != nHeight))))
return nRow;
-
- nRow = std::min( nFlagsEndRow, nHeightEndRow );
}
return MAXROW+1;
}
diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx
index 8418cb3c3a25..99da4979a1b6 100644
--- a/sc/source/core/data/fillinfo.cxx
+++ b/sc/source/core/data/fillinfo.cxx
@@ -219,6 +219,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
nArrY=0;
SCROW nYExtra = nY2+1;
+ USHORT nDocHeight = ScGlobal::nStdRowHeight;
+ SCROW nDocHeightEndRow = -1;
for (nSignedY=((SCsROW)nY1)-1; nSignedY<=(SCsROW)nYExtra; nSignedY++)
{
if (nSignedY >= 0)
@@ -226,11 +228,13 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
else
nY = MAXROW+1; // ungueltig
- USHORT nDocHeight;
- if (ValidRow(nY))
- nDocHeight = GetRowHeight( nY, nTab );
- else
- nDocHeight = ScGlobal::nStdRowHeight;
+ if (nY > nDocHeightEndRow)
+ {
+ if (ValidRow(nY))
+ nDocHeight = GetRowHeight( nY, nTab, NULL, &nDocHeightEndRow );
+ else
+ nDocHeight = ScGlobal::nStdRowHeight;
+ }
if ( nArrY==0 || nDocHeight || nY > MAXROW )
{
@@ -384,11 +388,15 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
nArrY = 1;
SCSIZE nUIndex;
+ bool bHiddenRow = true;
+ SCROW nHiddenEndRow = -1;
(void) pThisCol->Search( nY1, nUIndex );
while ( nUIndex < pThisCol->nCount &&
(nThisRow=pThisCol->pItems[nUIndex].nRow) <= nY2 )
{
- if ( !RowHidden( nThisRow,nTab ) )
+ if (nThisRow > nHiddenEndRow)
+ bHiddenRow = RowHidden( nThisRow, nTab, nHiddenEndRow);
+ if ( !bHiddenRow )
{
while ( pRowInfo[nArrY].nRowNo < nThisRow )
++nArrY;
diff --git a/sc/source/core/data/markdata.cxx b/sc/source/core/data/markdata.cxx
index baf3f4cf3f95..d6ea90f1cacf 100644
--- a/sc/source/core/data/markdata.cxx
+++ b/sc/source/core/data/markdata.cxx
@@ -429,18 +429,28 @@ SCCOLROW ScMarkData::GetMarkColumnRanges( SCCOLROW* pRanges )
if (!bMultiMarked)
return 0;
- DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
+ DBG_ASSERT(pMultiSel, "bMultiMarked, but pMultiSel == 0");
+
+ const SCCOLROW nMultiStart = aMultiRange.aStart.Col();
+ const SCCOLROW nMultiEnd = aMultiRange.aEnd.Col();
+ if (nMultiStart == 0 && nMultiEnd == MAXCOL)
+ {
+ // One or more entire rows.
+ pRanges[0] = 0;
+ pRanges[1] = MAXCOL;
+ return 1;
+ }
SCCOLROW nRangeCnt = 0;
- SCCOLROW nStart = 0;
- while (nStart<=MAXCOL)
+ SCCOLROW nStart = nMultiStart;
+ while (nStart <= nMultiEnd)
{
- while (nStart<MAXCOL && !pMultiSel[nStart].HasMarks())
+ while (nStart < nMultiEnd && !pMultiSel[nStart].HasMarks())
++nStart;
if (pMultiSel[nStart].HasMarks())
{
SCCOLROW nEnd = nStart;
- while (nEnd<MAXCOL && pMultiSel[nEnd].HasMarks())
+ while (nEnd < nMultiEnd && pMultiSel[nEnd].HasMarks())
++nEnd;
if (!pMultiSel[nEnd].HasMarks())
--nEnd;
@@ -450,7 +460,7 @@ SCCOLROW ScMarkData::GetMarkColumnRanges( SCCOLROW* pRanges )
nStart = nEnd+1;
}
else
- nStart = MAXCOL+1;
+ nStart = nMultiEnd+1;
}
return nRangeCnt;
@@ -464,37 +474,51 @@ SCCOLROW ScMarkData::GetMarkRowRanges( SCCOLROW* pRanges )
if (!bMultiMarked)
return 0;
- DBG_ASSERT(pMultiSel, "bMultiMarked, aber pMultiSel == 0");
+ DBG_ASSERT(pMultiSel, "bMultiMarked, but pMultiSel == 0");
- // Welche Zeilen sind markiert?
+ // Which rows are marked?
- BOOL* bRowMarked = new BOOL[MAXROW+1];
+ // Optimized to not loop over MAXCOL*MAXROW as worst case, i.e. Ctrl+A
+
+ const SCCOLROW nMultiStart = aMultiRange.aStart.Row();
+ const SCCOLROW nMultiEnd = aMultiRange.aEnd.Row();
+
+ BOOL* bRowMarked = new BOOL[MAXROWCOUNT];
+ memset( bRowMarked, 0, sizeof(BOOL) * MAXROWCOUNT);
SCROW nRow;
SCCOL nCol;
- for (nRow=0; nRow<=MAXROW; nRow++)
- bRowMarked[nRow] = FALSE;
SCROW nTop, nBottom;
- for (nCol=0; nCol<=MAXCOL; nCol++)
+ for (nCol = aMultiRange.aStart.Col(); nCol <= aMultiRange.aEnd.Col(); ++nCol)
{
ScMarkArrayIter aMarkIter( &pMultiSel[nCol] );
while (aMarkIter.Next( nTop, nBottom ))
for (nRow=nTop; nRow<=nBottom; nRow++)
bRowMarked[nRow] = TRUE;
+ if (nTop == nMultiStart && nBottom == nMultiEnd)
+ break; // for, all relevant rows marked
+ }
+
+ if (nTop == nMultiStart && nBottom == nMultiEnd)
+ {
+ pRanges[0] = nTop;
+ pRanges[1] = nBottom;
+ delete[] bRowMarked;
+ return 1;
}
- // zu Bereichen zusammenfassen
+ // Combine to ranges of rows.
SCCOLROW nRangeCnt = 0;
- SCCOLROW nStart = 0;
- while (nStart<=MAXROW)
+ SCCOLROW nStart = nMultiStart;
+ while (nStart <= nMultiEnd)
{
- while (nStart<MAXROW && !bRowMarked[nStart])
+ while (nStart < nMultiEnd && !bRowMarked[nStart])
++nStart;
if (bRowMarked[nStart])
{
SCCOLROW nEnd = nStart;
- while (nEnd<MAXROW && bRowMarked[nEnd])
+ while (nEnd < nMultiEnd && bRowMarked[nEnd])
++nEnd;
if (!bRowMarked[nEnd])
--nEnd;
@@ -504,7 +528,7 @@ SCCOLROW ScMarkData::GetMarkRowRanges( SCCOLROW* pRanges )
nStart = nEnd+1;
}
else
- nStart = MAXROW+1;
+ nStart = nMultiEnd+1;
}
delete[] bRowMarked;
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 9bd5b031fde5..b8bd9037c900 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -2241,7 +2241,7 @@ void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual )
}
-USHORT ScTable::GetColWidth( SCCOL nCol )
+USHORT ScTable::GetColWidth( SCCOL nCol ) const
{
DBG_ASSERT(VALIDCOL(nCol),"Falsche Spaltennummer");
@@ -2315,34 +2315,50 @@ USHORT ScTable::GetCommonWidth( SCCOL nEndCol )
}
-USHORT ScTable::GetRowHeight( SCROW nRow, SCROW* pStartRow, SCROW* pEndRow, bool bHiddenAsZero )
+USHORT ScTable::GetRowHeight( SCROW nRow, SCROW* pStartRow, SCROW* pEndRow, bool bHiddenAsZero ) const
{
- DBG_ASSERT(VALIDROW(nRow),"Falsche Zeilennummer");
+ DBG_ASSERT(VALIDROW(nRow),"Invalid row number");
if (VALIDROW(nRow) && mpRowHeights)
{
- if (bHiddenAsZero && RowHidden(nRow))
+ if (bHiddenAsZero && RowHidden( nRow, pStartRow, pEndRow))
return 0;
else
{
ScFlatUInt16RowSegments::RangeData aData;
if (!mpRowHeights->getRangeData(nRow, aData))
+ {
+ if (pStartRow)
+ *pStartRow = nRow;
+ if (pEndRow)
+ *pEndRow = nRow;
// TODO: What should we return in case the search fails?
return 0;
+ }
+ // If bHiddenAsZero, pStartRow and pEndRow were initialized to
+ // boundaries of a non-hidden segment. Assume that the previous and
+ // next segment are hidden then and limit the current height
+ // segment.
if (pStartRow)
- *pStartRow = aData.mnRow1;
+ *pStartRow = (bHiddenAsZero ? std::max( *pStartRow, aData.mnRow1) : aData.mnRow1);
if (pEndRow)
- *pEndRow = aData.mnRow2;
+ *pEndRow = (bHiddenAsZero ? std::min( *pEndRow, aData.mnRow2) : aData.mnRow2);
return aData.mnValue;
}
}
else
+ {
+ if (pStartRow)
+ *pStartRow = nRow;
+ if (pEndRow)
+ *pEndRow = nRow;
return (USHORT) ScGlobal::nStdRowHeight;
+ }
}
-ULONG ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow )
+ULONG ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow ) const
{
DBG_ASSERT(VALIDROW(nStartRow) && VALIDROW(nEndRow),"Falsche Zeilennummer");
@@ -2368,7 +2384,7 @@ ULONG ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow )
}
-ULONG ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale )
+ULONG ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale ) const
{
DBG_ASSERT(VALIDROW(nStartRow) && VALIDROW(nEndRow),"Falsche Zeilennummer");
@@ -3036,7 +3052,7 @@ void ScTable::SetDrawPageSize(bool bResetStreamValid, bool bUpdateNoteCaptionPos
}
-ULONG ScTable::GetRowOffset( SCROW nRow )
+ULONG ScTable::GetRowOffset( SCROW nRow ) const
{
ULONG n = 0;
if ( mpHiddenRows && mpRowHeights )
@@ -3059,7 +3075,7 @@ ULONG ScTable::GetRowOffset( SCROW nRow )
return n;
}
-SCROW ScTable::GetRowForHeight(ULONG nHeight)
+SCROW ScTable::GetRowForHeight(ULONG nHeight) const
{
sal_uInt32 nSum = 0;
@@ -3086,7 +3102,7 @@ SCROW ScTable::GetRowForHeight(ULONG nHeight)
}
-ULONG ScTable::GetColOffset( SCCOL nCol )
+ULONG ScTable::GetColOffset( SCCOL nCol ) const
{
ULONG n = 0;
if ( pColWidth )
diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx
index 2635b5821e4f..e7ee96367785 100644
--- a/sc/source/core/data/table5.cxx
+++ b/sc/source/core/data/table5.cxx
@@ -355,7 +355,7 @@ bool ScTable::HasRowPageBreak(SCROW nRow) const
if (!ValidRow(nRow))
return false;
- return maRowPageBreaks.count(nRow) > 0;
+ return maRowPageBreaks.find(nRow) != maRowPageBreaks.end();
}
bool ScTable::HasColPageBreak(SCCOL nCol) const
@@ -363,7 +363,7 @@ bool ScTable::HasColPageBreak(SCCOL nCol) const
if (!ValidCol(nCol))
return false;
- return maColPageBreaks.count(nCol) > 0;
+ return maColPageBreaks.find(nCol) != maColPageBreaks.end();
}
bool ScTable::HasRowManualBreak(SCROW nRow) const
@@ -371,7 +371,7 @@ bool ScTable::HasRowManualBreak(SCROW nRow) const
if (!ValidRow(nRow))
return false;
- return maRowManualBreaks.count(nRow) > 0;
+ return maRowManualBreaks.find(nRow) != maRowManualBreaks.end();
}
bool ScTable::HasColManualBreak(SCCOL nCol) const
@@ -379,7 +379,7 @@ bool ScTable::HasColManualBreak(SCCOL nCol) const
if (!ValidCol(nCol))
return false;
- return (maColManualBreaks.count(nCol) > 0);
+ return maColManualBreaks.find(nCol) != maColManualBreaks.end();
}
SCROW ScTable::GetNextManualBreak(SCROW nRow) const
@@ -483,15 +483,27 @@ Sequence<TablePageBreakData> ScTable::GetRowBreakData() const
return aSeq;
}
-bool ScTable::RowHidden(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow)
+bool ScTable::RowHidden(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow) const
{
if (!ValidRow(nRow))
+ {
+ if (pFirstRow)
+ *pFirstRow = nRow;
+ if (pLastRow)
+ *pLastRow = nRow;
return true;
+ }
ScFlatBoolRowSegments::RangeData aData;
if (!mpHiddenRows->getRangeData(nRow, aData))
+ {
// search failed.
+ if (pFirstRow)
+ *pFirstRow = nRow;
+ if (pLastRow)
+ *pLastRow = nRow;
return true;
+ }
if (pFirstRow)
*pFirstRow = aData.mnRow1;
@@ -502,7 +514,7 @@ bool ScTable::RowHidden(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow)
}
-bool ScTable::RowHidden(SCROW nRow, SCROW& rLastRow)
+bool ScTable::RowHidden(SCROW nRow, SCROW& rLastRow) const
{
rLastRow = nRow;
if (!ValidRow(nRow))
@@ -517,7 +529,7 @@ bool ScTable::RowHidden(SCROW nRow, SCROW& rLastRow)
return aData.mbValue;
}
-bool ScTable::HasHiddenRows(SCROW nStartRow, SCROW nEndRow)
+bool ScTable::HasHiddenRows(SCROW nStartRow, SCROW nEndRow) const
{
SCROW nRow = nStartRow;
while (nRow <= nEndRow)
@@ -532,7 +544,7 @@ bool ScTable::HasHiddenRows(SCROW nStartRow, SCROW nEndRow)
return false;
}
-bool ScTable::ColHidden(SCCOL nCol, SCCOL& rLastCol)
+bool ScTable::ColHidden(SCCOL nCol, SCCOL& rLastCol) const
{
rLastCol = nCol;
if (!ValidCol(nCol))
@@ -546,7 +558,7 @@ bool ScTable::ColHidden(SCCOL nCol, SCCOL& rLastCol)
return aData.mbValue;
}
-bool ScTable::ColHidden(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol)
+bool ScTable::ColHidden(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol) const
{
if (!ValidCol(nCol))
return true;
@@ -627,7 +639,7 @@ void ScTable::CopyRowHeight(ScTable& rSrcTable, SCROW nStartRow, SCROW nEndRow,
}
}
-SCROW ScTable::FirstVisibleRow(SCROW nStartRow, SCROW nEndRow)
+SCROW ScTable::FirstVisibleRow(SCROW nStartRow, SCROW nEndRow) const
{
SCROW nRow = nStartRow;
ScFlatBoolRowSegments::RangeData aData;
@@ -650,7 +662,7 @@ SCROW ScTable::FirstVisibleRow(SCROW nStartRow, SCROW nEndRow)
return ::std::numeric_limits<SCROW>::max();
}
-SCROW ScTable::LastVisibleRow(SCROW nStartRow, SCROW nEndRow)
+SCROW ScTable::LastVisibleRow(SCROW nStartRow, SCROW nEndRow) const
{
SCROW nRow = nEndRow;
ScFlatBoolRowSegments::RangeData aData;
@@ -673,7 +685,7 @@ SCROW ScTable::LastVisibleRow(SCROW nStartRow, SCROW nEndRow)
return ::std::numeric_limits<SCROW>::max();
}
-SCROW ScTable::CountVisibleRows(SCROW nStartRow, SCROW nEndRow)
+SCROW ScTable::CountVisibleRows(SCROW nStartRow, SCROW nEndRow) const
{
SCROW nCount = 0;
SCROW nRow = nStartRow;
@@ -694,7 +706,7 @@ SCROW ScTable::CountVisibleRows(SCROW nStartRow, SCROW nEndRow)
return nCount;
}
-sal_uInt32 ScTable::GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow)
+sal_uInt32 ScTable::GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow) const
{
sal_uInt32 nHeight = 0;
SCROW nRow = nStartRow;
@@ -717,7 +729,7 @@ sal_uInt32 ScTable::GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow)
return nHeight;
}
-SCCOLROW ScTable::LastHiddenColRow(SCCOLROW nPos, bool bCol)
+SCCOLROW ScTable::LastHiddenColRow(SCCOLROW nPos, bool bCol) const
{
if (bCol)
{
@@ -741,7 +753,7 @@ SCCOLROW ScTable::LastHiddenColRow(SCCOLROW nPos, bool bCol)
return ::std::numeric_limits<SCCOLROW>::max();
}
-bool ScTable::RowFiltered(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow)
+bool ScTable::RowFiltered(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow) const
{
if (!ValidRow(nRow))
return false;
@@ -759,7 +771,7 @@ bool ScTable::RowFiltered(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow)
return aData.mbValue;
}
-bool ScTable::ColFiltered(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol)
+bool ScTable::ColFiltered(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol) const
{
if (!ValidCol(nCol))
return false;
@@ -777,7 +789,7 @@ bool ScTable::ColFiltered(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol)
return aData.mbValue;
}
-bool ScTable::HasFilteredRows(SCROW nStartRow, SCROW nEndRow)
+bool ScTable::HasFilteredRows(SCROW nStartRow, SCROW nEndRow) const
{
SCROW nRow = nStartRow;
while (nRow <= nEndRow)
@@ -837,7 +849,7 @@ void ScTable::SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, bool bFiltered)
mpFilteredCols->setFalse(nStartCol, nEndCol);
}
-SCROW ScTable::FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow)
+SCROW ScTable::FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow) const
{
SCROW nRow = nStartRow;
ScFlatBoolRowSegments::RangeData aData;
@@ -860,7 +872,7 @@ SCROW ScTable::FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow)
return ::std::numeric_limits<SCROW>::max();
}
-SCROW ScTable::LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow)
+SCROW ScTable::LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow) const
{
SCROW nRow = nEndRow;
ScFlatBoolRowSegments::RangeData aData;
@@ -883,7 +895,7 @@ SCROW ScTable::LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow)
return ::std::numeric_limits<SCROW>::max();
}
-SCROW ScTable::CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow)
+SCROW ScTable::CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow) const
{
SCROW nCount = 0;
SCROW nRow = nStartRow;
diff --git a/sc/source/filter/xml/XMLStylesExportHelper.cxx b/sc/source/filter/xml/XMLStylesExportHelper.cxx
index f8bafa32f205..66f3ea613a3a 100644
--- a/sc/source/filter/xml/XMLStylesExportHelper.cxx
+++ b/sc/source/filter/xml/XMLStylesExportHelper.cxx
@@ -1234,10 +1234,31 @@ void ScRowStyles::AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nFie
const sal_Int32 nStringIndex)
{
DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
- DBG_ASSERT(aTables[nTable].size() >= static_cast<sal_uInt32>(nField), "wrong field");
- if (aTables[nTable].size() == static_cast<sal_uInt32>(nField))
+ DBG_ASSERT(aTables[nTable].size() >= static_cast<size_t>(nField), "wrong field");
+ if (aTables[nTable].size() == static_cast<size_t>(nField))
aTables[nTable].push_back(nStringIndex);
- aTables[nTable][nField] = nStringIndex;
+ else
+ aTables[nTable][nField] = nStringIndex;
+}
+
+void ScRowStyles::AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nStartField,
+ const sal_Int32 nStringIndex, const sal_Int32 nEndField)
+{
+ DBG_ASSERT( nStartField <= nEndField, "bad field range");
+ DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+ DBG_ASSERT(aTables[nTable].size() >= static_cast<size_t>(nStartField), "wrong field");
+ ScMysalInt32Vec& rTable = aTables[nTable];
+ size_t nSize = rTable.size();
+ if (nSize == static_cast<size_t>(nStartField))
+ rTable.insert( rTable.end(), static_cast<size_t>(nEndField - nStartField + 1), nStringIndex);
+ else
+ {
+ size_t nField = static_cast<size_t>(nStartField);
+ for ( ; nField < nSize && nField <= static_cast<size_t>(nEndField); ++nField)
+ rTable[nField] = nStringIndex;
+ if (nField <= static_cast<size_t>(nEndField))
+ rTable.insert( rTable.end(), static_cast<size_t>(nEndField - nField + 1), nStringIndex);
+ }
}
rtl::OUString* ScRowStyles::GetStyleName(const sal_Int32 nTable, const sal_Int32 nField)
diff --git a/sc/source/filter/xml/XMLStylesExportHelper.hxx b/sc/source/filter/xml/XMLStylesExportHelper.hxx
index 34672aeef96e..79b19b7ce9ab 100644
--- a/sc/source/filter/xml/XMLStylesExportHelper.hxx
+++ b/sc/source/filter/xml/XMLStylesExportHelper.hxx
@@ -286,6 +286,7 @@ public:
virtual void AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields);
sal_Int32 GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nField);
void AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nField, const sal_Int32 nStringIndex);
+ void AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nStartField, const sal_Int32 nStringIndex, const sal_Int32 nEndField);
virtual rtl::OUString* GetStyleName(const sal_Int32 nTable, const sal_Int32 nField);
};
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 0563f6430063..b34abb29443c 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -2576,14 +2576,13 @@ void ScXMLExport::_ExportAutoStyles()
}
sal_Int32 nOld(nRow);
nRow = pDoc->GetNextDifferentChangedRow(sal::static_int_cast<SCTAB>(nTable), static_cast<SCROW>(nRow), false);
- for (sal_Int32 i = nOld + 1; i < nRow; ++i)
- pRowStyles->AddFieldStyleName(nTable, i, nIndex);
+ if (nRow > nOld + 1)
+ pRowStyles->AddFieldStyleName(nTable, nOld + 1, nIndex, nRow - 1);
}
if (aCellAddress.EndRow > nRows)
{
sal_Int32 nIndex(pRowStyles->GetStyleNameIndex(nTable, nRows));
- for (sal_Int32 i = nRows + 1; i <= aCellAddress.EndRow; ++i)
- pRowStyles->AddFieldStyleName(nTable, i, nIndex);
+ pRowStyles->AddFieldStyleName(nTable, nRows + 1, nIndex, aCellAddress.EndRow);
}
}
}
diff --git a/sc/source/ui/inc/viewdata.hxx b/sc/source/ui/inc/viewdata.hxx
index 106d196a8175..fb9c674a4488 100644
--- a/sc/source/ui/inc/viewdata.hxx
+++ b/sc/source/ui/inc/viewdata.hxx
@@ -482,6 +482,24 @@ public:
BOOL IsSelCtrlMouseClick() { return bSelCtrlMouseClick; }
static inline long ToPixel( USHORT nTwips, double nFactor );
+
+ /** while (rScrY <= nEndPixels && rPosY <= nEndRow) add pixels of row
+ heights converted with nPPTY to rScrY, optimized for row height
+ segments. Upon return rPosY is the last row evaluated <= nEndRow, rScrY
+ may be > nEndPixels!
+ */
+ static void AddPixelsWhile( long & rScrY, long nEndPixels,
+ SCROW & rPosY, SCROW nEndRow, double nPPTY,
+ const ScDocument * pDoc, SCTAB nTabNo );
+
+ /** while (rScrY <= nEndPixels && rPosY >= nStartRow) add pixels of row
+ heights converted with nPPTY to rScrY, optimized for row height
+ segments. Upon return rPosY is the last row evaluated >= nStartRow,
+ rScrY may be > nEndPixels!
+ */
+ static void AddPixelsWhileBackward( long & rScrY, long nEndPixels,
+ SCROW & rPosY, SCROW nStartRow, double nPPTY,
+ const ScDocument * pDoc, SCTAB nTabNo );
};
diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx
index c284045c5b11..3fb2c74a9954 100644
--- a/sc/source/ui/undo/undoblk.cxx
+++ b/sc/source/ui/undo/undoblk.cxx
@@ -592,7 +592,7 @@ ScUndoDeleteMulti::ScUndoDeleteMulti( ScDocShell* pNewDocShell,
__EXPORT ScUndoDeleteMulti::~ScUndoDeleteMulti()
{
- delete pRanges;
+ delete [] pRanges;
}
String __EXPORT ScUndoDeleteMulti::GetComment() const
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index 6bf27387314a..ba73fbf00269 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -401,17 +401,13 @@ void __EXPORT ScGridWindow::Paint( const Rectangle& rRect )
nScrX += ScViewData::ToPixel( pDoc->GetColWidth( nX2, nTab ), nPPTX );
}
- long nScrY = ScViewData::ToPixel( pDoc->GetRowHeight( nY1, nTab ), nPPTY );
- while ( nScrY <= aPixRect.Top() && nY1 < MAXROW )
- {
- ++nY1;
- nScrY += ScViewData::ToPixel( pDoc->GetRowHeight( nY1, nTab ), nPPTY );
- }
+ long nScrY = 0;
+ ScViewData::AddPixelsWhile( nScrY, aPixRect.Top(), nY1, MAXROW, nPPTY, pDoc, nTab);
SCROW nY2 = nY1;
- while ( nScrY <= aPixRect.Bottom() && nY2 < MAXROW )
+ if (nScrY <= aPixRect.Bottom() && nY2 < MAXROW)
{
++nY2;
- nScrY += ScViewData::ToPixel( pDoc->GetRowHeight( nY2, nTab ), nPPTY );
+ ScViewData::AddPixelsWhile( nScrY, aPixRect.Bottom(), nY2, MAXROW, nPPTY, pDoc, nTab);
}
Draw( nX1,nY1,nX2,nY2, SC_UPDATE_MARKS ); // nicht weiterzeichnen
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
index 961572fc0185..7b27ddf3f8cc 100644
--- a/sc/source/ui/view/output.cxx
+++ b/sc/source/ui/view/output.cxx
@@ -489,6 +489,8 @@ void ScOutputData::DrawGrid( BOOL bGrid, BOOL bPage )
// Horizontale Linien
//
+ bool bHiddenRow = true;
+ SCROW nHiddenEndRow = -1;
nPosY = nScrY;
for (nArrY=1; nArrY+1<nArrCount; nArrY++)
{
@@ -503,9 +505,17 @@ void ScOutputData::DrawGrid( BOOL bGrid, BOOL bPage )
{
for (SCROW i = nYplus1; i <= MAXROW; ++i)
{
+ if (i > nHiddenEndRow)
+ bHiddenRow = pDoc->RowHidden(i, nTab, nHiddenEndRow);
+ /* TODO: optimize the row break thing for large hidden
+ * segments where HasRowBreak() has to be called
+ * nevertheless for each row, as a row break is drawn also
+ * for hidden rows, above them. This needed to be done only
+ * once per hidden segment, maybe giving manual breaks
+ * priority. Something like GetNextRowBreak() and
+ * GetNextManualRowBreak(). */
nBreak = pDoc->HasRowBreak(i, nTab);
- bool bHidden = pDoc->RowHidden(i, nTab);
- if (nBreak || !bHidden)
+ if (!bHiddenRow || nBreak)
break;
}
diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx
index c034836d4d4a..38d5aa60eaeb 100644
--- a/sc/source/ui/view/viewdata.cxx
+++ b/sc/source/ui/view/viewdata.cxx
@@ -1696,50 +1696,32 @@ SCROW ScViewData::CellsAtY( SCsROW nPosY, SCsROW nDir, ScVSplitPos eWhichY, USHO
if (pView)
((ScViewData*)this)->aScrSize.Height() = pView->GetGridHeight(eWhichY);
- SCROW nY;
- USHORT nScrPosY = 0;
-
if (nScrSizeY == SC_SIZE_NONE) nScrSizeY = (USHORT) aScrSize.Height();
- if (nDir==1)
- nY = nPosY; // vorwaerts
- else
- nY = nPosY-1; // rueckwaerts
-
- BOOL bOut = FALSE;
- for ( ; nScrPosY<=nScrSizeY && !bOut; nY+=nDir )
- {
- SCsROW nRowNo = nY;
- if ( nRowNo < 0 || nRowNo > MAXROW )
- bOut = TRUE;
- else
- {
- USHORT nTSize = pDoc->GetRowHeight( nRowNo, nTabNo );
- if (nTSize)
- {
- long nSizeYPix = ToPixel( nTSize, nPPTY );
- nScrPosY = sal::static_int_cast<USHORT>( nScrPosY + (USHORT) nSizeYPix );
- }
- else if ( nDir == 1 && nRowNo < MAXROW )
- {
- // skip multiple hidden rows (forward only for now)
- SCROW nNext = pDoc->FirstVisibleRow(nRowNo + 1, MAXROW, nTabNo);
- if ( nNext > MAXROW )
- {
- // same behavior as without the optimization: set bOut with nY=MAXROW+1
- nY = MAXROW+1;
- bOut = TRUE;
- }
- else
- nY = nNext - 1; // +=nDir advances to next visible row
- }
- }
- }
+ SCROW nY;
if (nDir==1)
+ {
+ // forward
+ nY = nPosY;
+ long nScrPosY = 0;
+ AddPixelsWhile( nScrPosY, nScrSizeY, nY, MAXROW, nPPTY, pDoc, nTabNo);
+ // Original loop ended on last evaluated +1 or if that was MAXROW even
+ // on MAXROW+2.
+ nY += (nY == MAXROW ? 2 : 1);
nY -= nPosY;
+ }
else
+ {
+ // backward
+ nY = nPosY-1;
+ long nScrPosY = 0;
+ AddPixelsWhileBackward( nScrPosY, nScrSizeY, nY, 0, nPPTY, pDoc, nTabNo);
+ // Original loop ended on last evaluated -1 or if that was 0 even on
+ // -2.
+ nY -= (nY == 0 ? 2 : 1);
nY = (nPosY-1)-nY;
+ }
if (nY>0) --nY;
return nY;
@@ -1855,16 +1837,10 @@ BOOL ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich,
}
if (nClickY > 0)
- {
- while ( rPosY<=MAXROW && nClickY >= nScrY )
- {
- nScrY += ToPixel( pDoc->GetRowHeight( rPosY, nTabNo ), nPPTY );
- ++rPosY;
- }
- --rPosY;
- }
+ AddPixelsWhile( nScrY, nClickY, rPosY, MAXROW, nPPTY, pDoc, nTabNo );
else
{
+ /* TODO: could need some "SubPixelsWhileBackward" method */
while ( rPosY>0 && nClickY < nScrY )
{
--rPosY;
@@ -1984,20 +1960,24 @@ void ScViewData::SetPosY( ScVSplitPos eWhich, SCROW nNewPosY )
SCROW nOldPosY = pThisTab->nPosY[eWhich];
long nTPosY = pThisTab->nTPosY[eWhich];
long nPixPosY = pThisTab->nPixPosY[eWhich];
- SCROW i;
+ SCROW i, nHeightEndRow;
if ( nNewPosY > nOldPosY )
for ( i=nOldPosY; i<nNewPosY; i++ )
{
- long nThis = pDoc->GetRowHeight( i,nTabNo );
- nTPosY -= nThis;
- nPixPosY -= ToPixel(sal::static_int_cast<USHORT>(nThis), nPPTY);
+ long nThis = pDoc->GetRowHeight( i, nTabNo, NULL, &nHeightEndRow );
+ SCROW nRows = std::min( nNewPosY, nHeightEndRow + 1) - i;
+ i = nHeightEndRow;
+ nTPosY -= nThis * nRows;
+ nPixPosY -= ToPixel(sal::static_int_cast<USHORT>(nThis), nPPTY) * nRows;
}
else
for ( i=nNewPosY; i<nOldPosY; i++ )
{
- long nThis = pDoc->GetRowHeight( i,nTabNo );
- nTPosY += nThis;
- nPixPosY += ToPixel(sal::static_int_cast<USHORT>(nThis), nPPTY);
+ long nThis = pDoc->GetRowHeight( i, nTabNo, NULL, &nHeightEndRow );
+ SCROW nRows = std::min( nOldPosY, nHeightEndRow + 1) - i;
+ i = nHeightEndRow;
+ nTPosY += nThis * nRows;
+ nPixPosY += ToPixel(sal::static_int_cast<USHORT>(nThis), nPPTY) * nRows;
}
pThisTab->nPosY[eWhich] = nNewPosY;
@@ -3118,5 +3098,82 @@ ScAddress ScViewData::GetCurPos() const
}
+// static
+void ScViewData::AddPixelsWhile( long & rScrY, long nEndPixels, SCROW & rPosY,
+ SCROW nEndRow, double nPPTY, const ScDocument * pDoc, SCTAB nTabNo )
+{
+ SCROW nRow = rPosY;
+ while (rScrY <= nEndPixels && nRow <= nEndRow)
+ {
+ SCROW nHeightEndRow;
+ USHORT nHeight = pDoc->GetRowHeight( nRow, nTabNo, NULL, &nHeightEndRow);
+ if (nHeightEndRow > nEndRow)
+ nHeightEndRow = nEndRow;
+ if (!nHeight)
+ nRow = nHeightEndRow + 1;
+ else
+ {
+ SCROW nRows = nHeightEndRow - nRow + 1;
+ sal_Int64 nPixel = ToPixel( nHeight, nPPTY);
+ sal_Int64 nAdd = nPixel * nRows;
+ if (nAdd + rScrY > nEndPixels)
+ {
+ sal_Int64 nDiff = rScrY + nAdd - nEndPixels;
+ nRows -= nDiff / nPixel;
+ nAdd = nPixel * nRows;
+ // We're looking for a value that satisfies loop condition.
+ if (nAdd + rScrY <= nEndPixels)
+ {
+ ++nRows;
+ nAdd += nPixel;
+ }
+ }
+ rScrY += static_cast<long>(nAdd);
+ nRow += nRows;
+ }
+ }
+ if (nRow > rPosY)
+ --nRow;
+ rPosY = nRow;
+}
+// static
+void ScViewData::AddPixelsWhileBackward( long & rScrY, long nEndPixels,
+ SCROW & rPosY, SCROW nStartRow, double nPPTY, const ScDocument * pDoc,
+ SCTAB nTabNo )
+{
+ SCROW nRow = rPosY;
+ while (rScrY <= nEndPixels && nRow >= nStartRow)
+ {
+ SCROW nHeightStartRow;
+ USHORT nHeight = pDoc->GetRowHeight( nRow, nTabNo, &nHeightStartRow, NULL);
+ if (nHeightStartRow < nStartRow)
+ nHeightStartRow = nStartRow;
+ if (!nHeight)
+ nRow = nHeightStartRow - 1;
+ else
+ {
+ SCROW nRows = nRow - nHeightStartRow + 1;
+ sal_Int64 nPixel = ToPixel( nHeight, nPPTY);
+ sal_Int64 nAdd = nPixel * nRows;
+ if (nAdd + rScrY > nEndPixels)
+ {
+ sal_Int64 nDiff = nAdd + rScrY - nEndPixels;
+ nRows -= nDiff / nPixel;
+ nAdd = nPixel * nRows;
+ // We're looking for a value that satisfies loop condition.
+ if (nAdd + rScrY <= nEndPixels)
+ {
+ ++nRows;
+ nAdd += nPixel;
+ }
+ }
+ rScrY += static_cast<long>(nAdd);
+ nRow -= nRows;
+ }
+ }
+ if (nRow < rPosY)
+ ++nRow;
+ rPosY = nRow;
+}