Mercurial > octave
changeset 27298:1805f8586179
new gui dialog for modifying octaves load path (bug #43549)
Originally submitted by JunWang,
Edited by Rik, jwe, and Torsten.
* main-window.cc (main_window): initialize new m_settings_dlg class variable;
(~main_window): delete set path dialog;
(handle_set_path_dialog_request): new slot for opening the path dialog;
(set_global_shortcuts): set shortcut for opening new path dialog;
(construct_edit_menu): add and connect related action to the edit menu;
(configure_shortcuts): read the shortcut from the preferences file
* main-window.h: include path dialog header, new path variable and new action
for dialog
* module.mk: add new files
* set-path-dialog.cc: new file
(set_path_dialog): constructing the dialog with widgets and buttons,
connecting all action signals, adding model object;
(add_dir): open file dailog to select directory to be added to the path;
(rm_dir): call rm_dir method in model object for removing selected dirs;
(move_dir_up, move_dir_bottom, move_dir_top, move_dir_bottom):
call related model object for moving selected dirs and update selection
and view accordingly;
* set-path-dialog.h: new header for path dialog
* set-path-model.cc: new file for path dialog model
(set_path_model): data signal connections and calling construct method;
(to_string): make a string from the current list of directories;
(model_to_path): set the octave path to the current model data;
(clear): clear the current model data;
(save): save current model data using savepath;
(revert) reset the model data to the state from dialog start;
(revert_last): Reset the model data to the state before the latest change;
(add_dir): add a directory to the current model data and path;
(rm_dir): remoce a directory from current model data and path;
(move_dir_up, move_dir_down, move_dir_top, move_dir_bottom): move one ore
more directory entries wihtin the path;
(rowCount): retiurn the size if the current model data;
(data): reimplemeneted method for returning data from the model;
(construct): loading the current path into the model;
(update_data): slot for update data signal
* set-path-model.h: model header file
* shortcut-manager.cc (do_init_data): initialize shortcut for path dialog
with empty key sequence
author | JunWang <jstzwj@aliyun.com> |
---|---|
date | Mon, 22 Jul 2019 23:51:01 -0400 |
parents | 6ac42f6615bb |
children | 6ec7b2e73b5b |
files | libgui/src/main-window.cc libgui/src/main-window.h libgui/src/module.mk libgui/src/set-path-dialog.cc libgui/src/set-path-dialog.h libgui/src/set-path-model.cc libgui/src/set-path-model.h libgui/src/shortcut-manager.cc |
diffstat | 8 files changed, 788 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/libgui/src/main-window.cc Sun Jul 28 21:51:26 2019 -0700 +++ b/libgui/src/main-window.cc Mon Jul 22 23:51:01 2019 -0400 @@ -103,8 +103,8 @@ m_doc_browser_window (nullptr), m_editor_window (nullptr), m_workspace_window (nullptr), m_variable_editor_window (nullptr), m_external_editor (new external_editor_interface (this)), - m_active_editor (m_external_editor), - m_settings_dlg (nullptr), m_find_files_dlg (nullptr), + m_active_editor (m_external_editor), m_settings_dlg (nullptr), + m_find_files_dlg (nullptr), m_set_path_dlg (nullptr), m_release_notes_window (nullptr), m_community_news_window (nullptr), m_clipboard (QApplication::clipboard ()), m_prevent_readline_conflicts (true), m_suppress_dbg_location (true), @@ -236,7 +236,7 @@ delete m_find_files_dlg; delete m_release_notes_window; - delete m_settings_dlg; + delete m_community_news_window; delete m_community_news_window; } @@ -1707,6 +1707,18 @@ focus_command_window (); // make sure that the command window has focus } + void main_window::handle_set_path_dialog_request (void) + { + if (m_set_path_dlg) // m_set_path_dlg is a guarded pointer! + return; + + m_set_path_dlg = new set_path_dialog (this); + + m_set_path_dlg->setModal (false); + m_set_path_dlg->setAttribute (Qt::WA_DeleteOnClose); + m_set_path_dlg->show (); + } + void main_window::find_files (const QString& start_dir) { @@ -1764,6 +1776,7 @@ m_load_workspace_action->setShortcut (no_key); m_save_workspace_action->setShortcut (no_key); m_preferences_action->setShortcut (no_key); + m_set_path_action->setShortcut (no_key); m_exit_action->setShortcut (no_key); // edit menu @@ -2407,6 +2420,9 @@ edit_menu->addSeparator (); + m_set_path_action + = edit_menu->addAction (tr ("Set Path")); + m_preferences_action = edit_menu->addAction (resource_manager::icon ("preferences-system"), tr ("Preferences...")); @@ -2436,6 +2452,10 @@ connect (m_preferences_action, SIGNAL (triggered (void)), this, SLOT (process_settings_dialog_request (void))); + + connect (m_set_path_action, SIGNAL (triggered (void)), + this, SLOT (handle_set_path_dialog_request (void))); + } QAction * main_window::construct_debug_menu_item (const char *icon, @@ -2769,7 +2789,6 @@ "main_file:load_workspace"); shortcut_manager::set_shortcut (m_save_workspace_action, "main_file:save_workspace"); - shortcut_manager::set_shortcut (m_preferences_action, "main_file:preferences"); shortcut_manager::set_shortcut (m_exit_action,"main_file:exit"); // edit menu @@ -2786,6 +2805,8 @@ "main_edit:clear_command_window"); shortcut_manager::set_shortcut (m_clear_workspace_action, "main_edit:clear_workspace"); + shortcut_manager::set_shortcut (m_set_path_action, "main_edit:set_path"); + shortcut_manager::set_shortcut (m_preferences_action, "main_edit:preferences"); // debug menu shortcut_manager::set_shortcut (m_debug_step_over, "main_debug:step_over");
--- a/libgui/src/main-window.h Sun Jul 28 21:51:26 2019 -0700 +++ b/libgui/src/main-window.h Mon Jul 22 23:51:01 2019 -0400 @@ -49,6 +49,7 @@ #include "documentation-dock-widget.h" #include "files-dock-widget.h" #include "find-files-dialog.h" +#include "set-path-dialog.h" #include "history-dock-widget.h" #include "octave-dock-widget.h" #include "qt-interpreter-events.h" @@ -198,6 +199,8 @@ void handle_octave_ready (); + void handle_set_path_dialog_request (void); + //! Find files dialog. //!@{ void find_files (const QString& startdir = QDir::currentPath ()); @@ -330,6 +333,7 @@ QAction *m_new_figure_action; QAction *m_load_workspace_action; QAction *m_save_workspace_action; + QAction *m_set_path_action; QAction *m_preferences_action; QAction *m_exit_action; @@ -386,6 +390,9 @@ find_files_dialog *m_find_files_dlg; + //! Set path dialog + QPointer<set_path_dialog> m_set_path_dlg; + //! Release notes window. QWidget *m_release_notes_window;
--- a/libgui/src/module.mk Sun Jul 28 21:51:26 2019 -0700 +++ b/libgui/src/module.mk Mon Jul 22 23:51:01 2019 -0400 @@ -156,7 +156,9 @@ %reldir%/moc-variable-editor-model.cc \ %reldir%/moc-find-files-dialog.cc \ %reldir%/moc-find-files-model.cc \ - %reldir%/moc-octave-dock-widget.cc + %reldir%/moc-octave-dock-widget.cc \ + %reldir%/moc-set-path-dialog.cc \ + %reldir%/moc-set-path-model.cc octave_gui_MOC += \ $(OCTAVE_GUI_SRC_MOC) \ @@ -214,7 +216,10 @@ %reldir%/workspace-model.h \ %reldir%/workspace-view.h \ %reldir%/variable-editor.h \ - %reldir%/variable-editor-model.h + %reldir%/variable-editor-model.h \ + %reldir%/set-path-dialog.h \ + %reldir%/set-path-model.h + %canon_reldir%_%canon_reldir%_la_SOURCES = \ %reldir%/dialog.cc \ @@ -249,7 +254,9 @@ %reldir%/workspace-model.cc \ %reldir%/workspace-view.cc \ %reldir%/variable-editor.cc \ - %reldir%/variable-editor-model.cc + %reldir%/variable-editor-model.cc \ + %reldir%/set-path-dialog.cc \ + %reldir%/set-path-model.cc nodist_%canon_reldir%_%canon_reldir%_la_SOURCES = \ $(octave_gui_MOC) \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgui/src/set-path-dialog.cc Mon Jul 22 23:51:01 2019 -0400 @@ -0,0 +1,240 @@ +/* + +Copyright (C) 2019 JunWang + +This file is part of Octave. + +Octave 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. + +Octave 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 Octave; see the file COPYING. If not, see +<https://www.gnu.org/licenses/>. + +*/ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +#include <QPushButton> +#include <QDialogButtonBox> +#include <QGridLayout> +#include <QVBoxLayout> +#include <QHBoxLayout> +#include <QLabel> +#include <QLineEdit> +#include <QComboBox> +#include <QCheckBox> +#include <QHeaderView> +#include <QListView> +#include <QFileDialog> +#include <QStatusBar> +#include <QIcon> +#include <QFileInfo> +#include <QTimer> +#include <QDirIterator> +#include <QTextStream> +#include <QGroupBox> +#include <QFileDialog> + +#include "set-path-dialog.h" +#include "set-path-model.h" +#include "resource-manager.h" + +namespace octave +{ + set_path_dialog::set_path_dialog (QWidget *parent) + : QDialog (parent) + { + setWindowTitle (tr ("Set Path")); + + m_info_label = new QLabel (tr ("All changes take effect immediately.")); + + m_add_folder_button = new QPushButton (tr ("Add Folder...")); + m_move_to_top_button = new QPushButton (tr ("Move to Top")); + m_move_to_bottom_button = new QPushButton (tr ("Move to Bottom")); + m_move_up_button = new QPushButton (tr ("Move Up")); + m_move_down_button = new QPushButton (tr ("Move Down")); + m_remove_button = new QPushButton (tr ("Remove")); + + m_save_button = new QPushButton (tr ("Save")); + m_revert_button = new QPushButton (tr ("Revert")); + m_revert_last_button = new QPushButton (tr ("Revert Last")); + + m_save_button->setFocus (); + + connect (m_add_folder_button, SIGNAL (clicked (void)), + this, SLOT (add_dir (void))); + + connect (m_remove_button, SIGNAL (clicked (void)), + this, SLOT (rm_dir (void))); + + connect (m_move_to_top_button, SIGNAL (clicked (void)), + this, SLOT (move_dir_top (void))); + + connect (m_move_to_bottom_button, SIGNAL (clicked (void)), + this, SLOT (move_dir_bottom (void))); + + connect (m_move_up_button, SIGNAL (clicked (void)), + this, SLOT (move_dir_up (void))); + + connect (m_move_down_button, SIGNAL (clicked (void)), + this, SLOT (move_dir_down (void))); + + set_path_model *model = new set_path_model (this); + + connect (m_save_button, SIGNAL (clicked (void)), + model, SLOT (save (void))); + + connect (m_revert_button, SIGNAL (clicked (void)), + model, SLOT (revert (void))); + + connect (m_revert_last_button, SIGNAL (clicked (void)), + model, SLOT (revert_last (void))); + + m_path_list = new QListView (this); + m_path_list->setWordWrap (false); + m_path_list->setModel (model); + m_path_list->setSelectionBehavior (QAbstractItemView::SelectRows); + m_path_list->setSelectionMode (QAbstractItemView::ExtendedSelection); + m_path_list->setAlternatingRowColors (true); + + // layout everything + QDialogButtonBox *button_box = new QDialogButtonBox (Qt::Horizontal); + button_box->addButton (m_save_button, QDialogButtonBox::ActionRole); + + // add dialog close button + m_close_button = button_box->addButton (QDialogButtonBox::Close); + connect (button_box, SIGNAL (rejected (void)), this, SLOT (close (void))); + + button_box->addButton (m_revert_last_button, QDialogButtonBox::ActionRole); + button_box->addButton (m_revert_button, QDialogButtonBox::ActionRole); + + // path edit options + QDialogButtonBox *path_edit_layout = new QDialogButtonBox (Qt::Vertical); + path_edit_layout->addButton (m_add_folder_button, QDialogButtonBox::ActionRole); + path_edit_layout->addButton (m_move_to_top_button, QDialogButtonBox::ActionRole); + path_edit_layout->addButton (m_move_up_button, QDialogButtonBox::ActionRole); + path_edit_layout->addButton (m_move_down_button, QDialogButtonBox::ActionRole); + path_edit_layout->addButton (m_move_to_bottom_button, QDialogButtonBox::ActionRole); + path_edit_layout->addButton (m_remove_button, QDialogButtonBox::ActionRole); + + // main layout + QHBoxLayout *main_hboxlayout = new QHBoxLayout; + main_hboxlayout->addWidget(path_edit_layout); + main_hboxlayout->addWidget(m_path_list); + + QGridLayout *main_layout = new QGridLayout; + main_layout->addWidget (m_info_label, 0, 0); + main_layout->addLayout (main_hboxlayout, 1, 0); + main_layout->addWidget (button_box,2, 0); + + setLayout (main_layout); + } + + set_path_dialog::~set_path_dialog (void) + { + } + + void set_path_dialog::add_dir(void) + { + QString dir + = QFileDialog::getExistingDirectory (this, tr ("Open Directory"), + "", + (QFileDialog::ShowDirsOnly + | QFileDialog::DontResolveSymlinks)); + set_path_model *m = static_cast<set_path_model *> (m_path_list->model ()); + m->add_dir (dir); + } + + void set_path_dialog::rm_dir (void) + { + set_path_model *m = static_cast<set_path_model *> (m_path_list->model ()); + QItemSelectionModel *selmodel = m_path_list->selectionModel (); + QModelIndexList indexlist = selmodel->selectedIndexes(); + m->rm_dir (indexlist); + + selmodel->clearSelection (); + } + + void set_path_dialog::move_dir_up (void) + { + set_path_model *m = static_cast<set_path_model *> (m_path_list->model ()); + QItemSelectionModel *selmodel = m_path_list->selectionModel (); + QModelIndexList indexlist = selmodel->selectedIndexes(); + m->move_dir_up (indexlist); + + // Update selection and view + selmodel->clearSelection (); + int min_row = m->rowCount () - 1; + for (int i = 0; i < indexlist.length (); i++) + { + int new_row = std::max (indexlist.at (i).row () - 1, 0); + min_row = std::min (min_row, new_row); + selmodel->select (m->index (new_row), QItemSelectionModel::Select); + } + + m_path_list->scrollTo (m->index (min_row)); + } + + void set_path_dialog::move_dir_down (void) + { + set_path_model *m = static_cast<set_path_model *> (m_path_list->model ()); + QItemSelectionModel *selmodel = m_path_list->selectionModel (); + QModelIndexList indexlist = selmodel->selectedIndexes(); + m->move_dir_down (indexlist); + + // Update selection and view + selmodel->clearSelection (); + int max_row = 0; + for (int i = 0; i < indexlist.length (); i++) + { + int new_row = std::min (indexlist.at (i).row () + 1, m->rowCount () - 1); + max_row = std::max (max_row, new_row); + selmodel->select (m->index (new_row), QItemSelectionModel::Select); + } + + m_path_list->scrollTo (m->index (max_row)); + } + + void set_path_dialog::move_dir_top (void) + { + set_path_model *m = static_cast<set_path_model *> (m_path_list->model ()); + QItemSelectionModel *selmodel = m_path_list->selectionModel (); + QModelIndexList indexlist = selmodel->selectedIndexes(); + m->move_dir_top (indexlist); + + // Update selection and view + selmodel->clearSelection (); + for (int i = 0; i < indexlist.length (); i++) + selmodel->select (m->index (i), QItemSelectionModel::Select); + + m_path_list->scrollTo (m->index (0)); + } + + void set_path_dialog::move_dir_bottom (void) + { + set_path_model *m = static_cast<set_path_model *> (m_path_list->model ()); + QItemSelectionModel *selmodel = m_path_list->selectionModel (); + QModelIndexList indexlist = selmodel->selectedIndexes(); + m->move_dir_bottom (indexlist); + + // Update selection and view + selmodel->clearSelection (); + int row_count = m->rowCount (); + for (int i = 0; i < indexlist.length (); i++) + selmodel->select (m->index (row_count - 1 - i), + QItemSelectionModel::Select); + + m_path_list->scrollTo (m->index (row_count - 1)); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgui/src/set-path-dialog.h Mon Jul 22 23:51:01 2019 -0400 @@ -0,0 +1,80 @@ +/* + +Copyright (C) 2019 JunWang + +This file is part of Octave. + +Octave 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. + +Octave 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 Octave; see the file COPYING. If not, see +<https://www.gnu.org/licenses/>. + +*/ +#if ! defined (octave_set_path_dialog_h) +#define octave_set_path_dialog_h 1 + +#include <QDialog> +#include <QModelIndex> +#include <QFileInfo> + +class QLabel; +class QPushButton; +class QListView; +class QVBoxLayout; +class QHBoxLayout; + +namespace octave +{ + class set_path_dialog : public QDialog + { + Q_OBJECT + + public: + + set_path_dialog (QWidget *parent = nullptr); + + virtual ~set_path_dialog (void); + + private slots: + + void add_dir(void); + + void rm_dir (void); + + void move_dir_up (void); + + void move_dir_down (void); + + void move_dir_top (void); + + void move_dir_bottom (void); + + private: + + QLabel *m_info_label; + QPushButton *m_save_button; + QPushButton *m_close_button; + QPushButton *m_revert_button; + QPushButton *m_revert_last_button; + + QListView *m_path_list; + + QPushButton *m_add_folder_button; + QPushButton *m_move_to_top_button; + QPushButton *m_move_to_bottom_button; + QPushButton *m_move_up_button; + QPushButton *m_move_down_button; + QPushButton *m_remove_button; + }; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgui/src/set-path-model.cc Mon Jul 22 23:51:01 2019 -0400 @@ -0,0 +1,329 @@ +/* + +Copyright (C) 2019 JunWang + +This file is part of Octave. + +Octave 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. + +Octave 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 Octave; see the file COPYING. If not, see +<https://www.gnu.org/licenses/>. + +*/ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +#include <iostream> + +#include <string> +#include <algorithm> + +#include <QFileIconProvider> +#include <QtAlgorithms> +#include <QMessageBox> + +#include "pathsearch.h" + +#include "event-manager.h" +#include "interpreter-private.h" +#include "interpreter.h" +#include "load-path.h" + +#include "set-path-model.h" + +namespace octave +{ + set_path_model::set_path_model (QObject *p) + : QAbstractListModel (p) + { + connect (this, SIGNAL (update_data_signal (const QStringList&)), + this, SLOT (update_data (const QStringList&))); + + construct (); + } + + std::string set_path_model::to_string (void) + { + std::string path_sep = directory_path::path_sep_str (); + + std::string path_str; + + QStringList::iterator it = m_dirs.begin (); + + while (it < m_dirs.end ()) + { + if (it != m_dirs.begin ()) + path_str += path_sep; + path_str += it->toStdString (); + ++it; + } + + return path_str; + } + + void set_path_model::model_to_path (void) + { + event_manager& evmgr + = __get_event_manager__ ("set_path_model::model_to_path"); + + std::string path_str = to_string (); + + evmgr.post_event + ([path_str] (void) + { + // INTERPRETER THREAD + + load_path& lp = __get_load_path__ ("set_path_model::model_to_path"); + + lp.set (path_str); + + }); + } + + void set_path_model::clear (void) + { + beginResetModel (); + + m_dirs.clear (); + + endResetModel (); + } + + void set_path_model::save (void) + { + model_to_path (); + + event_manager& evmgr = __get_event_manager__ ("set_path_model::save"); + + evmgr.post_event + ([] (void) + { + // INTERPRETER THREAD + + interpreter& interp = __get_interpreter__ ("set_path_model::save"); + + interp.feval ("savepath"); + }); + } + + void set_path_model::revert (void) + { + clear (); + + beginInsertRows (QModelIndex (), 0, m_orig_dirs.size () - 1); + m_dirs = m_orig_dirs; + endInsertRows (); + + model_to_path (); + } + + void set_path_model::revert_last (void) + { + clear (); + + beginInsertRows (QModelIndex (), 0, m_last_dirs.size () - 1); + m_dirs = m_last_dirs; + endInsertRows (); + + model_to_path (); + } + + void set_path_model::add_dir (const QString& p) + { + m_last_dirs = m_dirs; + + beginInsertRows (QModelIndex (), m_dirs.size (), m_dirs.size ()); + + QList<QString>::Iterator it = m_dirs.begin(); + + m_dirs.insert (it, p); + + endInsertRows (); + + model_to_path (); + } + + void set_path_model::rm_dir (const QModelIndexList& indices) + { + m_last_dirs = m_dirs; + + for (int i = indices.size () - 1; i >= 0; i--) + { + const QModelIndex& idx = indices.at (i); + + beginRemoveRows (idx, idx.row (), idx.row ()); + m_dirs.removeAt (idx.row ()); + endRemoveRows (); + } + + model_to_path (); + } + + void set_path_model::move_dir_up (const QModelIndexList& indices) + { + m_last_dirs = m_dirs; + + for (int i = 0; i < indices.size (); i++) + { + const QModelIndex& idx = indices.at (i); + + if (idx.row () == 0 ) + continue; // already at top position + + beginMoveRows (idx, idx.row (), idx.row (), + this->index (idx.row () - 1), idx.row () - 1); + + m_dirs.move (idx.row (), idx.row () - 1); + + endMoveRows (); + } + + model_to_path (); + } + + void set_path_model::move_dir_down (const QModelIndexList& indices) + { + m_last_dirs = m_dirs; + + for (int i = indices.size () - 1; i >= 0; i--) + { + const QModelIndex& idx = indices.at (i); + int bottom = m_dirs.size () - 1; + + if (idx.row () >= bottom) + continue; // already at bottom position + + beginMoveRows (idx, idx.row (), idx.row (), + this->index (idx.row () + 1), idx.row () + 1); + + m_dirs.move (idx.row (), idx.row () + 1); + + endMoveRows (); + } + + model_to_path (); + } + + void set_path_model::move_dir_top (const QModelIndexList& indices) + { + m_last_dirs = m_dirs; + + for (int i = 0; i < indices.size (); i++) + { + const QModelIndex& idx = indices.at (i); + + if (idx.row () == i) + continue; // already at target position + + beginMoveRows (idx, idx.row (), idx.row (), this->index (i), i); + + m_dirs.move (idx.row (), i); + + endMoveRows (); + } + + model_to_path (); + } + + void set_path_model::move_dir_bottom (const QModelIndexList& indices) + { + m_last_dirs = m_dirs; + + for (int i = 0; i < indices.size (); i++) + { + const QModelIndex& idx = indices.at (i); + int target = m_dirs.size () - 1 - i; + + if (idx.row () == target) + continue; // already at target position + + beginMoveRows (idx, idx.row (), idx.row (), + this->index (target), target); + + m_dirs.move (idx.row (), target); + + endMoveRows (); + } + + model_to_path (); + } + + int set_path_model::rowCount (const QModelIndex&) const + { + return m_dirs.size (); + } + + QVariant set_path_model::data (const QModelIndex& idx, int role) const + { + QVariant retval; + if (idx.isValid ()) + { + switch (role) + { + case Qt::DisplayRole: + retval = QVariant (m_dirs[idx.row ()]); + break; + + case Qt::DecorationRole: + retval = QVariant (QIcon ()); + break; + + case Qt::SizeHintRole: + retval = QVariant (QSize (10, 20)); + break; + } + } + + return retval; + } + + void set_path_model::construct (void) + { + event_manager& evmgr = __get_event_manager__ ("set_path_model::construct"); + + evmgr.post_event + ([this] (void) + { + load_path& lp = __get_load_path__ ("set_path_model::construct"); + + std::list<std::string> dir_list = lp.dir_list (); + + QStringList qs_dir_list; + + for (const auto& dir : dir_list) + qs_dir_list << QString::fromStdString (dir); + + emit update_data_signal (qs_dir_list); + }); + } + + void set_path_model::update_data (const QStringList& dirs) + { + m_dirs = dirs; + + m_dirs.removeAll ("."); + + if (m_orig_dirs.isEmpty ()) + { + // first time update + m_orig_dirs = m_dirs; + m_last_dirs = m_dirs; + } + + int numel = m_dirs.size (); + + emit dataChanged (QAbstractListModel::index (0, 0), + QAbstractListModel::index (numel-1, 0)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgui/src/set-path-model.h Mon Jul 22 23:51:01 2019 -0400 @@ -0,0 +1,96 @@ +/* + +Copyright (C) 2019 JunWang + +This file is part of Octave. + +Octave 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. + +Octave 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 Octave; see the file COPYING. If not, see +<https://www.gnu.org/licenses/>. + +*/ + +#if ! defined (octave_set_path_model_h) +#define octave_set_path_model_h 1 + +#include <QAbstractListModel> +#include <QStringList> +#include <QList> +#include <QFileInfo> +#include <QIcon> + +namespace octave +{ + class set_path_model : public QAbstractListModel + { + Q_OBJECT + + public: + + set_path_model (QObject *p = nullptr); + + ~set_path_model (void) = default; + + void clear (void); + + void add_dir (const QString& p); + + void rm_dir (const QModelIndexList& indices); + + void move_dir_up (const QModelIndexList& indices); + + void move_dir_down (const QModelIndexList& indices); + + void move_dir_top (const QModelIndexList& indices); + + void move_dir_bottom (const QModelIndexList& indices); + + std::string to_string (void); + + // Overloaded Qt methods + + void model_to_path (void); + + int rowCount (const QModelIndex& p = QModelIndex ()) const; + + QVariant data (const QModelIndex& idx, int role) const; + + public slots: + + void save (void); + + void revert (void); + + void revert_last (void); + + signals: + + void update_data_signal (const QStringList& dirs); + + private slots: + + void update_data (const QStringList& dirs); + + private: + + void construct (void); + + QStringList m_dirs; + + QStringList m_orig_dirs; + + QStringList m_last_dirs; + }; +} + +#endif
--- a/libgui/src/shortcut-manager.cc Sun Jul 28 21:51:26 2019 -0700 +++ b/libgui/src/shortcut-manager.cc Mon Jul 22 23:51:01 2019 -0400 @@ -262,6 +262,7 @@ init (tr ("Clear Command History"), "main_edit:clear_history", QKeySequence ()); init (tr ("Clear Workspace"), "main_edit:clear_workspace", QKeySequence ()); + init (tr ("Set Path"), "main_edit:set_path", QKeySequence ()); init (tr ("Preferences"), "main_edit:preferences", QKeySequence ()); // debug