sc/source/ui/app/inputhdl.cxx |   19 ++++++++++++-------
 sc/source/ui/inc/inputhdl.hxx |    1 +
 sc/source/ui/view/cellsh4.cxx |   13 +++++++++++--
 3 files changed, 24 insertions(+), 9 deletions(-)

New commits:
commit 41acf1ab0e102c2341d2ae0d5d5949c21a962cf2
Author:     Neil Roberts <[email protected]>
AuthorDate: Wed Sep 3 13:09:15 2025 +0200
Commit:     Noel Grandin <[email protected]>
CommitDate: Thu Sep 4 10:48:05 2025 +0200

    tdf#108911 Toggle input modes in Cell Edit handler, not input handler
    
    The F2 key by default maps to “Cell Edit” which sets the input mode to
    SC_INPUT_TABLE to start editing the cell. If you press F2 again, the key
    event handling code in the input handler had a hardcoded handler for F2
    which switched to SC_INPUT_TYPE mode when the mode is already
    TABLE. This meant that you could press F2 to toggle between the two
    modes. This is useful if you are editing an equation because sometimes
    you want the cursor keys to move the text input cursor and sometimes you
    want it to move the cell cursor to help type a cell reference.
    
    This feature relies on the fact that the input handler code gets to see
    the key event before the accelerator handler code. With the GTK backend
    this works fine but on MacOS the accelerator code ends up eating the key
    event before the input handler gets to see it. This meant that pressing
    F2 always set TABLE mode instead of toggling. There’s also the slight
    weirdness on all platforms that if you reassign “Cell Edit” to a
    different shortcut key then it no longer works like a toggle and instead
    you always have to press F2 to get to TYPE mode once you’re in TABLE
    mode. It also means that if you tried to reassign F2 to a different
    command then it wouldn’t work if you are editing a cell.
    
    This patch changes the behaviour so that the toggling is done directly
    in the handler for the “Cell Edit” command. The hardcoded handler for F2
    in the input handler is removed. That means that the toggling will work
    regardless of what key the command is assigned to and the input handler
    doesn’t need to see the key before the accelerator key handler.
    
    Change-Id: I79aa6fa515f7a720335f3535146c95eae874ea0a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190557
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <[email protected]>

diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx
index 376da33c677e..a5d8669fcc45 100644
--- a/sc/source/ui/app/inputhdl.cxx
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -3097,6 +3097,18 @@ void ScInputHandler::SetMode( ScInputMode eNewMode, 
const OUString* pInitText, S
     bInOwnChange = false;
 }
 
+void ScInputHandler::StartOrToggleEditMode()
+{
+    // Switch to SC_INPUT_TABLE mode unless we’re already in that mode
+    // in which case we’ll switch to SC_INPUT_TYPE. This has the
+    // effect of toggling between those two modes if this is called
+    // multiple times.
+    ScInputMode eNewMode = eMode == SC_INPUT_TABLE
+        ? SC_INPUT_TYPE
+        : SC_INPUT_TABLE;
+    SetMode(eNewMode);
+}
+
 /**
  * @return true if rString only contains digits (no autocorrect then)
  */
@@ -3931,13 +3943,6 @@ bool ScInputHandler::KeyInput( const KeyEvent& rKEvt, 
bool bStartEdit /* = false
             else
                 bSkip = true;
             break;
-        case KEY_F2:
-            if ( !bShift && !bControl && !bAlt && eMode == SC_INPUT_TABLE )
-            {
-                eMode = SC_INPUT_TYPE;
-                bUsed = true;
-            }
-            break;
     }
 
     // Only execute cursor keys if already in EditMode
diff --git a/sc/source/ui/inc/inputhdl.hxx b/sc/source/ui/inc/inputhdl.hxx
index 0f8ff07e31db..b1656c4c5656 100644
--- a/sc/source/ui/inc/inputhdl.hxx
+++ b/sc/source/ui/inc/inputhdl.hxx
@@ -182,6 +182,7 @@ public:
 
     void            SetMode( ScInputMode eNewMode, const OUString* pInitText = 
nullptr,
                              ScEditEngineDefaulter* pTopEngine = nullptr );
+    void            StartOrToggleEditMode();
     bool            IsInputMode() const { return (eMode != SC_INPUT_NONE); }
     bool            IsEditMode() const  { return (eMode != SC_INPUT_NONE &&
                                                   eMode != SC_INPUT_TYPE); }
diff --git a/sc/source/ui/view/cellsh4.cxx b/sc/source/ui/view/cellsh4.cxx
index ee1cfbfb5ff3..36d4198777ac 100644
--- a/sc/source/ui/view/cellsh4.cxx
+++ b/sc/source/ui/view/cellsh4.cxx
@@ -325,7 +325,7 @@ void ScCellShell::ExecuteMove( SfxRequest& rReq )
     sal_uInt16 nSlotId  = rReq.GetSlot();
     const SfxItemSet* pReqArgs = rReq.GetArgs();
 
-    if(nSlotId != SID_CURSORTOPOFSCREEN && nSlotId != SID_CURSORENDOFSCREEN)
+    if(nSlotId != SID_CURSORTOPOFSCREEN && nSlotId != SID_CURSORENDOFSCREEN && 
nSlotId != SID_SETINPUTMODE)
         pTabViewShell->ExecuteInputDirect();
     switch ( nSlotId )
     {
@@ -409,7 +409,16 @@ void ScCellShell::ExecuteMove( SfxRequest& rReq )
             break;
 
         case SID_SETINPUTMODE:
-            ScModule::get()->SetInputMode(SC_INPUT_TABLE);
+            if (ScInputHandler* pHdl = 
ScModule::get()->GetInputHdl(pTabViewShell))
+            {
+                // We don’t want to call ExecuteInputDirect if we’re
+                // actually trying to toggle between TABLE and TYPE
+                // modes because it would reset the mode back to NONE
+                // and the toggle won’t work.
+                if (!pHdl->IsInputMode() || pHdl->IsTopMode())
+                    pTabViewShell->ExecuteInputDirect();
+                pHdl->StartOrToggleEditMode();
+            }
             break;
 
         case SID_FOCUS_INPUTLINE:

Reply via email to