Mercurial > hg > octave-lyh
changeset 14720:cecc7da96e2a gui
Added update events for the command history model and workspace model.
* history-dockwidget.cc: Moved string list model to dock widget.
* octave-event-observer.h: Removed constness from accepted and rejected methods.
* octave-event.h: Removed constness from accepted and rejected methods, add new event types.
* octave-link: Almost removed all Qt code.
* workspace-model: Moved update timer to model.
* workspace-view: Model workspace model to widget.
author | Jacob Dawid <jacob.dawid@googlemail.com> |
---|---|
date | Mon, 04 Jun 2012 21:28:08 +0200 |
parents | 89c64340e9ab |
children | ec76264adca9 |
files | gui/src/history-dockwidget.cc gui/src/history-dockwidget.h 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/workspace-model.cc gui/src/workspace-model.h gui/src/workspace-view.cc gui/src/workspace-view.h |
diffstat | 10 files changed, 218 insertions(+), 203 deletions(-) [+] |
line wrap: on
line diff
--- a/gui/src/history-dockwidget.cc +++ b/gui/src/history-dockwidget.cc @@ -18,37 +18,91 @@ #include "history-dockwidget.h" #include <QVBoxLayout> -history_dock_widget::history_dock_widget (QWidget * parent):QDockWidget (parent) +history_dock_widget::history_dock_widget (QWidget * parent) + : QDockWidget (parent), octave_event_observer () { setObjectName ("HistoryDockWidget"); construct (); } void +history_dock_widget::event_accepted (octave_event *e) +{ + if (dynamic_cast <octave_update_history_event*> (e)) + { + // Determine the client's (our) history length and the one of the server. + int clientHistoryLength = _history_model->rowCount (); + int serverHistoryLength = command_history::length (); + + // If were behind the server, iterate through all new entries and add + // them to our history. + if (clientHistoryLength < serverHistoryLength) + { + for (int i = clientHistoryLength; i < serverHistoryLength; i++) + { + _history_model->insertRow (0); + _history_model->setData (_history_model->index (0), + QString (command_history::get_entry (i).c_str ())); + } + } + } + + delete e; +} + +void +history_dock_widget::event_reject (octave_event *e) +{ + delete e; +} + +void history_dock_widget::construct () { - m_sortFilterProxyModel.setSourceModel(octave_link::instance ()->get_history_model()); - m_historyListView = new QListView (this); - m_historyListView->setModel (&m_sortFilterProxyModel); - m_historyListView->setAlternatingRowColors (true); - m_historyListView->setEditTriggers (QAbstractItemView::NoEditTriggers); - m_historyListView->setStatusTip (tr ("Doubleclick a command to transfer it to the terminal.")); - m_filterLineEdit = new QLineEdit (this); - m_filterLineEdit->setStatusTip (tr ("Enter text to filter the command history.")); + _history_model = new QStringListModel (); + _sort_filter_proxy_model.setSourceModel (_history_model); + _history_list_view = new QListView (this); + _history_list_view->setModel (&_sort_filter_proxy_model); + _history_list_view->setAlternatingRowColors (true); + _history_list_view->setEditTriggers (QAbstractItemView::NoEditTriggers); + _history_list_view->setStatusTip (tr ("Doubleclick a command to transfer it to the terminal.")); + _filter_line_edit = new QLineEdit (this); + _filter_line_edit->setStatusTip (tr ("Enter text to filter the command history.")); QVBoxLayout *layout = new QVBoxLayout (); setWindowTitle (tr ("Command History")); setWidget (new QWidget ()); - layout->addWidget (m_historyListView); - layout->addWidget (m_filterLineEdit); + layout->addWidget (_history_list_view); + layout->addWidget (_filter_line_edit); layout->setMargin (2); widget ()->setLayout (layout); - connect (m_filterLineEdit, SIGNAL (textEdited (QString)), &m_sortFilterProxyModel, SLOT (setFilterWildcard(QString))); - connect (m_historyListView, SIGNAL (doubleClicked (QModelIndex)), this, SLOT (handle_double_click (QModelIndex))); - connect (this, SIGNAL (visibilityChanged(bool)), this, SLOT(handle_visibility_changed(bool))); + connect (_filter_line_edit, + SIGNAL (textEdited (QString)), + &_sort_filter_proxy_model, + SLOT (setFilterWildcard (QString))); + + connect (_history_list_view, + SIGNAL (doubleClicked (QModelIndex)), + this, + SLOT (handle_double_click (QModelIndex))); + + connect (this, + SIGNAL (visibilityChanged (bool)), + this, + SLOT (handle_visibility_changed (bool))); + + _update_history_model_timer.setInterval (200); + _update_history_model_timer.setSingleShot (false); + + connect (&_update_history_model_timer, + SIGNAL (timeout ()), + this, + SLOT (request_history_model_update ())); + + _update_history_model_timer.start (); } void @@ -65,6 +119,13 @@ } void +history_dock_widget::request_history_model_update () +{ + octave_link::instance () + ->post_event (new octave_update_history_event (*this)); +} + +void history_dock_widget::closeEvent (QCloseEvent *event) { emit active_changed (false);
--- a/gui/src/history-dockwidget.h +++ b/gui/src/history-dockwidget.h @@ -22,17 +22,24 @@ #include <QLineEdit> #include <QListView> #include <QSortFilterProxyModel> -#include "octave-link.h" +#include <QStringListModel> +#include <QTimer> -class history_dock_widget:public QDockWidget +#include "octave-link.h" +#include "octave-event-observer.h" + +class history_dock_widget : public QDockWidget, public octave_event_observer { Q_OBJECT public: history_dock_widget (QWidget *parent = 0); - void update_history (QStringList history); + + void event_accepted (octave_event *e); + void event_reject (octave_event *e); public slots: void handle_visibility_changed (bool visible); + void request_history_model_update (); signals: void information (QString message); @@ -46,9 +53,14 @@ private: void construct (); - QListView *m_historyListView; - QLineEdit *m_filterLineEdit; - QSortFilterProxyModel m_sortFilterProxyModel; + QListView *_history_list_view; + QLineEdit *_filter_line_edit; + QSortFilterProxyModel _sort_filter_proxy_model; + + /** Stores the current history_model. */ + QStringListModel *_history_model; + + QTimer _update_history_model_timer; }; #endif // HISTORYDOCKWIDGET_H
--- a/gui/src/octave-adapter/octave-event-observer.h +++ b/gui/src/octave-adapter/octave-event-observer.h @@ -34,13 +34,13 @@ * This will be called when an event has been accepted. Operations * in this routine will be processed in the octave thread. */ - virtual void event_accepted (octave_event *e) const = 0; + virtual void event_accepted (octave_event *e) = 0; /** * This will be called when an event has been rejected. Operations * in this routine will be processed in the octave thread. */ - virtual void event_reject (octave_event *e) const = 0; + virtual void event_reject (octave_event *e) = 0; }; #include "octave-event.h"
--- a/gui/src/octave-adapter/octave-event.h +++ b/gui/src/octave-adapter/octave-event.h @@ -38,14 +38,14 @@ class octave_event { public: - octave_event (const octave_event_observer& o) + octave_event (octave_event_observer& o) : _octave_event_observer (o) { } virtual ~octave_event () { } - /** Performs what it necessary to make this event happen. + /** Performs what is necessary to make this event happen. * This code is thread-safe since it will be executed in the octave thread. * However, you should take care to keep this code as short as possible. */ virtual bool perform () const = 0; @@ -65,7 +65,31 @@ { _octave_event_observer.event_reject (this); } private: - const octave_event_observer& _octave_event_observer; + octave_event_observer& _octave_event_observer; +}; + +class octave_update_history_event : public octave_event +{ + public: + /** Creates a new octave_exit_event. */ + octave_update_history_event (octave_event_observer& o) + : octave_event (o) + { } + + bool perform () const + { return true; /* Always grant. */ } +}; + +class octave_update_workspace_event : public octave_event +{ + public: + /** Creates a new octave_exit_event. */ + octave_update_workspace_event (octave_event_observer& o) + : octave_event (o) + { } + + bool perform () const + { return true; /* Always grant. */ } }; /** Implements an octave exit event. */ @@ -73,7 +97,7 @@ { public: /** Creates a new octave_exit_event. */ - octave_exit_event (const octave_event_observer& o) + octave_exit_event (octave_event_observer& o) : octave_event (o) { } @@ -86,7 +110,7 @@ { public: /** Creates a new octave_change_directory_event. */ - octave_change_directory_event (const octave_event_observer& o, + octave_change_directory_event (octave_event_observer& o, std::string directory) : octave_event (o) { _directory = directory; }
--- a/gui/src/octave-adapter/octave-link.cc +++ b/gui/src/octave-adapter/octave-link.cc @@ -22,9 +22,6 @@ int octave_readline_hook () { - octave_link::instance ()->trigger_update_history_model (); - octave_link::instance ()->build_symbol_information (); - octave_link::instance ()->generate_events (); octave_link::instance ()->process_events (); return 0; @@ -40,9 +37,6 @@ octave_link::octave_link () { - _history_model = new QStringListModel (); - _workspace_model = new workspace_model (qApp); - _symbol_information_semaphore = new QSemaphore (1); _event_queue_semaphore = new QSemaphore (1); _last_working_directory = ""; } @@ -64,74 +58,9 @@ } void -octave_link::trigger_update_history_model () -{ - // Determine the client's (our) history length and the one of the server. - int clientHistoryLength = _history_model->rowCount (); - int serverHistoryLength = command_history::length (); - - // If were behind the server, iterate through all new entries and add them to our history. - if (clientHistoryLength < serverHistoryLength) - { - for (int i = clientHistoryLength; i < serverHistoryLength; i++) - { - _history_model->insertRow (0); - _history_model->setData (_history_model->index (0), QString (command_history::get_entry (i).c_str ())); - } - } -} - -void -octave_link::acquire_symbol_information () -{ - _symbol_information_semaphore->acquire (1); -} - -void -octave_link::release_symbol_information () -{ - _symbol_information_semaphore->release (1); -} - -void -octave_link::build_symbol_information () -{ - std::list < symbol_table::symbol_record > symbolTable = symbol_table::all_variables (); - - acquire_symbol_information (); - _symbol_information.clear (); - for (std::list < symbol_table::symbol_record > ::iterator iterator = symbolTable.begin (); - iterator != symbolTable.end (); iterator++) - { - symbol_information symbolInformation; - symbolInformation.from_symbol_record (*iterator); - _symbol_information.push_back (symbolInformation); - } - release_symbol_information (); -} - -const QList <symbol_information>& -octave_link::get_symbol_information () const -{ - return _symbol_information; -} - -void octave_link::register_event_listener (octave_event_listener *oel) { _octave_event_listener = oel; } -QStringListModel * -octave_link::get_history_model () -{ - return _history_model; -} - -workspace_model * -octave_link::get_workspace_model () -{ - return _workspace_model; -} - void octave_link::generate_events () { @@ -173,11 +102,11 @@ } void -octave_link::event_accepted (octave_event *e) const +octave_link::event_accepted (octave_event *e) { delete e; } void -octave_link::event_reject (octave_event *e) const +octave_link::event_reject (octave_event *e) { delete e; } void
--- a/gui/src/octave-adapter/octave-link.h +++ b/gui/src/octave-adapter/octave-link.h @@ -62,17 +62,7 @@ #include <queue> // Qt includes -#include <QMutexLocker> -#include <QMutex> -#include <QFileInfo> -#include <QList> -#include <QString> -#include <QStringList> -#include <QVector> #include <QSemaphore> -#include <QStringListModel> -#include <QTimer> -#include <QQueue> #include "workspace-model.h" #include "octave-main-thread.h" @@ -98,40 +88,13 @@ /** Starts octave. */ void launch_octave (); - - /** Returns the current history model. */ - QStringListModel *get_history_model (); - - /** Returns the current workspace model. */ - workspace_model *get_workspace_model (); - - /** Triggers an update of the history model. */ - void trigger_update_history_model (); - - /** Acquires the symbol information. You need to acquire that before - * actually accessing it. Make sure that you release it properly in order - * to avoid deadlocks. */ - void acquire_symbol_information (); - - /** Releases access to the symbol information. */ - void release_symbol_information (); - - /** Update symbol information from octave's symboltable. */ - void build_symbol_information (); - - /** Provides acces to the current symbol information. - * WARNING: Always acquire the symbol information before actually - * using it and make sure you release it properly afterwards. - */ - const QList <symbol_information>& get_symbol_information () const; - void register_event_listener (octave_event_listener *oel); void generate_events (); void process_events (); void post_event (octave_event *e); - void event_accepted (octave_event *e) const; - void event_reject (octave_event *e) const; + void event_accepted (octave_event *e); + void event_reject (octave_event *e); void request_working_directory_change (std::string directory); void request_octave_exit (); @@ -143,27 +106,15 @@ octave_event_listener *_octave_event_listener; - /** Stores the current history_model. */ - QStringListModel *_history_model; - - /** Stores the current workspace model. */ - workspace_model *_workspace_model; - /** Thread running octave_main. */ octave_main_thread *_octave_main_thread; - /** 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. */ std::queue <octave_event *> _event_queue; - /** Stores the current symbol information. */ - QList <symbol_information> _symbol_information; - /** Stores the last known current working directory of octave. */ std::string _last_working_directory;
--- a/gui/src/workspace-model.cc +++ b/gui/src/workspace-model.cc @@ -21,7 +21,7 @@ #include "octave-link.h" workspace_model::workspace_model(QObject *parent) - : QAbstractItemModel(parent) + : QAbstractItemModel(parent), octave_event_observer () { QList<QVariant> rootData; rootData << tr ("Name") << tr ("Type") << tr ("Value"); @@ -31,6 +31,15 @@ insert_top_level_item(1, new tree_item ("Global")); insert_top_level_item(2, new tree_item ("Persistent")); insert_top_level_item(3, new tree_item ("Hidden")); + + connect(&_update_workspace_model_timer, + SIGNAL (timeout ()), + this, + SLOT (request_update_workspace())); + + _update_workspace_model_timer.setInterval (500); + _update_workspace_model_timer.setSingleShot (false); + _update_workspace_model_timer.start (); } workspace_model::~workspace_model() @@ -38,6 +47,63 @@ delete _rootItem; } +void +workspace_model::request_update_workspace () +{ + octave_link::instance () + ->post_event (new octave_update_workspace_event (*this)); +} + +void +workspace_model::event_accepted (octave_event *e) +{ + if (dynamic_cast <octave_update_workspace_event*> (e)) + { + std::list < symbol_table::symbol_record > symbolTable = symbol_table::all_variables (); + + _symbol_information.clear (); + for (std::list < symbol_table::symbol_record > ::iterator iterator = symbolTable.begin (); + iterator != symbolTable.end (); iterator++) + { + symbol_information symbolInformation; + symbolInformation.from_symbol_record (*iterator); + _symbol_information.push_back (symbolInformation); + } + + top_level_item (0)->delete_child_items (); + top_level_item (1)->delete_child_items (); + top_level_item (2)->delete_child_items (); + top_level_item (3)->delete_child_items (); + + foreach (const symbol_information& s, _symbol_information) + { + tree_item *child = new tree_item (); + + child->set_data (0, s._symbol); + child->set_data (1, s._type); + child->set_data (2, s._value); + + switch (s._scope) + { + case symbol_information::local: top_level_item (0)->add_child (child); break; + case symbol_information::global: top_level_item (1)->add_child (child); break; + case symbol_information::persistent: top_level_item (2)->add_child (child); break; + case symbol_information::hidden: top_level_item (3)->add_child (child); break; + } + } + + reset(); + emit expand_request(); + } + delete e; +} + +void +workspace_model::event_reject (octave_event *e) +{ + delete e; +} + QModelIndex workspace_model::index(int row, int column, const QModelIndex &parent) const { @@ -141,37 +207,3 @@ return item->data(index.column()); } - -void -workspace_model::update_from_symbol_table () -{ - top_level_item (0)->delete_child_items (); - top_level_item (1)->delete_child_items (); - top_level_item (2)->delete_child_items (); - top_level_item (3)->delete_child_items (); - - octave_link::instance ()-> acquire_symbol_information(); - const QList <symbol_information>& symbolInformation = octave_link::instance() ->get_symbol_information (); - - foreach (const symbol_information& s, symbolInformation) - { - tree_item *child = new tree_item (); - - child->set_data (0, s._symbol); - child->set_data (1, s._type); - child->set_data (2, s._value); - - switch (s._scope) - { - case symbol_information::local: top_level_item (0)->add_child (child); break; - case symbol_information::global: top_level_item (1)->add_child (child); break; - case symbol_information::persistent: top_level_item (2)->add_child (child); break; - case symbol_information::hidden: top_level_item (3)->add_child (child); break; - } - } - - octave_link::instance ()-> release_symbol_information(); - - reset(); - emit expand_request(); -}
--- a/gui/src/workspace-model.h +++ b/gui/src/workspace-model.h @@ -24,6 +24,9 @@ #include <QSemaphore> #include <QTimer> +#include "symbol-information.h" +#include "octave-event-observer.h" + class tree_item { public: @@ -103,13 +106,17 @@ tree_item *_parent_item; }; -class workspace_model : public QAbstractItemModel +class workspace_model + : public QAbstractItemModel, public octave_event_observer { Q_OBJECT public: - workspace_model(QObject *parent = 0); - ~workspace_model(); + workspace_model (QObject *parent = 0); + ~workspace_model (); + + void event_accepted (octave_event *e); + void event_reject (octave_event *e); QVariant data(const QModelIndex &index, int role) const; Qt::ItemFlags flags(const QModelIndex &index) const; @@ -125,12 +132,18 @@ tree_item *top_level_item (int at); public slots: - void update_from_symbol_table (); + void request_update_workspace (); signals: void expand_request(); private: + /** Timer for periodically updating the workspace model from the current + * symbol information. */ + QTimer _update_workspace_model_timer; + + /** Stores the current symbol information. */ + QList <symbol_information> _symbol_information; tree_item *_rootItem; };
--- a/gui/src/workspace-view.cc +++ b/gui/src/workspace-view.cc @@ -26,11 +26,13 @@ setObjectName ("WorkspaceView"); setWindowTitle (tr ("Workspace")); + _workspace_model = new workspace_model (); + _workspace_tree_view = new QTreeView (this); _workspace_tree_view->setHeaderHidden (false); _workspace_tree_view->setAlternatingRowColors (true); _workspace_tree_view->setAnimated (true); - _workspace_tree_view->setModel(octave_link::instance()->get_workspace_model()); + _workspace_tree_view->setModel (_workspace_model); setWidget (new QWidget (this)); QVBoxLayout *layout = new QVBoxLayout (); @@ -41,16 +43,8 @@ connect (this, SIGNAL (visibilityChanged (bool)), this, SLOT(handle_visibility_changed (bool))); - connect (octave_link::instance()->get_workspace_model(), SIGNAL(expand_request()), + connect (_workspace_model, SIGNAL(expand_request()), _workspace_tree_view, SLOT(expandAll())); - - connect(&_update_workspace_model_timer, SIGNAL (timeout ()), - octave_link::instance()->get_workspace_model(), - SLOT (update_from_symbol_table ())); - - _update_workspace_model_timer.setInterval (1000); - _update_workspace_model_timer.setSingleShot (false); - _update_workspace_model_timer.start (); } void
--- a/gui/src/workspace-view.h +++ b/gui/src/workspace-view.h @@ -42,9 +42,8 @@ private: QTreeView *_workspace_tree_view; - /** Timer for periodically updating the workspace model from the current - * symbol information. */ - QTimer _update_workspace_model_timer; + /** Stores the current workspace model. */ + workspace_model *_workspace_model; }; #endif // WORKSPACEVIEW_H