changeset 25745:d3c6de326bae

close/reload editor tab when file is (re)moved in gui terminal (bug #43922) * file-editor.cc (handle_file_remove): new code structure * main-window.cc (construct): connect new signals from octave_qt_link to the slot handle_file_renamed and the new proxy slot file_remove_proxy; (file_remove_proxy): proxy calling handle_file_remove but protected by the mutex of octave_qt_link synchronizing worker and gui thread * main-window.h: new slot file_remove_proxy * octave-qt-link.cc (do_file_remove): new method for renaming or removing files which signals the editor (gui thread) for closing the files before removing is carried out; (do_file_renamed): new method for re-loading renamed files into editor; * octave-qt-link.h: new methods do_file_remove and do_file_renamed, new signals used in the new methods for signaling the editor slots * dirfns.cc (rmdir): call the new static octave_link method for removing a file, which might be opened in the editor before removing a dir; (rename): call the new static octave_link method for renaming a file, which might be opened in the editor before renaming it and call the method for reloading the new renamed file; * octave-link.h (file_remove): new static method calling purely virtual method do_file_remove, which is implemented in octave_qt_link; (file_renamed): new static method calling purely virtual method do_file_renamed, which is implemented in octave_qt_link * syscalls.cc (unlink): call the new static octave_link method for removing a file, which might be opened in the editor before removing it
author Torsten <mttl@mailbox.org>
date Sun, 17 Sep 2017 05:52:33 +0200
parents a3f2b06c599a
children c2a703df0215
files libgui/src/m-editor/file-editor-interface.h libgui/src/m-editor/file-editor.cc libgui/src/main-window.cc libgui/src/main-window.h libgui/src/octave-qt-link.cc libgui/src/octave-qt-link.h libinterp/corefcn/dirfns.cc libinterp/corefcn/octave-link.h libinterp/corefcn/syscalls.cc
diffstat 9 files changed, 121 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/m-editor/file-editor-interface.h	Sat Aug 04 13:35:29 2018 +0200
+++ b/libgui/src/m-editor/file-editor-interface.h	Sun Sep 17 05:52:33 2017 +0200
@@ -73,6 +73,8 @@
 
   public slots:
 
+    virtual void handle_file_remove (const QString& o, const QString& n) = 0;
+
     virtual void request_new_file (const QString& command = QString ()) = 0;
 
     virtual void request_open_file (const QString& openFileName,
--- a/libgui/src/m-editor/file-editor.cc	Sat Aug 04 13:35:29 2018 +0200
+++ b/libgui/src/m-editor/file-editor.cc	Sun Sep 17 05:52:33 2017 +0200
@@ -934,35 +934,36 @@
       {
         // Call the function which handles directories and return
         handle_dir_remove (old_name, new_name);
-        return;
       }
-
-    // Is old file open?
-    file_editor_tab *editor_tab
-      = static_cast<file_editor_tab *> (find_tab_widget (old_name));
-
-    if (editor_tab)
+    else
       {
-        // Yes, close it silently
-        m_no_focus = true;  // Remember for not focussing editor
-        editor_tab->file_has_changed (QString (), true);  // Close the tab
-        m_no_focus = false;  // Back to normal
-
-        m_tmp_closed_files << old_name;  // for reloading if error removing
-
-        if (! new_name.isEmpty ())
-          m_tmp_closed_files << new_name;  // store new name
-        else
-          m_tmp_closed_files << ""; // no new name, just removing this file
-
-        // Get and store the related encoding
-        for (auto p = m_editor_tab_map.cbegin ();
-             p != m_editor_tab_map.cend (); p++)
+        // It is a single file. IT is open?
+        file_editor_tab *editor_tab
+          = static_cast<file_editor_tab *> (find_tab_widget (old_name));
+
+        if (editor_tab)
           {
-            if (editor_tab == p->second.fet_ID)
+            // Yes, close it silently
+            m_no_focus = true;  // Remember for not focussing editor
+            editor_tab->file_has_changed (QString (), true);  // Close the tab
+            m_no_focus = false;  // Back to normal
+
+            m_tmp_closed_files << old_name;  // for reloading if error removing
+
+            if (! new_name.isEmpty ())
+              m_tmp_closed_files << new_name;  // store new name
+            else
+              m_tmp_closed_files << ""; // no new name, just removing this file
+
+            // Get and store the related encoding
+            for (editor_tab_map_const_iterator p = m_editor_tab_map.begin ();
+                  p != m_editor_tab_map.end (); p++)
               {
-                m_tmp_closed_files << p->second.encoding;
-                break;
+                if (editor_tab == p->second.fet_ID)
+                  {
+                    m_tmp_closed_files << p->second.encoding;
+                    break;
+                  }
               }
           }
       }
--- a/libgui/src/main-window.cc	Sat Aug 04 13:35:29 2018 +0200
+++ b/libgui/src/main-window.cc	Sun Sep 17 05:52:33 2017 +0200
@@ -462,6 +462,19 @@
     handle_edit_mfile_request (name, QString (), QString (), line);
   }
 
+  void main_window::file_remove_proxy (const QString& o, const QString& n)
+  {
+    // Wait for worker to suspend
+    m_octave_qt_link->lock ();
+
+    // Close the file if opened
+    m_editor_window->handle_file_remove (o, n);
+
+    // We are done: Unlock and wake the worker thread
+    m_octave_qt_link->unlock ();
+    m_octave_qt_link->wake_all ();
+  }
+
   void main_window::open_online_documentation_page (void)
   {
     QDesktopServices::openUrl (
@@ -1932,6 +1945,7 @@
                                                                 int,
                                                                 const QString&)));
 
+        // Signals for removing/renaming files/dirs in the file browser
         connect (m_file_browser_window,
                  SIGNAL (file_remove_signal (const QString&, const QString&)),
                  m_editor_window,
@@ -1939,6 +1953,13 @@
 
         connect (m_file_browser_window, SIGNAL (file_renamed_signal (bool)),
                  m_editor_window, SLOT (handle_file_renamed (bool)));
+
+        // Signals for removing/renaming files/dirs in the temrinal window
+        connect (m_octave_qt_link,
+                 SIGNAL (file_remove_signal (const QString&, const QString&)),
+                 this, SLOT (file_remove_proxy (const QString&, const QString&)));
+        connect (m_octave_qt_link, SIGNAL (file_renamed_signal (bool)),
+                 m_editor_window, SLOT (handle_file_renamed (bool)));
 #endif
 
         octave_link::post_event (this,
--- a/libgui/src/main-window.h	Sat Aug 04 13:35:29 2018 +0200
+++ b/libgui/src/main-window.h	Sun Sep 17 05:52:33 2017 +0200
@@ -155,6 +155,7 @@
     void new_file (const QString& commands = QString ());
     void open_file (const QString& file_name = QString (), int line = -1);
     void edit_mfile (const QString&, int);
+    void file_remove_proxy (const QString& o, const QString& n);
     void open_online_documentation_page (void);
     void display_release_notes (void);
     void load_and_display_community_news (int serial = -1);
--- a/libgui/src/octave-qt-link.cc	Sat Aug 04 13:35:29 2018 +0200
+++ b/libgui/src/octave-qt-link.cc	Sun Sep 17 05:52:33 2017 +0200
@@ -405,6 +405,26 @@
     emit change_directory_signal (QString::fromStdString (dir));
   }
 
+  void octave_qt_link::do_file_remove (const std::string& old_name,
+                                       const std::string& new_name)
+  {
+    // Lock the mutex before signaling
+    lock ();
+
+    // Emit the signal for the editor for closing the file if it is open
+    emit file_remove_signal (QString::fromStdString (old_name),
+                             QString::fromStdString (new_name));
+
+    // Wait for the GUI and unlock when resumed
+    wait ();
+    unlock ();
+  }
+
+  void octave_qt_link::do_file_renamed (bool load_new)
+  {
+    emit file_renamed_signal (load_new);
+  }
+
   void octave_qt_link::do_execute_command_in_terminal
     (const std::string& command)
   {
--- a/libgui/src/octave-qt-link.h	Sat Aug 04 13:35:29 2018 +0200
+++ b/libgui/src/octave-qt-link.h	Sun Sep 17 05:52:33 2017 +0200
@@ -112,6 +112,10 @@
 
     void do_change_directory (const std::string& dir);
 
+    void do_file_remove (const std::string& old_name,
+                         const std::string& new_name);
+    void do_file_renamed (bool load_new = true);
+
     void do_execute_command_in_terminal (const std::string& command);
 
     void do_set_workspace (bool top_level, bool debug,
@@ -173,6 +177,9 @@
 
     void change_directory_signal (const QString& dir);
 
+    void file_remove_signal (const QString& old_name, const QString& new_name);
+    void file_renamed_signal (bool load_new);
+
     void execute_command_in_terminal_signal (const QString& command);
 
     void set_workspace_signal (bool top_level, bool debug,
--- a/libinterp/corefcn/dirfns.cc	Sat Aug 04 13:35:29 2018 +0200
+++ b/libinterp/corefcn/dirfns.cc	Sun Sep 17 05:52:33 2017 +0200
@@ -298,10 +298,18 @@
         }
 
       if (doit)
-        status = octave::sys::recursive_rmdir (fulldir, msg);
+        {
+          octave_link::file_remove (fulldir, "");
+          status = octave::sys::recursive_rmdir (fulldir, msg);
+        }
     }
   else
-    status = octave::sys::rmdir (fulldir, msg);
+    {
+      octave_link::file_remove (fulldir, "");
+      status = octave::sys::rmdir (fulldir, msg);
+    }
+
+  octave_link::file_renamed (status >= 0);
 
   if (status < 0)
     return ovl (false, msg, "rmdir");
@@ -424,12 +432,20 @@
 
   std::string msg;
 
+  octave_link::file_remove (from, to);
+
   int status = octave::sys::rename (from, to, msg);
 
   if (status < 0)
-    return ovl (-1.0, msg);
+    {
+      octave_link::file_renamed (false);
+      return ovl (-1.0, msg);
+    }
   else
-    return ovl (status, "");
+    {
+      octave_link::file_renamed (true);
+      return ovl (status, "");
+    }
 }
 
 DEFUN (glob, args, ,
--- a/libinterp/corefcn/octave-link.h	Sat Aug 04 13:35:29 2018 +0200
+++ b/libinterp/corefcn/octave-link.h	Sun Sep 17 05:52:33 2017 +0200
@@ -31,7 +31,7 @@
 #include <string>
 
 #include "oct-mutex.h"
-
+#include "octave.h"
 #include "event-queue.h"
 
 class octave_value;
@@ -221,6 +221,20 @@
       instance->do_change_directory (dir);
   }
 
+  // Methods for removing/renaming files which might be open in editor
+  static void file_remove (const std::string& old_name,
+                           const std::string& new_name)
+  {
+    if (octave::application::is_gui_running () && enabled ())
+      instance->do_file_remove (old_name, new_name);
+  }
+
+  static void file_renamed (bool load_new)
+  {
+    if (octave::application::is_gui_running () && enabled ())
+      instance->do_file_renamed (load_new);
+  }
+
   // Preserves pending input.
   static void execute_command_in_terminal (const std::string& command)
   {
@@ -516,6 +530,10 @@
 
   virtual void do_change_directory (const std::string& dir) = 0;
 
+  virtual void do_file_remove (const std::string& old_name,
+                               const std::string& new_name) = 0;
+  virtual void do_file_renamed (bool) = 0;
+
   virtual void do_execute_command_in_terminal (const std::string& command) = 0;
 
   virtual void
--- a/libinterp/corefcn/syscalls.cc	Sat Aug 04 13:35:29 2018 +0200
+++ b/libinterp/corefcn/syscalls.cc	Sun Sep 17 05:52:33 2017 +0200
@@ -42,7 +42,6 @@
 #include "oct-env.h"
 #include "oct-syscalls.h"
 #include "oct-uname.h"
-
 #include "defun.h"
 #include "error.h"
 #include "errwarn.h"
@@ -52,6 +51,7 @@
 #include "ovl.h"
 #include "oct-stdstrm.h"
 #include "oct-stream.h"
+#include "octave-link.h"
 #include "sysdep.h"
 #include "utils.h"
 #include "variables.h"
@@ -1088,8 +1088,12 @@
 
   std::string msg;
 
+  octave_link::file_remove (name, "");
+
   int status = octave::sys::unlink (name, msg);
 
+  octave_link::file_renamed (status == 0);
+
   return ovl (status, msg);
 }