Mercurial > hg > octave-lojdl
changeset 16502:45ae1038ee89
allow renaming of variables in workspace viewer
* main-window.h, main-window.cc
(main_window::handle_rename_variable_request): New function.
(main_window::construct_octave_qt_link): Connect
_workspace_model::rename_variable to
main_window::handle_rename_variable_request.
(main_window::rename_variable_callback): New function.
* octave-qt-link.h, octave-qt-link.cc
(octave_qt_link::do_set_workspace,
octave_qt_link::set_workspace_signal): New argument, top_level.
Change all uses.
* octave-link.h, octave-link.cc (octave_link::post_event):
Provide two-argument version.
(octave_link::set_workspace, octave_link::do_set_workspace):
New argument, top_level. Change all uses.
* workspace-model.h, workspace-model.cc (workspace_model::flags):
Conditionally add Qt::ItemIsEditable to flags.
(workspace_model::data): Also return value for column 0 if it is
editable.
(workspace_model::setData): Handle setting new values.
(workspace_model::_top_level): New data member.
(workspace_model::set_workspace): New argument, top_level.
(workspace_model::rename_variable): New signal.
* workspace-view.h, workspace-view.cc (variable_name_editor):
New class.
(workspace_view::var_name_editor): New data member.
(workspace_view::workspace_view): Initialize it. Set var_name_editor
as delegate for column 0.
(workspace_view::~workspace_view): Delete var_name_editor.
(workspace_view::item_double_clicked): Delete.
* symtab.h (symbol_table::rename, symbol_table::do_rename,
symbol_table::symbol_record::rename): New functions.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 12 Apr 2013 14:50:56 -0400 |
parents | 3781abc74540 |
children | c1ff738d606d |
files | libgui/src/main-window.cc libgui/src/main-window.h libgui/src/octave-qt-link.cc libgui/src/octave-qt-link.h libgui/src/workspace-model.cc libgui/src/workspace-model.h libgui/src/workspace-view.cc libgui/src/workspace-view.h libinterp/interpfcn/input.cc libinterp/interpfcn/octave-link.h libinterp/interpfcn/symtab.h |
diffstat | 11 files changed, 266 insertions(+), 54 deletions(-) [+] |
line wrap: on
line diff
--- a/libgui/src/main-window.cc +++ b/libgui/src/main-window.cc @@ -39,6 +39,8 @@ #include <QMessageBox> #include <QIcon> +#include <utility> + #ifdef HAVE_QSCINTILLA #include "file-editor.h" #endif @@ -49,6 +51,7 @@ #include "builtin-defun-decls.h" #include "defaults.h" +#include "symtab.h" #include "version.h" static file_editor_interface * @@ -148,6 +151,17 @@ } void +main_window::handle_rename_variable_request (const QString& old_name, + const QString& new_name) + +{ + name_pair names (old_name.toStdString (), new_name.toStdString ()); + + octave_link::post_event (this, &main_window::rename_variable_callback, + names); +} + +void main_window::handle_clear_history_request (void) { octave_link::post_event (this, &main_window::clear_history_callback); @@ -598,12 +612,14 @@ connect (_octave_qt_link, SIGNAL (set_workspace_signal - (const QString&, const QStringList&, const QStringList&, - const QStringList&, const QStringList&)), + (bool, const QString&, const QStringList&, + const QStringList&, const QStringList&, + const QStringList&)), _workspace_model, SLOT (set_workspace - (const QString&, const QStringList&,const QStringList&, - const QStringList&, const QStringList&))); + (bool, const QString&, const QStringList&, + const QStringList&, const QStringList&, + const QStringList&))); connect (_octave_qt_link, SIGNAL (clear_workspace_signal ()), _workspace_model, SLOT (clear_workspace ())); @@ -649,6 +665,12 @@ editor_window, SLOT (handle_delete_debugger_pointer_request (const QString&, int))); + connect (_workspace_model, + SIGNAL (rename_variable (const QString&, const QString&)), + this, + SLOT (handle_rename_variable_request (const QString&, + const QString&))); + _octave_qt_link->execute_interpreter (); octave_link::connect_link (_octave_qt_link); @@ -1184,6 +1206,18 @@ } void +main_window::rename_variable_callback (const main_window::name_pair& names) +{ + /* bool status = */ symbol_table::rename (names.first, names.second); + + // if (status) + octave_link::set_workspace (true, symbol_table::workspace_info ()); + + // else + // ; // we need an octave_link action that runs a GUI error option. +} + +void main_window::clear_history_callback (void) { Fhistory (ovl ("-c"));
--- a/libgui/src/main-window.h +++ b/libgui/src/main-window.h @@ -64,6 +64,8 @@ public: + typedef std::pair <std::string, std::string> name_pair; + main_window (QWidget *parent = 0); ~main_window (void); @@ -82,6 +84,8 @@ void handle_load_workspace_request (void); void handle_clear_workspace_request (void); void handle_clear_history_request (void); + void handle_rename_variable_request (const QString& old_name, + const QString& new_name); void new_file (const QString& commands = QString ()); void open_file (const QString& file_name = QString ()); void open_online_documentation_page (void); @@ -150,6 +154,8 @@ void load_workspace_callback (const std::string& file); + void rename_variable_callback (const name_pair& names); + void clear_workspace_callback (void); void clear_history_callback (void);
--- a/libgui/src/octave-qt-link.cc +++ b/libgui/src/octave-qt-link.cc @@ -69,7 +69,8 @@ } void -octave_qt_link::do_set_workspace (const std::list<workspace_element>& ws) +octave_qt_link::do_set_workspace (bool top_level, + const std::list<workspace_element>& ws) { QString scopes; QStringList symbols; @@ -87,7 +88,8 @@ values.append (QString::fromStdString (it->value ())); } - emit set_workspace_signal (scopes, symbols, class_names, dimensions, values); + emit set_workspace_signal (top_level, scopes, symbols, class_names, + dimensions, values); } void
--- a/libgui/src/octave-qt-link.h +++ b/libgui/src/octave-qt-link.h @@ -61,7 +61,9 @@ void do_change_directory (const std::string& dir); - void do_set_workspace (const std::list<workspace_element>& ws); + void do_set_workspace (bool top_level, + const std::list<workspace_element>& ws); + void do_clear_workspace (void); void do_set_history (const string_vector& hist); @@ -99,7 +101,8 @@ void change_directory_signal (const QString& dir); - void set_workspace_signal (const QString& scopes, + void set_workspace_signal (bool top_level, + const QString& scopes, const QStringList& symbols, const QStringList& class_names, const QStringList& dimensions,
--- a/libgui/src/workspace-model.cc +++ b/libgui/src/workspace-model.cc @@ -27,8 +27,7 @@ #include <QTreeWidget> -#include "symtab.h" -#include "variables.h" +#include "utils.h" #include "workspace-model.h" @@ -56,10 +55,15 @@ Qt::ItemFlags workspace_model::flags (const QModelIndex& idx) const { - if (! idx.isValid ()) - return 0; + Qt::ItemFlags retval = 0; + + if (idx.isValid ()) + retval |= Qt::ItemIsEnabled | Qt::ItemIsSelectable; - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + if (idx.column () == 0) + retval |= Qt::ItemIsEditable; + + return retval; } QVariant @@ -75,37 +79,73 @@ QVariant workspace_model::data (const QModelIndex& idx, int role) const { - if (!idx.isValid()) - return QVariant(); + QVariant retval; - if (role != Qt::DisplayRole) - return QVariant (); - - switch (idx.column ()) + if (idx.isValid () + && (role == Qt::DisplayRole + || (idx.column () == 0 && role == Qt::EditRole))) { - case 0: - return QVariant(_symbols[idx.row()]); + switch (idx.column ()) + { + case 0: + retval = QVariant (_symbols[idx.row()]); + break; - case 1: - return QVariant(_class_names[idx.row()]); + case 1: + retval = QVariant (_class_names[idx.row()]); + break; - case 2: - return QVariant(_dimensions[idx.row()]); + case 2: + retval = QVariant (_dimensions[idx.row()]); + break; - case 3: - return QVariant(_values[idx.row()]); + case 3: + retval = QVariant (_values[idx.row()]); + break; + + default: + break; + } } - return QVariant (); + return retval; } +bool +workspace_model::setData (const QModelIndex& idx, const QVariant& value, + int role) +{ + bool retval = false; + + if (idx.column () == 0 && role == Qt::EditRole) + { + QString qold_name = _symbols[idx.row()]; + + QString qnew_name = value.toString (); + + std::string new_name = qnew_name.toStdString (); + + if (valid_identifier (new_name)) + { + emit rename_variable (qold_name, qnew_name); + + retval = true; + } + } + + return retval; +} + + void -workspace_model::set_workspace (const QString& scopes, +workspace_model::set_workspace (bool top_level, + const QString& scopes, const QStringList& symbols, const QStringList& class_names, const QStringList& dimensions, const QStringList& values) { + _top_level = top_level; _scopes = scopes; _symbols = symbols; _class_names = class_names; @@ -129,6 +169,7 @@ void workspace_model::clear_data (void) { + _top_level = false; _scopes = QString (); _symbols = QStringList (); _class_names = QStringList ();
--- a/libgui/src/workspace-model.h +++ b/libgui/src/workspace-model.h @@ -42,6 +42,9 @@ QVariant data (const QModelIndex& index, int role) const; + bool setData (const QModelIndex& index, const QVariant& value, + int role = Qt::EditRole); + Qt::ItemFlags flags (const QModelIndex& index) const; QVariant headerData (int section, Qt::Orientation orientation, @@ -51,9 +54,12 @@ int columnCount (const QModelIndex& parent = QModelIndex ()) const; + bool is_top_level (void) const { return _top_level; } + public slots: - void set_workspace (const QString& scopes, + void set_workspace (bool top_level, + const QString& scopes, const QStringList& symbols, const QStringList& class_names, const QStringList& dimensions, @@ -65,11 +71,14 @@ void model_changed (void); + void rename_variable (const QString& old_name, const QString& new_name); + private: void clear_data (void); void update_table (void); + bool _top_level; QString _scopes; QStringList _symbols; QStringList _class_names;
--- a/libgui/src/workspace-view.cc +++ b/libgui/src/workspace-view.cc @@ -25,24 +25,85 @@ #include <config.h> #endif -#include "workspace-view.h" -#include "resource-manager.h" +#include <QMessageBox> +#include <QLineEdit> #include <QHeaderView> #include <QHBoxLayout> #include <QVBoxLayout> #include <QPushButton> #include <QMenu> +#include "workspace-view.h" +#include "resource-manager.h" + +QWidget * +variable_name_editor::createEditor (QWidget *p, const QStyleOptionViewItem&, + const QModelIndex& index) const +{ + QWidget *retval = 0; + + const QAbstractItemModel *m = index.model (); + + const workspace_model *wm = static_cast<const workspace_model *> (m); + + if (wm->is_top_level ()) + retval = new QLineEdit (p); + else + { + QMessageBox *msg_box + = new QMessageBox (QMessageBox::Critical, + tr ("Workspace Viewer"), + tr ("Only top-level symbols may be renamed.\n"), + QMessageBox::Ok); + + msg_box->setWindowModality (Qt::NonModal); + msg_box->setAttribute (Qt::WA_DeleteOnClose); + msg_box->show (); + } + + return retval; +} + +void +variable_name_editor::setEditorData (QWidget *editor, + const QModelIndex& index) const +{ + QLineEdit *line_editor = static_cast<QLineEdit *> (editor); + + const QAbstractItemModel *m = index.model (); + + QVariant d = m->data (index, Qt::EditRole); + + line_editor->insert (d.toString ()); +} + +void +variable_name_editor::setModelData (QWidget *editor, + QAbstractItemModel *model, + const QModelIndex& index) const +{ + QLineEdit *line_editor = static_cast<QLineEdit*> (editor); + + model->setData (index, line_editor->text (), Qt::EditRole); +} + +void +variable_name_editor::updateEditorGeometry (QWidget *editor, + const QStyleOptionViewItem& option, + const QModelIndex&) const +{ + editor->setGeometry (option.rect); +} + workspace_view::workspace_view (QWidget *p) - : octave_dock_widget (p) + : octave_dock_widget (p), view (new QTableView (this)), + var_name_editor (new variable_name_editor (this)) { setObjectName ("WorkspaceView"); setWindowIcon (QIcon (":/actions/icons/logo.png")); setWindowTitle (tr ("Workspace")); setStatusTip (tr ("View the variables in the active workspace.")); - view = new QTableView (this); - view->setWordWrap (false); view->setContextMenuPolicy (Qt::CustomContextMenu); @@ -61,16 +122,13 @@ QSettings *settings = resource_manager::get_settings (); - // FIXME -- what should happen if settings is 0? - // Initialize column order and width of the workspace view->horizontalHeader ()->restoreState (settings->value ("workspaceview/column_state").toByteArray ()); - // Connect signals and slots. + view->setItemDelegateForColumn (0, var_name_editor); - connect (view, SIGNAL (doubleClicked (QModelIndex)), - this, SLOT (item_double_clicked (QModelIndex))); + // Connect signals and slots. connect (view, SIGNAL (customContextMenuRequested (const QPoint&)), this, SLOT(contextmenu_requested (const QPoint&))); @@ -87,13 +145,8 @@ view->horizontalHeader ()->saveState ()); settings->sync (); -} -void -workspace_view::item_double_clicked (QModelIndex) -{ - // TODO: Implement opening a dialog that allows the user to change a - // variable in the workspace. + delete var_name_editor; } void
--- a/libgui/src/workspace-view.h +++ b/libgui/src/workspace-view.h @@ -24,12 +24,34 @@ #if !defined (workspace_view_h) #define workspace_view_h 1 +#include <QItemDelegate> #include <QTableView> #include <QSemaphore> #include "octave-dock-widget.h" #include "workspace-model.h" +class variable_name_editor : public QItemDelegate +{ + Q_OBJECT + +public: + + variable_name_editor (QObject *p = 0) : QItemDelegate (p) { } + + QWidget *createEditor (QWidget *p, const QStyleOptionViewItem& option, + const QModelIndex& index) const; + + void setEditorData (QWidget *editor, const QModelIndex& index) const; + + void setModelData (QWidget *editor, QAbstractItemModel *model, + const QModelIndex& index) const; + + void updateEditorGeometry (QWidget *editor, + const QStyleOptionViewItem& option, + const QModelIndex&) const; +}; + class workspace_view : public octave_dock_widget { Q_OBJECT @@ -44,7 +66,6 @@ void setModel (workspace_model *model) { view->setModel (model); } - signals: /** signal that user had requested a command on a variable */ @@ -56,7 +77,6 @@ protected slots: - void item_double_clicked (QModelIndex index); void contextmenu_requested (const QPoint& pos); // context menu slots @@ -68,7 +88,9 @@ void relay_contextmenu_command (const QString& cmdname); - QTableView * view; + QTableView *view; + + variable_name_editor *var_name_editor; }; #endif
--- a/libinterp/interpfcn/input.cc +++ b/libinterp/interpfcn/input.cc @@ -219,7 +219,9 @@ octave_link::pre_input_event (); - octave_link::set_workspace (symbol_table::workspace_info ()); + octave_link::set_workspace ((symbol_table::current_scope () + == symbol_table::top_scope ()), + symbol_table::workspace_info ()); // FIXME -- this call should happen any time the terminal window // size changes, not just prior to prompting for input. @@ -526,7 +528,9 @@ { octave_link::enter_debugger_event (nm, curr_debug_line); - octave_link::set_workspace (symbol_table::workspace_info ()); + octave_link::set_workspace ((symbol_table::current_scope () + == symbol_table::top_scope ()), + symbol_table::workspace_info ()); frame.add_fcn (execute_in_debugger_handler, std::pair<std::string, int> (nm, curr_debug_line));
--- a/libinterp/interpfcn/octave-link.h +++ b/libinterp/interpfcn/octave-link.h @@ -108,6 +108,14 @@ instance->do_post_event (obj, method, arg); } + template <class T, class A, class B> + static void post_event (T *obj, void (T::*method) (const A&, const B&), + const A& arg_a, const B& arg_b) + { + if (enabled ()) + instance->do_post_event (obj, method, arg_a, arg_b); + } + static void entered_readline_hook (void) { if (enabled ()) @@ -132,10 +140,11 @@ instance->do_change_directory (dir); } - static void set_workspace (const std::list<workspace_element>& ws) + static void set_workspace (bool top_level, + const std::list<workspace_element>& ws) { if (enabled ()) - instance->do_set_workspace (ws); + instance->do_set_workspace (top_level, ws); } static void clear_workspace (void) @@ -269,7 +278,8 @@ virtual void do_change_directory (const std::string& dir) = 0; virtual void - do_set_workspace (const std::list<workspace_element>& ws) = 0; + do_set_workspace (bool top_level, + const std::list<workspace_element>& ws) = 0; virtual void do_clear_workspace (void) = 0;
--- a/libinterp/interpfcn/symtab.h +++ b/libinterp/interpfcn/symtab.h @@ -527,6 +527,8 @@ const std::string& name (void) const { return rep->name; } + void rename (const std::string& new_name) { rep->name = new_name; } + octave_value find (const octave_value_list& args = octave_value_list ()) const; @@ -1283,6 +1285,16 @@ return inst ? inst->do_insert (name) : foobar; } + static void rename (const std::string& old_name, + const std::string& new_name, + scope_id scope = xcurrent_scope) + { + symbol_table *inst = get_instance (scope); + + if (inst) + inst->do_rename (old_name, new_name); + } + static void assign (const std::string& name, const octave_value& value = octave_value (), scope_id scope = xcurrent_scope, @@ -2462,6 +2474,22 @@ return p->second; } + void do_rename (const std::string& old_name, const std::string& new_name) + { + table_iterator p = table.find (old_name); + + if (p != table.end ()) + { + symbol_record sr = p->second; + + sr.rename (new_name); + + table.erase (p); + + table[new_name] = sr; + } + } + void do_assign (const std::string& name, const octave_value& value, context_id context, bool force_add) {