changeset 29754:4c569e386e9b

improve behavior of dockable widgets (bug #60750) * main-window.h, main-window.cc (main_window::set_window_layout): Don't reset geometry of adopted dock_widgets. (main_window::construct): Don't connect qt_link edit_variable_signal to main_window edit_variable slot. (main_window::reset_windows): Force reset of all windows. (main_window::do_reset_windows): New argument, FORCE_ALL. Skip adoped dock_widgets unless force_all is true. * octave-dock-widget.h, octave-dock-widget.cc (octave_dock_widget::make_widget): If m_main_window is nonnull, set m_adopted to false. Disconnect any existing m_dock_action signals that are connected to the octave_dock_widget object before connecting the m_dock_action triggered signal to the octave_dock_widget make_window slot. (octave_dock_widget::m_adopted): New data member. (octave_dock_widget::set_adopted, (octave_dock_widget::adopted): New functions. * octave-qobject.h, octave-qobject.cc (base_qobject::documentation_widget, base_qobject::file_browser_widget, base_qobject::history_widget, base_qobject::workspace_widget, base_qobject::variable_editor_widget): Call set_main_window and set_adopted for widget if it already exists and main_window argument is nonnull. Otherwise, create widget if it doesn't already exist. (base_qobject::show_variable_editor_window): Rename slot from edit_variable. Change all uses. Acquire pointer to widget and forward to the widget's edit_variable method. * variable-editor.cc (variable_editor::variable_editor): Call make_window if parent is nullptr. (variable_editor::edit_variable): Don't call make_window.
author John W. Eaton <jwe@octave.org>
date Mon, 14 Jun 2021 12:39:51 -0400
parents 48382b9025a5
children 23cf249a0ad8
files libgui/src/main-window.cc libgui/src/main-window.h libgui/src/octave-dock-widget.cc libgui/src/octave-dock-widget.h libgui/src/octave-qobject.cc libgui/src/octave-qobject.h libgui/src/variable-editor.cc
diffstat 7 files changed, 119 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/main-window.cc	Mon Jun 14 10:42:08 2021 -0400
+++ b/libgui/src/main-window.cc	Mon Jun 14 12:39:51 2021 -0400
@@ -1639,8 +1639,15 @@
       }
 
     // Restore the geometry of all dock-widgets
+
     for (auto *widget : dock_widget_list ())
       {
+        // Leave any widgets that existed before main_window was created
+        // as they were.
+
+        if (widget->adopted ())
+          continue;
+
         QString name = widget->objectName ();
 
         if (! name.isEmpty ())
@@ -2109,9 +2116,6 @@
 
     qt_interpreter_events *qt_link = interp_qobj->qt_link ();
 
-    connect (qt_link, &qt_interpreter_events::edit_variable_signal,
-             this, &main_window::edit_variable);
-
     connect (qt_link, &qt_interpreter_events::refresh_variable_editor_signal,
              this, &main_window::refresh_variable_editor);
 
@@ -2970,16 +2974,18 @@
     // Slot for resetting the window layout to the default one
     hide ();
     showNormal ();              // Unmaximize
-    do_reset_windows (false);   // Add all widgets
+    do_reset_windows (false, true, true);   // Add all widgets
+
+    // FIXME: WHAT?!?
     // Re-add after giving time: This seems to be a reliable way to
     // reset the main window's layout
-    QTimer::singleShot (250, this, [=] () { do_reset_windows (); });
+    QTimer::singleShot (250, this, [=] () { do_reset_windows (false, true, true); });
   }
 
   // Create the default layout of the main window. Do not use
   // restoreState () and restoreGeometry () with default values since
   // this might lead to problems when the Qt version changes
-  void main_window::do_reset_windows (bool show, bool save)
+  void main_window::do_reset_windows (bool show, bool save, bool force_all)
   {
     // Set main window default geometry and store its width for
     // later resizing the command window
@@ -3001,17 +3007,46 @@
 #endif
 
     // Add the dock widgets and show them
-    addDockWidget (Qt::LeftDockWidgetArea, m_file_browser_window);
-    addDockWidget (Qt::LeftDockWidgetArea, m_workspace_window);
-    addDockWidget (Qt::LeftDockWidgetArea, m_history_window);
-
-    addDockWidget (Qt::RightDockWidgetArea, m_command_window);
-
-    addDockWidget (Qt::RightDockWidgetArea, m_doc_browser_window);
-    tabifyDockWidget (m_command_window, m_doc_browser_window);
-
-    addDockWidget (Qt::RightDockWidgetArea, m_variable_editor_window);
-    tabifyDockWidget (m_command_window, m_variable_editor_window);
+    if (! m_file_browser_window->adopted () || force_all)
+      {
+        // FIXME: Maybe there should be a main_window::add_dock_widget
+        // function that combines both of these actions?
+
+        addDockWidget (Qt::LeftDockWidgetArea, m_file_browser_window);
+        m_file_browser_window->set_adopted (false);
+      }
+
+    if (! m_workspace_window->adopted () || force_all)
+      {
+        addDockWidget (Qt::LeftDockWidgetArea, m_workspace_window);
+        m_workspace_window->set_adopted (false);
+      }
+
+    if (! m_history_window->adopted () || force_all)
+      {
+        addDockWidget (Qt::LeftDockWidgetArea, m_history_window);
+        m_history_window->set_adopted (false);
+      }
+
+    if (! m_command_window->adopted () || force_all)
+      {
+        addDockWidget (Qt::RightDockWidgetArea, m_command_window);
+        m_command_window->set_adopted (false);
+      }
+
+    if (! m_doc_browser_window->adopted () || force_all)
+      {
+        addDockWidget (Qt::RightDockWidgetArea, m_doc_browser_window);
+        tabifyDockWidget (m_command_window, m_doc_browser_window);
+        m_doc_browser_window->set_adopted (false);
+      }
+
+    if (! m_variable_editor_window->adopted () || force_all)
+      {
+        addDockWidget (Qt::RightDockWidgetArea, m_variable_editor_window);
+        tabifyDockWidget (m_command_window, m_variable_editor_window);
+        m_variable_editor_window->set_adopted (false);
+      }
 
 #if defined (HAVE_QSCINTILLA)
     addDockWidget (Qt::RightDockWidgetArea, m_editor_window);
--- a/libgui/src/main-window.h	Mon Jun 14 10:42:08 2021 -0400
+++ b/libgui/src/main-window.h	Mon Jun 14 12:39:51 2021 -0400
@@ -165,7 +165,8 @@
     void prepare_to_exit (void);
     void go_to_previous_widget (void);
     void reset_windows (void);
-    void do_reset_windows (bool show = true, bool save = true);
+    void do_reset_windows (bool show = true, bool save = true,
+                           bool force_all = false);
 
     void update_octave_directory (const QString& dir);
     void browse_for_directory (void);
--- a/libgui/src/octave-dock-widget.cc	Mon Jun 14 10:42:08 2021 -0400
+++ b/libgui/src/octave-dock-widget.cc	Mon Jun 14 12:39:51 2021 -0400
@@ -184,7 +184,8 @@
 
   octave_dock_widget::octave_dock_widget (const QString& obj_name, QWidget *p,
                                           base_qobject& oct_qobj)
-    : label_dock_widget (p, oct_qobj), m_focus_follows_mouse (false),
+    : label_dock_widget (p, oct_qobj), m_adopted (false),
+      m_custom_style (false), m_focus_follows_mouse (false),
       m_recent_float_geom (), m_recent_dock_geom (),
       m_waiting_for_mouse_button_release (false)
   {
@@ -345,11 +346,13 @@
     if (m_main_window)
       {
         settings->setValue (mw_state.key, m_main_window->saveState ());
+
         // Stay window, otherwise will bounce back to window by default
         // because there is no layout information for this widget in the
         // saved settings.
         setParent (m_main_window, Qt::Window);
         m_main_window->addDockWidget (Qt::BottomDockWidgetArea, this);
+        m_adopted = false;
         // recover old window states, hide and re-show new added widget
         m_main_window->restoreState (settings->value (mw_state.key).toByteArray ());
         setFloating (false);
@@ -360,6 +363,7 @@
       }
 
     // adjust the (un)dock icon
+    disconnect (m_dock_action, 0, this, 0);
     connect (m_dock_action, &QAction::triggered,
              this, &octave_dock_widget::make_window);
     if (titleBarWidget ())
--- a/libgui/src/octave-dock-widget.h	Mon Jun 14 10:42:08 2021 -0400
+++ b/libgui/src/octave-dock-widget.h	Mon Jun 14 12:39:51 2021 -0400
@@ -98,6 +98,9 @@
 
     void set_main_window (main_window *mw);
 
+    void set_adopted (bool adopted = true) { m_adopted = adopted; }
+    bool adopted (void) const { return m_adopted; }
+
   signals:
 
     //! Custom signal that tells whether a user has clicked away that dock
@@ -168,6 +171,7 @@
 
     main_window *m_main_window;
 
+    bool m_adopted;
     bool m_custom_style;
     bool m_focus_follows_mouse;
     int m_title_3d;
--- a/libgui/src/octave-qobject.cc	Mon Jun 14 10:42:08 2021 -0400
+++ b/libgui/src/octave-qobject.cc	Mon Jun 14 12:39:51 2021 -0400
@@ -262,7 +262,7 @@
              this, &base_qobject::show_workspace_window);
 
     connect (qt_link (), &qt_interpreter_events::edit_variable_signal,
-             this, &base_qobject::edit_variable);
+             this, &base_qobject::show_variable_editor_window);
 
     if (m_app_context.experimental_terminal_widget ())
       {
@@ -386,9 +386,12 @@
   QPointer<documentation_dock_widget>
   base_qobject::documentation_widget (main_window *mw)
   {
-    if (m_documentation_widget)
-      m_documentation_widget->set_main_window (mw);
-    else
+    if (m_documentation_widget && mw)
+      {
+        m_documentation_widget->set_main_window (mw);
+        m_documentation_widget->set_adopted (true);
+      }
+    else if (! m_documentation_widget)
       {
         m_documentation_widget
           = QPointer<documentation_dock_widget> (new documentation_dock_widget (mw, *this));
@@ -411,8 +414,11 @@
   base_qobject::file_browser_widget (main_window *mw)
   {
     if (m_file_browser_widget)
-      m_file_browser_widget->set_main_window (mw);
-    else
+      {
+        m_file_browser_widget->set_main_window (mw);
+        m_file_browser_widget->set_adopted (true);
+      }
+    else if (! m_file_browser_widget)
       m_file_browser_widget
         = QPointer<files_dock_widget> (new files_dock_widget (mw, *this));
 
@@ -423,8 +429,11 @@
   base_qobject::history_widget (main_window *mw)
   {
     if (m_history_widget)
-      m_history_widget->set_main_window (mw);
-    else
+      {
+        m_history_widget->set_main_window (mw);
+        m_history_widget->set_adopted (true);
+      }
+    else if (! m_history_widget)
       {
         m_history_widget
           = QPointer<history_dock_widget> (new history_dock_widget (mw, *this));
@@ -448,8 +457,11 @@
   base_qobject::workspace_widget (main_window *mw)
   {
     if (m_workspace_widget)
-      m_workspace_widget->set_main_window (mw);
-    else
+      {
+        m_workspace_widget->set_main_window (mw);
+        m_workspace_widget->set_adopted (true);
+      }
+    else if (! m_workspace_widget)
       {
         m_workspace_widget
           = QPointer<workspace_view> (new workspace_view (mw, *this));
@@ -473,9 +485,12 @@
   base_qobject::editor_widget (main_window */*mw*/)
   {
 #if 0
-    if (m_editor_widget)
-      m_editor_widget->set_main_window (mw);
-    else
+    if (m_editor_widget && mw)
+      {
+        m_editor_widget->set_main_window (mw);
+        m_editor_widget->set_adopted (true);
+      }
+    else if (! m_editor_widget)
       m_editor_widget = new file_editor (mw, *this);
 #endif
 
@@ -485,9 +500,12 @@
   QPointer<variable_editor>
   base_qobject::variable_editor_widget (main_window *mw)
   {
-    if (m_variable_editor_widget)
-      m_variable_editor_widget->set_main_window (mw);
-    else
+    if (m_variable_editor_widget && mw)
+      {
+        m_variable_editor_widget->set_main_window (mw);
+        m_variable_editor_widget->set_adopted (true);
+      }
+    else if (! m_variable_editor_widget)
       m_variable_editor_widget
         = QPointer<variable_editor> (new variable_editor (mw, *this));
 
@@ -543,7 +561,9 @@
 
   void base_qobject::show_documentation_window (const QString& file)
   {
-    documentation_dock_widget *widget = documentation_widget ();
+    documentation_dock_widget *widget
+      = (m_documentation_widget
+         ? m_documentation_widget : documentation_widget ());
 
     widget->showDoc (file);
 
@@ -556,7 +576,8 @@
 
   void base_qobject::show_file_browser_window (void)
   {
-    files_dock_widget *widget = file_browser_widget ();
+    files_dock_widget *widget
+      = m_file_browser_widget ? m_file_browser_widget : file_browser_widget ();
 
     if (! widget->isVisible ())
       {
@@ -567,7 +588,8 @@
 
   void base_qobject::show_command_history_window (void)
   {
-    history_dock_widget *widget = history_widget ();
+    history_dock_widget *widget
+      = m_history_widget ? m_history_widget : history_widget ();
 
     if (! widget->isVisible ())
       {
@@ -578,7 +600,8 @@
 
   void base_qobject::show_workspace_window (void)
   {
-    workspace_view *widget = workspace_widget ();
+    workspace_view *widget
+      = m_workspace_widget ? m_workspace_widget : workspace_widget ();
 
     if (! widget->isVisible ())
       {
@@ -587,28 +610,21 @@
       }
   }
 
-  void base_qobject::edit_variable (const QString& expr,
-                                    const octave_value& val)
+  void base_qobject::show_variable_editor_window (const QString& name,
+                                                  const octave_value& value)
   {
-    variable_editor *widget = variable_editor_widget ();
-
-#if 0
-    // FIXME: This connection needs to be made whether running with the
-    // GUI main window or not, but only needs to be made once.
-    // Currently we have handle_variable_editor_update methods here and
-    // in the main_window object.
-
-    connect (widget, &variable_editor::updated,
-             this, &base_qobject::handle_variable_editor_update);
-#endif
-
-    widget->edit_variable (expr, val);
+    variable_editor *widget
+      = (m_variable_editor_widget
+         ? m_variable_editor_widget : variable_editor_widget ());
 
     if (! widget->isVisible ())
       {
         widget->show ();
         widget->raise ();
       }
+
+    // FIXME: Should this be done with a signal/slot connection?
+    widget->edit_variable (name, value);
   }
 
   void base_qobject::handle_variable_editor_update (void)
--- a/libgui/src/octave-qobject.h	Mon Jun 14 10:42:08 2021 -0400
+++ b/libgui/src/octave-qobject.h	Mon Jun 14 12:39:51 2021 -0400
@@ -196,7 +196,8 @@
 
     void show_workspace_window (void);
 
-    void edit_variable (const QString& expr, const octave_value& val);
+    void show_variable_editor_window (const QString& name,
+                                      const octave_value& value);
 
     void handle_variable_editor_update (void);
 
--- a/libgui/src/variable-editor.cc	Mon Jun 14 10:42:08 2021 -0400
+++ b/libgui/src/variable-editor.cc	Mon Jun 14 12:39:51 2021 -0400
@@ -1147,6 +1147,9 @@
     m_main->setCentralWidget (central_mdiarea);
 
     setWidget (m_main);
+
+    if (! p)
+      make_window ();
   }
 
   void variable_editor::focusInEvent (QFocusEvent *ev)
@@ -1366,8 +1369,6 @@
           m_tool_bar->setEnabled (true);
       }
 
-    make_window ();
-
     show ();
     page->show ();
     page->raise ();