merge the formfield patch from ooo-build
[ooovba.git] / applied_patches / 0170-calc-selection-fixed-cursor.diff
blobba41ec1e375caf7224a2bb85de03e9fdf7cbe4c2
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,
18 return bChange;
21 +void ScDocument::SkipOverlapped( SCCOL& rCol, SCROW& rRow, SCTAB nTab ) const
23 + while (IsHorOverlapped(rCol, rRow, nTab))
24 + --rCol;
25 + while (IsVerOverlapped(rCol, rRow, nTab))
26 + --rRow;
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
35 @@ -37,6 +37,7 @@
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:
48 BOOL bInActivatePart;
49 BOOL bInZoomUpdate;
50 BOOL bMoveIsShift;
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);
63 protected:
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);
83 void MarkColumns();
84 void MarkRows();
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 @@ -52,6 +52,7 @@
91 #include "document.hxx"
92 #include "sc.hrc"
94 +#include "vcl/svapp.hxx"
96 //------------------------------------------------------------------
98 @@ -88,10 +88,56 @@ void ScCellShell::ExecuteCursor( SfxRequest& rReq )
100 // ADD mode: keep the selection, start a new block when marking with shift again
101 bKeep = TRUE;
102 - pTabViewShell->SetNewStartIfMarking();
106 + if (bSel)
108 + switch (nSlotId)
110 + case SID_CURSORDOWN:
111 + rReq.SetSlot(SID_CURSORDOWN_SEL);
112 + break;
113 + case SID_CURSORUP:
114 + rReq.SetSlot(SID_CURSORUP_SEL);
115 + break;
116 + case SID_CURSORRIGHT:
117 + rReq.SetSlot(SID_CURSORRIGHT_SEL);
118 + break;
119 + case SID_CURSORLEFT:
120 + rReq.SetSlot(SID_CURSORLEFT_SEL);
121 + break;
122 + case SID_CURSORPAGEDOWN:
123 + rReq.SetSlot(SID_CURSORPAGEDOWN_SEL);
124 + break;
125 + case SID_CURSORPAGEUP:
126 + rReq.SetSlot(SID_CURSORPAGEUP_SEL);
127 + break;
128 + case SID_CURSORPAGERIGHT:
129 + rReq.SetSlot(SID_CURSORPAGERIGHT_SEL);
130 + break;
131 + case SID_CURSORPAGELEFT:
132 + rReq.SetSlot(SID_CURSORPAGELEFT_SEL);
133 + break;
134 + case SID_CURSORBLKDOWN:
135 + rReq.SetSlot(SID_CURSORBLKDOWN_SEL);
136 + break;
137 + case SID_CURSORBLKUP:
138 + rReq.SetSlot(SID_CURSORBLKUP_SEL);
139 + break;
140 + case SID_CURSORBLKRIGHT:
141 + rReq.SetSlot(SID_CURSORBLKRIGHT_SEL);
142 + break;
143 + case SID_CURSORBLKLEFT:
144 + rReq.SetSlot(SID_CURSORBLKLEFT_SEL);
145 + break;
146 + default:
149 + ExecuteCursorSel(rReq);
150 + return;
153 SCsCOLROW nRTLSign = 1;
154 if ( pData->GetDocument()->IsLayoutRTL( pData->GetTabNo() ) )
156 @@ -172,38 +218,61 @@ void ScCellShell::GetStateCursor( SfxItemSet& /* rSet */ )
158 void ScCellShell::ExecuteCursorSel( SfxRequest& rReq )
160 - const SfxItemSet* pReqArgs = rReq.GetArgs();
161 - USHORT nSlotId = rReq.GetSlot();
162 - short nRepeat = 1;
164 - if ( pReqArgs != NULL )
166 - const SfxPoolItem* pItem;
167 - if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
168 - nRepeat = ((const SfxInt16Item*)pItem)->GetValue();
170 + sal_uInt16 nSlotId = rReq.GetSlot();
171 + ScTabViewShell* pViewShell = GetViewData()->GetViewShell();
172 + ScInputHandler* pInputHdl = pViewShell->GetInputHandler();
173 + pViewShell->HideAllCursors();
174 + if (pInputHdl && pInputHdl->IsInputMode())
176 + // the current cell is in edit mode. Commit the text before moving on.
177 + pViewShell->ExecuteInputDirect();
180 - switch ( nSlotId )
181 + // Horizontal direction depends on whether or not the UI language is RTL.
182 + SCsCOL nMovX = Application::GetSettings().GetLayoutRTL() ? -1 : 1;
184 + switch (nSlotId)
186 - case SID_CURSORDOWN_SEL: rReq.SetSlot( SID_CURSORDOWN ); break;
187 - case SID_CURSORBLKDOWN_SEL: rReq.SetSlot( SID_CURSORBLKDOWN ); break;
188 - case SID_CURSORUP_SEL: rReq.SetSlot( SID_CURSORUP ); break;
189 - case SID_CURSORBLKUP_SEL: rReq.SetSlot( SID_CURSORBLKUP ); break;
190 - case SID_CURSORLEFT_SEL: rReq.SetSlot( SID_CURSORLEFT ); break;
191 - case SID_CURSORBLKLEFT_SEL: rReq.SetSlot( SID_CURSORBLKLEFT ); break;
192 - case SID_CURSORRIGHT_SEL: rReq.SetSlot( SID_CURSORRIGHT ); break;
193 - case SID_CURSORBLKRIGHT_SEL: rReq.SetSlot( SID_CURSORBLKRIGHT ); break;
194 - case SID_CURSORPAGEDOWN_SEL: rReq.SetSlot( SID_CURSORPAGEDOWN ); break;
195 - case SID_CURSORPAGEUP_SEL: rReq.SetSlot( SID_CURSORPAGEUP ); break;
196 - case SID_CURSORPAGERIGHT_SEL: rReq.SetSlot( SID_CURSORPAGERIGHT_ ); break;
197 - case SID_CURSORPAGELEFT_SEL: rReq.SetSlot( SID_CURSORPAGELEFT_ ); break;
198 + case SID_CURSORDOWN_SEL:
199 + pViewShell->ExpandBlock(0, 1, SC_FOLLOW_LINE);
200 + break;
201 + case SID_CURSORUP_SEL:
202 + pViewShell->ExpandBlock(0, -1, SC_FOLLOW_LINE);
203 + break;
204 + case SID_CURSORRIGHT_SEL:
205 + pViewShell->ExpandBlock(nMovX, 0, SC_FOLLOW_LINE);
206 + break;
207 + case SID_CURSORLEFT_SEL:
208 + pViewShell->ExpandBlock(-nMovX, 0, SC_FOLLOW_LINE);
209 + break;
210 + case SID_CURSORPAGEUP_SEL:
211 + pViewShell->ExpandBlockPage(0, -1);
212 + break;
213 + case SID_CURSORPAGEDOWN_SEL:
214 + pViewShell->ExpandBlockPage(0, 1);
215 + break;
216 + case SID_CURSORPAGERIGHT_SEL:
217 + pViewShell->ExpandBlockPage(nMovX, 0);
218 + break;
219 + case SID_CURSORPAGELEFT_SEL:
220 + pViewShell->ExpandBlockPage(-nMovX, 0);
221 + break;
222 + case SID_CURSORBLKDOWN_SEL:
223 + pViewShell->ExpandBlockArea(0, 1);
224 + break;
225 + case SID_CURSORBLKUP_SEL:
226 + pViewShell->ExpandBlockArea(0, -1);
227 + break;
228 + case SID_CURSORBLKRIGHT_SEL:
229 + pViewShell->ExpandBlockArea(nMovX, 0);
230 + break;
231 + case SID_CURSORBLKLEFT_SEL:
232 + pViewShell->ExpandBlockArea(-nMovX, 0);
233 + break;
234 default:
235 - DBG_ERROR("Unbekannte Message bei ViewShell (CursorSel)");
236 - return;
239 - rReq.AppendItem( SfxInt16Item(FN_PARAM_1, nRepeat ) );
240 - rReq.AppendItem( SfxBoolItem(FN_PARAM_2, TRUE) );
241 - ExecuteSlot( rReq, GetInterface() );
242 + pViewShell->ShowAllCursors();
245 void ScCellShell::ExecuteMove( SfxRequest& rReq )
246 @@ -348,7 +406,6 @@ void ScCellShell::ExecutePage( SfxRequest& rReq )
248 // ADD mode: keep the selection, start a new block when marking with shift again
249 bKeep = TRUE;
250 - pTabViewShell->SetNewStartIfMarking();
254 diff --git sc/source/ui/view/gridwin.cxx sc/source/ui/view/gridwin.cxx
255 index ad12e86..b5bb7c6 100644
256 --- sc/source/ui/view/gridwin.cxx
257 +++ sc/source/ui/view/gridwin.cxx
258 @@ -2200,8 +2200,12 @@ void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt )
261 SfxStringItem aPosItem( SID_CURRENTCELL, aAddr );
262 + // We don't want to align to the cursor position because if the
263 + // cell cursor isn't visible after making selection, it would jump
264 + // back to the origin of the selection where the cell cursor is.
265 + SfxBoolItem aAlignCursorItem( FN_PARAM_2, false );
266 pDisp->Execute( SID_CURRENTCELL, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
267 - &aPosItem, (void*)0L );
268 + &aPosItem, &aAlignCursorItem, (void*)0L );
270 pViewData->GetView()->InvalidateAttribs();
272 @@ -3960,7 +3960,10 @@ sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPos
273 if ( bDone )
275 pView->MarkRange( aDest, FALSE, FALSE );
276 - pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
278 + SCCOL nDCol = pViewData->GetCurX() - aSource.aStart.Col();
279 + SCROW nDRow = pViewData->GetCurY() - aSource.aStart.Row();
280 + pView->SetCursor( aDest.aStart.Col() + nDCol, aDest.aStart.Row() + nDRow );
283 pDocSh->GetUndoManager()->LeaveListAction();
284 @@ -4068,7 +4071,7 @@ sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPos
285 pView->EnterMatrix( aFormula );
287 pView->MarkRange( aDest, FALSE, FALSE );
288 - pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
289 + pView->SetCursor( aDest.aStart.Col(), aDest.aStart.Row() );
292 pDocSh->GetUndoManager()->LeaveListAction();
293 @@ -4102,7 +4105,7 @@ sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPos
294 if ( bDone )
296 pView->MarkRange( aDest, FALSE, FALSE );
297 - pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
298 + pView->SetCursor( aDest.aStart.Col(), aDest.aStart.Row() );
302 diff --git sc/source/ui/view/select.cxx sc/source/ui/view/select.cxx
303 index d41fe45..e983ca9 100644
304 --- sc/source/ui/view/select.cxx
305 +++ sc/source/ui/view/select.cxx
306 @@ -667,7 +667,10 @@ BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScrol
309 if (bStarted)
310 + // If the selection is already started, don't set the cursor.
311 pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab, FALSE, FALSE, TRUE );
312 + else
313 + pView->SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
315 else
317 @@ -703,9 +706,9 @@ BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScrol
319 bStarted = TRUE;
321 + pView->SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
324 - pView->SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
325 pViewData->SetRefStart( nPosX, nPosY, nTab );
326 if (bHideCur)
327 pView->ShowAllCursors();
328 diff --git sc/source/ui/view/tabview.cxx sc/source/ui/view/tabview.cxx
329 index dacaee8..5274b50 100644
330 --- sc/source/ui/view/tabview.cxx
331 +++ sc/source/ui/view/tabview.cxx
332 @@ -384,7 +384,6 @@ BOOL lcl_HasRowOutline( const ScViewData& rViewData )
333 bInActivatePart( FALSE ), \
334 bInZoomUpdate( FALSE ), \
335 - bMoveIsShift( FALSE ), \
336 - bNewStartIfMarking( FALSE )
337 + bMoveIsShift( FALSE )
340 ScTabView::ScTabView( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
341 diff --git sc/source/ui/view/tabview2.cxx sc/source/ui/view/tabview2.cxx
342 index bd9515c..bd744e4 100644
343 --- sc/source/ui/view/tabview2.cxx
344 +++ sc/source/ui/view/tabview2.cxx
345 @@ -62,6 +62,7 @@
346 #include "waitoff.hxx"
347 #include "globstr.hrc"
348 #include "scmod.hxx"
349 +#include "tabprotection.hxx"
351 #define SC_BLOCKMODE_NONE 0
352 #define SC_BLOCKMODE_NORMAL 1
353 @@ -178,16 +179,9 @@ void ScTabView::InitBlockMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
354 InvertBlockMark( nBlockStartX,nBlockStartY,nBlockEndX,nBlockEndY );
355 #endif
356 UpdateSelectionOverlay();
358 - bNewStartIfMarking = FALSE; // use only once
362 -void ScTabView::SetNewStartIfMarking()
364 - bNewStartIfMarking = TRUE;
367 void ScTabView::DoneBlockMode( BOOL bContinue ) // Default FALSE
369 // Wenn zwischen Tabellen- und Header SelectionEngine gewechselt wird,
370 @@ -414,6 +408,305 @@ void ScTabView::MarkCursor( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
371 aHdrFunc.SetAnchorFlag( FALSE );
374 +void ScTabView::GetPageMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, SCsCOL& rPageX, SCsROW& rPageY)
376 + SCCOL nCurX;
377 + SCROW nCurY;
378 + aViewData.GetMoveCursor( nCurX,nCurY );
380 + ScSplitPos eWhich = aViewData.GetActivePart();
381 + ScHSplitPos eWhichX = WhichH( eWhich );
382 + ScVSplitPos eWhichY = WhichV( eWhich );
384 + SCsCOL nPageX;
385 + SCsROW nPageY;
386 + if (nMovX >= 0)
387 + nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, 1, eWhichX )) * nMovX;
388 + else
389 + nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, -1, eWhichX )) * nMovX;
391 + if (nMovY >= 0)
392 + nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, 1, eWhichY )) * nMovY;
393 + else
394 + nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, -1, eWhichY )) * nMovY;
396 + if (nMovX != 0 && nPageX == 0) nPageX = (nMovX>0) ? 1 : -1;
397 + if (nMovY != 0 && nPageY == 0) nPageY = (nMovY>0) ? 1 : -1;
399 + rPageX = nPageX;
400 + rPageY = nPageY;
403 +void ScTabView::GetAreaMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
404 + SCsCOL& rAreaX, SCsROW& rAreaY, ScFollowMode& rMode)
406 + SCCOL nNewX = -1;
407 + SCROW nNewY = -1;
408 + SCCOL nCurX = -1;
409 + SCROW nCurY = -1;
411 + if (aViewData.IsRefMode())
413 + nNewX = aViewData.GetRefEndX();
414 + nNewY = aViewData.GetRefEndY();
416 + else if (IsBlockMode())
418 + nNewX = nBlockEndX;
419 + nNewY = nBlockEndY;
421 + else
423 + nNewX = nCurX = aViewData.GetCurX();
424 + nNewY = nCurY = aViewData.GetCurY();
427 + ScDocument* pDoc = aViewData.GetDocument();
428 + SCTAB nTab = aViewData.GetTabNo();
430 + // FindAreaPos kennt nur -1 oder 1 als Richtung
432 + SCsCOLROW i;
433 + if ( nMovX > 0 )
434 + for ( i=0; i<nMovX; i++ )
435 + pDoc->FindAreaPos( nNewX, nNewY, nTab, 1, 0 );
436 + if ( nMovX < 0 )
437 + for ( i=0; i<-nMovX; i++ )
438 + pDoc->FindAreaPos( nNewX, nNewY, nTab, -1, 0 );
439 + if ( nMovY > 0 )
440 + for ( i=0; i<nMovY; i++ )
441 + pDoc->FindAreaPos( nNewX, nNewY, nTab, 0, 1 );
442 + if ( nMovY < 0 )
443 + for ( i=0; i<-nMovY; i++ )
444 + pDoc->FindAreaPos( nNewX, nNewY, nTab, 0, -1 );
446 + if (eMode==SC_FOLLOW_JUMP) // unten/rechts nicht zuviel grau anzeigen
448 + if (nMovX != 0 && nNewX == MAXCOL)
449 + eMode = SC_FOLLOW_LINE;
450 + if (nMovY != 0 && nNewY == MAXROW)
451 + eMode = SC_FOLLOW_LINE;
454 + if (aViewData.IsRefMode())
456 + rAreaX = nNewX - aViewData.GetRefEndX();
457 + rAreaY = nNewY - aViewData.GetRefEndY();
459 + else if (IsBlockMode())
461 + rAreaX = nNewX - nBlockEndX;
462 + rAreaY = nNewY - nBlockEndY;
464 + else
466 + rAreaX = nNewX - nCurX;
467 + rAreaY = nNewY - nCurY;
469 + rMode = eMode;
472 +namespace {
474 +bool lcl_isCellQualified(ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, bool bSelectLocked, bool bSelectUnlocked)
476 + bool bCellProtected = pDoc->HasAttrib(
477 + nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_PROTECTED);
479 + if (bCellProtected && !bSelectLocked)
480 + return false;
482 + if (!bCellProtected && !bSelectUnlocked)
483 + return false;
485 + return true;
488 +void lcl_moveCursorByProtRule(
489 + SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY, SCTAB nTab, ScDocument* pDoc)
491 + bool bSelectLocked = true;
492 + bool bSelectUnlocked = true;
493 + ScTableProtection* pTabProtection = pDoc->GetTabProtection(nTab);
494 + if (pTabProtection && pTabProtection->isProtected())
496 + bSelectLocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
497 + bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
500 + if (nMovX > 0)
502 + if (rCol < MAXCOL)
504 + for (SCCOL i = 0; i < nMovX; ++i)
506 + if (!lcl_isCellQualified(pDoc, rCol+1, rRow, nTab, bSelectLocked, bSelectUnlocked))
507 + break;
508 + ++rCol;
512 + else if (nMovX < 0)
514 + if (rCol > 0)
516 + nMovX = -nMovX;
517 + for (SCCOL i = 0; i < nMovX; ++i)
519 + if (!lcl_isCellQualified(pDoc, rCol-1, rRow, nTab, bSelectLocked, bSelectUnlocked))
520 + break;
521 + --rCol;
526 + if (nMovY > 0)
528 + if (rRow < MAXROW)
530 + for (SCROW i = 0; i < nMovY; ++i)
532 + if (!lcl_isCellQualified(pDoc, rCol, rRow+1, nTab, bSelectLocked, bSelectUnlocked))
533 + break;
534 + ++rRow;
538 + else if (nMovY < 0)
540 + if (rRow > 0)
542 + nMovY = -nMovY;
543 + for (SCROW i = 0; i < nMovY; ++i)
545 + if (!lcl_isCellQualified(pDoc, rCol, rRow-1, nTab, bSelectLocked, bSelectUnlocked))
546 + break;
547 + --rRow;
555 +void ScTabView::ExpandBlock(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode)
557 + if (!nMovX && !nMovY)
558 + // Nothing to do. Bail out.
559 + return;
561 + ScTabViewShell* pViewShell = aViewData.GetViewShell();
562 + bool bRefInputMode = pViewShell && pViewShell->IsRefInputMode();
563 + if (bRefInputMode && !aViewData.IsRefMode())
564 + // initialize formula reference mode if it hasn't already.
565 + InitRefMode(aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo(), SC_REFTYPE_REF);
567 + ScDocument* pDoc = aViewData.GetDocument();
569 + if (aViewData.IsRefMode())
571 + // formula reference mode
573 + SCCOL nNewX = aViewData.GetRefEndX();
574 + SCROW nNewY = aViewData.GetRefEndY();
575 + SCTAB nRefTab = aViewData.GetRefEndZ();
577 + bool bSelectLocked = true;
578 + bool bSelectUnlocked = true;
579 + ScTableProtection* pTabProtection = pDoc->GetTabProtection(nRefTab);
580 + if (pTabProtection && pTabProtection->isProtected())
582 + bSelectLocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
583 + bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
586 + lcl_moveCursorByProtRule(nNewX, nNewY, nMovX, nMovY, nRefTab, pDoc);
588 + if (nMovX)
590 + SCCOL nTempX = nNewX;
591 + while (pDoc->IsHorOverlapped(nTempX, nNewY, nRefTab))
593 + if (nMovX > 0)
594 + ++nTempX;
595 + else
596 + --nTempX;
598 + if (lcl_isCellQualified(pDoc, nTempX, nNewY, nRefTab, bSelectLocked, bSelectUnlocked))
599 + nNewX = nTempX;
602 + if (nMovY)
604 + SCROW nTempY = nNewY;
605 + while (pDoc->IsVerOverlapped(nNewX, nTempY, nRefTab))
607 + if (nMovY > 0)
608 + ++nTempY;
609 + else
610 + --nTempY;
612 + if (lcl_isCellQualified(pDoc, nNewX, nTempY, nRefTab, bSelectLocked, bSelectUnlocked))
613 + nNewY = nTempY;
616 + pDoc->SkipOverlapped(nNewX, nNewY, nRefTab);
617 + UpdateRef(nNewX, nNewY, nRefTab);
618 + AlignToCursor(nNewX, nNewY, eMode);
620 + else
622 + // normal selection mode
624 + SCTAB nTab = aViewData.GetTabNo();
626 + if (!IsBlockMode())
627 + InitBlockMode(aViewData.GetCurX(), aViewData.GetCurY(), nTab, true);
629 + lcl_moveCursorByProtRule(nBlockEndX, nBlockEndY, nMovX, nMovY, nTab, pDoc);
631 + if (nBlockEndX < 0)
632 + nBlockEndX = 0;
633 + else if (nBlockEndX > MAXCOL)
634 + nBlockEndX = MAXCOL;
636 + if (nBlockEndY < 0)
637 + nBlockEndY = 0;
638 + else if (nBlockEndY > MAXROW)
639 + nBlockEndY = MAXROW;
641 + pDoc->SkipOverlapped(nBlockEndX, nBlockEndY, nTab);
642 + MarkCursor(nBlockEndX, nBlockEndY, nTab, false, false, true);
644 + // Check if the entire row(s) or column(s) are selected.
645 + ScSplitPos eActive = aViewData.GetActivePart();
646 + bool bRowSelected = (nBlockStartX == 0 && nBlockEndX == MAXCOL);
647 + bool bColSelected = (nBlockStartY == 0 && nBlockEndY == MAXROW);
648 + SCsCOL nAlignX = bRowSelected ? aViewData.GetPosX(WhichH(eActive)) : nBlockEndX;
649 + SCsROW nAlignY = bColSelected ? aViewData.GetPosY(WhichV(eActive)) : nBlockEndY;
650 + AlignToCursor(nAlignX, nAlignY, eMode);
652 + UpdateAutoFillMark();
656 +void ScTabView::ExpandBlockPage(SCsCOL nMovX, SCsROW nMovY)
658 + SCsCOL nPageX;
659 + SCsROW nPageY;
660 + GetPageMoveEndPosition(nMovX, nMovY, nPageX, nPageY);
661 + ExpandBlock(nPageX, nPageY, SC_FOLLOW_FIX);
664 +void ScTabView::ExpandBlockArea(SCsCOL nMovX, SCsROW nMovY)
666 + SCsCOL nAreaX;
667 + SCsROW nAreaY;
668 + ScFollowMode eMode;
669 + GetAreaMoveEndPosition(nMovX, nMovY, SC_FOLLOW_JUMP, nAreaX, nAreaY, eMode);
670 + ExpandBlock(nAreaX, nAreaY, eMode);
673 void ScTabView::UpdateSelectionOverlay()
675 for (USHORT i=0; i<4; i++)
676 diff --git sc/source/ui/view/tabview3.cxx sc/source/ui/view/tabview3.cxx
677 index 1b4879c..da85e44 100644
678 --- sc/source/ui/view/tabview3.cxx
679 +++ sc/source/ui/view/tabview3.cxx
680 @@ -125,10 +125,7 @@ void ScTabView::ClickCursor( SCCOL nPosX, SCROW nPosY, BOOL bControl )
682 ScDocument* pDoc = aViewData.GetDocument();
683 SCTAB nTab = aViewData.GetTabNo();
684 - while (pDoc->IsHorOverlapped( nPosX, nPosY, nTab )) //! ViewData !!!
685 - --nPosX;
686 - while (pDoc->IsVerOverlapped( nPosX, nPosY, nTab ))
687 - --nPosY;
688 + pDoc->SkipOverlapped(nPosX, nPosY, nTab);
690 BOOL bRefMode = SC_MOD()->IsFormulaMode();
692 @@ -921,22 +918,36 @@ void ScTabView::MoveCursorAbs( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
694 HideAllCursors();
696 - if ( bShift && bNewStartIfMarking && IsBlockMode() )
698 - // used for ADD selection mode: start a new block from the cursor position
699 - DoneBlockMode( TRUE );
700 - InitBlockMode( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo(), TRUE );
703 // aktiven Teil umschalten jetzt in AlignToCursor
705 AlignToCursor( nCurX, nCurY, eMode );
706 //! auf OS/2: SC_FOLLOW_JUMP statt SC_FOLLOW_LINE, um Nachlaufen zu verhindern ???
708 if (bKeepSel)
709 + {
710 SetCursor( nCurX, nCurY ); // Markierung stehenlassen
712 + // If the cursor is in existing selection, it's a cursor movement by
713 + // ENTER or TAB. If not, then it's a new selection during ADD
714 + // selection mode.
716 + const ScMarkData& rMark = aViewData.GetMarkData();
717 + ScRangeList aSelList;
718 + rMark.FillRangeListWithMarks(&aSelList, false);
719 + if (!aSelList.In(ScRange(nCurX, nCurY, aViewData.GetTabNo())))
720 + // Cursor not in existing selection. Start a new selection.
721 + DoneBlockMode(true);
723 else
725 + if (!bShift)
727 + // Remove all marked data on cursor movement unless the Shift is locked.
728 + ScMarkData aData(aViewData.GetMarkData());
729 + aData.ResetMark();
730 + SetMarkData(aData);
733 BOOL bSame = ( nCurX == aViewData.GetCurX() && nCurY == aViewData.GetCurY() );
734 bMoveIsShift = bShift;
735 pSelEngine->CursorPosChanging( bShift, bControl );
736 @@ -1080,68 +1091,18 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
738 void ScTabView::MoveCursorPage( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bShift, BOOL bKeepSel )
740 - SCCOL nCurX;
741 - SCROW nCurY;
742 - aViewData.GetMoveCursor( nCurX,nCurY );
744 - ScSplitPos eWhich = aViewData.GetActivePart();
745 - ScHSplitPos eWhichX = WhichH( eWhich );
746 - ScVSplitPos eWhichY = WhichV( eWhich );
748 SCsCOL nPageX;
749 SCsROW nPageY;
750 - if (nMovX >= 0)
751 - nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, 1, eWhichX )) * nMovX;
752 - else
753 - nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, -1, eWhichX )) * nMovX;
755 - if (nMovY >= 0)
756 - nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, 1, eWhichY )) * nMovY;
757 - else
758 - nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, -1, eWhichY )) * nMovY;
760 - if (nMovX != 0 && nPageX == 0) nPageX = (nMovX>0) ? 1 : -1;
761 - if (nMovY != 0 && nPageY == 0) nPageY = (nMovY>0) ? 1 : -1;
763 + GetPageMoveEndPosition(nMovX, nMovY, nPageX, nPageY);
764 MoveCursorRel( nPageX, nPageY, eMode, bShift, bKeepSel );
767 void ScTabView::MoveCursorArea( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bShift, BOOL bKeepSel )
769 - SCCOL nCurX;
770 - SCROW nCurY;
771 - aViewData.GetMoveCursor( nCurX,nCurY );
772 - SCCOL nNewX = nCurX;
773 - SCROW nNewY = nCurY;
775 - ScDocument* pDoc = aViewData.GetDocument();
776 - SCTAB nTab = aViewData.GetTabNo();
778 - // FindAreaPos kennt nur -1 oder 1 als Richtung
780 - SCsCOLROW i;
781 - if ( nMovX > 0 )
782 - for ( i=0; i<nMovX; i++ )
783 - pDoc->FindAreaPos( nNewX, nNewY, nTab, 1, 0 );
784 - if ( nMovX < 0 )
785 - for ( i=0; i<-nMovX; i++ )
786 - pDoc->FindAreaPos( nNewX, nNewY, nTab, -1, 0 );
787 - if ( nMovY > 0 )
788 - for ( i=0; i<nMovY; i++ )
789 - pDoc->FindAreaPos( nNewX, nNewY, nTab, 0, 1 );
790 - if ( nMovY < 0 )
791 - for ( i=0; i<-nMovY; i++ )
792 - pDoc->FindAreaPos( nNewX, nNewY, nTab, 0, -1 );
794 - if (eMode==SC_FOLLOW_JUMP) // unten/rechts nicht zuviel grau anzeigen
796 - if (nMovX != 0 && nNewX == MAXCOL)
797 - eMode = SC_FOLLOW_LINE;
798 - if (nMovY != 0 && nNewY == MAXROW)
799 - eMode = SC_FOLLOW_LINE;
802 - MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY, eMode, bShift, bKeepSel );
803 + SCsCOL nNewX;
804 + SCsROW nNewY;
805 + GetAreaMoveEndPosition(nMovX, nMovY, eMode, nNewX, nNewY, eMode);
806 + MoveCursorRel(nNewX, nNewY, eMode, bShift, bKeepSel);
809 void ScTabView::MoveCursorEnd( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bShift, BOOL bKeepSel )
810 @@ -1206,14 +1167,8 @@ void ScTabView::MoveCursorScreen( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode
811 else if (nMovY>0)
812 nNewY=nPosY+nAddY;
814 -// aViewData.ResetOldCursor();
815 aViewData.SetOldCursor( nNewX,nNewY );
817 - while (pDoc->IsHorOverlapped( nNewX, nNewY, nTab ))
818 - --nNewX;
819 - while (pDoc->IsVerOverlapped( nNewX, nNewY, nTab ))
820 - --nNewY;
822 + pDoc->SkipOverlapped(nNewX, nNewY, nTab);
823 MoveCursorAbs( nNewX, nNewY, eMode, bShift, FALSE, TRUE );
826 @@ -1497,11 +1452,7 @@ void ScTabView::MarkRange( const ScRange& rRange, BOOL bSetCursor, BOOL bContinu
827 SCCOL nPosX = rRange.aStart.Col();
828 SCROW nPosY = rRange.aStart.Row();
829 ScDocument* pDoc = aViewData.GetDocument();
831 - while (pDoc->IsHorOverlapped( nPosX, nPosY, nTab )) //! ViewData !!!
832 - --nPosX;
833 - while (pDoc->IsVerOverlapped( nPosX, nPosY, nTab ))
834 - --nPosY;
835 + pDoc->SkipOverlapped(nPosX, nPosY, nTab);
837 aViewData.ResetOldCursor();
838 SetCursor( nPosX, nPosY );
839 diff --git sc/source/ui/view/tabvwsh3.cxx sc/source/ui/view/tabvwsh3.cxx
840 index caea267..74505f4 100644
841 --- sc/source/ui/view/tabvwsh3.cxx
842 +++ sc/source/ui/view/tabvwsh3.cxx
843 @@ -276,6 +276,10 @@ void ScTabViewShell::Execute( SfxRequest& rReq )
844 if ( pReqArgs->GetItemState( FN_PARAM_1, TRUE, &pItem ) == SFX_ITEM_SET )
845 bUnmark = ((const SfxBoolItem*)pItem)->GetValue();
847 + bool bAlignToCursor = true;
848 + if (pReqArgs->GetItemState(FN_PARAM_2, true, &pItem) == SFX_ITEM_SET)
849 + bAlignToCursor = static_cast<const SfxBoolItem*>(pItem)->GetValue();
851 if ( nSlot == SID_JUMPTOMARK )
853 // #106586# URL has to be decoded for escaped characters (%20)
854 @@ -396,10 +396,7 @@ void ScTabViewShell::Execute( SfxRequest& rReq )
855 // und Cursor setzen
857 // zusammengefasste Zellen beruecksichtigen:
858 - while ( pDoc->IsHorOverlapped( nCol, nRow, nTab ) ) //! ViewData !!!
859 - --nCol;
860 - while ( pDoc->IsVerOverlapped( nCol, nRow, nTab ) )
861 - --nRow;
862 + pDoc->SkipOverlapped(nCol, nRow, nTab);
864 // Navigator-Aufrufe sind nicht API!!!
866 @@ -417,9 +421,13 @@ void ScTabViewShell::Execute( SfxRequest& rReq )
867 if (!rReq.IsAPI())
868 rReq.Done();
870 - // align to cursor even if the cursor position hasn't changed,
871 - // because the cursor may be set outside the visible area.
872 - AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
874 + if (bAlignToCursor)
876 + // align to cursor even if the cursor position hasn't changed,
877 + // because the cursor may be set outside the visible area.
878 + AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
881 rReq.SetReturnValue( SfxStringItem( SID_CURRENTCELL, aAddress ) );
883 diff --git sc/source/ui/view/viewdata.cxx sc/source/ui/view/viewdata.cxx
884 index f69ab24..66c07c4 100644
885 --- sc/source/ui/view/viewdata.cxx
886 +++ sc/source/ui/view/viewdata.cxx
887 @@ -1891,12 +1891,11 @@ BOOL ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich,
889 //! public Methode um Position anzupassen
891 - BOOL bHOver = FALSE;
892 - while (pDoc->IsHorOverlapped( rPosX, rPosY, nTabNo ))
893 - { --rPosX; bHOver=TRUE; }
894 - BOOL bVOver = FALSE;
895 - while (pDoc->IsVerOverlapped( rPosX, rPosY, nTabNo ))
896 - { --rPosY; bVOver=TRUE; }
897 + SCCOL nOrigX = rPosX;
898 + SCROW nOrigY = rPosY;
899 + pDoc->SkipOverlapped(rPosX, rPosY, nTabNo);
900 + bool bHOver = (nOrigX != rPosX);
901 + bool bVOver = (nOrigY != rPosY);
903 if ( bRepair && ( bHOver || bVOver ) )