changeset 20995:aab7a3c7168e

edit a file from an error message in the terminal (bug #35619) * QTerminal.cc (handleCustomContextMenuRequested): move slot for the context menu from header file, detect an error location by regular expressions; (edit_file): slot context menu entry for editing a file in an error message * QTerminal.h: new signal for editing a file from an error message, slot handleCustomContextMenuRequested moved into QTerminal.cc, new edit action in the context menu, new slot for context menu entry, connect new edit signal to related slot in the main window * file-editor-tab.cc (handle_context_menu_edit): only keep searching for an embedded function, move the rest of the search into the editor, called via a new signal; (goto_line): center the new line in all cases * file-editor-tab.h: new signal for editing an m-file * file-editor.cc (handle_edit_mfile_request): partly moved from file-editor-tab; (construct): connect new signals from file-editor-tab and from main window to the new slot for searching and editing an m-file * file-editor.h: new slot for searching and editing an m-file * main-window.cc (edit_mfile): new slot for editing an m-file, just emitting the signal for the editor * main-window.h: new slot and new signal for editing an m-file
author Torsten <ttl@justmail.de>
date Mon, 28 Dec 2015 16:44:10 +0100
parents dd1dcef1ee33
children 20bd3d4fabad
files libgui/qterminal/libqterminal/QTerminal.cc libgui/qterminal/libqterminal/QTerminal.h libgui/src/m-editor/file-editor-tab.cc libgui/src/m-editor/file-editor-tab.h libgui/src/m-editor/file-editor.cc libgui/src/m-editor/file-editor.h libgui/src/main-window.cc libgui/src/main-window.h
diffstat 8 files changed, 170 insertions(+), 85 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/qterminal/libqterminal/QTerminal.cc	Mon Dec 28 12:10:05 2015 +0100
+++ b/libgui/qterminal/libqterminal/QTerminal.cc	Mon Dec 28 16:44:10 2015 +0100
@@ -89,6 +89,53 @@
       }
   }
 
+// slot for the terminal's context menu
+void
+QTerminal::handleCustomContextMenuRequested (const QPoint& at)
+  {
+    QClipboard * cb = QApplication::clipboard ();
+    QString selected_text = selectedText();
+    bool has_selected_text = ! selected_text.isEmpty ();
+
+    _edit_action->setVisible (false);
+
+    if (has_selected_text)
+      {
+        QRegExp file ("(?:[ \\t]+)(\\S+) at line (\\d+) column (?:\\d+)");
+
+        int pos = file.indexIn (selected_text);
+
+        if (pos > -1)
+          {
+            QString file_name = file.cap (1);
+            QString line = file.cap (2);
+
+            _edit_action->setVisible (true);
+            _edit_action->setText (tr ("Edit %1 at line %2")
+                                   .arg (file_name).arg (line));
+
+            QStringList data;
+            data << file_name << line;
+            _edit_action->setData (data);
+          }
+      }
+
+    _paste_action->setEnabled (cb->text().length() > 0);
+    _copy_action->setEnabled (has_selected_text);
+
+    _contextMenu->exec (mapToGlobal (at));
+  }
+
+// slot for edit files in error messages
+void
+QTerminal::edit_file ()
+{
+  QString file = _edit_action->data ().toStringList ().at (0);
+  int line = _edit_action->data ().toStringList ().at (1).toInt ();
+
+  emit edit_mfile_request (file,line);
+}
+
 void
 QTerminal::notice_settings (const QSettings *settings)
 {
--- a/libgui/qterminal/libqterminal/QTerminal.h	Mon Dec 28 12:10:05 2015 +0100
+++ b/libgui/qterminal/libqterminal/QTerminal.h	Mon Dec 28 16:44:10 2015 +0100
@@ -94,6 +94,8 @@
 
   void interrupt_signal (void);
 
+  void edit_mfile_request (const QString&, int);
+
 public slots:
 
   virtual void copyClipboard (void) = 0;
@@ -102,15 +104,7 @@
 
   virtual void selectAll (void) = 0;
 
-  virtual void handleCustomContextMenuRequested (const QPoint& at)
-  {
-    QClipboard * cb = QApplication::clipboard ();
-
-    _paste_action->setEnabled (cb->text().length() > 0);
-    _copy_action->setEnabled (selectedText().length() > 0);
-
-    _contextMenu->exec (mapToGlobal (at));
-  }
+  virtual void handleCustomContextMenuRequested (const QPoint& at);
 
   void notice_settings (const QSettings *settings);
 
@@ -120,6 +114,8 @@
 
   void set_global_shortcuts (bool focus_out);
 
+  void edit_file (void);
+
 protected:
 
   QTerminal (QWidget *xparent = 0) : QWidget (xparent)
@@ -142,6 +138,8 @@
     _selectall_action = _contextMenu->addAction (
                       tr ("Select All"), this, SLOT (selectAll ()));
 
+    _edit_action = _contextMenu->addAction (
+                      tr (""), this, SLOT (edit_file ()));
 
     _contextMenu->addSeparator ();
 
@@ -154,6 +152,9 @@
     connect (this, SIGNAL (report_status_message (const QString&)),
              xparent, SLOT (report_status_message (const QString&)));
 
+    connect (this, SIGNAL (edit_mfile_request (const QString&, int)),
+             xparent, SLOT (edit_mfile (const QString&, int)));
+
     connect (xparent, SIGNAL (settings_changed (const QSettings *)),
              this, SLOT (notice_settings (const QSettings *)));
 
@@ -193,6 +194,7 @@
   QAction * _copy_action;
   QAction * _paste_action;
   QAction * _selectall_action;
+  QAction * _edit_action;
 
   QAction *_interrupt_action;
   QAction *_nop_action;
--- a/libgui/src/m-editor/file-editor-tab.cc	Mon Dec 28 12:10:05 2015 +0100
+++ b/libgui/src/m-editor/file-editor-tab.cc	Mon Dec 28 16:44:10 2015 +0100
@@ -284,79 +284,9 @@
       return;
     }
 
-  // Is it a regular function within the search path? (Call __which__)
-  octave_value_list fct = F__which__ (ovl (word_at_cursor.toStdString ()),0);
-  octave_map map = fct(0).map_value ();
-
-  QString type = QString::fromStdString (
-                         map.contents ("type").data ()[0].string_value ());
-  QString name = QString::fromStdString (
-                         map.contents ("name").data ()[0].string_value ());
-
-  QString message = QString ();
-  QString filename = QString ();
-
-  if (type == QString("built-in function"))
-    { // built in function: can't edit
-      message = tr ("%1 is a built-in function");
-    }
-  else if (type.isEmpty ())
-    {
-      // function not known to octave -> try directory of edited file
-      // get directory
-      QDir dir;
-      if (_file_name.isEmpty ())
-        dir = _ced;
-      else
-        dir = QDir (QFileInfo (_file_name).canonicalPath ());
-
-      // function not known to octave -> try directory of edited file
-      QFileInfo file = QFileInfo (dir, word_at_cursor + ".m");
+  emit edit_mfile_request (word_at_cursor, _file_name, _ced, -1);
+}
 
-      if (file.exists ())
-        {
-          filename = file.canonicalFilePath (); // local file exists
-        }
-      else
-        { // local file does not exist -> try private directory
-          file = QFileInfo (_file_name);
-          file = QFileInfo (QDir (file.canonicalPath () + "/private"),
-                            word_at_cursor + ".m");
-
-          if (file.exists ())
-            {
-              filename = file.canonicalFilePath ();  // private function exists
-            }
-          else
-            {
-              message = tr ("Can not find function %1");  // no file found
-            }
-        }
-    }
-
-  if (! message.isEmpty ())
-    {
-      QMessageBox *msgBox
-          = new QMessageBox (QMessageBox::Critical,
-                             tr ("Octave Editor"),
-                             message.arg (name),
-                             QMessageBox::Ok, this);
-
-      msgBox->setWindowModality (Qt::NonModal);
-      msgBox->setAttribute (Qt::WA_DeleteOnClose);
-      msgBox->show ();
-      return;
-    }
-
-  if ( filename.isEmpty ())
-    filename = QString::fromStdString (
-                           map.contents ("file").data ()[0].string_value ());
-
-  if (! filename.endsWith (".m"))
-    filename.append (".m");
-
-  emit request_open_file (filename);
-}
 
 void
 file_editor_tab::set_file_name (const QString& fileName)
@@ -1124,13 +1054,12 @@
                                    tr ("Line number"), line+1, 1,
                                    _edit_area->lines (), 1, &ok);
       if (ok)
-        {
-          _edit_area->setCursorPosition (line-1, 0);
-          center_current_line ();
-        }
+        _edit_area->setCursorPosition (line-1, 0);
     }
   else  // go to given line without dialog
     _edit_area->setCursorPosition (line-1, 0);
+
+  center_current_line ();
 }
 
 void
--- a/libgui/src/m-editor/file-editor-tab.h	Mon Dec 28 12:10:05 2015 +0100
+++ b/libgui/src/m-editor/file-editor-tab.h	Mon Dec 28 16:44:10 2015 +0100
@@ -141,6 +141,8 @@
                                    bool remove_on_success);
   void run_file_signal (const QFileInfo& info);
   void request_open_file (const QString&);
+  void  edit_mfile_request (const QString&, const QString&,
+                            const QString&, int);
 
 protected:
 
--- a/libgui/src/m-editor/file-editor.cc	Mon Dec 28 12:10:05 2015 +0100
+++ b/libgui/src/m-editor/file-editor.cc	Mon Dec 28 16:44:10 2015 +0100
@@ -46,6 +46,7 @@
 #include "octave-link.h"
 #include "utils.h"
 #include "main-window.h"
+#include <oct-map.h>
 
 file_editor::file_editor (QWidget *p)
   : file_editor_interface (p)
@@ -623,6 +624,90 @@
 }
 
 void
+file_editor::handle_edit_mfile_request (const QString& fname,
+                                        const QString& ffile,
+                                        const QString& curr_dir, int line)
+{
+  // Is it a regular function within the search path? (Call __which__)
+  octave_value_list fct = F__which__ (ovl (fname.toStdString ()),0);
+  octave_map map = fct(0).map_value ();
+
+  QString type = QString::fromStdString (
+                         map.contents ("type").data ()[0].string_value ());
+  QString name = QString::fromStdString (
+                         map.contents ("name").data ()[0].string_value ());
+
+  QString message = QString ();
+  QString filename = QString ();
+
+  if (type == QString("built-in function"))
+    { // built in function: can't edit
+      message = tr ("%1 is a built-in function");
+    }
+  else if (type.isEmpty ())
+    {
+      // function not known to octave -> try directory of edited file
+      // get directory
+      QDir dir;
+      if (ffile.isEmpty ())
+        {
+          if (curr_dir.isEmpty ())
+            dir = QDir (ced);
+          else
+            dir = QDir (curr_dir);
+        }
+      else
+        dir = QDir (QFileInfo (ffile).canonicalPath ());
+
+      // function not known to octave -> try directory of edited file
+      QFileInfo file = QFileInfo (dir, fname + ".m");
+
+      if (file.exists ())
+        {
+          filename = file.canonicalFilePath (); // local file exists
+        }
+      else
+        { // local file does not exist -> try private directory
+          file = QFileInfo (ffile);
+          file = QFileInfo (QDir (file.canonicalPath () + "/private"),
+                            fname + ".m");
+
+          if (file.exists ())
+            {
+              filename = file.canonicalFilePath ();  // private function exists
+            }
+          else
+            {
+              message = tr ("Can not find function %1");  // no file found
+            }
+        }
+    }
+
+  if (! message.isEmpty ())
+    {
+      QMessageBox *msgBox
+          = new QMessageBox (QMessageBox::Critical,
+                             tr ("Octave Editor"),
+                             message.arg (name),
+                             QMessageBox::Ok, this);
+
+      msgBox->setWindowModality (Qt::NonModal);
+      msgBox->setAttribute (Qt::WA_DeleteOnClose);
+      msgBox->show ();
+      return;
+    }
+
+  if ( filename.isEmpty ())
+    filename = QString::fromStdString (
+                           map.contents ("file").data ()[0].string_value ());
+
+  if (! filename.endsWith (".m"))
+    filename.append (".m");
+
+  request_open_file (filename, QString (), line);  // default encoding
+}
+
+void
 file_editor::handle_insert_debugger_pointer_request (const QString& file,
                                                      int line)
 {
@@ -1717,6 +1802,11 @@
   connect (main_win (), SIGNAL (open_file_signal (const QString&)),
            this, SLOT (request_open_file (const QString&)));
 
+  connect (main_win (), SIGNAL (edit_mfile_request (const QString&,
+                                       const QString&, const QString&, int)),
+           this, SLOT (handle_edit_mfile_request (const QString&,
+                                       const QString&, const QString&, int)));
+
   connect (_mru_file_menu, SIGNAL (triggered (QAction *)),
            this, SLOT (request_mru_open_file (QAction *)));
 
@@ -1829,6 +1919,11 @@
   connect (f, SIGNAL (request_open_file (const QString&)),
            this, SLOT (request_open_file (const QString&)));
 
+  connect (f, SIGNAL (edit_mfile_request (const QString&, const QString&,
+                                          const QString&, int)),
+           this, SLOT (edit_mfile_request (const QString&, const QString&,
+                                           const QString&, int)));
+
   // Signals from the file_editor non-trivial operations
   connect (this, SIGNAL (fetab_settings_changed (const QSettings *)),
            f, SLOT (notice_settings (const QSettings *)));
--- a/libgui/src/m-editor/file-editor.h	Mon Dec 28 12:10:05 2015 +0100
+++ b/libgui/src/m-editor/file-editor.h	Mon Dec 28 16:44:10 2015 +0100
@@ -235,6 +235,8 @@
   void handle_delete_debugger_pointer_request (const QString& file, int line);
   void handle_update_breakpoint_marker_request (bool insert,
                                                 const QString& file, int line);
+  void handle_edit_mfile_request (const QString& name, const QString& file,
+                                  const QString& curr_dir, int line);
 
   void handle_edit_file_request (const QString& file);
 
--- a/libgui/src/main-window.cc	Mon Dec 28 12:10:05 2015 +0100
+++ b/libgui/src/main-window.cc	Mon Dec 28 16:44:10 2015 +0100
@@ -240,6 +240,12 @@
 {
   emit open_file_signal (file_name);
 }
+void
+
+main_window::edit_mfile (const QString& name, int line)
+{
+  emit edit_mfile_request (name, QString (), QString (), line);
+}
 
 void
 main_window::report_status_message (const QString& statusMessage)
--- a/libgui/src/main-window.h	Mon Dec 28 12:10:05 2015 +0100
+++ b/libgui/src/main-window.h	Mon Dec 28 16:44:10 2015 +0100
@@ -92,6 +92,7 @@
   void init_terminal_size_signal (void);
   void new_file_signal (const QString&);
   void open_file_signal (const QString&);
+  void edit_mfile_request (const QString&, const QString&, const QString&, int);
 
   void show_doc_signal (const QString&);
 
@@ -123,6 +124,7 @@
   void handle_undo_request (void);
   void new_file (const QString& commands = QString ());
   void open_file (const QString& file_name = QString ());
+  void edit_mfile (const QString&, int);
   void open_online_documentation_page (void);
   void display_release_notes (void);
   void load_and_display_community_news (int serial = -1);