GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
history-dock-widget.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2011-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 <QApplication>
31 #include <QClipboard>
32 #include <QCompleter>
33 #include <QLabel>
34 #include <QMenu>
35 #include <QScrollBar>
36 #include <QVBoxLayout>
37 
38 #include "gui-preferences-cs.h"
39 #include "gui-preferences-global.h"
40 #include "gui-preferences-hw.h"
41 #include "history-dock-widget.h"
42 #include "octave-qobject.h"
43 
44 #include "cmd-hist.h"
45 
46 #include "error.h"
47 
48 namespace octave
49 {
51  : octave_dock_widget ("HistoryDockWidget", p, oct_qobj)
52  {
53  setStatusTip (tr ("Browse and search the command history."));
54 
55  connect (this, SIGNAL (command_create_script (const QString&)),
56  p, SLOT (new_file (const QString&)));
57 
58  connect (this, SIGNAL (information (const QString&)),
59  p, SLOT (report_status_message (const QString&)));
60 
61  connect (this, SIGNAL (command_double_clicked (const QString&)),
62  p, SLOT (execute_command_in_terminal (const QString&)));
63 
64  construct ();
65  }
66 
67  void history_dock_widget::set_history (const QStringList& hist)
68  {
69  m_history_model->setStringList (hist);
70  m_history_list_view->scrollToBottom ();
71  }
72 
73  void history_dock_widget::append_history (const QString& hist_entry)
74  {
75  QStringList lst = m_history_model->stringList ();
76  lst.append (hist_entry);
77 
78  QScrollBar *scroll_bar = m_history_list_view->verticalScrollBar ();
79 
80  bool at_bottom = scroll_bar->maximum () - scroll_bar->value () < 1;
81 
82  m_history_model->setStringList (lst);
83 
84  // Scroll if slider position at bottom.
85  if (at_bottom)
86  m_history_list_view->scrollToBottom ();
87  }
88 
90  {
91  m_history_model->setStringList (QStringList ());
92  }
93 
95  {
98 
99  if (! settings)
100  return;
101 
102  settings->setValue (hw_filter_active.key, m_filter_checkbox->isChecked ());
104 
105  QStringList mru;
106  for (int i = 0; i < m_filter->count (); i++)
107  mru.append (m_filter->itemText (i));
108  settings->setValue (hw_mru_list.key, mru);
109 
110  settings->sync ();
111 
113  }
114 
116  {
117  QString text = m_filter->currentText (); // get current text
118  int index = m_filter->findText (text); // and its actual index
119 
120  if (index > -1)
121  m_filter->removeItem (index); // remove if already existing
122 
123  m_filter->insertItem (0, text); // (re)insert at beginning
124  m_filter->setCurrentIndex (0);
125  }
126 
128  {
129  m_filter->setEnabled (state);
130  m_sort_filter_proxy_model.setDynamicSortFilter (state);
131 
132  if (state)
133  m_sort_filter_proxy_model.setFilterWildcard (m_filter->currentText ());
134  else
135  m_sort_filter_proxy_model.setFilterWildcard (QString ());
136  }
137 
138  void history_dock_widget::ctxMenu (const QPoint& xpos)
139  {
140  QMenu menu (this);
141 
142  QModelIndex index = m_history_list_view->indexAt (xpos);
143 
144  if (index.isValid () && index.column () == 0)
145  {
147 
148  menu.addAction (rmgr.icon ("edit-copy"), tr ("Copy"), this,
149  SLOT (handle_contextmenu_copy (bool)));
150  menu.addAction (tr ("Evaluate"), this,
151  SLOT (handle_contextmenu_evaluate (bool)));
152  menu.addAction (rmgr.icon ("document-new"), tr ("Create script"), this,
153  SLOT (handle_contextmenu_create_script (bool)));
154  }
155  if (m_filter_shown)
156  menu.addAction (tr ("Hide filter"), this,
157  SLOT (handle_contextmenu_filter ()));
158  else
159  menu.addAction (tr ("Show filter"), this,
160  SLOT (handle_contextmenu_filter ()));
161 
162  menu.exec (m_history_list_view->mapToGlobal (xpos));
163  }
164 
165  void history_dock_widget::handle_double_click (QModelIndex modelIndex)
166  {
167  emit command_double_clicked (modelIndex.data ().toString ());
168  }
169 
171  {
172  QString text;
173  QItemSelectionModel *selectionModel = m_history_list_view->selectionModel ();
174  QModelIndexList rows = selectionModel->selectedRows ();
175  bool prev_valid_row = false;
176  for (auto it = rows.begin (); it != rows.end (); it++)
177  {
178  if ((*it).isValid ())
179  {
180  if (prev_valid_row)
181  text += '\n';
182  text += (*it).data ().toString ();
183  prev_valid_row = true;
184  }
185  }
186  QApplication::clipboard ()->setText (text);
187  }
188 
190  {
191  QItemSelectionModel *selectionModel = m_history_list_view->selectionModel ();
192  QModelIndexList rows = selectionModel->selectedRows ();
193  for (auto it = rows.begin () ; it != rows.end (); it++)
194  {
195  if ((*it).isValid ())
196  emit command_double_clicked ((*it).data ().toString ());
197  }
198  }
199 
201  {
202  QString text;
203  QItemSelectionModel *selectionModel = m_history_list_view->selectionModel ();
204  QModelIndexList rows = selectionModel->selectedRows ();
205 
206  bool prev_valid_row = false;
207  for (auto it = rows.begin (); it != rows.end (); it++)
208  {
209  if ((*it).isValid ())
210  {
211  if (prev_valid_row)
212  text += '\n';
213  text += (*it).data ().toString ();
214  prev_valid_row = true;
215  }
216  }
217 
218  if (text.length () > 0)
220  }
221 
223  {
225  m_filter_widget->setVisible (m_filter_shown);
226  }
227 
229  {
230  if (m_history_list_view->hasFocus ())
232  if (m_filter->lineEdit ()->hasFocus ()
233  && m_filter->lineEdit ()->hasSelectedText ())
234  {
235  QClipboard *clipboard = QApplication::clipboard ();
236  clipboard->setText (m_filter->lineEdit ()->selectedText ());
237  }
238  }
239 
241  {
242  if (m_filter->lineEdit ()->hasFocus ())
243  {
244  QClipboard *clipboard = QApplication::clipboard ();
245  QString str = clipboard->text ();
246  if (str.length () > 0)
247  m_filter->lineEdit ()->insert (str);
248  }
249  }
250 
252  {
253  if (m_filter->lineEdit ()->hasFocus ())
254  m_filter->lineEdit ()->selectAll ();
255 
256  if (m_history_list_view->hasFocus ())
257  m_history_list_view->selectAll ();
258  }
259 
261  {
263 
264  if (visible)
265  {
266  int filter_state = m_filter_checkbox->isChecked ();
267  filter_activate (filter_state);
268  }
269  }
270 
272  {
273  m_history_model = new QStringListModel ();
275  m_history_list_view = new QListView (this);
277  m_history_list_view->setAlternatingRowColors (true);
278  m_history_list_view->setEditTriggers (QAbstractItemView::NoEditTriggers);
279  m_history_list_view->setStatusTip
280  (tr ("Double-click a command to transfer it to the Command Window."));
281  m_history_list_view->setSelectionMode (QAbstractItemView::ExtendedSelection);
282  m_history_list_view->setContextMenuPolicy (Qt::CustomContextMenu);
283  connect (m_history_list_view,
284  SIGNAL (customContextMenuRequested (const QPoint &)), this,
285  SLOT (ctxMenu (const QPoint &)));
286 
287  m_filter = new QComboBox (this);
288  m_filter->setToolTip (tr ("Enter text to filter the command history"));
289  m_filter->setEditable (true);
290  m_filter->setMaxCount (MaxFilterHistory);
291  m_filter->setInsertPolicy (QComboBox::NoInsert);
292  m_filter->setSizeAdjustPolicy
293  (QComboBox::AdjustToMinimumContentsLengthWithIcon);
294  QSizePolicy sizePol (QSizePolicy::Expanding, QSizePolicy::Preferred);
295  m_filter->setSizePolicy (sizePol);
296  m_filter->completer ()->setCaseSensitivity (Qt::CaseSensitive);
297 
298  QLabel *filter_label = new QLabel (tr ("Filter"));
299 
300  m_filter_checkbox = new QCheckBox ();
301 
302  setWindowIcon (QIcon (":/actions/icons/logo.png"));
303  set_title (tr ("Command History"));
304  setWidget (new QWidget ());
305 
306  m_filter_widget = new QWidget (this);
307  QHBoxLayout *filter_layout = new QHBoxLayout ();
308  filter_layout->addWidget (filter_label);
309  filter_layout->addWidget (m_filter_checkbox);
310  filter_layout->addWidget (m_filter);
311  filter_layout->setMargin(0);
312  m_filter_widget->setLayout (filter_layout);
313 
314  QVBoxLayout *hist_layout = new QVBoxLayout ();
315  hist_layout->addWidget (m_filter_widget);
316  hist_layout->addWidget (m_history_list_view);
317 
318  hist_layout->setMargin (2);
319  hist_layout->setSpacing (0);
320  widget ()->setLayout (hist_layout);
321 
322  // Init state of the filter
325 
327  = settings->value (hw_filter_shown).toBool ();
328  m_filter_widget->setVisible (m_filter_shown);
329 
330  m_filter->addItems (settings->value (hw_mru_list).toStringList ());
331 
332  bool filter_state
333  = settings->value (hw_filter_active).toBool ();
334  m_filter_checkbox->setChecked (filter_state);
335  filter_activate (filter_state);
336 
337  // Connect signals and slots
338  connect (m_filter, SIGNAL (editTextChanged (const QString&)),
340  SLOT (setFilterWildcard (const QString&)));
341  connect (m_filter_checkbox, SIGNAL (toggled (bool)),
342  this, SLOT (filter_activate (bool)));
343  connect (m_filter->lineEdit (), SIGNAL (editingFinished (void)),
344  this, SLOT (update_filter_history (void)));
345 
346  connect (m_history_list_view, SIGNAL (doubleClicked (QModelIndex)),
347  this, SLOT (handle_double_click (QModelIndex)));
348 
349  m_history_list_view->setTextElideMode (Qt::ElideRight);
350  }
351 
353  {
354  QFont font = QFont ();
355 
356  font.setStyleHint (QFont::TypeWriter);
357  QString default_font = settings->value (global_mono_font).toString ();
358 
359  font.setFamily (settings->value (cs_font.key, default_font).toString ());
360  font.setPointSize (settings->value (cs_font_size).toInt ());
361 
362  m_history_list_view->setFont (font);
363  }
364 
365 }
Base class for Octave interfaces that use Qt.
resource_manager & get_resource_manager(void)
void append_history(const QString &hist_entry)
void ctxMenu(const QPoint &pos)
void set_history(const QStringList &hist)
history_dock_widget(QWidget *parent, base_qobject &oct_qobj)
void handle_contextmenu_create_script(bool flag)
void notice_settings(const gui_settings *)
void handle_contextmenu_evaluate(bool flag)
void information(const QString &message)
void command_double_clicked(const QString &command)
Signal emitted whenever the user double-clicks a command in the history.
void command_create_script(const QString &commands)
Signal emitted whenever the user selects commands and chooses "Create script" from the popup menu.
QStringListModel * m_history_model
Stores the current history_model.
void handle_double_click(QModelIndex modelIndex)
QSortFilterProxyModel m_sort_filter_proxy_model
virtual void handle_visibility(bool visible)
void set_title(const QString &)
virtual void handle_visibility(bool visible)
gui_settings * get_settings(void) const
QIcon icon(const QString &icon_name, bool fallback=true)
const gui_pref cs_font_size("terminal/fontSize", QVariant(10))
const gui_pref cs_font("terminal/fontName", QVariant())
const gui_pref global_mono_font("monospace_font", global_font_family)
const gui_pref hw_filter_active("history_dock_widget/filter_active", QVariant(false))
const gui_pref hw_filter_shown("history_dock_widget/filter_shown", QVariant(true))
const gui_pref hw_mru_list("history_dock_widget/mru_list", QVariant())
static uint32_t state[624]
Definition: randmtzig.cc:190
const QString key