Mercurial > hg > octave-lyh
changeset 16570:d5ae5aa80d42
preserve pending command line input when running commands from GUI actions
* QTerminal.h, QTerminal.cc (QTerminal::relay_command): Delete.
* file-editor-tab.cc (file_editor_tab::run_file_callback): New
argument, bp_info. Save pending command line input and execute
command.
(file_editor_tab::run_file): Use octave_link to execute file.
* main-window.h, main-window.cc
(main_window::execute_command_in_terminal): Rename from
main_window::handle_command_double_clicked. Post event through
octave_link to execute command.
(main_window::construct_octave_qt_link): Connect
_octave_qt_link::execute_command_in_terminal_signal to
main_window::execute_command_in_terminal.
(main_window::execute_command_callback): New function.
(main_window::relay_command_signal): Delete signal. Remove all uses.
* octave-qt-link.h, octave-qt-link.cc
(octave_qt_link::do_execute_command_in_terminal): New function.
(octave_qt_link::execute_command_in_terminal_signal): New signal.
* terminal-dock-widget.h, terminal-dock-widget.cc
(terminal_dock_widget::relay_command_signal): Delete signal. Remove
all uses.
* octave-link.h (octave_link::execute_command_in_terminal,
octave_link::do_execute_command_in_terminal): New functions.
* cmd-edit.h, cmd-edit.cc
(command_editor::pre_input_hook_set): New variable.
(gnu_readline::previous_pre_input_hook,
command_editor::intial_input): New member variables.
(command_editor::restore_pre_input_hook,
command_editor::do_get_current_line,
command_editor::do_replace_line, command_editor::set_pre_input_hook,
gnu_readline::do_get_current_line, gnu_readline::do_replace_line,
gnu_readline::set_pre_input_hook, command_editor::set_initial_input,
gnu_readline::restore_pre_input_hook,
default_command_editor::do_get_current_line,
default_command_editor::do_replace_line,
command_editor::insert_initial_input,
command_editor::pre_input_handler, command_editor::get_current_line,
command_editor::replace_line, command_editor::add_pre_input_hook,
command_editor::do_insert_initial_input,
command_editor::set_pre_input_hook,
command_editor::restore_pre_input_hook): New functions.
(command_editor::readline): Handle initial input.
(command_editor::interrupt): Give argument a default value.
* oct-rl-edit.h, oct-rl-edit.c (octave_rl_copy_line,
octave_rl_replace_line, octave_rl_set_pre_input_hook,
octave_rl_get_pre_input_hook): New functions.
(rl_pre_input_hook_fcn_ptr): New typedef.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 25 Apr 2013 17:57:55 -0400 |
parents | ab1df81adaa0 |
children | 4d8462fe15b9 |
files | libgui/qterminal/libqterminal/QTerminal.cc libgui/qterminal/libqterminal/QTerminal.h libgui/src/files-dock-widget.cc libgui/src/history-dock-widget.cc 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/main-window.cc libgui/src/main-window.h libgui/src/octave-qt-link.cc libgui/src/octave-qt-link.h libgui/src/terminal-dock-widget.cc libgui/src/terminal-dock-widget.h libgui/src/workspace-view.cc libinterp/interpfcn/octave-link.h liboctave/util/cmd-edit.cc liboctave/util/cmd-edit.h liboctave/util/oct-rl-edit.c liboctave/util/oct-rl-edit.h |
diffstat | 19 files changed, 298 insertions(+), 51 deletions(-) [+] |
line wrap: on
line diff
--- a/libgui/qterminal/libqterminal/QTerminal.cc +++ b/libgui/qterminal/libqterminal/QTerminal.cc @@ -42,9 +42,3 @@ else if (cursorType == "underline") setCursorType(QTerminalInterface::UnderlineCursor, cursorBlinking); } - -void -QTerminal::relay_command (const QString& command) -{ - sendText (command); -}
--- a/libgui/qterminal/libqterminal/QTerminal.h +++ b/libgui/qterminal/libqterminal/QTerminal.h @@ -38,7 +38,6 @@ public slots: void notice_settings (const QSettings *settings); - void relay_command (const QString& text); }; #else #include "unix/QUnixTerminalImpl.h" @@ -52,7 +51,6 @@ public slots: void notice_settings (const QSettings *settings); - void relay_command (const QString& command); }; #endif
--- a/libgui/src/files-dock-widget.cc +++ b/libgui/src/files-dock-widget.cc @@ -177,7 +177,7 @@ this, SLOT (set_current_directory (const QString &))); connect (this, SIGNAL (run_file_signal (const QString&)), - parent (), SLOT (handle_command_double_clicked (const QString&))); + parent (), SLOT (execute_command_in_terminal (const QString&))); QCompleter *completer = new QCompleter (_file_system_model, this); _current_directory->setCompleter (completer);
--- a/libgui/src/history-dock-widget.cc +++ b/libgui/src/history-dock-widget.cc @@ -48,7 +48,7 @@ p, SLOT (report_status_message (const QString&))); connect (this, SIGNAL (command_double_clicked (const QString&)), - p, SLOT (handle_command_double_clicked (const QString&))); + p, SLOT (execute_command_in_terminal (const QString&))); construct (); }
--- a/libgui/src/m-editor/file-editor-tab.cc +++ b/libgui/src/m-editor/file-editor-tab.cc @@ -48,6 +48,8 @@ #include "file-editor-tab.h" #include "file-editor.h" +#include "cmd-edit.h" + #include "builtin-defun-decls.h" #include "debug.h" #include "load-path.h" @@ -355,9 +357,21 @@ void -file_editor_tab::run_file_callback (void) +file_editor_tab::run_file_callback (const bp_info& info) { - // Maybe someday we will do something here? + if (file_in_path (info.file, info.dir)) + { + std::string pending_input = command_editor::get_current_line (); + + command_editor::set_initial_input (pending_input); + + command_editor::replace_line (info.function_name); + command_editor::redisplay (); + + // We are executing inside the command editor event loop. Force + // the current line to be returned for processing. + command_editor::interrupt (); + } } void @@ -372,15 +386,11 @@ QFileInfo file_info (_file_name); QString dir = file_info.absolutePath (); QString function_name = file_info.fileName (); + function_name.chop (file_info.suffix ().length () + 1); - // We have to cut off the suffix, because octave appends it. - function_name.chop (file_info.suffix ().length () + 1); - emit process_octave_code (QString ("cd \'%1\'\n%2\n") - .arg (dir).arg (function_name)); - - // TODO: Sending a run event crashes for long scripts. Find out why. - // octave_link::post_event - // (this, &file_editor_tab::run_file_callback, _file_name.toStdString ())); + bp_info info (_file_name, dir, function_name, 1); + + octave_link::post_event (this, &file_editor_tab::run_file_callback, info); } void
--- a/libgui/src/m-editor/file-editor-tab.h +++ b/libgui/src/m-editor/file-editor-tab.h @@ -170,7 +170,7 @@ int check_file_modified (); void do_comment_selected_text (bool comment); - void run_file_callback (void); + void run_file_callback (const bp_info& info); bool file_in_path (const std::string& file, const std::string& dir);
--- a/libgui/src/m-editor/file-editor.cc +++ b/libgui/src/m-editor/file-editor.cc @@ -1040,7 +1040,7 @@ this, SLOT (handle_mru_add_file (const QString&))); connect (f, SIGNAL (process_octave_code (const QString&)), - parent (), SLOT (handle_command_double_clicked (const QString&))); + parent (), SLOT (execute_command_in_terminal (const QString&))); // Signals from the file_editor non-trivial operations connect (this, SIGNAL (fetab_settings_changed (const QSettings *)),
--- a/libgui/src/main-window.cc +++ b/libgui/src/main-window.cc @@ -188,11 +188,12 @@ } void -main_window::handle_command_double_clicked (const QString& command) +main_window::execute_command_in_terminal (const QString& command) { - emit relay_command_signal (command); + octave_link::post_event (this, &main_window::execute_command_callback, + command.toStdString ()); - command_window->focus (); + focus_command_window (); } void @@ -764,6 +765,10 @@ this, SLOT (change_directory (QString))); connect (_octave_qt_link, + SIGNAL (execute_command_in_terminal_signal (QString)), + this, SLOT (execute_command_in_terminal (QString))); + + connect (_octave_qt_link, SIGNAL (set_history_signal (const QStringList&)), history_window, SLOT (set_history (const QStringList&))); @@ -1337,6 +1342,21 @@ } void +main_window::execute_command_callback (const std::string& command) +{ + std::string pending_input = command_editor::get_current_line (); + + command_editor::set_initial_input (pending_input); + + command_editor::replace_line (command); + command_editor::redisplay (); + + // We are executing inside the command editor event loop. Force + // the current line to be returned for processing. + command_editor::interrupt (); +} + +void main_window::new_figure_callback (void) { Fbuiltin (ovl ("figure"));
--- a/libgui/src/main-window.h +++ b/libgui/src/main-window.h @@ -76,7 +76,6 @@ signals: void settings_changed (const QSettings *); - void relay_command_signal (const QString&); void new_file_signal (const QString&); void open_file_signal (const QString&); @@ -109,7 +108,7 @@ void change_directory_up (void); void accept_directory_line_edit (void); - void handle_command_double_clicked (const QString& command); + void execute_command_in_terminal(const QString& dir); void handle_new_figure_request (void); @@ -195,6 +194,8 @@ void clear_history_callback (void); + void execute_command_callback (const std::string& command); + void new_figure_callback (void); void change_directory_callback (const std::string& directory);
--- a/libgui/src/octave-qt-link.cc +++ b/libgui/src/octave-qt-link.cc @@ -243,6 +243,12 @@ } void +octave_qt_link::do_execute_command_in_terminal (const std::string& command) +{ + emit execute_command_in_terminal_signal (QString::fromStdString (command)); +} + +void octave_qt_link::do_set_workspace (bool top_level, const std::list<workspace_element>& ws) {
--- a/libgui/src/octave-qt-link.h +++ b/libgui/src/octave-qt-link.h @@ -91,6 +91,8 @@ void do_change_directory (const std::string& dir); + void do_execute_command_in_terminal (const std::string& command); + void do_set_workspace (bool top_level, const std::list<workspace_element>& ws); @@ -134,6 +136,8 @@ void change_directory_signal (const QString& dir); + void execute_command_in_terminal_signal (const QString& command); + void set_workspace_signal (bool top_level, const QString& scopes, const QStringList& symbols,
--- a/libgui/src/terminal-dock-widget.cc +++ b/libgui/src/terminal-dock-widget.cc @@ -44,17 +44,11 @@ connect (this, SIGNAL (visibilityChanged (bool)), this, SLOT (handle_visibility (bool))); - connect (parent (), SIGNAL (relay_command_signal (const QString&)), - this, SLOT (relay_command (const QString&))); - // Forward signals to QTerminal widget. connect (this, SIGNAL (notice_settings_signal (const QSettings *)), terminal, SLOT (notice_settings (const QSettings *))); - connect (this, SIGNAL (relay_command_signal (const QString&)), - terminal, SLOT (relay_command (const QString&))); - connect (this, SIGNAL (copyClipboard_signal (void)), terminal, SLOT (copyClipboard (void))); @@ -69,12 +63,6 @@ } void -terminal_dock_widget::relay_command (const QString& command) -{ - emit relay_command_signal (command); -} - -void terminal_dock_widget::copyClipboard (void) { emit copyClipboard_signal ();
--- a/libgui/src/terminal-dock-widget.h +++ b/libgui/src/terminal-dock-widget.h @@ -43,8 +43,6 @@ void notice_settings (const QSettings *settings); - void relay_command (const QString& command); - void copyClipboard (void); void pasteClipboard (void); @@ -55,8 +53,6 @@ void notice_settings_signal (const QSettings *settings); - void relay_command_signal (const QString& command); - void copyClipboard_signal (void); void pasteClipboard_signal (void);
--- a/libgui/src/workspace-view.cc +++ b/libgui/src/workspace-view.cc @@ -75,7 +75,7 @@ this, SLOT(contextmenu_requested (const QPoint&))); connect (this, SIGNAL (command_requested (const QString&)), - p, SLOT (handle_command_double_clicked (const QString&))); + p, SLOT (execute_command_in_terminal (const QString&))); } workspace_view::~workspace_view (void)
--- a/libinterp/interpfcn/octave-link.h +++ b/libinterp/interpfcn/octave-link.h @@ -193,6 +193,13 @@ instance->do_change_directory (dir); } + // Preserves pending input. + static void execute_command_in_terminal (const std::string& command) + { + if (enabled ()) + instance->do_execute_command_in_terminal (command); + } + static void set_workspace (void); static void set_workspace (bool top_level, @@ -370,6 +377,8 @@ virtual void do_change_directory (const std::string& dir) = 0; + virtual void do_execute_command_in_terminal (const std::string& command) = 0; + virtual void do_set_workspace (bool top_level, const std::list<workspace_element>& ws) = 0;
--- a/liboctave/util/cmd-edit.cc +++ b/liboctave/util/cmd-edit.cc @@ -48,6 +48,8 @@ std::set<command_editor::startup_hook_fcn> command_editor::startup_hook_set; +std::set<command_editor::pre_input_hook_fcn> command_editor::pre_input_hook_set; + std::set<command_editor::event_hook_fcn> command_editor::event_hook_set; static octave_mutex event_hook_lock; @@ -66,6 +68,8 @@ typedef command_editor::startup_hook_fcn startup_hook_fcn; + typedef command_editor::pre_input_hook_fcn pre_input_hook_fcn; + typedef command_editor::event_hook_fcn event_hook_fcn; typedef command_editor::completion_fcn completion_fcn; @@ -139,6 +143,10 @@ std::string do_get_line_buffer (void) const; + std::string do_get_current_line (void) const; + + void do_replace_line (const std::string& text, bool clear_undo); + void do_insert_text (const std::string& text); void do_newline (void); @@ -153,6 +161,10 @@ void restore_startup_hook (void); + void set_pre_input_hook (pre_input_hook_fcn f); + + void restore_pre_input_hook (void); + void set_event_hook (event_hook_fcn f); void restore_event_hook (void); @@ -179,6 +191,8 @@ startup_hook_fcn previous_startup_hook; + pre_input_hook_fcn previous_pre_input_hook; + event_hook_fcn previous_event_hook; completion_fcn completion_function; @@ -205,6 +219,7 @@ gnu_readline::gnu_readline () : command_editor (), previous_startup_hook (0), + previous_pre_input_hook (0), previous_event_hook (0), completion_function (0), quoting_function (0), dequoting_function (0), char_is_quoted_function (0), user_accept_line_function (0) @@ -522,6 +537,22 @@ return ::octave_rl_line_buffer (); } +std::string +gnu_readline::do_get_current_line (void) const +{ + std::string retval; + char *buf = ::octave_rl_copy_line (); + retval = buf; + free (buf); + return retval; +} + +void +gnu_readline::do_replace_line (const std::string& text, bool clear_undo) +{ + ::octave_rl_replace_line (text.c_str (), clear_undo); +} + void gnu_readline::do_insert_text (const std::string& text) { @@ -568,6 +599,21 @@ } void +gnu_readline::set_pre_input_hook (pre_input_hook_fcn f) +{ + previous_pre_input_hook = ::octave_rl_get_pre_input_hook (); + + if (f != previous_pre_input_hook) + ::octave_rl_set_pre_input_hook (f); +} + +void +gnu_readline::restore_pre_input_hook (void) +{ + ::octave_rl_set_pre_input_hook (previous_pre_input_hook); +} + +void gnu_readline::set_event_hook (event_hook_fcn f) { previous_event_hook = octave_rl_get_event_hook (); @@ -767,7 +813,11 @@ std::string do_get_line_buffer (void) const; - void do_insert_text (const std::string&); + std::string do_get_current_line (void) const; + + void do_replace_line (const std::string& text, bool clear_undo); + + void do_insert_text (const std::string& text); void do_newline (void); @@ -832,6 +882,19 @@ return ""; } +std::string +default_command_editor::do_get_current_line (void) const +{ + // FIXME + return std::string (); +} + +void +default_command_editor::do_replace_line (const std::string&, bool) +{ + // FIXME +} + void default_command_editor::do_insert_text (const std::string&) { @@ -891,6 +954,19 @@ instance = new default_command_editor (); } +void +command_editor::set_initial_input (const std::string& text) +{ + if (instance_ok ()) + instance->initial_input = text; +} + +int +command_editor::insert_initial_input (void) +{ + return instance_ok () ? instance->do_insert_initial_input () : 0; +} + int command_editor::startup_handler (void) { @@ -907,6 +983,21 @@ } int +command_editor::pre_input_handler (void) +{ + for (pre_input_hook_set_iterator p = pre_input_hook_set.begin (); + p != pre_input_hook_set.end (); p++) + { + pre_input_hook_fcn f = *p; + + if (f) + f (); + } + + return 0; +} + +int command_editor::event_handler (void) { event_hook_lock.lock (); @@ -945,8 +1036,17 @@ std::string command_editor::readline (const std::string& prompt, bool& eof) { - return (instance_ok ()) - ? instance->do_readline (prompt, eof) : std::string (); + std::string retval; + + if (instance_ok ()) + { + if (! instance->initial_input.empty ()) + add_pre_input_hook (command_editor::insert_initial_input); + + retval = instance->do_readline (prompt, eof); + } + + return retval; } void @@ -1179,6 +1279,19 @@ return (instance_ok ()) ? instance->do_get_line_buffer () : ""; } +std::string +command_editor::get_current_line (void) +{ + return (instance_ok ()) ? instance->do_get_current_line () : ""; +} + +void +command_editor::replace_line (const std::string& text, bool clear_undo) +{ + if (instance_ok ()) + instance->do_replace_line (text, clear_undo); +} + void command_editor::insert_text (const std::string& text) { @@ -1240,6 +1353,32 @@ } void +command_editor::add_pre_input_hook (pre_input_hook_fcn f) +{ + if (instance_ok ()) + { + pre_input_hook_set.insert (f); + + instance->set_pre_input_hook (pre_input_handler); + } +} + +void +command_editor::remove_pre_input_hook (pre_input_hook_fcn f) +{ + if (instance_ok ()) + { + pre_input_hook_set_iterator p = pre_input_hook_set.find (f); + + if (p != pre_input_hook_set.end ()) + pre_input_hook_set.erase (p); + + if (pre_input_hook_set.empty ()) + instance->restore_pre_input_hook (); + } +} + +void command_editor::add_event_hook (event_hook_fcn f) { octave_autolock guard (event_hook_lock); @@ -1586,6 +1725,21 @@ return result; } +int +command_editor::do_insert_initial_input (void) +{ + std::string input = initial_input; + + initial_input = ""; + + do_insert_text (input); + + // Is it really right to redisplay here? + do_redisplay (); + + return 0; +} + // Return the octal number parsed from STRING, or -1 to indicate that // the string contained a bad number.
--- a/liboctave/util/cmd-edit.h +++ b/liboctave/util/cmd-edit.h @@ -37,12 +37,14 @@ protected: command_editor (void) - : command_number (0), interrupted (false) { } + : command_number (0), interrupted (false), initial_input () { } public: typedef int (*startup_hook_fcn) (void); + typedef int (*pre_input_hook_fcn) (void); + typedef int (*event_hook_fcn) (void); typedef std::string (*completion_fcn) (const std::string&, int); @@ -123,6 +125,10 @@ static std::string get_line_buffer (void); + static std::string get_current_line (void); + + static void replace_line (const std::string& text, bool clear_undo = true); + static void insert_text (const std::string& text); static void newline (void); @@ -137,6 +143,10 @@ static void remove_startup_hook (startup_hook_fcn f); + static void add_pre_input_hook (pre_input_hook_fcn f); + + static void remove_pre_input_hook (pre_input_hook_fcn f); + static void add_event_hook (event_hook_fcn f); static void remove_event_hook (event_hook_fcn f); @@ -151,7 +161,7 @@ static bool filename_quoting_desired (bool); - static bool interrupt (bool); + static bool interrupt (bool = true); static int current_command_number (void); @@ -161,6 +171,10 @@ static void force_default_editor (void); + static void set_initial_input (const std::string& text); + + static int insert_initial_input (void); + private: // No copying! @@ -175,15 +189,22 @@ static int startup_handler (void); + static int pre_input_handler (void); + static int event_handler (void); static std::set<startup_hook_fcn> startup_hook_set; + static std::set<pre_input_hook_fcn> pre_input_hook_set; + static std::set<event_hook_fcn> event_hook_set; typedef std::set<startup_hook_fcn>::iterator startup_hook_set_iterator; typedef std::set<startup_hook_fcn>::const_iterator startup_hook_set_const_iterator; + typedef std::set<pre_input_hook_fcn>::iterator pre_input_hook_set_iterator; + typedef std::set<pre_input_hook_fcn>::const_iterator pre_input_hook_set_const_iterator; + typedef std::set<event_hook_fcn>::iterator event_hook_set_iterator; typedef std::set<event_hook_fcn>::const_iterator event_hook_set_const_iterator; @@ -271,7 +292,11 @@ virtual std::string do_get_line_buffer (void) const = 0; - virtual void do_insert_text (const std::string&) = 0; + virtual std::string do_get_current_line (void) const = 0; + + virtual void do_replace_line (const std::string& text, bool clear_undo) = 0; + + virtual void do_insert_text (const std::string& text) = 0; virtual void do_newline (void) = 0; @@ -285,7 +310,11 @@ virtual void restore_startup_hook (void) { } - virtual void set_event_hook (startup_hook_fcn) { } + virtual void set_pre_input_hook (pre_input_hook_fcn) { } + + virtual void restore_pre_input_hook (void) { } + + virtual void set_event_hook (event_hook_fcn) { } virtual void restore_event_hook (void) { } @@ -299,6 +328,8 @@ virtual void do_interrupt (bool) { } + int do_insert_initial_input (void); + int read_octal (const std::string& s); void error (int); @@ -309,6 +340,8 @@ int command_number; bool interrupted; + + std::string initial_input; }; #endif
--- a/liboctave/util/oct-rl-edit.c +++ b/liboctave/util/oct-rl-edit.c @@ -123,6 +123,18 @@ rl_deprep_term_function (); } +char * +octave_rl_copy_line (void) +{ + return rl_copy_text (0, rl_end); +} + +void +octave_rl_replace_line (const char *s, int clear_undo) +{ + rl_replace_line (s, clear_undo); +} + void octave_rl_insert_text (const char *s) { @@ -325,6 +337,18 @@ } void +octave_rl_set_pre_input_hook (rl_pre_input_hook_fcn_ptr f) +{ + rl_pre_input_hook = f; +} + +rl_pre_input_hook_fcn_ptr +octave_rl_get_pre_input_hook (void) +{ + return rl_pre_input_hook; +} + +void octave_rl_set_event_hook (rl_event_hook_fcn_ptr f) { rl_event_hook = f;
--- a/liboctave/util/oct-rl-edit.h +++ b/liboctave/util/oct-rl-edit.h @@ -25,6 +25,8 @@ typedef int (*rl_startup_hook_fcn_ptr) (void); +typedef int (*rl_pre_input_hook_fcn_ptr) (void); + typedef int (*rl_event_hook_fcn_ptr) (void); typedef int (*rl_fcn_ptr) (int, int); @@ -62,6 +64,10 @@ extern void octave_rl_restore_terminal_state (void); +extern char *octave_rl_copy_line (void); + +extern void octave_rl_replace_line (const char *s, int clear_undo); + extern void octave_rl_insert_text (const char *); extern int octave_rl_newline (int, int); @@ -123,6 +129,10 @@ extern rl_startup_hook_fcn_ptr octave_rl_get_startup_hook (void); +extern void octave_rl_set_pre_input_hook (rl_startup_hook_fcn_ptr); + +extern rl_pre_input_hook_fcn_ptr octave_rl_get_pre_input_hook (void); + extern void octave_rl_set_event_hook (rl_event_hook_fcn_ptr f); extern rl_event_hook_fcn_ptr octave_rl_get_event_hook (void);