# HG changeset patch
# User Torsten Lilge <ttl-octave@mailbox.org>
# Date 1589826968 -7200
#      Mon May 18 20:36:08 2020 +0200
# Branch stable
# Node ID 87d5ca1b3afe9826cb49aa8981a68903396a23ea
# Parent  1127bcb30e610b9aa040326cb24d4b63a2312f19
fix focus issues in editor due to qt bug with focus proxy chains (bug #57635)

* file-editor.cc (activate): do not emit signal for focussing current
  editor tab but call new method reset_focus where the signal is emitted;
  (handle_autoc_complete): slot for signal when auto-completion list
  is regularily finished, calling reset_focus;
  (handle_autoc_cancelled): slot for signal when auto-completion list
  is cancelled, calling reset_focus with true flag for hide and reshow
  editor;
  (reset_focus): new method for resetting focus to the editor, in worst
  case, hiding and reshowing it;
  (make_file_editor_tab): connect signals for finished/cancelled
  auto-completion list to related new slots

* file-editor.h: new slots handle_autoc_cancelled and
  handle_autoc_complete, new method reset_focus

diff -r 1127bcb30e61 -r 87d5ca1b3afe libgui/src/m-editor/file-editor.cc
--- a/libgui/src/m-editor/file-editor.cc	Sat May 16 03:46:38 2020 -0400
+++ b/libgui/src/m-editor/file-editor.cc	Mon May 18 20:36:08 2020 +0200
@@ -340,9 +340,7 @@ namespace octave
     octave_dock_widget::activate ();
 
     // set focus to current tab
-    QWidget *fileEditorTab = m_tab_widget->currentWidget ();
-    if (fileEditorTab)
-      emit fetab_set_focus (fileEditorTab);
+    reset_focus (false);
   }
 
   void file_editor::set_focus (QWidget *fet)
@@ -2275,6 +2273,9 @@ namespace octave
              main_win (),
              SLOT (process_settings_dialog_request (const QString&)));
 
+    connect (this, SIGNAL (reset_editor_focus (void)),
+             main_win (), SLOT (reset_editor_focus (void)));
+
     connect (this, SIGNAL (request_dbcont_signal (void)),
              main_win (), SLOT (debug_continue (void)));
 
@@ -2296,6 +2297,41 @@ namespace octave
     check_actions ();
   }
 
+  // Slot when autocompletion list was finished
+  void file_editor::handle_autoc_complete (const char*, int, int, int)
+  {
+    reset_focus (false);  // reset focus only
+  }
+
+  // Slot when autocompletion list was cancelled
+  void file_editor::handle_autoc_cancelled (void)
+  {
+    reset_focus (true);   // Reset the autoc list mechanism, too
+  }
+
+  void file_editor::reset_focus (bool full)
+  {
+    // Reset the focus of the tab and the related edit area
+    file_editor_tab *f
+       = static_cast<file_editor_tab *> (m_tab_widget->currentWidget ());
+     emit fetab_set_focus (f);
+
+     if (full)
+        {
+          // List was cancelled but somehow still active. Accept it and
+          // undo the text insertion, if any
+          octave_qscintilla *qsci = f->qsci_edit_area ();
+          int line, col;
+          qsci->getCursorPosition (&line, &col);
+          int l1 = qsci->lineLength (line); // Current line length
+          // Accept autocompletin
+          qsci->SendScintilla (QsciScintillaBase::SCI_AUTOCCOMPLETE);
+          // Was text inserted? If yes, undo
+          if (qsci->text (line).length () - l1)
+            qsci->undo ();
+        }
+  }
+
   file_editor_tab *
   file_editor::make_file_editor_tab (const QString& directory)
   {
@@ -2319,6 +2355,12 @@ namespace octave
              SIGNAL (focus_console_after_command_signal (void)),
              main_win (), SLOT (focus_console_after_command (void)));
 
+    connect (f->qsci_edit_area (), SIGNAL (SCN_AUTOCCANCELLED (void)),
+             this, SLOT (handle_autoc_cancelled (void)));
+
+    connect (f->qsci_edit_area (), SIGNAL (SCN_AUTOCCOMPLETED (const char*, int, int, int)),
+             this, SLOT (handle_autoc_complete (const char*, int, int, int)));
+
     // Signals from the file editor_tab
     connect (f, SIGNAL (file_name_changed (const QString&, const QString&, bool)),
              this, SLOT (handle_file_name_changed (const QString&,
diff -r 1127bcb30e61 -r 87d5ca1b3afe libgui/src/m-editor/file-editor.h
--- a/libgui/src/m-editor/file-editor.h	Sat May 16 03:46:38 2020 -0400
+++ b/libgui/src/m-editor/file-editor.h	Mon May 18 20:36:08 2020 +0200
@@ -175,6 +175,8 @@ namespace octave
     void editor_tabs_changed_signal (bool);
     void request_dbcont_signal (void);
 
+    void reset_editor_focus (void);
+
   public slots:
 
     void activate (void);
@@ -274,6 +276,9 @@ namespace octave
 
     void toplevel_change (bool toplevel);
 
+    void handle_autoc_cancelled (void);
+    void handle_autoc_complete (const char*, int, int, int);
+
   protected slots:
 
     void copyClipboard (void);
@@ -331,6 +336,8 @@ namespace octave
 
     void find_create (void);
 
+    void reset_focus (bool full);
+
     file_editor_tab * find_tab_widget (const QString& openFileName);
     QAction * add_action (QMenu *menu, const QString& text,
                           const char *member, QWidget *receiver = nullptr);
diff -r 1127bcb30e61 -r 87d5ca1b3afe libgui/src/main-window.cc
--- a/libgui/src/main-window.cc	Sat May 16 03:46:38 2020 -0400
+++ b/libgui/src/main-window.cc	Mon May 18 20:36:08 2020 +0200
@@ -1455,6 +1455,15 @@ namespace octave
       focus_command_window ();
   }
 
+  void main_window::reset_editor_focus (void)
+  {
+#if defined (HAVE_QSCINTILLA)
+    m_editor_window->clearFocus ();
+    m_current_directory_combo_box->setFocus ();
+    m_editor_window->activate ();
+#endif
+  }
+
   void main_window::read_settings (void)
   {
     resource_manager& rmgr = m_octave_qobj.get_resource_manager ();
diff -r 1127bcb30e61 -r 87d5ca1b3afe libgui/src/main-window.h
--- a/libgui/src/main-window.h	Sat May 16 03:46:38 2020 -0400
+++ b/libgui/src/main-window.h	Mon May 18 20:36:08 2020 +0200
@@ -193,6 +193,7 @@ namespace octave
     void handle_update_breakpoint_marker_request (bool insert,
                                                   const QString& file, int line,
                                                   const QString& cond);
+    void reset_editor_focus (void);
 
     void read_settings (void);
     void init_terminal_size (void);
