changeset 27588:f0e3f3e28a8e

move qt_interpreter_events object from interpreter_qobject to octave_qobject * interpreter-qobject.h, interpreter-qobject.cc (interpreter_qobject::m_qt_link): Delete data member and all uses. (interpreter_qobject::execute): Don't connect confirm_shutdown_signal and copy_image_to_clipboard_signal here. (interpreter_qobject::confirm_shutdown): Delete. * octave-qobject.h, octave-qobject.cc (base_qobject::octave_qobject): Connect copy_image_to_clipboard_signal here. (base_qobject::m_qt_interpreter_events): New data member. (base_qobject::confirm_shutdown): New function. (base_qobject::confirm_shutdown_octave): Delete. (bool gui_qobject::confirm_shutdown): New function. (base_qobject::get_qt_interpreter_events, base_qobject::qt_link): New functions. * interpreter.h, interpreter.cc (interpreter::quit): New arg, confirm. * main-window.h, main-window.cc (main_window::confirm_shutdown): Rename from confirm_shutdown_octave. Change all uses. (main_window::closeEvent): Check confirm_shutdown first, then if exit is confirmed, call interpreter::quit with extra argument to skip confirmation. * qt-interpreter-events.h, qt-interpreter-events.cc (qt_interpreter_events::m_octave_qobject): New data member. (qt_interpreter_events::qt_interpreter_events): Connect confirm_shutdown_signal to confirm_shutdown_octave slot here. (qt_interpreter_events::confirm_shutdown_octave): New function.
author John W. Eaton <jwe@octave.org>
date Sat, 26 Oct 2019 12:20:29 -0400
parents 494d6243c188
children 12cfa32dc29e
files libgui/src/interpreter-qobject.cc libgui/src/interpreter-qobject.h libgui/src/main-window.cc libgui/src/main-window.h libgui/src/octave-qobject.cc libgui/src/octave-qobject.h libgui/src/qt-interpreter-events.cc libgui/src/qt-interpreter-events.h libinterp/corefcn/interpreter.cc libinterp/corefcn/interpreter.h
diffstat 10 files changed, 129 insertions(+), 103 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/interpreter-qobject.cc	Tue Oct 29 11:36:14 2019 -0400
+++ b/libgui/src/interpreter-qobject.cc	Sat Oct 26 12:20:29 2019 -0400
@@ -35,32 +35,23 @@
 
 namespace octave
 {
-  interpreter_qobject::interpreter_qobject (base_qobject *oct_qobj)
-    : QObject (), m_octave_qobject (oct_qobj), m_interpreter (nullptr),
-      m_qt_link (new qt_interpreter_events ())
+  interpreter_qobject::interpreter_qobject (base_qobject& oct_qobj)
+    : QObject (), m_octave_qobj (oct_qobj), m_interpreter (nullptr)
   { }
 
   void interpreter_qobject::execute (void)
   {
     // The Octave application context owns the interpreter.
 
-    qt_application& app_context = m_octave_qobject->app_context ();
+    qt_application& app_context = m_octave_qobj.app_context ();
 
     interpreter& interp = app_context.create_interpreter ();
 
     event_manager& evmgr = interp.get_event_manager ();
 
-    evmgr.connect_link (m_qt_link);
+    evmgr.connect_link (m_octave_qobj.get_qt_interpreter_events ());
     evmgr.enable ();
 
-    connect (qt_link (), SIGNAL (confirm_shutdown_signal (void)),
-             m_octave_qobject, SLOT (confirm_shutdown_octave (void)));
-
-    connect (qt_link (),
-             SIGNAL (copy_image_to_clipboard_signal (const QString&, bool)),
-             m_octave_qobject,
-             SLOT (copy_image_to_clipboard (const QString&, bool)));
-
     int exit_status = 0;
 
     try
@@ -128,16 +119,8 @@
     evmgr.post_event (meth);
   }
 
-  void interpreter_qobject::confirm_shutdown (bool closenow)
+  qt_interpreter_events * interpreter_qobject::qt_link (void)
   {
-    // Wait for link thread to go to sleep state.
-    m_qt_link->lock ();
-
-    m_qt_link->shutdown_confirmation (closenow);
-
-    m_qt_link->unlock ();
-
-    // Awake the worker thread so that it continues shutting down (or not).
-    m_qt_link->wake_all ();
+    return m_octave_qobj.qt_link ();
   }
 }
--- a/libgui/src/interpreter-qobject.h	Tue Oct 29 11:36:14 2019 -0400
+++ b/libgui/src/interpreter-qobject.h	Sat Oct 26 12:20:29 2019 -0400
@@ -24,8 +24,6 @@
 #if ! defined (octave_interpreter_qobject_h)
 #define octave_interpreter_qobject_h 1
 
-#include <memory>
-
 #include <QObject>
 
 #include "qt-interpreter-events.h"
@@ -42,13 +40,11 @@
 
   public:
 
-    interpreter_qobject (base_qobject *oct_qobj);
+    interpreter_qobject (base_qobject& oct_qobj);
 
     ~interpreter_qobject (void) = default;
 
-    qt_interpreter_events * qt_link (void) { return m_qt_link.get (); }
-
-    void confirm_shutdown (bool closenow);
+    qt_interpreter_events * qt_link (void);
 
     void interpreter_event (const fcn_callback& fcn);
 
@@ -86,11 +82,9 @@
 
   private:
 
-    base_qobject *m_octave_qobject;
+    base_qobject& m_octave_qobj;
 
     interpreter *m_interpreter;
-
-    std::shared_ptr<qt_interpreter_events> m_qt_link;
   };
 }
 
--- a/libgui/src/main-window.cc	Tue Oct 29 11:36:14 2019 -0400
+++ b/libgui/src/main-window.cc	Sat Oct 26 12:20:29 2019 -0400
@@ -99,8 +99,8 @@
 #endif
   }
 
-  main_window::main_window (base_qobject& qobj)
-    : QMainWindow (), m_octave_qobj (qobj), m_workspace_model (nullptr),
+  main_window::main_window (base_qobject& oct_qobj)
+    : QMainWindow (), m_octave_qobj (oct_qobj), m_workspace_model (nullptr),
       m_status_bar (nullptr), m_command_window (nullptr),
       m_history_window (nullptr), m_file_browser_window (nullptr),
       m_doc_browser_window (nullptr), m_editor_window (nullptr),
@@ -116,7 +116,7 @@
     if (resource_manager::is_first_run ())
       {
         // Before wizard.
-        qobj.config_translators ();
+        m_octave_qobj.config_translators ();
 
         welcome_wizard welcomeWizard;
 
@@ -132,7 +132,7 @@
         resource_manager::reload_settings ();
 
         // After settings.
-        qobj.config_translators ();
+        m_octave_qobj.config_translators ();
       }
 
     resource_manager::update_network_settings ();
@@ -253,6 +253,32 @@
     m_command_window->activate ();
   }
 
+  bool main_window::confirm_shutdown (void)
+  {
+    bool closenow = true;
+
+    QSettings *settings = resource_manager::get_settings ();
+
+    if (settings->value ("prompt_to_exit", false).toBool ())
+      {
+        int ans = QMessageBox::question (this, tr ("Octave"),
+                                         tr ("Are you sure you want to exit Octave?"),
+                                         (QMessageBox::Ok
+                                          | QMessageBox::Cancel),
+                                         QMessageBox::Ok);
+
+        if (ans != QMessageBox::Ok)
+          closenow = false;
+      }
+
+#if defined (HAVE_QSCINTILLA)
+    if (closenow)
+      closenow = m_editor_window->check_closing ();
+#endif
+
+    return closenow;
+  }
+
   // catch focus changes and determine the active dock widget
   void main_window::focus_changed (QWidget *, QWidget *new_widget)
   {
@@ -899,32 +925,6 @@
 
   }
 
-  bool main_window::confirm_shutdown_octave (void)
-  {
-    bool closenow = true;
-
-    QSettings *settings = resource_manager::get_settings ();
-
-    if (settings->value ("prompt_to_exit", false).toBool ())
-      {
-        int ans = QMessageBox::question (this, tr ("Octave"),
-                                         tr ("Are you sure you want to exit Octave?"),
-                                         (QMessageBox::Ok
-                                          | QMessageBox::Cancel),
-                                         QMessageBox::Ok);
-
-        if (ans != QMessageBox::Ok)
-          closenow = false;
-      }
-
-#if defined (HAVE_QSCINTILLA)
-    if (closenow)
-      closenow = m_editor_window->check_closing ();
-#endif
-
-    return closenow;
-  }
-
   void main_window::prepare_to_exit (void)
   {
     // Find files dialog is constructed dynamically, not at time of main_window
@@ -1892,15 +1892,27 @@
 
   void main_window::closeEvent (QCloseEvent *e)
   {
-    e->ignore ();
-
-    emit interpreter_event
-      ([] (interpreter& interp)
-       {
-         // INTERPRETER THREAD
-
-         Fquit (interp);
-       });
+    if (confirm_shutdown ())
+      {
+        // FIXME: Instead of ignoring the event and posting an
+        // interpreter event, should we just accept the event and
+        // shutdown and clean up the interprter as part of closing the
+        // GUI?  Going that route might make it easier to close the GUI
+        // without having to stop the interpreter, for example, if the
+        // GUI is started from the interpreter command line.
+
+        e->ignore ();
+
+        emit interpreter_event
+          ([] (interpreter& interp)
+           {
+             // INTERPRETER THREAD
+
+             interp.quit (0, false, false);
+           });
+      }
+    else
+      e->ignore ();
   }
 
   void main_window::construct_central_widget (void)
--- a/libgui/src/main-window.h	Tue Oct 29 11:36:14 2019 -0400
+++ b/libgui/src/main-window.h	Sat Oct 26 12:20:29 2019 -0400
@@ -79,7 +79,7 @@
     typedef std::pair <std::string, std::string> name_pair;
     typedef std::pair <int, int> int_pair;
 
-    main_window (base_qobject& qapp);
+    main_window (base_qobject& oct_qobj);
 
     ~main_window (void);
 
@@ -87,6 +87,8 @@
 
     void focus_command_window (void);
 
+    bool confirm_shutdown (void);
+
   signals:
 
     void active_dock_changed (octave_dock_widget *, octave_dock_widget *);
@@ -151,7 +153,6 @@
 
     void show_about_octave (void);
     void notice_settings (const QSettings *settings);
-    bool confirm_shutdown_octave (void);
     void prepare_to_exit (void);
     void reset_windows (void);
 
--- a/libgui/src/octave-qobject.cc	Tue Oct 29 11:36:14 2019 -0400
+++ b/libgui/src/octave-qobject.cc	Sat Oct 26 12:20:29 2019 -0400
@@ -103,7 +103,8 @@
       m_qapplication (new octave_qapplication (m_argc, m_argv)),
       m_qt_tr (new QTranslator ()), m_gui_tr (new QTranslator ()),
       m_qsci_tr (new QTranslator ()), m_translators_installed (false),
-      m_interpreter_qobj (new interpreter_qobject (this)),
+      m_qt_interpreter_events (new qt_interpreter_events (*this)),
+      m_interpreter_qobj (new interpreter_qobject (*this)),
       m_main_thread (new QThread ())
   {
     std::string show_gui_msgs =
@@ -161,6 +162,10 @@
 
     connect (m_qapplication, SIGNAL (interpreter_event (const meth_callback&)),
              this, SLOT (interpreter_event (const meth_callback&)));
+
+    connect (qt_link (),
+             SIGNAL (copy_image_to_clipboard_signal (const QString&, bool)),
+             this, SLOT (copy_image_to_clipboard (const QString&, bool)));
   }
 
   base_qobject::~base_qobject (void)
@@ -256,6 +261,11 @@
     return m_qapplication->exec ();
   }
 
+  bool base_qobject::confirm_shutdown (void)
+  {
+    return true;
+  }
+
   void base_qobject::handle_octave_finished (int exit_status)
   {
 #if defined (Q_OS_MAC)
@@ -292,11 +302,6 @@
     m_interpreter_qobj->interpreter_event (meth);
   }
 
-  void base_qobject::confirm_shutdown_octave (void)
-  {
-    m_interpreter_qobj->confirm_shutdown (true);
-  }
-
   void base_qobject::copy_image_to_clipboard (const QString& file,
                                               bool remove_file)
   {
@@ -346,13 +351,8 @@
     delete m_main_window;
   }
 
-  void gui_qobject::confirm_shutdown_octave (void)
+  bool gui_qobject::confirm_shutdown (void)
   {
-    bool closenow = true;
-
-    if (m_main_window)
-      closenow = m_main_window->confirm_shutdown_octave ();
-
-    m_interpreter_qobj->confirm_shutdown (closenow);
+    return m_main_window ? m_main_window->confirm_shutdown () : true;
   }
 }
--- a/libgui/src/octave-qobject.h	Tue Oct 29 11:36:14 2019 -0400
+++ b/libgui/src/octave-qobject.h	Sat Oct 26 12:20:29 2019 -0400
@@ -24,6 +24,8 @@
 #if ! defined (octave_octave_qobject_h)
 #define octave_octave_qobject_h 1
 
+#include <memory>
+
 #include <QApplication>
 #include <QList>
 #include <QObject>
@@ -36,6 +38,7 @@
 {
   class main_window;
   class qt_application;
+  class qt_interpreter_events;
 
   //! This class is a simple wrapper around QApplication so that we can
   //! reimplement QApplication::notify.  The octave_qapplication object
@@ -91,6 +94,16 @@
     // The Qt QApplication.
     QApplication * qapplication (void) { return m_qapplication; };
 
+    std::shared_ptr<qt_interpreter_events> get_qt_interpreter_events (void)
+    {
+      return m_qt_interpreter_events;
+    }
+
+    qt_interpreter_events * qt_link (void)
+    {
+      return m_qt_interpreter_events.get ();
+    }
+
     interpreter_qobject * interpreter_qobj (void)
     {
       return m_interpreter_qobj;
@@ -98,18 +111,18 @@
 
     QThread *main_thread (void) { return m_main_thread; }
 
+    virtual bool confirm_shutdown (void);
+
   public slots:
 
     void handle_octave_finished (int);
 
-    virtual void confirm_shutdown_octave (void);
-
-    void copy_image_to_clipboard (const QString& file, bool remove_file);
-
     void interpreter_event (const fcn_callback& fcn);
 
     void interpreter_event (const meth_callback& meth);
 
+    void copy_image_to_clipboard (const QString& file, bool remove_file);
+
   protected:
 
     qt_application& m_app_context;
@@ -128,6 +141,8 @@
 
     bool m_translators_installed;
 
+    std::shared_ptr<qt_interpreter_events> m_qt_interpreter_events;
+
     interpreter_qobject *m_interpreter_qobj;
 
     QThread *m_main_thread;
@@ -160,9 +175,7 @@
 
     ~gui_qobject (void);
 
-  public slots:
-
-    void confirm_shutdown_octave (void);
+    bool confirm_shutdown (void);
 
   private:
 
--- a/libgui/src/qt-interpreter-events.cc	Tue Oct 29 11:36:14 2019 -0400
+++ b/libgui/src/qt-interpreter-events.cc	Sat Oct 26 12:20:29 2019 -0400
@@ -33,6 +33,7 @@
 #include <QStringList>
 
 #include "dialog.h"
+#include "octave-qobject.h"
 #include "qt-interpreter-events.h"
 #include "resource-manager.h"
 
@@ -100,9 +101,10 @@
     return retval;
   }
 
-  qt_interpreter_events::qt_interpreter_events (void)
-    : interpreter_events (), m_shutdown_confirm_result (false),
-      m_mutex (), m_waitcondition (), m_uiwidget_creator ()
+  qt_interpreter_events::qt_interpreter_events (base_qobject& oct_qobj)
+    : interpreter_events (), m_octave_qobj (oct_qobj),
+      m_shutdown_confirm_result (false), m_mutex (),
+      m_waitcondition (), m_uiwidget_creator ()
   {
     qRegisterMetaType<QIntList> ("QIntList");
     qRegisterMetaType<QFloatList> ("QFloatList");
@@ -112,6 +114,9 @@
 
     qRegisterMetaType<fcn_callback> ("fcn_callback");
     qRegisterMetaType<meth_callback> ("meth_callback");
+
+    connect (this, SIGNAL (confirm_shutdown_signal (void)),
+             this, SLOT (confirm_shutdown_octave (void)));
   }
 
   std::list<std::string>
@@ -248,7 +253,7 @@
 
     emit confirm_shutdown_signal ();
 
-    // Wait while the GUI shuts down.
+    // Wait for result.
     wait ();
 
     // The GUI has sent a signal and the thread has been awakened.
@@ -513,4 +518,16 @@
   {
     emit delete_debugger_pointer_signal (QString::fromStdString (file), line);
   }
+
+  void
+  qt_interpreter_events::confirm_shutdown_octave (void)
+  {
+    lock ();
+
+    m_shutdown_confirm_result = m_octave_qobj.confirm_shutdown ();
+
+    unlock ();
+
+    wake_all ();
+  }
 }
--- a/libgui/src/qt-interpreter-events.h	Tue Oct 29 11:36:14 2019 -0400
+++ b/libgui/src/qt-interpreter-events.h	Sat Oct 26 12:20:29 2019 -0400
@@ -45,6 +45,8 @@
 
 namespace octave
 {
+  class base_qobject;
+
   // The functions in this class are not normally called directly, but
   // are invoked from the Octave interpreter thead by methods in the
   // event_manager class.  In most cases, they should only translate
@@ -67,7 +69,7 @@
 
   public:
 
-    qt_interpreter_events (void);
+    qt_interpreter_events (base_qobject& oct_qobj);
 
     // No copying!
 
@@ -166,8 +168,6 @@
     void update_breakpoint (bool insert, const std::string& file, int line,
                             const std::string& cond);
 
-    void shutdown_confirmation (bool sd) { m_shutdown_confirm_result = sd; }
-
     void lock (void) { m_mutex.lock (); }
 
     void wait (void) { m_waitcondition.wait (&m_mutex); }
@@ -176,12 +176,18 @@
 
     void wake_all (void) { m_waitcondition.wakeAll (); }
 
+  public slots:
+
+    void confirm_shutdown_octave (void);
+
   private:
 
     void insert_debugger_pointer (const std::string& file, int line);
 
     void delete_debugger_pointer (const std::string& file, int line);
 
+    base_qobject& m_octave_qobj;
+
     bool m_shutdown_confirm_result;
 
     QMutex m_mutex;
--- a/libinterp/corefcn/interpreter.cc	Tue Oct 29 11:36:14 2019 -0400
+++ b/libinterp/corefcn/interpreter.cc	Sat Oct 26 12:20:29 2019 -0400
@@ -1740,7 +1740,7 @@
     m_tmp_files.cleanup ();
   }
 
-  void interpreter::quit (int exit_status, bool force)
+  void interpreter::quit (int exit_status, bool force, bool confirm)
   {
     if (! force)
       {
@@ -1766,7 +1766,7 @@
 
             // Check for confirmation.
 
-            if (! m_event_manager.confirm_shutdown ())
+            if (confirm && ! m_event_manager.confirm_shutdown ())
               return;
           }
         catch (const execution_exception& ee)
--- a/libinterp/corefcn/interpreter.h	Tue Oct 29 11:36:14 2019 -0400
+++ b/libinterp/corefcn/interpreter.h	Sat Oct 26 12:20:29 2019 -0400
@@ -437,7 +437,7 @@
 
     void cleanup_tmp_files (void);
 
-    void quit (int exit_status, bool force = false);
+    void quit (int exit_status, bool force = false, bool confirm = true);
 
     void cancel_quit (bool flag) { m_cancel_quit = flag; }