GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
set-path-dialog.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2019-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <QCheckBox>
31 #include <QComboBox>
32 #include <QDialogButtonBox>
33 #include <QDirIterator>
34 #include <QFileDialog>
35 #include <QFileDialog>
36 #include <QFileInfo>
37 #include <QGridLayout>
38 #include <QGroupBox>
39 #include <QHBoxLayout>
40 #include <QHeaderView>
41 #include <QIcon>
42 #include <QLabel>
43 #include <QLineEdit>
44 #include <QListView>
45 #include <QMenu>
46 #include <QPushButton>
47 #include <QStatusBar>
48 #include <QTextStream>
49 #include <QTimer>
50 #include <QVBoxLayout>
51 
52 #include "gui-preferences-pd.h"
53 #include "octave-qobject.h"
54 #include "set-path-dialog.h"
55 #include "set-path-model.h"
56 
57 #include "ovl.h"
58 
59 namespace octave
60 {
62  : QDialog (parent), m_octave_qobj (oct_qobj)
63  {
64  setWindowTitle (tr ("Set Path"));
65 
66  set_path_model *model = new set_path_model (this);
67 
68  m_info_label = new QLabel (tr ("All changes take effect immediately."));
69 
70  m_add_folder_button = new QPushButton (tr ("Add Folder..."));
71 
72  QMenu *add_dir_menu = new QMenu ();
73  m_add_folder_button->setMenu (add_dir_menu);
74  add_dir_menu->addAction (tr ("Single Folder"),
75  this, SLOT (add_dir (void)));
76  add_dir_menu->addAction (tr ("Folder with Subfolders"),
77  this, SLOT (add_dir_subdirs (void)));
78 
79  m_move_to_top_button = new QPushButton (tr ("Move to Top"));
80  m_move_to_bottom_button = new QPushButton (tr ("Move to Bottom"));
81  m_move_up_button = new QPushButton (tr ("Move Up"));
82  m_move_down_button = new QPushButton (tr ("Move Down"));
83  m_remove_button = new QPushButton (tr ("Remove"));
84 
85  m_reload_button = new QPushButton (tr ("Reload"));
86  m_save_button = new QPushButton (tr ("Save"));
87 
88  m_revert_button = new QPushButton (tr ("Revert"));
89 
90  QMenu *revert_menu = new QMenu ();
91  m_revert_button->setMenu (revert_menu);
92  revert_menu->addAction (tr ("Revert Last Change"),
93  model, SLOT (revert_last (void)));
94  revert_menu->addAction (tr ("Revert All Changes"),
95  model, SLOT (revert (void)));
96 
97  m_save_button->setFocus ();
98 
99  connect (m_remove_button, SIGNAL (clicked (void)),
100  this, SLOT (rm_dir (void)));
101 
102  connect (m_move_to_top_button, SIGNAL (clicked (void)),
103  this, SLOT (move_dir_top (void)));
104 
105  connect (m_move_to_bottom_button, SIGNAL (clicked (void)),
106  this, SLOT (move_dir_bottom (void)));
107 
108  connect (m_move_up_button, SIGNAL (clicked (void)),
109  this, SLOT (move_dir_up (void)));
110 
111  connect (m_move_down_button, SIGNAL (clicked (void)),
112  this, SLOT (move_dir_down (void)));
113 
114  connect (m_reload_button, SIGNAL (clicked (void)),
115  model, SLOT (path_to_model (void)));
116 
117  connect (m_save_button, SIGNAL (clicked (void)),
118  model, SLOT (save (void)));
119 
120  // Any interpreter_event signal from a set_path_model object is
121  // handled the same as for the parent set_path_dialog object.
122 
123  connect (model, SIGNAL (interpreter_event (const fcn_callback&)),
124  this, SIGNAL (interpreter_event (const fcn_callback&)));
125 
126  connect (model, SIGNAL (interpreter_event (const meth_callback&)),
127  this, SIGNAL (interpreter_event (const meth_callback&)));
128 
129  m_path_list = new QListView (this);
130  m_path_list->setWordWrap (false);
131  m_path_list->setModel (model);
132  m_path_list->setSelectionBehavior (QAbstractItemView::SelectRows);
133  m_path_list->setSelectionMode (QAbstractItemView::ExtendedSelection);
134  m_path_list->setAlternatingRowColors (true);
135  m_path_list->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
136 
137  // layout everything
138  QDialogButtonBox *button_box = new QDialogButtonBox (Qt::Horizontal);
139  button_box->addButton (m_save_button, QDialogButtonBox::ActionRole);
140  button_box->addButton (m_reload_button, QDialogButtonBox::ActionRole);
141 
142  // add dialog close button
143  m_close_button = button_box->addButton (QDialogButtonBox::Close);
144  connect (button_box, SIGNAL (rejected (void)), this, SLOT (close (void)));
145 
146  button_box->addButton (m_revert_button, QDialogButtonBox::ActionRole);
147 
148  // path edit options
149  QDialogButtonBox *path_edit_layout = new QDialogButtonBox (Qt::Vertical);
150  path_edit_layout->addButton (m_add_folder_button, QDialogButtonBox::ActionRole);
151  path_edit_layout->addButton (m_move_to_top_button, QDialogButtonBox::ActionRole);
152  path_edit_layout->addButton (m_move_up_button, QDialogButtonBox::ActionRole);
153  path_edit_layout->addButton (m_move_down_button, QDialogButtonBox::ActionRole);
154  path_edit_layout->addButton (m_move_to_bottom_button, QDialogButtonBox::ActionRole);
155  path_edit_layout->addButton (m_remove_button, QDialogButtonBox::ActionRole);
156 
157  // main layout
158  QHBoxLayout *main_hboxlayout = new QHBoxLayout;
159  main_hboxlayout->addWidget(path_edit_layout);
160  main_hboxlayout->addWidget(m_path_list);
161 
162  QGridLayout *main_layout = new QGridLayout;
163  main_layout->addWidget (m_info_label, 0, 0);
164  main_layout->addLayout (main_hboxlayout, 1, 0);
165  main_layout->addWidget (button_box,2, 0);
166 
167  setLayout (main_layout);
168 
171  restoreGeometry (
172  settings->value(pd_geometry.key).toByteArray());
173  }
174 
176  {
177  }
178 
180  {
181  set_path_model *m = static_cast<set_path_model *> (m_path_list->model ());
182  m->path_to_model ();
183  }
184 
186  {
187  QString dir
188  = QFileDialog::getExistingDirectory (this, tr ("Open Directory"),
189  "",
190  (QFileDialog::ShowDirsOnly
191  | QFileDialog::DontResolveSymlinks));
192 
193  if (! dir.isEmpty ())
194  {
195  if (subdirs)
196  {
197  // Use existing method mofifying load path and updating dialog
198  // instead of adding string and updating load path
199  octave_value_list dirlist = ovl ();
200  dirlist.append (dir.toStdString ());
201  emit modify_path_signal (dirlist, false, true);
202  }
203  else
204  {
206  = static_cast<set_path_model *> (m_path_list->model ());
207  m->add_dir (dir);
208  }
209  }
210  }
211 
213  {
214  add_dir_common (false);
215  }
216 
218  {
219  add_dir_common (true);
220  }
221 
223  {
224  set_path_model *m = static_cast<set_path_model *> (m_path_list->model ());
225  QItemSelectionModel *selmodel = m_path_list->selectionModel ();
226  QModelIndexList indexlist = selmodel->selectedIndexes();
227  m->rm_dir (indexlist);
228 
229  selmodel->clearSelection ();
230  }
231 
233  {
234  set_path_model *m = static_cast<set_path_model *> (m_path_list->model ());
235  QItemSelectionModel *selmodel = m_path_list->selectionModel ();
236  QModelIndexList indexlist = selmodel->selectedIndexes();
237  m->move_dir_up (indexlist);
238 
239  // Update selection and view
240  selmodel->clearSelection ();
241  int min_row = m->rowCount () - 1;
242  for (int i = 0; i < indexlist.length (); i++)
243  {
244  int new_row = std::max (indexlist.at (i).row () - 1, 0);
245  min_row = std::min (min_row, new_row);
246  selmodel->select (m->index (new_row), QItemSelectionModel::Select);
247  }
248 
249  m_path_list->scrollTo (m->index (min_row));
250  }
251 
253  {
254  set_path_model *m = static_cast<set_path_model *> (m_path_list->model ());
255  QItemSelectionModel *selmodel = m_path_list->selectionModel ();
256  QModelIndexList indexlist = selmodel->selectedIndexes();
257  m->move_dir_down (indexlist);
258 
259  // Update selection and view
260  selmodel->clearSelection ();
261  int max_row = 0;
262  for (int i = 0; i < indexlist.length (); i++)
263  {
264  int new_row = std::min (indexlist.at (i).row () + 1, m->rowCount () - 1);
265  max_row = std::max (max_row, new_row);
266  selmodel->select (m->index (new_row), QItemSelectionModel::Select);
267  }
268 
269  m_path_list->scrollTo (m->index (max_row));
270  }
271 
273  {
274  set_path_model *m = static_cast<set_path_model *> (m_path_list->model ());
275  QItemSelectionModel *selmodel = m_path_list->selectionModel ();
276  QModelIndexList indexlist = selmodel->selectedIndexes();
277  m->move_dir_top (indexlist);
278 
279  // Update selection and view
280  selmodel->clearSelection ();
281  for (int i = 0; i < indexlist.length (); i++)
282  selmodel->select (m->index (i), QItemSelectionModel::Select);
283 
284  m_path_list->scrollTo (m->index (0));
285  }
286 
288  {
289  set_path_model *m = static_cast<set_path_model *> (m_path_list->model ());
290  QItemSelectionModel *selmodel = m_path_list->selectionModel ();
291  QModelIndexList indexlist = selmodel->selectedIndexes();
292  m->move_dir_bottom (indexlist);
293 
294  // Update selection and view
295  selmodel->clearSelection ();
296  int row_count = m->rowCount ();
297  for (int i = 0; i < indexlist.length (); i++)
298  selmodel->select (m->index (row_count - 1 - i),
299  QItemSelectionModel::Select);
300 
301  m_path_list->scrollTo (m->index (row_count - 1));
302  }
303 
305  {
308  settings->setValue (pd_geometry.key, saveGeometry ());
309  }
310 
311  void set_path_dialog::closeEvent (QCloseEvent *e)
312  {
313  save_settings ();
314 
315  QWidget::closeEvent (e);
316  }
317 
318 }
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:230
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:207
Base class for Octave interfaces that use Qt.
resource_manager & get_resource_manager(void)
gui_settings * get_settings(void) const
virtual ~set_path_dialog(void)
void interpreter_event(const fcn_callback &fcn)
QPushButton * m_remove_button
set_path_dialog(QWidget *parent, base_qobject &oct_qobj)
QPushButton * m_move_to_top_button
void add_dir_common(bool subdirs)
base_qobject & m_octave_qobj
QPushButton * m_move_up_button
QPushButton * m_revert_button
QPushButton * m_add_folder_button
QPushButton * m_close_button
void modify_path_signal(const octave_value_list &dir_list, bool rm, bool subdirs)
Emitted, when the path has to be modified.
QPushButton * m_move_to_bottom_button
QPushButton * m_reload_button
QPushButton * m_move_down_button
void closeEvent(QCloseEvent *e)
octave_value_list & append(const octave_value &val)
Definition: ovl.cc:98
const gui_pref pd_geometry("path_dlg_geometry", QVariant(QByteArray()))
T octave_idx_type m
Definition: mx-inlines.cc:773
std::function< void(octave::interpreter &)> meth_callback
Definition: event-manager.h:47
std::function< void(void)> fcn_callback
Definition: event-manager.h:46
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:211
const QString key