diff options
author | Eike Rathke <erack@redhat.com> | 2018-07-04 20:43:34 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2018-07-05 00:20:45 +0200 |
commit | 7903fa04d2d2233fe193eef7dfd3c203430edcc6 (patch) | |
tree | ff0c482f7b48c20c151e214e13131cc18a4dce3d | |
parent | e55e6d863080b5f03f6d14820c5c08b84eeab600 (diff) |
Limit GetNextPos() loops to range, if available, tdf#68290 follow-up
It's unnecessary to check all columns if there was a range marked
anyway. Also use GetPrintArea() only for bUnprotected and enlarge
the result a bit to cover the case where a protected form may be
empty but not have vidsual indications either.
Also adding nMoveY to nCol was nonsense all the time already, what
was actually meant is to add the direction of movement. Worked by
chance because nMoveY was always +1/-1.
Change-Id: Ic1175a607a1169f3ef0e28d0f3a91f8c526314f4
Reviewed-on: https://gerrit.libreoffice.org/56966
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Jenkins
-rw-r--r-- | sc/source/core/data/table1.cxx | 75 |
1 files changed, 58 insertions, 17 deletions
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx index 4506d3e17fe0..9af3ad511c45 100644 --- a/sc/source/core/data/table1.cxx +++ b/sc/source/core/data/table1.cxx @@ -1382,45 +1382,86 @@ void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCCOL nMovX, SCROW nMovY, if ( nMovY && (bMarked || bUnprotected)) { bool bUp = ( nMovY < 0 ); - SCROW nUsedY = nRow; - SCCOL nUsedX = nCol; + const SCCOL nColAdd = (bUp ? -1 : 1); + SCCOL nStartCol, nEndCol; + SCROW nStartRow, nEndRow; + if (bMarked && rMark.IsMarked()) + { + ScRange aRange( ScAddress::UNINITIALIZED); + rMark.GetMarkArea( aRange); + nStartCol = aRange.aStart.Col(); + nStartRow = aRange.aStart.Row(); + nEndCol = aRange.aEnd.Col(); + nEndRow = aRange.aEnd.Row(); + } + else if (bMarked && rMark.IsMultiMarked()) + { + ScRange aRange( ScAddress::UNINITIALIZED); + rMark.GetMultiMarkArea( aRange); + nStartCol = aRange.aStart.Col(); + nStartRow = aRange.aStart.Row(); + nEndCol = aRange.aEnd.Col(); + nEndRow = aRange.aEnd.Row(); + } + else if (bUnprotected) + { + nStartCol = 0; + nStartRow = 0; + nEndCol = nCol; + nEndRow = nRow; + pDocument->GetPrintArea( nTab, nEndCol, nEndRow, true ); + // Add some cols/rows to the print area (which is "content or + // visually different from empty") to enable travelling through + // protected forms with empty cells and no visual indicator. + // 42 might be good enough and not too much.. + nEndCol = std::min<SCCOL>( nEndCol+42, MAXCOL); + nEndRow = std::min<SCROW>( nEndRow+42, MAXROW); + } + else + { + SAL_WARN("sc.core","ScTable::GetNextPos - bMarked but not marked"); + nStartCol = 0; + nStartRow = 0; + nEndCol = MAXCOL; + nEndRow = MAXROW; + } if (bMarked) nRow = rMark.GetNextMarked( nCol, nRow, bUp ); - pDocument->GetPrintArea( nTab, nUsedX, nUsedY ); - while ( SkipRow( nCol, nRow, nMovY, rMark, bUp, nUsedY, bMarked, bSheetProtected )) + while ( SkipRow( nCol, nRow, nMovY, rMark, bUp, nEndRow, bMarked, bSheetProtected )) ; - while ( nRow < 0 || nRow > MAXROW ) + while ( nRow < nStartRow || nRow > nEndRow ) { - nCol = sal::static_int_cast<SCCOL>( nCol + static_cast<SCCOL>(nMovY) ); + nCol += nColAdd; - while ( ValidCol(nCol) && ColHidden(nCol) ) - nCol = sal::static_int_cast<SCCOL>( nCol + static_cast<SCCOL>(nMovY) ); // skip hidden rows (see above) - if (nCol < 0) + while (nStartCol <= nCol && nCol <= nEndCol && ValidCol(nCol) && ColHidden(nCol)) + nCol += nColAdd; // skip hidden cols + + if (nCol < nStartCol) { - nCol = (bSheetProtected ? nUsedX : MAXCOL); + nCol = nEndCol; if (++nWrap >= 2) return; } - else if (nCol > MAXCOL || ( nCol > nUsedX && bSheetProtected )) + else if (nCol > nEndCol) { - nCol = 0; + nCol = nStartCol; if (++nWrap >= 2) return; } - if (nRow < 0) - nRow = MAXROW; - else if (nRow > MAXROW) - nRow = 0; + if (nRow < nStartRow) + nRow = nEndRow; + else if (nRow > nEndRow) + nRow = nStartRow; if (bMarked) nRow = rMark.GetNextMarked( nCol, nRow, bUp ); - while ( SkipRow( nCol, nRow, nMovY, rMark, bUp, nUsedY, bMarked, bSheetProtected )) + while ( SkipRow( nCol, nRow, nMovY, rMark, bUp, nEndRow, bMarked, bSheetProtected )) ; } } |