annotate libgui/src/command-widget.h @ 29503:3bfec185c9e2

experimental command window widget with server loop This changeset provides a new experimental proof-of-concept cross-platform command window. It is intended to demonstrate how communication between the GUI command window and the Octave interpreter can work when the GUI is completely responsible for user input instead of having the interpreter wait for input inside readline. This initial implementation uses a simple text box for input and a separate text edit area for output. This design is not intended to be the final arrangement, but was easy to implement for demonstration purposes. These changes also make it possible to run the command-line version of Octave in a similar client-server mode with a function gathering input in one thread and the Octave intepreter running in another. The new command window is not intended to provide a general-purpose terminal window. So running something like "system ('emacs')" will not bring up an instance of Emacs running in the command window. This also means that it will no longer be possible to use an external output pager such as "less" in the command window. OTOH, it is also no longer necessary to fork and exec a separate process on some Unixy systems when Octave starts solely to give up the controlling terminal so that "less" will function properly. With the new terminal window, it is now possible to start Octave in command line mode and later open the GUI desktop window and then return to the command line when the GUI window is closed. Some things that need to be finished: * Merge the input and output windows so that command input and output are interleaved as they are in a normal command window. * Provide real readline command editing in the GUI command window and at the client-server CLI prompt. We can use the readline callback interface for the GUI and the normal readline interface for the CLI. With this design, the command widget and the CLI front end hold a copy of the command history. They do not need to communicate with the interpreter to navigate the command history. * Create interpreter_event messages for handling user input so that the interpreter can ask the GUI to gather user input for functions like "input". * Consider passing results back to the command widget as octave_value objects and allowing the command widget to format and display them instead of passing formatted text from the interpreter to the command widget. * Provide an output pager feature for the GUI command window? Maybe this feature is not necessary since we have scroll bars in the GUI and we can also have the GUI ask the user whether to display output if it is large. ChangeLog: * options-usage.h (usage_string, octave_print_verbose_usage_and_exit): Include --experimental-terminal-widget in list of options. (EXPERIMENTAL_TERMINAL_WIDGET_OPTION): New macro. (long_opts): Include "experimental-terminal-widget" in the list. * octave.h, octave.cc (cmdline_options::cmdline_options): Handle EXPERIMENTAL_TERMINAL_WIDGET_OPTION. (cmdline_options::m_experimental_terminal_widget): New data member. (application::experimental_terminal_widget, cmdline_options::experimental_terminal_widget interpreter::experimental_terminal_widget): New functions. * main.in.cc (fork_and_exec): New static variable. (main): Don't fork and exec if argv includes --experimental-terminal-widget. * interpreter-qobject.h, interpreter-qobject.cc (interpreter_qobject::pause, interpreter_qobject::stop, interpreter_qobject::resume): New functions. (interpreter_qobject::execute): Don't set prompt strings here if using the new terminal widget. If using the new terminal widget, call interpreter::shutdown and emit the shutdown_finished signal after interpreter::execute returns. (interpreter_qobject::shutdown): Don't do anything if using the new terminal widget. * main-window.h, main-window.cc (main_window::handle_octave_ready): Set interpreter prompt strings here if using the new terminal widget. (main_window::close_gui_signal): New signal. (main_window::closeEvent): If using new terminal widget and shutdown is confirmed, simply emit close_gui_signal. (main_window::construct_octave_qt_link): If using new terminal widget, connect qt_interpreter_events::interpreter_output_signal to the terminal_dock_widget::interpreter_output slot and the qt_interpreter_events::update_prompt_signal to the terminal_dock_widget::update_prompt slot. * octave-qobject.h, octave-qobject.cc (base_qobject::interpreter_pause, base_qobject::interpreter_stop, base_qobject::interpreter_resume): New functions. (base_qobject::base_qobject): If using new terminal widget: Don't connect interpreter_qobject::execution_finished signal to octave_qobject::handle_interpreter_execution_finished slot Don't connect octave_qobject::request_interpreter_shutdown signal to the interpreter_qobject::shutdown slot. Do connect the qt_interpreter_events::start_gui_signal signal to the octave_qobject::start_gui slot and simply reload settings and call qt_application::setQuitOnLastWindowClosed. There is no need to create the main window here. (base_qobject::exec): If using new terminal widget, wait for main thread to finish after qt_application::exec returns. (base_qojbect::experimental_terminal_widget, base_qobject::gui_running): New functions. (base_qojbect::start_gui, base_qojbect::close_gui, base_qojbect::interpreter_pause, base_qojbect::interpreter_stop, base_qojbect::interpreter_resume): New slots. (base_qojbect::handle_interpreter_execution_finished): Do nothing if using new terminal widget. * qt-application.cc (qt_application::start_gui_p): Return dummy value if using new terminal widget. * qt-interpreter-events.h, qt-interpreter-events.cc (qt_interpreter_events::start_gui, qt_interpreter_events::close_gui, qt_interpreter_events::interpreter_output, qt_interpreter_events::display_exception, qt_interpreter_events::update_prompt): New functions. (qt_interpreter_events::start_gui_signal, qt_interpreter_events::close_gui_signal, qt_interpreter_events::update_prompt_signal, qt_interpreter_events::interpreter_output_signal): New signals. * command-widget.h, command-widget.cc: New files. * libgui/src/module.mk: Update. * terminal-dock-widget.h, terminal-dock-widget.cc (terminal_dock_widget::m_experimental_terminal_widget): New data member. (terminal_dock_widget::terminal_dock_widget): Optionally create and use new terminal widget. If using new terminal widget, connect command_widget::interpreter_event signals to terminal_dock_widget::interpreter_event signals. (terminal_dock_widget::interpreter_output, terminal_dock_widget::update_prompt): New slots. (terminal_dock_widget::update_prompt_signal, terminal_dock_widget::interpreter_output_signal): New signals. * event-manager.h, event-manager.cc (Fdesktop): New function. (interpreter_events::start_gui, interpreter_events::close_gui, interpreter_events::update_prompt): New virtual functions. (interpreter_events::confirm_shutdown): Return true. (event_manager::start_gui, event_manager::close_gui, event_manager::update_prompt): New functions. * interpreter.h, interpreter.cc (interpreter::initialize): If using new terminal widget, only display startup message if not initially starting GUI. (class cli_input_reader): New class. (interpreter::experimental_terminal_widget, interpreter::get_line_and_eval): New functions. (interpreter::execute): If using new terminal widget, start GUI or command line reader and then enter server loop. * pt-eval.cc (tree_evaluator::server_loop): Reset parser at top of loop. also catch exit exception.
author John W. Eaton <jwe@octave.org>
date Thu, 25 Mar 2021 23:06:40 -0400
parents
children d6b2d9f9e1e0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
29503
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
1 ////////////////////////////////////////////////////////////////////////
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
2 //
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
3 // Copyright (C) 2021 The Octave Project Developers
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
4 //
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
5 // See the file COPYRIGHT.md in the top-level directory of this
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
6 // distribution or <https://octave.org/copyright/>.
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
7 //
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
8 // This file is part of Octave.
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
9 //
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
10 // Octave is free software: you can redistribute it and/or modify it
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
11 // under the terms of the GNU General Public License as published by
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
12 // the Free Software Foundation, either version 3 of the License, or
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
13 // (at your option) any later version.
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
14 //
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
15 // Octave is distributed in the hope that it will be useful, but
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
18 // GNU General Public License for more details.
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
19 //
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
20 // You should have received a copy of the GNU General Public License
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
21 // along with Octave; see the file COPYING. If not, see
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
22 // <https://www.gnu.org/licenses/>.
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
23 //
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
24 ////////////////////////////////////////////////////////////////////////
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
25
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
26 #if ! defined (octave_command_widget_h)
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
27 #define octave_command_widget_h 1
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
28
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
29 #include <QWidget>
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
30
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
31 #include "octave-qobject.h"
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
32
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
33 class QLabel;
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
34 class QLineEdit;
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
35 class QStrung;
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
36 class QTextBrowser;
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
37
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
38 namespace octave
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
39 {
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
40 class base_qobject;
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
41
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
42 class command_widget : public QWidget
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
43 {
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
44 Q_OBJECT
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
45
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
46 public:
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
47
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
48 command_widget (base_qobject& oct_qobj, QWidget *p);
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
49
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
50 signals:
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
51
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
52 void clear_line_edit (void);
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
53
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
54 void interpreter_event (const fcn_callback& fcn);
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
55 void interpreter_event (const meth_callback& meth);
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
56
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
57 protected slots:
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
58
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
59 void accept_input_line (void);
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
60
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
61 void insert_interpreter_output (const QString& msg);
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
62
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
63 private:
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
64
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
65 bool m_incomplete_parse;
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
66 QLabel *m_prompt;
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
67 QLineEdit *m_line_edit;
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
68 QTextBrowser *m_output_display;
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
69 };
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
70 }
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
71
3bfec185c9e2 experimental command window widget with server loop
John W. Eaton <jwe@octave.org>
parents:
diff changeset
72 #endif