diff options
author | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2012-08-09 15:44:23 +0200 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2012-08-09 16:14:33 +0200 |
commit | 36bc405d72f1d1898437dfa25d8cb4bdfba63e06 (patch) | |
tree | 2679cc78c4e596284cc8725d3b60f4aec1c630b9 /sc | |
parent | 1150a1a8eb1759160b9d88e99d95e5ad082f40be (diff) |
fix column navigation with CTRL + direction, fdo#45020
Change-Id: I422b1b85e539d4e2819b93deaf8543410b44b9bd
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/column.hxx | 2 | ||||
-rw-r--r-- | sc/inc/document.hxx | 2 | ||||
-rw-r--r-- | sc/inc/global.hxx | 8 | ||||
-rw-r--r-- | sc/inc/table.hxx | 6 | ||||
-rw-r--r-- | sc/source/core/data/column2.cxx | 14 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/table1.cxx | 134 | ||||
-rw-r--r-- | sc/source/ui/vba/vbarange.cxx | 13 | ||||
-rw-r--r-- | sc/source/ui/view/tabview2.cxx | 8 | ||||
-rw-r--r-- | sc/source/ui/view/viewfun2.cxx | 4 |
10 files changed, 145 insertions, 50 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 6bc8c8c2f5b7..d9c18ec57585 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -167,7 +167,7 @@ public: SCROW GetFirstVisDataPos() const; bool GetPrevDataPos(SCROW& rRow) const; bool GetNextDataPos(SCROW& rRow) const; - void FindDataAreaPos(SCROW& rRow, long nMovY) const; // (without Broadcaster) + void FindDataAreaPos(SCROW& rRow, bool bDown) const; // (without Broadcaster) void FindUsed( SCROW nStartRow, SCROW nEndRow, bool* pUsed ) const; SCSIZE VisibleCount( SCROW nStartRow, SCROW nEndRow ) const; diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 9893e7aef448..8fcdc6d29e4b 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -959,7 +959,7 @@ public: SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, ScDirection eDir ); - SC_DLLPUBLIC void FindAreaPos( SCCOL& rCol, SCROW& rRow, SCTAB nTab, SCsCOL nMovX, SCsROW nMovY ); + SC_DLLPUBLIC void FindAreaPos( SCCOL& rCol, SCROW& rRow, SCTAB nTab, ScMoveDirection eDirection ); SC_DLLPUBLIC void GetNextPos( SCCOL& rCol, SCROW& rRow, SCTAB nTab, SCsCOL nMovX, SCsROW nMovY, bool bMarked, bool bUnprotected, const ScMarkData& rMark ); diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx index 371431fc0265..44d8810ddd2d 100644 --- a/sc/inc/global.hxx +++ b/sc/inc/global.hxx @@ -329,6 +329,14 @@ enum FillCmd FILL_AUTO }; +enum ScMoveDirection +{ + SC_MOVE_RIGHT, + SC_MOVE_LEFT, + SC_MOVE_UP, + SC_MOVE_DOWN +}; + enum FillDateCmd { FILL_DAY, diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index bb365dbf29d4..87483266ba82 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -424,7 +424,7 @@ public: SCSIZE GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, ScDirection eDir ); - void FindAreaPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY ); + void FindAreaPos( SCCOL& rCol, SCROW& rRow, ScMoveDirection eDirection ); void GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY, bool bMarked, bool bUnprotected, const ScMarkData& rMark ); @@ -913,6 +913,10 @@ private: void CopyPrintRange(const ScTable& rTable); + SCCOL FindNextVisibleColWithContent(SCCOL nCol, bool bRight, SCROW nRow); + + SCCOL FindNextVisibleCol(SCCOL nCol, bool bRight); + /** * Use this to iterate through non-empty visible cells in a single column. */ diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index f22fec0aafed..fbd84e762794 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -1396,12 +1396,8 @@ SCROW ScColumn::FindNextVisibleRowWithContent(SCROW nRow, bool bForward) const } } -void ScColumn::FindDataAreaPos(SCROW& rRow, long nMovY) const +void ScColumn::FindDataAreaPos(SCROW& rRow, bool bDown) const { - if (!nMovY) - return; - bool bForward = (nMovY>0); - // check if we are in a data area SCSIZE nIndex; bool bThere = Search(rRow, nIndex); @@ -1411,7 +1407,7 @@ void ScColumn::FindDataAreaPos(SCROW& rRow, long nMovY) const size_t nLastIndex = maItems.size() - 1; if (bThere) { - SCROW nNextRow = FindNextVisibleRow(rRow, bForward); + SCROW nNextRow = FindNextVisibleRow(rRow, bDown); SCSIZE nNewIndex; bool bNextThere = Search(nNextRow, nNewIndex); if(bNextThere && maItems[nNewIndex].pCell->IsBlank()) @@ -1423,7 +1419,7 @@ void ScColumn::FindDataAreaPos(SCROW& rRow, long nMovY) const nLastRow = nNextRow; do { - nNextRow = FindNextVisibleRow(nLastRow, bForward); + nNextRow = FindNextVisibleRow(nLastRow, bDown); bNextThere = Search(nNextRow, nNewIndex); if(!bNextThere || maItems[nNewIndex].pCell->IsBlank()) bNextThere = false; @@ -1436,12 +1432,12 @@ void ScColumn::FindDataAreaPos(SCROW& rRow, long nMovY) const } else { - rRow = FindNextVisibleRowWithContent(nNextRow, bForward); + rRow = FindNextVisibleRowWithContent(nNextRow, bDown); } } else { - rRow = FindNextVisibleRowWithContent(rRow, bForward); + rRow = FindNextVisibleRowWithContent(rRow, bDown); } } diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index de977d87e674..58f834f0f73a 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -5329,10 +5329,10 @@ SCSIZE ScDocument::GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow, SCTAB } -void ScDocument::FindAreaPos( SCCOL& rCol, SCROW& rRow, SCTAB nTab, SCsCOL nMovX, SCsROW nMovY ) +void ScDocument::FindAreaPos( SCCOL& rCol, SCROW& rRow, SCTAB nTab, ScMoveDirection eDirection ) { if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab]) - maTabs[nTab]->FindAreaPos( rCol, rRow, nMovX, nMovY ); + maTabs[nTab]->FindAreaPos( rCol, rRow, eDirection ); } diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx index 090345a66807..e8c5d2e63987 100644 --- a/sc/source/core/data/table1.cxx +++ b/sc/source/core/data/table1.cxx @@ -1053,44 +1053,132 @@ void ScTable::LimitChartArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol --rEndRow; } -void ScTable::FindAreaPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY ) +SCCOL ScTable::FindNextVisibleCol( SCCOL nCol, bool bRight ) { - if (nMovX) + if(bRight) { - SCsCOL nNewCol = (SCsCOL) rCol; - bool bThere = aCol[nNewCol].HasVisibleDataAt(rRow); - bool bFnd; - if (bThere) + nCol++; + SCCOL nEnd = 0; + bool bHidden = pDocument->ColHidden(nCol, nTab, NULL, &nEnd); + if(bHidden) + nCol = nEnd +1; + + return std::min<SCCOL>(MAXCOL, nCol); + } + else + { + nCol--; + SCCOL nStart = MAXCOL; + bool bHidden = pDocument->ColHidden(nCol, nTab, &nStart, NULL); + if(bHidden) + nCol = nStart - 1; + + return std::max<SCCOL>(0, nCol); + } +} + +SCCOL ScTable::FindNextVisibleColWithContent( SCCOL nCol, bool bRight, SCROW nRow ) +{ + if(bRight) + { + if(nCol == MAXCOL) + return MAXCOL; + + do { - do + nCol++; + SCCOL nEndCol = 0; + bool bHidden = pDocument->ColHidden( nCol, nTab, NULL, &nEndCol ); + if(bHidden) { - nNewCol = sal::static_int_cast<SCsCOL>( nNewCol + nMovX ); - bFnd = (nNewCol>=0 && nNewCol<=MAXCOL) ? aCol[nNewCol].HasVisibleDataAt(rRow) : false; + nCol = nEndCol +1; + if(nEndCol >= MAXCOL) + return MAXCOL; } - while (bFnd); - nNewCol = sal::static_int_cast<SCsCOL>( nNewCol - nMovX ); - if (nNewCol == (SCsCOL)rCol) - bThere = false; + if(aCol[nCol].HasVisibleDataAt(nRow)) + return nCol; } + while(nCol < MAXCOL); + + return MAXCOL; + } + else + { + if(nCol == 0) + return 0; - if (!bThere) + do { - do + nCol--; + SCCOL nStartCol = MAXCOL; + bool bHidden = pDocument->ColHidden( nCol, nTab, &nStartCol, NULL ); + if(bHidden) { - nNewCol = sal::static_int_cast<SCsCOL>( nNewCol + nMovX ); - bFnd = (nNewCol>=0 && nNewCol<=MAXCOL) ? aCol[nNewCol].HasVisibleDataAt(rRow) : true; + nCol = nStartCol -1; + if(nCol <= 0) + return 0; } - while (!bFnd); + + if(aCol[nCol].HasVisibleDataAt(nRow)) + return nCol; } + while(nCol > 0); - if (nNewCol<0) nNewCol=0; - if (nNewCol>MAXCOL) nNewCol=MAXCOL; - rCol = (SCCOL) nNewCol; + return 0; } +} + +void ScTable::FindAreaPos( SCCOL& rCol, SCROW& rRow, ScMoveDirection eDirection ) +{ + if (eDirection == SC_MOVE_LEFT || eDirection == SC_MOVE_RIGHT) + { + SCCOL nNewCol = rCol; + bool bThere = aCol[nNewCol].HasVisibleDataAt(rRow); + bool bRight = (eDirection == SC_MOVE_RIGHT); + if (bThere) + { + if(nNewCol >= MAXCOL && eDirection == SC_MOVE_RIGHT) + return; + else if(nNewCol == 0 && eDirection == SC_MOVE_LEFT) + return; - if (nMovY) - aCol[rCol].FindDataAreaPos(rRow,nMovY); + SCCOL nNextCol = FindNextVisibleCol( nNewCol, bRight ); + + if(aCol[nNextCol].HasVisibleDataAt(rRow)) + { + bool bFound = false; + nNewCol = nNextCol; + do + { + nNextCol = FindNextVisibleCol( nNewCol, bRight ); + if(aCol[nNextCol].HasVisibleDataAt(rRow)) + nNewCol = nNextCol; + else + bFound = true; + } + while(!bFound && nNextCol > 0 && nNextCol < MAXCOL); + } + else + { + nNewCol = FindNextVisibleColWithContent(nNewCol, bRight, rRow); + } + } + else + { + nNewCol = FindNextVisibleColWithContent(nNewCol, bRight, rRow); + } + + if (nNewCol<0) + nNewCol=0; + if (nNewCol>MAXCOL) + nNewCol=MAXCOL; + rCol = nNewCol; + } + else + { + aCol[rCol].FindDataAreaPos(rRow,eDirection == SC_MOVE_DOWN); + } } bool ScTable::ValidNextPos( SCCOL nCol, SCROW nRow, const ScMarkData& rMark, diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx index 3bc6e4f80009..7caa0e84a919 100644 --- a/sc/source/ui/vba/vbarange.cxx +++ b/sc/source/ui/vba/vbarange.cxx @@ -3705,21 +3705,20 @@ ScVbaRange::End( ::sal_Int32 Direction ) throw (uno::RuntimeException) ScDocShell* pDocShell = getScDocShell(); ScDocument* pDoc = pDocShell->GetDocument(); - SCsCOL nMoveX = 0; - SCsROW nMoveY = 0; + ScMoveDirection eDirection; switch ( Direction ) { case excel::XlDirection::xlDown: - nMoveY = 1; + eDirection = SC_MOVE_DOWN; break; case excel::XlDirection::xlUp: - nMoveY = -1; + eDirection = SC_MOVE_UP; break; case excel::XlDirection::xlToLeft: - nMoveX = -1; + eDirection = SC_MOVE_LEFT; break; case excel::XlDirection::xlToRight: - nMoveX = 1; + eDirection = SC_MOVE_RIGHT; break; default: throw uno::RuntimeException( ::rtl::OUString( "Invalid Direction" ), uno::Reference< uno::XInterface >() ); @@ -3727,7 +3726,7 @@ ScVbaRange::End( ::sal_Int32 Direction ) throw (uno::RuntimeException) if ( pDoc ) { - pDoc->FindAreaPos( nNewX, nNewY, nTab, nMoveX, nMoveY ); + pDoc->FindAreaPos( nNewX, nNewY, nTab, eDirection ); } ScRange aNewRange( (SCCOL)nNewX, (SCROW)nNewY, nTab, (SCCOL)nNewX, (SCROW)nNewY, nTab ); diff --git a/sc/source/ui/view/tabview2.cxx b/sc/source/ui/view/tabview2.cxx index e73bbfdcd969..e8f3fa5e137d 100644 --- a/sc/source/ui/view/tabview2.cxx +++ b/sc/source/ui/view/tabview2.cxx @@ -650,16 +650,16 @@ void ScTabView::GetAreaMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, ScFollowMode SCsCOLROW i; if ( nMovX > 0 ) for ( i=0; i<nMovX; i++ ) - pDoc->FindAreaPos( nNewX, nCurY, nTab, 1, 0 ); + pDoc->FindAreaPos( nNewX, nCurY, nTab, SC_MOVE_RIGHT ); if ( nMovX < 0 ) for ( i=0; i<-nMovX; i++ ) - pDoc->FindAreaPos( nNewX, nCurY, nTab, -1, 0 ); + pDoc->FindAreaPos( nNewX, nCurY, nTab, SC_MOVE_LEFT ); if ( nMovY > 0 ) for ( i=0; i<nMovY; i++ ) - pDoc->FindAreaPos( nCurX, nNewY, nTab, 0, 1 ); + pDoc->FindAreaPos( nCurX, nNewY, nTab, SC_MOVE_DOWN ); if ( nMovY < 0 ) for ( i=0; i<-nMovY; i++ ) - pDoc->FindAreaPos( nCurX, nNewY, nTab, 0, -1 ); + pDoc->FindAreaPos( nCurX, nNewY, nTab, SC_MOVE_UP ); if (eMode==SC_FOLLOW_JUMP) // unten/rechts nicht zuviel grau anzeigen { diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx index b55e1030cca6..4f1cbd98a2bf 100644 --- a/sc/source/ui/view/viewfun2.cxx +++ b/sc/source/ui/view/viewfun2.cxx @@ -1471,7 +1471,7 @@ void ScViewFunc::FillCrossDblClick() if ( pDoc->HasData( nMovX, nStartY, nTab ) && pDoc->HasData( nMovX, nStartY + 1, nTab ) ) { - pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 ); + pDoc->FindAreaPos( nMovX, nMovY, nTab, SC_MOVE_DOWN ); if ( nMovY > nEndY ) { @@ -1490,7 +1490,7 @@ void ScViewFunc::FillCrossDblClick() if ( pDoc->HasData( nMovX, nStartY, nTab ) && pDoc->HasData( nMovX, nStartY + 1, nTab ) ) { - pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 ); + pDoc->FindAreaPos( nMovX, nMovY, nTab, SC_MOVE_DOWN ); if ( nMovY > nEndY ) { |