Mercurial > hg > octave-terminal
changeset 14718:3df7ef0080c7 gui
Added event based processing and implement exit and change directory event.
* octave-event-observer.h: Implements observer part for the observer pattern.
* main-window.cc: Posting events instead of emulating keypresses.
* octave-event.h: Added new event types.
* octave-link: Subclassed octave_event_observer and implemented events.
* src.pro: Added file for tracking.
author | Jacob Dawid <jacob.dawid@googlemail.com> |
---|---|
date | Mon, 04 Jun 2012 01:42:58 +0200 |
parents | 572a707408b2 |
children | 89c64340e9ab |
files | gui/src/m-editor/file-editor.cc gui/src/main-window.cc gui/src/octave-adapter/octave-event-observer.h gui/src/octave-adapter/octave-event.h gui/src/octave-adapter/octave-link.cc gui/src/octave-adapter/octave-link.h gui/src/src.pro |
diffstat | 7 files changed, 253 insertions(+), 83 deletions(-) [+] |
line wrap: on
line diff
--- a/gui/src/m-editor/file-editor.cc +++ b/gui/src/m-editor/file-editor.cc @@ -284,42 +284,42 @@ _tab_widget->setTabsClosable (true); // Theme icons with QStyle icons as fallback - QAction *newAction = new QAction ( + QAction *new_action = new QAction ( QIcon::fromTheme("document-new",style->standardIcon (QStyle::SP_FileIcon)), tr("&New File"), _tool_bar); - QAction *openAction = new QAction ( + QAction *open_action = new QAction ( QIcon::fromTheme("document-open",style->standardIcon (QStyle::SP_DirOpenIcon)), tr("&Open File"), _tool_bar); - QAction *saveAction = new QAction ( + QAction *save_action = new QAction ( QIcon::fromTheme("document-save",style->standardIcon (QStyle::SP_DriveHDIcon)), tr("&Save File"), _tool_bar); - QAction *saveAsAction = new QAction ( + QAction *save_as_action = new QAction ( QIcon::fromTheme("document-save-as",style->standardIcon (QStyle::SP_DriveFDIcon)), tr("Save File &As"), _tool_bar); - QAction *undoAction = new QAction ( + QAction *undo_action = new QAction ( QIcon::fromTheme("edit-undo",style->standardIcon (QStyle::SP_ArrowLeft)), tr("&Undo"), _tool_bar); - QAction *redoAction = new QAction ( + QAction *redo_action = new QAction ( QIcon::fromTheme("edit-redo",style->standardIcon (QStyle::SP_ArrowRight)), tr("&Redo"), _tool_bar); _copy_action = new QAction (QIcon::fromTheme ("edit-copy"), tr ("&Copy"), _tool_bar); - _cut_action = new QAction (QIcon::fromTheme ("edit-cut"), tr ("Cu&t"), _tool_bar); + _cut_action = new QAction (QIcon::fromTheme ("edit-cut"), tr ("Cu&t"), _tool_bar); - QAction *pasteAction = new QAction (QIcon::fromTheme ("edit-paste"), tr ("&Paste"),_tool_bar); - QAction *nextBookmarkAction = new QAction (tr ("&Next Bookmark"),_tool_bar); - QAction *prevBookmarkAction = new QAction (tr ("Pre&vious Bookmark"),_tool_bar); - QAction *toggleBookmarkAction = new QAction (tr ("Toggle &Bookmark"),_tool_bar); - QAction *removeBookmarkAction = new QAction (tr ("&Remove All Bookmarks"),_tool_bar); - QAction *commentSelectedAction = new QAction (tr ("&Comment Selected Text"),_tool_bar); - QAction *uncommentSelectedAction = new QAction (tr ("&Uncomment Selected Text"),_tool_bar); + QAction *paste_action = new QAction (QIcon::fromTheme ("edit-paste"), tr ("&Paste"),_tool_bar); + QAction *next_bookmark_action = new QAction (tr ("&Next Bookmark"),_tool_bar); + QAction *previous_bookmark_action = new QAction (tr ("Pre&vious Bookmark"),_tool_bar); + QAction *toggle_bookmark_action = new QAction (tr ("Toggle &Bookmark"),_tool_bar); + QAction *remove_bookmark_action = new QAction (tr ("&Remove All Bookmarks"),_tool_bar); + QAction *comment_selection_action = new QAction (tr ("&Comment Selected Text"),_tool_bar); + QAction *uncomment_selection_action = new QAction (tr ("&Uncomment Selected Text"),_tool_bar); - QAction *runAction = new QAction ( + QAction *run_action = new QAction ( QIcon::fromTheme ("media-play", style->standardIcon (QStyle::SP_MediaPlay)), tr("&Run File"), _tool_bar); @@ -328,64 +328,79 @@ _cut_action->setEnabled(false); // short cuts - newAction->setShortcut (QKeySequence::New); - openAction->setShortcut (QKeySequence::Open); - saveAction->setShortcut (QKeySequence::Save); - saveAsAction->setShortcut (QKeySequence::SaveAs); - undoAction->setShortcut (QKeySequence::Undo); - redoAction->setShortcut (QKeySequence::Redo); - _copy_action->setShortcut (QKeySequence::Copy); - _cut_action->setShortcut (QKeySequence::Cut); - pasteAction->setShortcut (QKeySequence::Paste); - runAction->setShortcut (Qt::Key_F5); - nextBookmarkAction->setShortcut (Qt::Key_F2); - prevBookmarkAction->setShortcut (Qt::SHIFT + Qt::Key_F2); - toggleBookmarkAction->setShortcut (Qt::Key_F7); - commentSelectedAction->setShortcut (Qt::CTRL + Qt::Key_R); - uncommentSelectedAction->setShortcut(Qt::CTRL + Qt::Key_T); + new_action->setShortcut (QKeySequence::New); + new_action->setShortcutContext (Qt::WidgetShortcut); + open_action->setShortcut (QKeySequence::Open); + open_action->setShortcutContext (Qt::WidgetShortcut); + save_action->setShortcut (QKeySequence::Save); + save_action->setShortcutContext (Qt::WidgetShortcut); + save_as_action->setShortcut (QKeySequence::SaveAs); + save_as_action->setShortcutContext (Qt::WidgetShortcut); + undo_action->setShortcut (QKeySequence::Undo); + undo_action->setShortcutContext (Qt::WidgetShortcut); + redo_action->setShortcut (QKeySequence::Redo); + redo_action->setShortcutContext (Qt::WidgetShortcut); + _copy_action->setShortcut (QKeySequence::Copy); + _copy_action->setShortcutContext (Qt::WidgetShortcut); + _cut_action->setShortcut (QKeySequence::Cut); + _cut_action->setShortcutContext (Qt::WidgetShortcut); + paste_action->setShortcut (QKeySequence::Paste); + paste_action->setShortcutContext (Qt::WidgetShortcut); + run_action->setShortcut (Qt::Key_F5); + run_action->setShortcutContext (Qt::WidgetShortcut); + next_bookmark_action->setShortcut (Qt::Key_F2); + next_bookmark_action->setShortcutContext (Qt::WidgetShortcut); + previous_bookmark_action->setShortcut (Qt::SHIFT + Qt::Key_F2); + previous_bookmark_action->setShortcutContext (Qt::WidgetShortcut); + toggle_bookmark_action->setShortcut (Qt::Key_F7); + toggle_bookmark_action->setShortcutContext (Qt::WidgetShortcut); + comment_selection_action->setShortcut (Qt::CTRL + Qt::Key_R); + comment_selection_action->setShortcutContext (Qt::WidgetShortcut); + uncomment_selection_action->setShortcut (Qt::CTRL + Qt::Key_T); + uncomment_selection_action->setShortcutContext(Qt::WidgetShortcut); // toolbar - _tool_bar->addAction (newAction); - _tool_bar->addAction (openAction); - _tool_bar->addAction (saveAction); - _tool_bar->addAction (saveAsAction); + _tool_bar->addAction (new_action); + _tool_bar->addAction (open_action); + _tool_bar->addAction (save_action); + _tool_bar->addAction (save_as_action); _tool_bar->addSeparator (); - _tool_bar->addAction (undoAction); - _tool_bar->addAction (redoAction); + _tool_bar->addAction (undo_action); + _tool_bar->addAction (redo_action); _tool_bar->addAction (_copy_action); _tool_bar->addAction (_cut_action); - _tool_bar->addAction (pasteAction); + _tool_bar->addAction (paste_action); _tool_bar->addSeparator (); - _tool_bar->addAction (runAction); + _tool_bar->addAction (run_action); // menu bar QMenu *fileMenu = new QMenu (tr ("&File"), _menu_bar); - fileMenu->addAction (newAction); - fileMenu->addAction (openAction); - fileMenu->addAction (saveAction); - fileMenu->addAction (saveAsAction); + fileMenu->addAction (new_action); + fileMenu->addAction (open_action); + fileMenu->addAction (save_action); + fileMenu->addAction (save_as_action); fileMenu->addSeparator (); _menu_bar->addMenu (fileMenu); QMenu *editMenu = new QMenu (tr ("&Edit"), _menu_bar); - editMenu->addAction (undoAction); - editMenu->addAction (redoAction); + editMenu->addAction (undo_action); + editMenu->addAction (redo_action); editMenu->addSeparator (); editMenu->addAction (_copy_action); editMenu->addAction (_cut_action); - editMenu->addAction (pasteAction); + editMenu->addAction (paste_action); editMenu->addSeparator (); - editMenu->addAction (commentSelectedAction); - editMenu->addAction (uncommentSelectedAction); + editMenu->addAction (comment_selection_action); + editMenu->addAction (uncomment_selection_action); editMenu->addSeparator (); - editMenu->addAction (toggleBookmarkAction); - editMenu->addAction (nextBookmarkAction); - editMenu->addAction (prevBookmarkAction); - editMenu->addAction (removeBookmarkAction); + editMenu->addAction (toggle_bookmark_action); + editMenu->addAction (next_bookmark_action); + editMenu->addAction (previous_bookmark_action); + editMenu->addAction (remove_bookmark_action); _menu_bar->addMenu (editMenu); QMenu *runMenu = new QMenu (tr ("&Run"), _menu_bar); - runMenu->addAction (runAction); + runMenu->addAction (run_action); _menu_bar->addMenu (runMenu); QVBoxLayout *layout = new QVBoxLayout (); @@ -396,22 +411,22 @@ widget->setLayout (layout); setWidget (widget); - connect (newAction, SIGNAL (triggered ()), this, SLOT (request_new_file ())); - connect (openAction, SIGNAL (triggered ()), this, SLOT (request_open_file ())); - connect (undoAction, SIGNAL (triggered ()), this, SLOT (request_undo ())); - connect (redoAction, SIGNAL (triggered ()), this, SLOT (request_redo ())); + connect (new_action, SIGNAL (triggered ()), this, SLOT (request_new_file ())); + connect (open_action, SIGNAL (triggered ()), this, SLOT (request_open_file ())); + connect (undo_action, SIGNAL (triggered ()), this, SLOT (request_undo ())); + connect (redo_action, SIGNAL (triggered ()), this, SLOT (request_redo ())); connect (_copy_action, SIGNAL (triggered ()), this, SLOT (request_copy ())); connect (_cut_action, SIGNAL (triggered ()), this, SLOT (request_cut ())); - connect (pasteAction, SIGNAL (triggered ()), this, SLOT (request_paste ())); - connect (saveAction, SIGNAL (triggered ()), this, SLOT (request_save_file ())); - connect (saveAsAction, SIGNAL (triggered ()), this, SLOT (request_save_file_as ())); - connect (runAction, SIGNAL (triggered ()), this, SLOT (request_run_file ())); - connect (toggleBookmarkAction, SIGNAL (triggered ()), this, SLOT (request_toggle_bookmark ())); - connect (nextBookmarkAction, SIGNAL (triggered ()), this, SLOT (request_next_bookmark ())); - connect (prevBookmarkAction, SIGNAL (triggered ()), this, SLOT (request_previous_bookmark ())); - connect (removeBookmarkAction, SIGNAL (triggered ()), this, SLOT (request_remove_bookmark ())); - connect (commentSelectedAction, SIGNAL (triggered ()), this, SLOT (request_comment_selected_text ())); - connect (uncommentSelectedAction, SIGNAL (triggered ()), this, SLOT (request_uncomment_selected_text ())); + connect (paste_action, SIGNAL (triggered ()), this, SLOT (request_paste ())); + connect (save_action, SIGNAL (triggered ()), this, SLOT (request_save_file ())); + connect (save_as_action, SIGNAL (triggered ()), this, SLOT (request_save_file_as ())); + connect (run_action, SIGNAL (triggered ()), this, SLOT (request_run_file ())); + connect (toggle_bookmark_action, SIGNAL (triggered ()), this, SLOT (request_toggle_bookmark ())); + connect (next_bookmark_action, SIGNAL (triggered ()), this, SLOT (request_next_bookmark ())); + connect (previous_bookmark_action, SIGNAL (triggered ()), this, SLOT (request_previous_bookmark ())); + connect (remove_bookmark_action, SIGNAL (triggered ()), this, SLOT (request_remove_bookmark ())); + connect (comment_selection_action, SIGNAL (triggered ()), this, SLOT (request_comment_selected_text ())); + connect (uncomment_selection_action, SIGNAL (triggered ()), this, SLOT (request_uncomment_selected_text ())); connect (_tab_widget, SIGNAL (tabCloseRequested (int)), this, SLOT (handle_tab_close_request (int))); connect (_tab_widget, SIGNAL (currentChanged(int)), this, SLOT (active_tab_changed (int)));
--- a/gui/src/main-window.cc +++ b/gui/src/main-window.cc @@ -176,8 +176,7 @@ void main_window::change_current_working_directory (QString directory) { - _terminal->sendText (QString ("cd \'%1\'\n").arg (directory)); - _terminal->setFocus (); + octave_link::instance ()->request_working_directory_change (directory.toStdString ()); } void @@ -216,15 +215,8 @@ main_window::closeEvent (QCloseEvent * closeEvent) { closeEvent->ignore (); - _terminal->sendText ("exit\n"); - /* - report_status_message (tr ("Saving data and shutting down.")); - _closing = true; // inform editor window that whole application is closed - octave_link::instance ()->terminate_octave (); - - QMainWindow::closeEvent (closeEvent); - */ -} + octave_link::instance ()->request_octave_exit (); + } void main_window::read_settings ()
new file mode 100644 --- /dev/null +++ b/gui/src/octave-adapter/octave-event-observer.h @@ -0,0 +1,39 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef OCTAVEEVENTOBSERVER_H +#define OCTAVEEVENTOBSERVER_H + +class octave_event; + +/** + * \class octave_event_observer + * \brief Implements the observer part for the observer pattern. + */ +class octave_event_observer +{ + public: + octave_event_observer () { } + virtual ~octave_event_observer () { } + + virtual void event_accepted (octave_event *e) const = 0; + virtual void event_ignored (octave_event *e) const = 0; +}; + +#include "octave-event.h" + +#endif // OCTAVEEVENTOBSERVER_H
--- a/gui/src/octave-adapter/octave-event.h +++ b/gui/src/octave-adapter/octave-event.h @@ -18,6 +18,9 @@ #ifndef OCTAVEEVENT_H #define OCTAVEEVENT_H +#include <string> +#include "octave-event-observer.h" + /** * \class octave_event * \brief Base class for an octave event. @@ -25,15 +28,58 @@ class octave_event { public: - octave_event () + enum event_type { + exit_event, + change_directory_event + }; - } + octave_event (const octave_event_observer& o) + : _octave_event_observer (o) + { } virtual ~octave_event () - { + { } + + virtual event_type get_event_type () const = 0; + + void accept () + { _octave_event_observer.event_accepted (this); } + + void ignore () + { _octave_event_observer.event_ignored (this); } + + private: + const octave_event_observer& _octave_event_observer; +}; + +class octave_exit_event : public octave_event +{ + public: + octave_exit_event (const octave_event_observer& o) + : octave_event (o) + { } - } + event_type get_event_type () const + { return octave_event::exit_event; } +}; + +class octave_change_directory_event : public octave_event +{ + public: + octave_change_directory_event (const octave_event_observer& o, + std::string directory) + : octave_event (o) + { _directory = directory; } + + event_type get_event_type () const + { return octave_event::change_directory_event; } + + std::string get_directory () const + { return _directory; } + + private: + std::string _directory; }; #endif // OCTAVEEVENT_H
--- a/gui/src/octave-adapter/octave-link.cc +++ b/gui/src/octave-adapter/octave-link.cc @@ -26,6 +26,7 @@ octave_link::instance ()->trigger_update_history_model (); octave_link::instance ()->build_symbol_information (); octave_link::instance ()->update_current_working_directory (); + octave_link::instance ()->process_events (); return 0; } @@ -53,6 +54,7 @@ _workspace_model, SLOT (update_from_symbol_table ())); _symbol_information_semaphore = new QSemaphore (1); + _event_queue_semaphore = new QSemaphore (1); _current_working_directory = ""; } @@ -155,3 +157,61 @@ { return _workspace_model; } + +void +octave_link::process_events () +{ + _event_queue_semaphore->acquire (); + while (_event_queue.size () > 0) + { + octave_event * e = _event_queue.takeFirst (); + switch (e->get_event_type ()) + { + case octave_event::exit_event: + clean_up_and_exit (0); + e->accept (); + break; + + case octave_event::change_directory_event: + octave_change_directory_event * cde + = dynamic_cast <octave_change_directory_event *> (e); + if (cde) + { + std::string directory = cde->get_directory (); + if (octave_env::chdir (directory)) + e->accept (); + else + e->ignore (); + } + break; + } + } + _event_queue_semaphore->release (); +} + +void +octave_link::post_event (octave_event *e) +{ + if (e) + { + _event_queue_semaphore->acquire (); + _event_queue.push_front (e); + _event_queue_semaphore->release (); + } +} + +void +octave_link::event_accepted (octave_event *e) const +{ delete e; } + +void +octave_link::event_ignored (octave_event *e) const +{ delete e; } + +void +octave_link::request_working_directory_change (std::string directory) +{ post_event (new octave_change_directory_event (*this, directory)); } + +void +octave_link::request_octave_exit () +{ post_event (new octave_exit_event (*this)); }
--- a/gui/src/octave-adapter/octave-link.h +++ b/gui/src/octave-adapter/octave-link.h @@ -72,10 +72,12 @@ #include <QObject> #include <QStringListModel> #include <QTimer> +#include <QQueue> #include "workspace-model.h" #include "octave-main-thread.h" #include "octave-event.h" +#include "octave-event-observer.h" #include "symbol-information.h" /** @@ -86,7 +88,7 @@ * buffering access operations to octave and executing them in the readline * even hook, which lives in the octave thread. */ -class octave_link : public QObject +class octave_link : public QObject, public octave_event_observer { Q_OBJECT public: @@ -129,6 +131,15 @@ */ const QList <symbol_information>& get_symbol_information () const; + void process_events (); + void post_event (octave_event *e); + void event_accepted (octave_event *e) const; + void event_ignored (octave_event *e) const; + + + void request_working_directory_change (std::string directory); + void request_octave_exit (); + signals: /** Emitted, whenever the working directory of octave changed. */ void working_directory_changed (QString directory); @@ -154,6 +165,12 @@ /** Semaphore to lock access to the symbol information. */ QSemaphore *_symbol_information_semaphore; + /** Semaphore to lock access to the event queue. */ + QSemaphore *_event_queue_semaphore; + + /** Buffer for queueing events until they will be processed. */ + QQueue <octave_event *> _event_queue; + /** Stores the current symbol information. */ QList <symbol_information> _symbol_information;