1 diff --git sc/inc/document.hxx sc/inc/document.hxx
2 index 96b6809..cc91c1a 100644
3 --- sc/inc/document.hxx
4 +++ sc/inc/document.hxx
5 @@ -824,6 +824,7 @@ public:
6 ScRange* pLastRange = NULL,
7 Rectangle* pLastMM = NULL ) const;
9 + void SkipOverlapped( SCCOL& rCol, SCROW& rRow, SCTAB nTab ) const;
10 BOOL IsHorOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const;
11 BOOL IsVerOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const;
13 diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
14 index de89b1b..8ba6dfa 100644
15 --- sc/source/core/data/document.cxx
16 +++ sc/source/core/data/document.cxx
17 @@ -4534,6 +4534,13 @@ BOOL ScDocument::RefreshAutoFilter( SCCOL nStartCol, SCROW nStartRow,
21 +void ScDocument::SkipOverlapped( SCCOL& rCol, SCROW& rRow, SCTAB nTab ) const
23 + while (IsHorOverlapped(rCol, rRow, nTab))
25 + while (IsVerOverlapped(rCol, rRow, nTab))
29 BOOL ScDocument::IsHorOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
31 diff --git sc/source/ui/inc/cellsh.hxx sc/source/ui/inc/cellsh.hxx
32 index 97f6d0d..a42a336 100644
33 --- sc/source/ui/inc/cellsh.hxx
34 +++ sc/source/ui/inc/cellsh.hxx
36 #include <svx/svdmark.hxx>
37 #include <tools/link.hxx>
38 #include "formatsh.hxx"
39 +#include "address.hxx"
41 class SvxClipboardFmtItem;
42 class TransferableDataHelper;
43 diff --git sc/source/ui/inc/tabview.hxx sc/source/ui/inc/tabview.hxx
44 index 437b95b..804fbff 100644
45 --- sc/source/ui/inc/tabview.hxx
46 +++ sc/source/ui/inc/tabview.hxx
47 @@ -179,7 +179,6 @@ private:
51 - BOOL bNewStartIfMarking;
53 BOOL bOldSelection; // old style (inverting) of selection
55 @@ -203,6 +202,10 @@ private:
56 static void SetScrollBar( ScrollBar& rScroll, long nRangeMax, long nVisible, long nPos, BOOL bLayoutRTL );
57 static long GetScrollBarPos( ScrollBar& rScroll, BOOL bLayoutRTL );
59 + void GetPageMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, SCsCOL& rPageX, SCsROW& rPageY);
60 + void GetAreaMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
61 + SCsCOL& rAreaX, SCsROW& rAreaY, ScFollowMode& rMode);
64 void UpdateHeaderWidth( const ScVSplitPos* pWhich = NULL,
65 const SCROW* pPosY = NULL );
66 @@ -391,8 +394,6 @@ public:
68 void FindNextUnprot( BOOL bShift, BOOL bInSelection = TRUE );
70 - void SetNewStartIfMarking();
72 void SetTabNo( SCTAB nTab, BOOL bNew = FALSE, BOOL bExtendSelection = FALSE );
73 void SelectNextTab( short nDir, BOOL bExtendSelection = FALSE );
75 @@ -483,6 +484,10 @@ public:
77 BOOL IsBlockMode() const { return bIsBlockMode; }
79 + void ExpandBlock(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode);
80 + void ExpandBlockPage(SCsCOL nMovX, SCsROW nMovY);
81 + void ExpandBlockArea(SCsCOL nMovX, SCsROW nMovY);
85 void MarkDataArea( BOOL bIncludeCursor = TRUE );
86 diff --git sc/source/ui/view/cellsh4.cxx sc/source/ui/view/cellsh4.cxx
87 index 4cb00fb..3f80397 100644
88 --- sc/source/ui/view/cellsh4.cxx
89 +++ sc/source/ui/view/cellsh4.cxx
90 @@ -88,10 +88,56 @@ void ScCellShell::ExecuteCursor( SfxRequest& rReq )
92 // ADD mode: keep the selection, start a new block when marking with shift again
94 - pTabViewShell->SetNewStartIfMarking();
102 + case SID_CURSORDOWN:
103 + rReq.SetSlot(SID_CURSORDOWN_SEL);
106 + rReq.SetSlot(SID_CURSORUP_SEL);
108 + case SID_CURSORRIGHT:
109 + rReq.SetSlot(SID_CURSORRIGHT_SEL);
111 + case SID_CURSORLEFT:
112 + rReq.SetSlot(SID_CURSORLEFT_SEL);
114 + case SID_CURSORPAGEDOWN:
115 + rReq.SetSlot(SID_CURSORPAGEDOWN_SEL);
117 + case SID_CURSORPAGEUP:
118 + rReq.SetSlot(SID_CURSORPAGEUP_SEL);
120 + case SID_CURSORPAGERIGHT:
121 + rReq.SetSlot(SID_CURSORPAGERIGHT_SEL);
123 + case SID_CURSORPAGELEFT:
124 + rReq.SetSlot(SID_CURSORPAGELEFT_SEL);
126 + case SID_CURSORBLKDOWN:
127 + rReq.SetSlot(SID_CURSORBLKDOWN_SEL);
129 + case SID_CURSORBLKUP:
130 + rReq.SetSlot(SID_CURSORBLKUP_SEL);
132 + case SID_CURSORBLKRIGHT:
133 + rReq.SetSlot(SID_CURSORBLKRIGHT_SEL);
135 + case SID_CURSORBLKLEFT:
136 + rReq.SetSlot(SID_CURSORBLKLEFT_SEL);
141 + ExecuteCursorSel(rReq);
145 SCsCOLROW nRTLSign = 1;
146 if ( pData->GetDocument()->IsLayoutRTL( pData->GetTabNo() ) )
148 @@ -172,38 +218,50 @@ void ScCellShell::GetStateCursor( SfxItemSet& /* rSet */ )
150 void ScCellShell::ExecuteCursorSel( SfxRequest& rReq )
152 - const SfxItemSet* pReqArgs = rReq.GetArgs();
153 - USHORT nSlotId = rReq.GetSlot();
156 - if ( pReqArgs != NULL )
158 - const SfxPoolItem* pItem;
159 - if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
160 - nRepeat = ((const SfxInt16Item*)pItem)->GetValue();
162 + sal_uInt16 nSlotId = rReq.GetSlot();
163 + ScTabViewShell* pViewShell = GetViewData()->GetViewShell();
168 - case SID_CURSORDOWN_SEL: rReq.SetSlot( SID_CURSORDOWN ); break;
169 - case SID_CURSORBLKDOWN_SEL: rReq.SetSlot( SID_CURSORBLKDOWN ); break;
170 - case SID_CURSORUP_SEL: rReq.SetSlot( SID_CURSORUP ); break;
171 - case SID_CURSORBLKUP_SEL: rReq.SetSlot( SID_CURSORBLKUP ); break;
172 - case SID_CURSORLEFT_SEL: rReq.SetSlot( SID_CURSORLEFT ); break;
173 - case SID_CURSORBLKLEFT_SEL: rReq.SetSlot( SID_CURSORBLKLEFT ); break;
174 - case SID_CURSORRIGHT_SEL: rReq.SetSlot( SID_CURSORRIGHT ); break;
175 - case SID_CURSORBLKRIGHT_SEL: rReq.SetSlot( SID_CURSORBLKRIGHT ); break;
176 - case SID_CURSORPAGEDOWN_SEL: rReq.SetSlot( SID_CURSORPAGEDOWN ); break;
177 - case SID_CURSORPAGEUP_SEL: rReq.SetSlot( SID_CURSORPAGEUP ); break;
178 - case SID_CURSORPAGERIGHT_SEL: rReq.SetSlot( SID_CURSORPAGERIGHT_ ); break;
179 - case SID_CURSORPAGELEFT_SEL: rReq.SetSlot( SID_CURSORPAGELEFT_ ); break;
180 + case SID_CURSORDOWN_SEL:
181 + pViewShell->ExpandBlock(0, 1, SC_FOLLOW_LINE);
183 + case SID_CURSORUP_SEL:
184 + pViewShell->ExpandBlock(0, -1, SC_FOLLOW_LINE);
186 + case SID_CURSORRIGHT_SEL:
187 + pViewShell->ExpandBlock(1, 0, SC_FOLLOW_LINE);
189 + case SID_CURSORLEFT_SEL:
190 + pViewShell->ExpandBlock(-1, 0, SC_FOLLOW_LINE);
192 + case SID_CURSORPAGEUP_SEL:
193 + pViewShell->ExpandBlockPage(0, -1);
195 + case SID_CURSORPAGEDOWN_SEL:
196 + pViewShell->ExpandBlockPage(0, 1);
198 + case SID_CURSORPAGERIGHT_SEL:
199 + pViewShell->ExpandBlockPage(1, 0);
201 + case SID_CURSORPAGELEFT_SEL:
202 + pViewShell->ExpandBlockPage(-1, 0);
204 + case SID_CURSORBLKDOWN_SEL:
205 + pViewShell->ExpandBlockArea(0, 1);
207 + case SID_CURSORBLKUP_SEL:
208 + pViewShell->ExpandBlockArea(0, -1);
210 + case SID_CURSORBLKRIGHT_SEL:
211 + pViewShell->ExpandBlockArea(1, 0);
213 + case SID_CURSORBLKLEFT_SEL:
214 + pViewShell->ExpandBlockArea(-1, 0);
217 - DBG_ERROR("Unbekannte Message bei ViewShell (CursorSel)");
221 - rReq.AppendItem( SfxInt16Item(FN_PARAM_1, nRepeat ) );
222 - rReq.AppendItem( SfxBoolItem(FN_PARAM_2, TRUE) );
223 - ExecuteSlot( rReq, GetInterface() );
226 void ScCellShell::ExecuteMove( SfxRequest& rReq )
227 @@ -348,7 +406,6 @@ void ScCellShell::ExecutePage( SfxRequest& rReq )
229 // ADD mode: keep the selection, start a new block when marking with shift again
231 - pTabViewShell->SetNewStartIfMarking();
235 diff --git sc/source/ui/view/gridwin.cxx sc/source/ui/view/gridwin.cxx
236 index ad12e86..b5bb7c6 100644
237 --- sc/source/ui/view/gridwin.cxx
238 +++ sc/source/ui/view/gridwin.cxx
239 @@ -2200,8 +2200,12 @@ void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt )
242 SfxStringItem aPosItem( SID_CURRENTCELL, aAddr );
243 + // We don't want to align to the cursor position because if the
244 + // cell cursor isn't visible after making selection, it would jump
245 + // back to the origin of the selection where the cell cursor is.
246 + SfxBoolItem aAlignCursorItem( FN_PARAM_2, false );
247 pDisp->Execute( SID_CURRENTCELL, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
248 - &aPosItem, (void*)0L );
249 + &aPosItem, &aAlignCursorItem, (void*)0L );
251 pViewData->GetView()->InvalidateAttribs();
253 @@ -3960,7 +3960,10 @@ sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPos
256 pView->MarkRange( aDest, FALSE, FALSE );
257 - pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
259 + SCCOL nDCol = pViewData->GetCurX() - aSource.aStart.Col();
260 + SCROW nDRow = pViewData->GetCurY() - aSource.aStart.Row();
261 + pView->SetCursor( aDest.aStart.Col() + nDCol, aDest.aStart.Row() + nDRow );
264 pDocSh->GetUndoManager()->LeaveListAction();
265 @@ -4068,7 +4071,7 @@ sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPos
266 pView->EnterMatrix( aFormula );
268 pView->MarkRange( aDest, FALSE, FALSE );
269 - pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
270 + pView->SetCursor( aDest.aStart.Col(), aDest.aStart.Row() );
273 pDocSh->GetUndoManager()->LeaveListAction();
274 @@ -4102,7 +4105,7 @@ sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPos
277 pView->MarkRange( aDest, FALSE, FALSE );
278 - pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
279 + pView->SetCursor( aDest.aStart.Col(), aDest.aStart.Row() );
283 diff --git sc/source/ui/view/select.cxx sc/source/ui/view/select.cxx
284 index d41fe45..e983ca9 100644
285 --- sc/source/ui/view/select.cxx
286 +++ sc/source/ui/view/select.cxx
287 @@ -667,7 +667,10 @@ BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScrol
291 + // If the selection is already started, don't set the cursor.
292 pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab, FALSE, FALSE, TRUE );
294 + pView->SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
298 @@ -703,9 +706,9 @@ BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScrol
302 + pView->SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
305 - pView->SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
306 pViewData->SetRefStart( nPosX, nPosY, nTab );
308 pView->ShowAllCursors();
309 diff --git sc/source/ui/view/tabview.cxx sc/source/ui/view/tabview.cxx
310 index dacaee8..5274b50 100644
311 --- sc/source/ui/view/tabview.cxx
312 +++ sc/source/ui/view/tabview.cxx
313 @@ -384,7 +384,6 @@ BOOL lcl_HasRowOutline( const ScViewData& rViewData )
314 bInActivatePart( FALSE ), \
315 bInZoomUpdate( FALSE ), \
316 bMoveIsShift( FALSE ), \
317 - bNewStartIfMarking( FALSE ), \
318 bOldSelection( FALSE )
321 diff --git sc/source/ui/view/tabview2.cxx sc/source/ui/view/tabview2.cxx
322 index bd9515c..bd744e4 100644
323 --- sc/source/ui/view/tabview2.cxx
324 +++ sc/source/ui/view/tabview2.cxx
326 #include "waitoff.hxx"
327 #include "globstr.hrc"
329 +#include "tabprotection.hxx"
331 #define SC_BLOCKMODE_NONE 0
332 #define SC_BLOCKMODE_NORMAL 1
333 @@ -178,16 +179,9 @@ void ScTabView::InitBlockMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
334 InvertBlockMark( nBlockStartX,nBlockStartY,nBlockEndX,nBlockEndY );
336 UpdateSelectionOverlay();
338 - bNewStartIfMarking = FALSE; // use only once
342 -void ScTabView::SetNewStartIfMarking()
344 - bNewStartIfMarking = TRUE;
347 void ScTabView::DoneBlockMode( BOOL bContinue ) // Default FALSE
349 // Wenn zwischen Tabellen- und Header SelectionEngine gewechselt wird,
350 @@ -414,6 +408,297 @@ void ScTabView::MarkCursor( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
351 aHdrFunc.SetAnchorFlag( FALSE );
354 +void ScTabView::GetPageMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, SCsCOL& rPageX, SCsROW& rPageY)
358 + aViewData.GetMoveCursor( nCurX,nCurY );
360 + ScSplitPos eWhich = aViewData.GetActivePart();
361 + ScHSplitPos eWhichX = WhichH( eWhich );
362 + ScVSplitPos eWhichY = WhichV( eWhich );
367 + nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, 1, eWhichX )) * nMovX;
369 + nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, -1, eWhichX )) * nMovX;
372 + nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, 1, eWhichY )) * nMovY;
374 + nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, -1, eWhichY )) * nMovY;
376 + if (nMovX != 0 && nPageX == 0) nPageX = (nMovX>0) ? 1 : -1;
377 + if (nMovY != 0 && nPageY == 0) nPageY = (nMovY>0) ? 1 : -1;
383 +void ScTabView::GetAreaMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
384 + SCsCOL& rAreaX, SCsROW& rAreaY, ScFollowMode& rMode)
391 + if (aViewData.IsRefMode())
393 + nNewX = aViewData.GetRefEndX();
394 + nNewY = aViewData.GetRefEndY();
396 + else if (IsBlockMode())
398 + nNewX = nBlockEndX;
399 + nNewY = nBlockEndY;
403 + nNewX = nCurX = aViewData.GetCurX();
404 + nNewY = nCurY = aViewData.GetCurY();
407 + ScDocument* pDoc = aViewData.GetDocument();
408 + SCTAB nTab = aViewData.GetTabNo();
410 + // FindAreaPos kennt nur -1 oder 1 als Richtung
414 + for ( i=0; i<nMovX; i++ )
415 + pDoc->FindAreaPos( nNewX, nNewY, nTab, 1, 0 );
417 + for ( i=0; i<-nMovX; i++ )
418 + pDoc->FindAreaPos( nNewX, nNewY, nTab, -1, 0 );
420 + for ( i=0; i<nMovY; i++ )
421 + pDoc->FindAreaPos( nNewX, nNewY, nTab, 0, 1 );
423 + for ( i=0; i<-nMovY; i++ )
424 + pDoc->FindAreaPos( nNewX, nNewY, nTab, 0, -1 );
426 + if (eMode==SC_FOLLOW_JUMP) // unten/rechts nicht zuviel grau anzeigen
428 + if (nMovX != 0 && nNewX == MAXCOL)
429 + eMode = SC_FOLLOW_LINE;
430 + if (nMovY != 0 && nNewY == MAXROW)
431 + eMode = SC_FOLLOW_LINE;
434 + if (aViewData.IsRefMode())
436 + rAreaX = nNewX - aViewData.GetRefEndX();
437 + rAreaY = nNewY - aViewData.GetRefEndY();
439 + else if (IsBlockMode())
441 + rAreaX = nNewX - nBlockEndX;
442 + rAreaY = nNewY - nBlockEndY;
446 + rAreaX = nNewX - nCurX;
447 + rAreaY = nNewY - nCurY;
454 +bool lcl_isCellQualified(ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, bool bSelectLocked, bool bSelectUnlocked)
456 + bool bCellProtected = pDoc->HasAttrib(
457 + nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_PROTECTED);
459 + if (bCellProtected && !bSelectLocked)
462 + if (!bCellProtected && !bSelectUnlocked)
468 +void lcl_moveCursorByProtRule(
469 + SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY, SCTAB nTab, ScDocument* pDoc)
471 + bool bSelectLocked = true;
472 + bool bSelectUnlocked = true;
473 + ScTableProtection* pTabProtection = pDoc->GetTabProtection(nTab);
474 + if (pTabProtection && pTabProtection->isProtected())
476 + bSelectLocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
477 + bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
484 + for (SCCOL i = 0; i < nMovX; ++i)
486 + if (!lcl_isCellQualified(pDoc, rCol+1, rRow, nTab, bSelectLocked, bSelectUnlocked))
492 + else if (nMovX < 0)
497 + for (SCCOL i = 0; i < nMovX; ++i)
499 + if (!lcl_isCellQualified(pDoc, rCol-1, rRow, nTab, bSelectLocked, bSelectUnlocked))
510 + for (SCROW i = 0; i < nMovY; ++i)
512 + if (!lcl_isCellQualified(pDoc, rCol, rRow+1, nTab, bSelectLocked, bSelectUnlocked))
518 + else if (nMovY < 0)
523 + for (SCROW i = 0; i < nMovY; ++i)
525 + if (!lcl_isCellQualified(pDoc, rCol, rRow-1, nTab, bSelectLocked, bSelectUnlocked))
535 +void ScTabView::ExpandBlock(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode)
537 + if (!nMovX && !nMovY)
538 + // Nothing to do. Bail out.
541 + ScTabViewShell* pViewShell = aViewData.GetViewShell();
542 + bool bRefInputMode = pViewShell && pViewShell->IsRefInputMode();
543 + if (bRefInputMode && !aViewData.IsRefMode())
544 + // initialize formula reference mode if it hasn't already.
545 + InitRefMode(aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo(), SC_REFTYPE_REF);
547 + ScDocument* pDoc = aViewData.GetDocument();
549 + if (aViewData.IsRefMode())
551 + // formula reference mode
553 + SCCOL nNewX = aViewData.GetRefEndX();
554 + SCROW nNewY = aViewData.GetRefEndY();
555 + SCTAB nRefTab = aViewData.GetRefEndZ();
557 + bool bSelectLocked = true;
558 + bool bSelectUnlocked = true;
559 + ScTableProtection* pTabProtection = pDoc->GetTabProtection(nRefTab);
560 + if (pTabProtection && pTabProtection->isProtected())
562 + bSelectLocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
563 + bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
566 + lcl_moveCursorByProtRule(nNewX, nNewY, nMovX, nMovY, nRefTab, pDoc);
570 + SCCOL nTempX = nNewX;
571 + while (pDoc->IsHorOverlapped(nTempX, nNewY, nRefTab))
578 + if (lcl_isCellQualified(pDoc, nTempX, nNewY, nRefTab, bSelectLocked, bSelectUnlocked))
584 + SCROW nTempY = nNewY;
585 + while (pDoc->IsVerOverlapped(nNewX, nTempY, nRefTab))
592 + if (lcl_isCellQualified(pDoc, nNewX, nTempY, nRefTab, bSelectLocked, bSelectUnlocked))
596 + pDoc->SkipOverlapped(nNewX, nNewY, nRefTab);
597 + UpdateRef(nNewX, nNewY, nRefTab);
598 + AlignToCursor(nNewX, nNewY, eMode);
602 + // normal selection mode
604 + SCTAB nTab = aViewData.GetTabNo();
606 + if (!IsBlockMode())
607 + InitBlockMode(aViewData.GetCurX(), aViewData.GetCurY(), nTab, true);
609 + lcl_moveCursorByProtRule(nBlockEndX, nBlockEndY, nMovX, nMovY, nTab, pDoc);
611 + if (nBlockEndX < 0)
613 + else if (nBlockEndX > MAXCOL)
614 + nBlockEndX = MAXCOL;
616 + if (nBlockEndY < 0)
618 + else if (nBlockEndY > MAXROW)
619 + nBlockEndY = MAXROW;
621 + pDoc->SkipOverlapped(nBlockEndX, nBlockEndY, nTab);
622 + MarkCursor(nBlockEndX, nBlockEndY, nTab, false, false, true);
623 + AlignToCursor(nBlockEndX, nBlockEndY, eMode);
624 + UpdateAutoFillMark();
628 +void ScTabView::ExpandBlockPage(SCsCOL nMovX, SCsROW nMovY)
632 + GetPageMoveEndPosition(nMovX, nMovY, nPageX, nPageY);
633 + ExpandBlock(nPageX, nPageY, SC_FOLLOW_FIX);
636 +void ScTabView::ExpandBlockArea(SCsCOL nMovX, SCsROW nMovY)
640 + ScFollowMode eMode;
641 + GetAreaMoveEndPosition(nMovX, nMovY, SC_FOLLOW_JUMP, nAreaX, nAreaY, eMode);
642 + ExpandBlock(nAreaX, nAreaY, eMode);
645 void ScTabView::UpdateSelectionOverlay()
647 for (USHORT i=0; i<4; i++)
648 diff --git sc/source/ui/view/tabview3.cxx sc/source/ui/view/tabview3.cxx
649 index 1b4879c..da85e44 100644
650 --- sc/source/ui/view/tabview3.cxx
651 +++ sc/source/ui/view/tabview3.cxx
652 @@ -125,10 +125,7 @@ void ScTabView::ClickCursor( SCCOL nPosX, SCROW nPosY, BOOL bControl )
654 ScDocument* pDoc = aViewData.GetDocument();
655 SCTAB nTab = aViewData.GetTabNo();
656 - while (pDoc->IsHorOverlapped( nPosX, nPosY, nTab )) //! ViewData !!!
658 - while (pDoc->IsVerOverlapped( nPosX, nPosY, nTab ))
660 + pDoc->SkipOverlapped(nPosX, nPosY, nTab);
662 BOOL bRefMode = SC_MOD()->IsFormulaMode();
664 @@ -921,22 +918,36 @@ void ScTabView::MoveCursorAbs( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
668 - if ( bShift && bNewStartIfMarking && IsBlockMode() )
670 - // used for ADD selection mode: start a new block from the cursor position
671 - DoneBlockMode( TRUE );
672 - InitBlockMode( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo(), TRUE );
675 // aktiven Teil umschalten jetzt in AlignToCursor
677 AlignToCursor( nCurX, nCurY, eMode );
678 //! auf OS/2: SC_FOLLOW_JUMP statt SC_FOLLOW_LINE, um Nachlaufen zu verhindern ???
682 SetCursor( nCurX, nCurY ); // Markierung stehenlassen
684 + // If the cursor is in existing selection, it's a cursor movement by
685 + // ENTER or TAB. If not, then it's a new selection during ADD
688 + const ScMarkData& rMark = aViewData.GetMarkData();
689 + ScRangeList aSelList;
690 + rMark.FillRangeListWithMarks(&aSelList, false);
691 + if (!aSelList.In(ScRange(nCurX, nCurY, aViewData.GetTabNo())))
692 + // Cursor not in existing selection. Start a new selection.
693 + DoneBlockMode(true);
699 + // Remove all marked data on cursor movement unless the Shift is locked.
700 + ScMarkData aData(aViewData.GetMarkData());
702 + SetMarkData(aData);
705 BOOL bSame = ( nCurX == aViewData.GetCurX() && nCurY == aViewData.GetCurY() );
706 bMoveIsShift = bShift;
707 pSelEngine->CursorPosChanging( bShift, bControl );
708 @@ -1080,68 +1091,18 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
710 void ScTabView::MoveCursorPage( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bShift, BOOL bKeepSel )
714 - aViewData.GetMoveCursor( nCurX,nCurY );
716 - ScSplitPos eWhich = aViewData.GetActivePart();
717 - ScHSplitPos eWhichX = WhichH( eWhich );
718 - ScVSplitPos eWhichY = WhichV( eWhich );
723 - nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, 1, eWhichX )) * nMovX;
725 - nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, -1, eWhichX )) * nMovX;
728 - nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, 1, eWhichY )) * nMovY;
730 - nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, -1, eWhichY )) * nMovY;
732 - if (nMovX != 0 && nPageX == 0) nPageX = (nMovX>0) ? 1 : -1;
733 - if (nMovY != 0 && nPageY == 0) nPageY = (nMovY>0) ? 1 : -1;
735 + GetPageMoveEndPosition(nMovX, nMovY, nPageX, nPageY);
736 MoveCursorRel( nPageX, nPageY, eMode, bShift, bKeepSel );
739 void ScTabView::MoveCursorArea( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bShift, BOOL bKeepSel )
743 - aViewData.GetMoveCursor( nCurX,nCurY );
744 - SCCOL nNewX = nCurX;
745 - SCROW nNewY = nCurY;
747 - ScDocument* pDoc = aViewData.GetDocument();
748 - SCTAB nTab = aViewData.GetTabNo();
750 - // FindAreaPos kennt nur -1 oder 1 als Richtung
754 - for ( i=0; i<nMovX; i++ )
755 - pDoc->FindAreaPos( nNewX, nNewY, nTab, 1, 0 );
757 - for ( i=0; i<-nMovX; i++ )
758 - pDoc->FindAreaPos( nNewX, nNewY, nTab, -1, 0 );
760 - for ( i=0; i<nMovY; i++ )
761 - pDoc->FindAreaPos( nNewX, nNewY, nTab, 0, 1 );
763 - for ( i=0; i<-nMovY; i++ )
764 - pDoc->FindAreaPos( nNewX, nNewY, nTab, 0, -1 );
766 - if (eMode==SC_FOLLOW_JUMP) // unten/rechts nicht zuviel grau anzeigen
768 - if (nMovX != 0 && nNewX == MAXCOL)
769 - eMode = SC_FOLLOW_LINE;
770 - if (nMovY != 0 && nNewY == MAXROW)
771 - eMode = SC_FOLLOW_LINE;
774 - MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY, eMode, bShift, bKeepSel );
777 + GetAreaMoveEndPosition(nMovX, nMovY, eMode, nNewX, nNewY, eMode);
778 + MoveCursorRel(nNewX, nNewY, eMode, bShift, bKeepSel);
781 void ScTabView::MoveCursorEnd( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bShift, BOOL bKeepSel )
782 @@ -1206,14 +1167,8 @@ void ScTabView::MoveCursorScreen( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode
786 -// aViewData.ResetOldCursor();
787 aViewData.SetOldCursor( nNewX,nNewY );
789 - while (pDoc->IsHorOverlapped( nNewX, nNewY, nTab ))
791 - while (pDoc->IsVerOverlapped( nNewX, nNewY, nTab ))
794 + pDoc->SkipOverlapped(nNewX, nNewY, nTab);
795 MoveCursorAbs( nNewX, nNewY, eMode, bShift, FALSE, TRUE );
798 @@ -1497,11 +1452,7 @@ void ScTabView::MarkRange( const ScRange& rRange, BOOL bSetCursor, BOOL bContinu
799 SCCOL nPosX = rRange.aStart.Col();
800 SCROW nPosY = rRange.aStart.Row();
801 ScDocument* pDoc = aViewData.GetDocument();
803 - while (pDoc->IsHorOverlapped( nPosX, nPosY, nTab )) //! ViewData !!!
805 - while (pDoc->IsVerOverlapped( nPosX, nPosY, nTab ))
807 + pDoc->SkipOverlapped(nPosX, nPosY, nTab);
809 aViewData.ResetOldCursor();
810 SetCursor( nPosX, nPosY );
811 diff --git sc/source/ui/view/tabvwsh3.cxx sc/source/ui/view/tabvwsh3.cxx
812 index caea267..74505f4 100644
813 --- sc/source/ui/view/tabvwsh3.cxx
814 +++ sc/source/ui/view/tabvwsh3.cxx
815 @@ -276,6 +276,10 @@ void ScTabViewShell::Execute( SfxRequest& rReq )
816 if ( pReqArgs->GetItemState( FN_PARAM_1, TRUE, &pItem ) == SFX_ITEM_SET )
817 bUnmark = ((const SfxBoolItem*)pItem)->GetValue();
819 + bool bAlignToCursor = true;
820 + if (pReqArgs->GetItemState(FN_PARAM_2, true, &pItem) == SFX_ITEM_SET)
821 + bAlignToCursor = static_cast<const SfxBoolItem*>(pItem)->GetValue();
823 if ( nSlot == SID_JUMPTOMARK )
825 // #106586# URL has to be decoded for escaped characters (%20)
826 @@ -396,10 +396,7 @@ void ScTabViewShell::Execute( SfxRequest& rReq )
829 // zusammengefasste Zellen beruecksichtigen:
830 - while ( pDoc->IsHorOverlapped( nCol, nRow, nTab ) ) //! ViewData !!!
832 - while ( pDoc->IsVerOverlapped( nCol, nRow, nTab ) )
834 + pDoc->SkipOverlapped(nCol, nRow, nTab);
836 // Navigator-Aufrufe sind nicht API!!!
838 @@ -417,9 +421,13 @@ void ScTabViewShell::Execute( SfxRequest& rReq )
842 - // align to cursor even if the cursor position hasn't changed,
843 - // because the cursor may be set outside the visible area.
844 - AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
846 + if (bAlignToCursor)
848 + // align to cursor even if the cursor position hasn't changed,
849 + // because the cursor may be set outside the visible area.
850 + AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
853 rReq.SetReturnValue( SfxStringItem( SID_CURRENTCELL, aAddress ) );
855 diff --git sc/source/ui/view/viewdata.cxx sc/source/ui/view/viewdata.cxx
856 index f69ab24..66c07c4 100644
857 --- sc/source/ui/view/viewdata.cxx
858 +++ sc/source/ui/view/viewdata.cxx
859 @@ -1891,12 +1891,11 @@ BOOL ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich,
861 //! public Methode um Position anzupassen
863 - BOOL bHOver = FALSE;
864 - while (pDoc->IsHorOverlapped( rPosX, rPosY, nTabNo ))
865 - { --rPosX; bHOver=TRUE; }
866 - BOOL bVOver = FALSE;
867 - while (pDoc->IsVerOverlapped( rPosX, rPosY, nTabNo ))
868 - { --rPosY; bVOver=TRUE; }
869 + SCCOL nOrigX = rPosX;
870 + SCROW nOrigY = rPosY;
871 + pDoc->SkipOverlapped(rPosX, rPosY, nTabNo);
872 + bool bHOver = (nOrigX != rPosX);
873 + bool bVOver = (nOrigY != rPosY);
875 if ( bRepair && ( bHOver || bVOver ) )