1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sfx2/request.hxx>
21 #include <osl/diagnose.h>
24 #include <tabvwsh.hxx>
27 #include <inputhdl.hxx>
28 #include <inputwin.hxx>
29 #include <document.hxx>
30 #include <officecfg/Office/Calc.hxx>
33 void ScCellShell::ExecuteCursor( SfxRequest
& rReq
)
35 ScViewData
& rData
= GetViewData();
36 ScTabViewShell
* pTabViewShell
= rData
.GetViewShell();
37 const SfxItemSet
* pReqArgs
= rReq
.GetArgs();
38 sal_uInt16 nSlotId
= rReq
.GetSlot();
43 if ( pReqArgs
!= nullptr )
45 const SfxPoolItem
* pItem
;
46 if (pReqArgs
->HasItem(FN_PARAM_1
, &pItem
))
47 nRepeat
= static_cast<SCCOLROW
>(static_cast<const SfxInt16Item
*>(pItem
)->GetValue());
48 if (pReqArgs
->HasItem(FN_PARAM_2
, &pItem
))
49 bSel
= static_cast<const SfxBoolItem
*>(pItem
)->GetValue();
53 // evaluate locked selection mode
55 sal_uInt16 nLocked
= pTabViewShell
->GetLockedModifiers();
56 if ( nLocked
& KEY_SHIFT
)
58 else if ( nLocked
& KEY_MOD1
)
60 // ADD mode: keep the selection, start a new block when marking with shift again
70 rReq
.SetSlot(SID_CURSORDOWN_SEL
);
73 rReq
.SetSlot(SID_CURSORUP_SEL
);
76 rReq
.SetSlot(SID_CURSORRIGHT_SEL
);
79 rReq
.SetSlot(SID_CURSORLEFT_SEL
);
81 case SID_CURSORPAGEDOWN
:
82 rReq
.SetSlot(SID_CURSORPAGEDOWN_SEL
);
84 case SID_CURSORPAGEUP
:
85 rReq
.SetSlot(SID_CURSORPAGEUP_SEL
);
87 case SID_CURSORBLKDOWN
:
88 rReq
.SetSlot(SID_CURSORBLKDOWN_SEL
);
91 rReq
.SetSlot(SID_CURSORBLKUP_SEL
);
93 case SID_CURSORBLKRIGHT
:
94 rReq
.SetSlot(SID_CURSORBLKRIGHT_SEL
);
96 case SID_CURSORBLKLEFT
:
97 rReq
.SetSlot(SID_CURSORBLKLEFT_SEL
);
102 ExecuteCursorSel(rReq
);
106 SCCOLROW nRTLSign
= 1;
107 if ( rData
.GetDocument().IsLayoutRTL( rData
.GetTabNo() ) )
109 //! evaluate cursor movement option?
113 // once extra, so that the cursor will not be painted too often with ExecuteInputDirect:
114 pTabViewShell
->HideAllCursors();
117 if( pTabViewShell
->GetCurObjectSelectionType() == OST_Editing
)
118 pTabViewShell
->SetForceFocusOnCurCell(true);
120 pTabViewShell
->SetForceFocusOnCurCell(false);
122 // If ScrollLock key is active, cell cursor stays on the current cell while
123 // scrolling the grid.
124 bool bScrollLock
= false;
125 // tdf#112876 - allow to disable for special keyboards
126 if (officecfg::Office::Calc::Input::UseScrollLock::get())
128 KeyIndicatorState eState
= pFrameWin
->GetIndicatorState();
129 if (eState
& KeyIndicatorState::SCROLLLOCK
)
132 //OS: once for all should do, however!
133 pTabViewShell
->ExecuteInputDirect();
138 pTabViewShell
->ScrollY( nRepeat
, SC_SPLIT_BOTTOM
);
140 pTabViewShell
->MoveCursorRel( 0, nRepeat
, SC_FOLLOW_LINE
, bSel
, bKeep
);
143 case SID_CURSORBLKDOWN
:
144 pTabViewShell
->MoveCursorArea( 0, nRepeat
, SC_FOLLOW_JUMP
, bSel
, bKeep
, !rReq
.IsAPI() );
149 pTabViewShell
->ScrollY( -nRepeat
, SC_SPLIT_BOTTOM
);
151 pTabViewShell
->MoveCursorRel( 0, -nRepeat
, SC_FOLLOW_LINE
, bSel
, bKeep
);
154 case SID_CURSORBLKUP
:
155 pTabViewShell
->MoveCursorArea( 0, -nRepeat
, SC_FOLLOW_JUMP
, bSel
, bKeep
, !rReq
.IsAPI() );
160 pTabViewShell
->ScrollX( static_cast<SCCOL
>(-nRepeat
* nRTLSign
), SC_SPLIT_LEFT
);
162 pTabViewShell
->MoveCursorRel( static_cast<SCCOL
>(-nRepeat
* nRTLSign
), 0, SC_FOLLOW_LINE
, bSel
, bKeep
);
165 case SID_CURSORBLKLEFT
:
166 pTabViewShell
->MoveCursorArea( static_cast<SCCOL
>(-nRepeat
* nRTLSign
), 0, SC_FOLLOW_JUMP
, bSel
, bKeep
, !rReq
.IsAPI() );
169 case SID_CURSORRIGHT
:
171 pTabViewShell
->ScrollX( static_cast<SCCOL
>(nRepeat
* nRTLSign
), SC_SPLIT_LEFT
);
173 pTabViewShell
->MoveCursorRel( static_cast<SCCOL
>(nRepeat
* nRTLSign
), 0, SC_FOLLOW_LINE
, bSel
, bKeep
);
176 case SID_CURSORBLKRIGHT
:
177 pTabViewShell
->MoveCursorArea( static_cast<SCCOL
>(nRepeat
* nRTLSign
), 0, SC_FOLLOW_JUMP
, bSel
, bKeep
, !rReq
.IsAPI() );
180 case SID_CURSORPAGEDOWN
:
185 pTabViewShell
->GetPageMoveEndPosition( 0, nRepeat
, nPageX
, nPageY
);
186 pTabViewShell
->ScrollY( nPageY
, SC_SPLIT_BOTTOM
);
189 pTabViewShell
->MoveCursorPage( 0, nRepeat
, SC_FOLLOW_FIX
, bSel
, bKeep
);
192 case SID_CURSORPAGEUP
:
197 pTabViewShell
->GetPageMoveEndPosition( 0, nRepeat
, nPageX
, nPageY
);
198 pTabViewShell
->ScrollY( -nPageY
, SC_SPLIT_BOTTOM
);
201 pTabViewShell
->MoveCursorPage( 0, -nRepeat
, SC_FOLLOW_FIX
, bSel
, bKeep
);
204 case SID_CURSORPAGERIGHT_
: //XXX !!!
209 pTabViewShell
->GetPageMoveEndPosition( static_cast<SCCOL
>(nRepeat
), 0, nPageX
, nPageY
);
210 pTabViewShell
->ScrollX( nPageX
, SC_SPLIT_LEFT
);
213 pTabViewShell
->MoveCursorPage( static_cast<SCCOL
>(nRepeat
), 0, SC_FOLLOW_FIX
, bSel
, bKeep
);
216 case SID_CURSORPAGELEFT_
: //XXX !!!
221 pTabViewShell
->GetPageMoveEndPosition( static_cast<SCCOL
>(nRepeat
), 0, nPageX
, nPageY
);
222 pTabViewShell
->ScrollX( -nPageX
, SC_SPLIT_LEFT
);
225 pTabViewShell
->MoveCursorPage( static_cast<SCCOL
>(-nRepeat
), 0, SC_FOLLOW_FIX
, bSel
, bKeep
);
229 OSL_FAIL("Unknown message in ViewShell (Cursor)");
233 pTabViewShell
->ShowAllCursors();
235 rReq
.AppendItem( SfxInt16Item(FN_PARAM_1
, static_cast<sal_Int16
>(nRepeat
)) );
236 rReq
.AppendItem( SfxBoolItem(FN_PARAM_2
, bSel
) );
240 void ScCellShell::GetStateCursor( SAL_UNUSED_PARAMETER SfxItemSet
& /* rSet */ )
244 void ScCellShell::ExecuteCursorSel( SfxRequest
& rReq
)
246 sal_uInt16 nSlotId
= rReq
.GetSlot();
247 ScTabViewShell
* pViewShell
= GetViewData().GetViewShell();
248 ScInputHandler
* pInputHdl
= pViewShell
->GetInputHandler();
249 pViewShell
->HideAllCursors();
250 if (pInputHdl
&& pInputHdl
->IsInputMode())
252 // the current cell is in edit mode. Commit the text before moving on.
253 pViewShell
->ExecuteInputDirect();
256 SCCOLROW nRepeat
= 1;
257 const SfxItemSet
* pReqArgs
= rReq
.GetArgs();
259 if ( pReqArgs
!= nullptr )
261 const SfxPoolItem
* pItem
;
262 if (pReqArgs
->HasItem(FN_PARAM_1
, &pItem
))
263 nRepeat
= static_cast<SCCOLROW
>(static_cast<const SfxInt16Item
*>(pItem
)->GetValue());
266 SCROW nMovY
= nRepeat
;
267 // Horizontal direction depends on whether or not the UI language is RTL.
268 SCCOL nMovX
= nRepeat
;
269 if (GetViewData().GetDocument().IsLayoutRTL(GetViewData().GetTabNo()))
271 // mirror horizontal movement for right-to-left mode.
277 case SID_CURSORDOWN_SEL
:
278 pViewShell
->ExpandBlock(0, nMovY
, SC_FOLLOW_LINE
);
280 case SID_CURSORUP_SEL
:
281 pViewShell
->ExpandBlock(0, -nMovY
, SC_FOLLOW_LINE
);
283 case SID_CURSORRIGHT_SEL
:
284 pViewShell
->ExpandBlock(nMovX
, 0, SC_FOLLOW_LINE
);
286 case SID_CURSORLEFT_SEL
:
287 pViewShell
->ExpandBlock(-nMovX
, 0, SC_FOLLOW_LINE
);
289 case SID_CURSORPAGEUP_SEL
:
290 pViewShell
->ExpandBlockPage(0, -nMovY
);
292 case SID_CURSORPAGEDOWN_SEL
:
293 pViewShell
->ExpandBlockPage(0, nMovY
);
295 case SID_CURSORPAGERIGHT_SEL
:
296 pViewShell
->ExpandBlockPage(nMovX
, 0);
298 case SID_CURSORPAGELEFT_SEL
:
299 pViewShell
->ExpandBlockPage(-nMovX
, 0);
301 case SID_CURSORBLKDOWN_SEL
:
302 pViewShell
->ExpandBlockArea(0, nMovY
);
304 case SID_CURSORBLKUP_SEL
:
305 pViewShell
->ExpandBlockArea(0, -nMovY
);
307 case SID_CURSORBLKRIGHT_SEL
:
308 pViewShell
->ExpandBlockArea(nMovX
, 0);
310 case SID_CURSORBLKLEFT_SEL
:
311 pViewShell
->ExpandBlockArea(-nMovX
, 0);
316 pViewShell
->ShowAllCursors();
318 rReq
.AppendItem( SfxInt16Item(FN_PARAM_1
,static_cast<sal_Int16
>(nRepeat
)) );
322 void ScCellShell::ExecuteMove( SfxRequest
& rReq
)
324 ScTabViewShell
* pTabViewShell
= GetViewData().GetViewShell();
325 sal_uInt16 nSlotId
= rReq
.GetSlot();
326 const SfxItemSet
* pReqArgs
= rReq
.GetArgs();
328 if(nSlotId
!= SID_CURSORTOPOFSCREEN
&& nSlotId
!= SID_CURSORENDOFSCREEN
)
329 pTabViewShell
->ExecuteInputDirect();
333 case SID_NEXT_TABLE_SEL
:
334 pTabViewShell
->SelectNextTab( 1, (nSlotId
== SID_NEXT_TABLE_SEL
) );
338 case SID_PREV_TABLE_SEL
:
339 pTabViewShell
->SelectNextTab( -1, (nSlotId
== SID_PREV_TABLE_SEL
) );
342 // cursor movements in range do not originate from Basic,
343 // because the ScSbxRange-object changes the marking at input
345 case SID_NEXT_UNPROTECT
:
346 pTabViewShell
->FindNextUnprot( false, !rReq
.IsAPI() );
349 case SID_PREV_UNPROTECT
:
350 pTabViewShell
->FindNextUnprot( true, !rReq
.IsAPI() );
353 case SID_CURSORENTERUP
:
355 pTabViewShell
->MoveCursorRel( 0, -1, SC_FOLLOW_LINE
, false );
357 pTabViewShell
->MoveCursorEnter( true );
360 case SID_CURSORENTERDOWN
:
362 pTabViewShell
->MoveCursorRel( 0, 1, SC_FOLLOW_LINE
, false );
364 pTabViewShell
->MoveCursorEnter( false );
368 if (const SfxPoolItem
*pColItem
, *pModifierItem
;
369 pReqArgs
&& pReqArgs
->HasItem(FN_PARAM_1
, &pColItem
)
370 && pReqArgs
->HasItem(FN_PARAM_2
, &pModifierItem
))
372 SCCOL nCol
= static_cast<SCCOL
>(static_cast<const SfxInt32Item
*>(pColItem
)->GetValue());
373 sal_Int16 nModifier
= static_cast<const SfxInt16Item
*>(pModifierItem
)->GetValue();
375 pTabViewShell
->MarkColumns( nCol
, nModifier
);
378 pTabViewShell
->MarkColumns();
382 if (const SfxPoolItem
*pRowItem
, *pModifierItem
;
383 pReqArgs
&& pReqArgs
->HasItem(FN_PARAM_1
, &pRowItem
)
384 && pReqArgs
->HasItem(FN_PARAM_2
, &pModifierItem
))
386 SCROW nRow
= static_cast<SCROW
>(static_cast<const SfxInt32Item
*>(pRowItem
)->GetValue());
387 sal_Int16 nModifier
= static_cast<const SfxInt16Item
*>(pModifierItem
)->GetValue();
389 pTabViewShell
->MarkRows( nRow
, nModifier
);
392 pTabViewShell
->MarkRows();
395 case SID_SELECT_NONE
:
396 pTabViewShell
->Unmark();
399 case SID_ALIGNCURSOR
:
400 pTabViewShell
->AlignToCursor( GetViewData().GetCurX(), GetViewData().GetCurY(), SC_FOLLOW_JUMP
);
403 case SID_MARKDATAAREA
:
404 pTabViewShell
->MarkDataArea();
407 case SID_MARKARRAYFORMULA
:
408 pTabViewShell
->MarkMatrixFormula();
411 case SID_SETINPUTMODE
:
412 ScModule::get()->SetInputMode(SC_INPUT_TABLE
);
415 case SID_FOCUS_INPUTLINE
:
416 if (ScInputHandler
* pHdl
= ScModule::get()->GetInputHdl(pTabViewShell
))
417 if (ScInputWindow
* pWin
= pHdl
->GetInputWindow())
418 pWin
->SwitchToTextWin();
421 case SID_CURSORTOPOFSCREEN
:
422 pTabViewShell
->MoveCursorScreen( 0, -1, SC_FOLLOW_LINE
, false );
425 case SID_CURSORENDOFSCREEN
:
426 pTabViewShell
->MoveCursorScreen( 0, 1, SC_FOLLOW_LINE
, false );
430 OSL_FAIL("Unknown message in ViewShell (Cursor)");
437 void ScCellShell::ExecutePageSel( SfxRequest
& rReq
)
439 sal_uInt16 nSlotId
= rReq
.GetSlot();
442 case SID_CURSORHOME_SEL
: rReq
.SetSlot( SID_CURSORHOME
); break;
443 case SID_CURSOREND_SEL
: rReq
.SetSlot( SID_CURSOREND
); break;
444 case SID_CURSORTOPOFFILE_SEL
: rReq
.SetSlot( SID_CURSORTOPOFFILE
); break;
445 case SID_CURSORENDOFFILE_SEL
: rReq
.SetSlot( SID_CURSORENDOFFILE
); break;
447 OSL_FAIL("Unknown message in ViewShell (ExecutePageSel)");
450 rReq
.AppendItem( SfxBoolItem(FN_PARAM_2
, true) );
451 ExecuteSlot( rReq
, GetInterface() );
454 void ScCellShell::ExecutePage( SfxRequest
& rReq
)
456 ScTabViewShell
* pTabViewShell
= GetViewData().GetViewShell();
457 const SfxItemSet
* pReqArgs
= rReq
.GetArgs();
458 sal_uInt16 nSlotId
= rReq
.GetSlot();
462 if ( pReqArgs
!= nullptr )
464 const SfxPoolItem
* pItem
;
465 if (pReqArgs
->HasItem(FN_PARAM_2
, &pItem
))
466 bSel
= static_cast<const SfxBoolItem
*>(pItem
)->GetValue();
470 // evaluate locked selection mode
472 sal_uInt16 nLocked
= pTabViewShell
->GetLockedModifiers();
473 if ( nLocked
& KEY_SHIFT
)
475 else if ( nLocked
& KEY_MOD1
)
477 // ADD mode: keep the selection, start a new block when marking with shift again
482 pTabViewShell
->ExecuteInputDirect();
486 pTabViewShell
->MoveCursorEnd( -1, 0, SC_FOLLOW_LINE
, bSel
, bKeep
);
490 pTabViewShell
->MoveCursorEnd( 1, 0, SC_FOLLOW_JUMP
, bSel
, bKeep
);
493 case SID_CURSORTOPOFFILE
:
494 pTabViewShell
->MoveCursorEnd( -1, -1, SC_FOLLOW_LINE
, bSel
, bKeep
);
497 case SID_CURSORENDOFFILE
:
498 pTabViewShell
->MoveCursorEnd( 1, 1, SC_FOLLOW_JUMP_END
, bSel
, bKeep
);
502 OSL_FAIL("Unknown message in ViewShell (ExecutePage)");
506 rReq
.AppendItem( SfxBoolItem(FN_PARAM_2
, bSel
) );
510 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */