GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
shortcut-manager.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2014-2018 Torsten <ttl@justmail.de>
4 
5 This file is part of Octave.
6 
7 Octave is free software: you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <https://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include <QtCore>
28 #include <QMessageBox>
29 #include <QDebug>
30 #include <QGridLayout>
31 #include <QVBoxLayout>
32 #include <QDialogButtonBox>
33 #include <QKeySequence>
34 #include <QPushButton>
35 #include <QLineEdit>
36 #include <QCheckBox>
37 #include <QHeaderView>
38 #include <QAction>
39 #include <QFileDialog>
40 
41 #include "error.h"
42 #include "resource-manager.h"
43 #include "shortcut-manager.h"
44 
45 namespace octave
46 {
47  // enter_shortcut:
48  // class derived from QLineEdit for directly entering key sequences which
49 
51  {
52  m_direct_shortcut = true; // the shortcut is directly entered
53  }
54 
55  // new keyPressEvent
56  void enter_shortcut::keyPressEvent (QKeyEvent *e)
57  {
58  if (! m_direct_shortcut)
59  {
60  QLineEdit::keyPressEvent (e);
61  return;
62  }
63 
64  if (e->type () == QEvent::KeyPress)
65  {
66  int key = e->key ();
67 
68  if (key == Qt::Key_unknown || key == 0)
69  return;
70 
71  Qt::KeyboardModifiers modifiers = e->modifiers ();
72 
73  if (modifiers & Qt::ShiftModifier)
74  key += Qt::SHIFT;
75  if (modifiers & Qt::ControlModifier)
76  key += Qt::CTRL;
77  if (modifiers & Qt::AltModifier)
78  key += Qt::ALT;
79  if (modifiers & Qt::MetaModifier)
80  key += Qt::META;
81 
82  setText (QKeySequence (key).toString ());
83  }
84  }
85 
86  // slot for checkbox whether the shortcut is directly entered or not
88  {
89  if (state)
90  m_direct_shortcut = true; // the shortcut is directly entered
91  else
92  m_direct_shortcut = false; // the shortcut has to be written as text
93  }
94 
96 
98  {
99  setObjectName ("Shortcut_Manager");
100 
101  // Mac: don't let Qt interpret CMD key ("Meta" in Qt terminology) as Ctrl
102 #if defined (Q_OS_MAC)
103  QCoreApplication::setAttribute (Qt::AA_MacDontSwapCtrlAndMeta, true);
104 #endif
105 
107  }
108 
109  void shortcut_manager::handle_double_clicked (QTreeWidgetItem *item, int col)
110  {
111  if (col != 2)
112  return;
113 
114  int i = m_item_index_hash[item];
115  if (i == 0)
116  return; // top-level-item clicked
117 
118  shortcut_dialog (i-1); // correct to index starting at 0
119  }
120 
122  {
123  if (result == QDialog::Rejected)
124  return;
125 
126  // check for duplicate
127  int double_index = m_shortcut_hash[m_edit_actual->text ()] - 1;
128 
129  if (double_index >= 0 && double_index != m_handled_index)
130  {
131  int ret = QMessageBox::warning (this, tr ("Double Shortcut"),
132  tr ("The chosen shortcut\n \"%1\"\n"
133  "is already used for the action\n \"%2\".\n"
134  "Do you want to use the shortcut anyhow removing it "
135  "from the previous action?")
136  .arg (m_edit_actual->text ())
137  .arg (m_sc.at (double_index).m_description),
138  QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
139 
140  if (ret == QMessageBox::Yes)
141  {
142  shortcut_t double_shortcut = m_sc.at (double_index);
143  double_shortcut.m_actual_sc = QKeySequence ();
144  m_sc.replace (double_index, double_shortcut);
145  m_index_item_hash[double_index]->setText (2, QString ());
146  }
147  else
148  return;
149  }
150 
151  shortcut_t shortcut = m_sc.at (m_handled_index);
152  if (! shortcut.m_actual_sc.isEmpty ())
153  m_shortcut_hash.remove (shortcut.m_actual_sc.toString ());
154  shortcut.m_actual_sc = m_edit_actual->text ();
155  m_sc.replace (m_handled_index, shortcut);
156 
157  m_index_item_hash[m_handled_index]->setText (2, shortcut.m_actual_sc.toString ());
158 
159  if (! shortcut.m_actual_sc.isEmpty ())
160  m_shortcut_hash[shortcut.m_actual_sc.toString ()] = m_handled_index + 1;
161  }
162 
164  {
165  m_edit_actual->setText (m_label_default->text ());
166  }
167 
169  {
170  bool retval = true;
171 
172  if (! instance)
173  instance = new shortcut_manager ();
174 
175  if (! instance)
176  {
177  error ("unable to create shortcut_manager object!");
178 
179  retval = false;
180  }
181 
182  return retval;
183  }
184 
185  void shortcut_manager::init (const QString& description, const QString& key,
186  const QKeySequence& def_sc)
187  {
188  QKeySequence actual
189  = QKeySequence (m_settings->value ("shortcuts/" + key, def_sc).toString ());
190 
191  // append the new shortcut to the list
192  shortcut_t shortcut_info;
193  shortcut_info.m_description = description;
194  shortcut_info.m_settings_key = key;
195  shortcut_info.m_actual_sc = actual;
196  shortcut_info.m_default_sc = def_sc;
197  m_sc << shortcut_info;
198 
199  // insert shortcut in order check for duplicates later
200  if (! actual.isEmpty ())
201  m_shortcut_hash[actual.toString ()] = m_sc.count ();
202  m_action_hash[key] = m_sc.count ();
203 
204  // check whether ctrl+d is used from main window, i.e. is a global shortcut
205  if (key.startsWith ("main_")
206  && actual == QKeySequence (Qt::ControlModifier+Qt::Key_D))
207  m_settings->setValue ("shortcuts/main_ctrld",true);
208  }
209 
211  {
212  Qt::KeyboardModifier ctrl;
213  int prefix;
214 #if defined (Q_OS_MAC)
215  // Use CMD key as an equivalent of Ctrl key on other platforms
216  ctrl = Qt::MetaModifier;
217  // Some of octave default shortcuts on windows/linux are already defined
218  // as system wide shortcuts on Mac Os X (almost all Function keys).
219  // Prefix those with Option (Alt) modifier to avoid conflicts.
220  prefix = Qt::AltModifier;
221 #else
222  ctrl = Qt::ControlModifier;
223  prefix = Qt::NoModifier;
224 #endif
225 
226  Qt::KeyboardModifiers ctrl_shift = ctrl | Qt::ShiftModifier;
227  Qt::KeyboardModifiers ctrl_alt = ctrl | Qt::AltModifier;
228 
229  // actions of the main window
230 
231  m_settings->setValue ("shortcuts/main_ctrld",false); // reset use fo ctrl-d
232 
233  // file
234  init (tr ("New File"), "main_file:new_file", QKeySequence::New);
235  init (tr ("New Function"), "main_file:new_function",
236  QKeySequence (ctrl_shift + Qt::Key_N));
237  init (tr ("New Figure"), "main_file:new_figure", QKeySequence ());
238  init (tr ("Open File"), "main_file:open_file", QKeySequence::Open);
239  init (tr ("Load Workspace"), "main_file:load_workspace", QKeySequence ());
240  init (tr ("Save Workspace As"), "main_file:save_workspace", QKeySequence ());
241  init (tr ("Exit Octave"), "main_file:exit", QKeySequence::Quit);
242 
243  // edit
244  init (tr ("Copy"), "main_edit:copy", QKeySequence::Copy);
245  init (tr ("Paste"), "main_edit:paste", QKeySequence::Paste);
246  init (tr ("Undo"), "main_edit:undo", QKeySequence::Undo);
247  init (tr ("Select All"), "main_edit:select_all", QKeySequence::SelectAll);
248  init (tr ("Clear Clipboard"), "main_edit:clear_clipboard", QKeySequence ());
249  init (tr ("Find in Files"), "main_edit:find_in_files",
250  QKeySequence (ctrl_shift + Qt::Key_F));
251  init (tr ("Clear Command Window"), "main_edit:clear_command_window",
252  QKeySequence ());
253  init (tr ("Clear Command History"), "main_edit:clear_history",
254  QKeySequence ());
255  init (tr ("Clear Workspace"), "main_edit:clear_workspace", QKeySequence ());
256  init (tr ("Preferences"), "main_edit:preferences", QKeySequence ());
257 
258  // debug
259  init (tr ("Step"), "main_debug:step_over",
260  QKeySequence (prefix + Qt::Key_F10));
261  init (tr ("Step Into"), "main_debug:step_into",
262  QKeySequence (prefix + Qt::Key_F11));
263  init (tr ("Step Out"), "main_debug:step_out",
264  QKeySequence (prefix + Qt::ShiftModifier + Qt::Key_F11));
265  init (tr ("Continue"), "main_debug:continue",
266  QKeySequence (prefix + Qt::Key_F5));
267  init (tr ("Quit Debug Mode"), "main_debug:quit",
268  QKeySequence (prefix + Qt::ShiftModifier + Qt::Key_F5));
269 
270  // window
271  init (tr ("Show Command Window"), "main_window:show_command",
272  prefix + ctrl_shift + Qt::Key_0);
273  init (tr ("Show Command History"), "main_window:show_history",
274  prefix + ctrl_shift + Qt::Key_1);
275  init (tr ("Show File Browser"), "main_window:show_file_browser",
276  prefix + ctrl_shift + Qt::Key_2);
277  init (tr ("Show Workspace"), "main_window:show_workspace",
278  prefix + ctrl_shift + Qt::Key_3);
279  init (tr ("Show Editor"), "main_window:show_editor",
280  prefix + ctrl_shift + Qt::Key_4);
281  init (tr ("Show Documentation"), "main_window:show_doc",
282  prefix + ctrl_shift + Qt::Key_5);
283  init (tr ("Show Variable Editor"), "main_window:show_variable_editor",
284  prefix + ctrl_shift + Qt::Key_6);
285  init (tr ("Command Window"), "main_window:command",
286  prefix + ctrl + Qt::Key_0);
287  init (tr ("Command History"), "main_window:history",
288  prefix + ctrl + Qt::Key_1);
289  init (tr ("File Browser"), "main_window:file_browser",
290  prefix + ctrl + Qt::Key_2);
291  init (tr ("Workspace"), "main_window:workspace",
292  prefix + ctrl + Qt::Key_3);
293  init (tr ("Editor"), "main_window:editor",
294  prefix + ctrl + Qt::Key_4);
295  init (tr ("Documentation"), "main_window:doc",
296  prefix + ctrl + Qt::Key_5);
297  init (tr ("Variable Editor"), "main_window:variable_editor",
298  prefix + ctrl + Qt::Key_6);
299  init (tr ("Reset Default Window Layout"), "main_window:reset", QKeySequence ());
300 
301  // help
302  init (tr ("Show Ondisk Documentation"), "main_help:ondisk_doc",
303  QKeySequence ());
304  init (tr ("Show Online Documentation"), "main_help:online_doc",
305  QKeySequence ());
306  init (tr ("Report Bug"), "main_help:report_bug", QKeySequence ());
307  init (tr ("Octave Packages"), "main_help:packages", QKeySequence ());
308  init (tr ("Contribute to Octave"), "main_help:contribute", QKeySequence ());
309  init (tr ("Octave Developer Resources"), "main_help:developer",
310  QKeySequence ());
311  init (tr ("About Octave"), "main_help:about", QKeySequence ());
312 
313  // news
314  init (tr ("Release Notes"), "main_news:release_notes", QKeySequence ());
315  init (tr ("Community News"), "main_news:community_news", QKeySequence ());
316 
317  // Tab handling
318  // The following shortcuts are moved into a separate tab. The key names
319  // are not change for preserving compatibility with older versions
320  init (tr ("Close Tab"), "editor_file:close", QKeySequence::Close);
321  init (tr ("Close All Tabs"), "editor_file:close_all", QKeySequence ());
322  init (tr ("Close Other Tabs"), "editor_file:close_other", QKeySequence ());
323  init (tr ("Switch to Left Tab"), "editor_tabs:switch_left_tab",
324  QKeySequence (ctrl + Qt::Key_PageUp));
325  init (tr ("Switch to Right Tab"), "editor_tabs:switch_right_tab",
326  QKeySequence (ctrl + Qt::Key_PageDown));
327  init (tr ("Move Tab Left"), "editor_tabs:move_tab_left",
328  QKeySequence (Qt::AltModifier + Qt::Key_PageUp));
329  init (tr ("Move Tab Right"), "editor_tabs:move_tab_right",
330  QKeySequence (Qt::AltModifier + Qt::Key_PageDown));
331 
332  // actions of the editor
333 
334  // file
335  init (tr ("Edit Function"), "editor_file:edit_function",
336  QKeySequence (ctrl + Qt::Key_E));
337  init (tr ("Save File"), "editor_file:save", QKeySequence::Save);
338  init (tr ("Save File As"), "editor_file:save_as", QKeySequence::SaveAs);
339  init (tr ("Print"), "editor_file:print", QKeySequence::Print);
340 
341  // edit
342  init (tr ("Redo"), "editor_edit:redo", QKeySequence::Redo);
343  init (tr ("Cut"), "editor_edit:cut", QKeySequence::Cut);
344  init (tr ("Find and Replace"), "editor_edit:find_replace",
345  QKeySequence::Find);
346  init (tr ("Find Next"), "editor_edit:find_next",
347  QKeySequence::FindNext);
348  init (tr ("Find Previous"), "editor_edit:find_previous",
349  QKeySequence::FindPrevious);
350  init (tr ("Delete to Start of Word"), "editor_edit:delete_start_word",
351  QKeySequence::DeleteStartOfWord);
352  init (tr ("Delete to End of Word"), "editor_edit:delete_end_word",
353  QKeySequence::DeleteEndOfWord);
354  init (tr ("Delete to Start of Line"), "editor_edit:delete_start_line",
355  QKeySequence (ctrl_shift + Qt::Key_Backspace));
356  init (tr ("Delete to End of Line"), "editor_edit:delete_end_line",
357  QKeySequence (ctrl_shift + Qt::Key_Delete));
358  init (tr ("Delete Line"), "editor_edit:delete_line",
359  QKeySequence (ctrl_shift + Qt::Key_L));
360  init (tr ("Copy Line"), "editor_edit:copy_line",
361  QKeySequence (ctrl_shift + Qt::Key_C));
362  init (tr ("Cut Line"), "editor_edit:cut_line",
363  QKeySequence (ctrl_shift + Qt::Key_X));
364  init (tr ("Duplicate Selection/Line"), "editor_edit:duplicate_selection",
365  QKeySequence (ctrl + Qt::Key_D));
366  init (tr ("Transpose Line"), "editor_edit:transpose_line",
367  QKeySequence (ctrl + Qt::Key_T));
368  init (tr ("Show Completion List"), "editor_edit:completion_list",
369  QKeySequence (ctrl + Qt::Key_Space));
370 
371  init (tr ("Comment Selection"), "editor_edit:comment_selection",
372  QKeySequence (ctrl + Qt::Key_R));
373  init (tr ("Uncomment Selection"), "editor_edit:uncomment_selection",
374  QKeySequence (ctrl_shift + Qt::Key_R));
375  init (tr ("Comment Selection (Choosing String)"), "editor_edit:comment_var_selection",
376  QKeySequence (ctrl_alt + Qt::Key_R));
377  init (tr ("Uppercase Selection"), "editor_edit:upper_case",
378  QKeySequence (ctrl + Qt::Key_U));
379  init (tr ("Lowercase Selection"), "editor_edit:lower_case",
380  QKeySequence (ctrl_alt + Qt::Key_U));
381 
382 #if defined (Q_OS_MAC)
383  init (tr ("Indent Selection Rigidly"), "editor_edit:indent_selection",
384  QKeySequence (prefix + Qt::Key_Tab));
385  init (tr ("Unindent Selection Rigidly"), "editor_edit:unindent_selection",
386  QKeySequence (prefix + Qt::ShiftModifier + Qt::Key_Tab));
387 #else
388  init (tr ("Indent Selection Rigidly"), "editor_edit:indent_selection",
389  QKeySequence (ctrl + Qt::Key_Tab));
390  init (tr ("Unindent Selection Rigidly"), "editor_edit:unindent_selection",
391  QKeySequence (ctrl_shift + Qt::Key_Tab));
392 #endif
393  init (tr ("Indent Code"), "editor_edit:smart_indent_line_or_selection",
394  QKeySequence ());
395 
396  init (tr ("Convert Line Endings to Windows"), "editor_edit:conv_eol_winows",
397  QKeySequence ());
398  init (tr ("Convert Line Endings to Unix"), "editor_edit:conv_eol_unix",
399  QKeySequence ());
400  init (tr ("Convert Line Endings to Mac"), "editor_edit:conv_eol_mac",
401  QKeySequence ());
402 
403  init (tr ("Goto Line"), "editor_edit:goto_line",
404  QKeySequence (ctrl + Qt::Key_L));
405  init (tr ("Move to Matching Brace"), "editor_edit:move_to_brace",
406  QKeySequence (ctrl + Qt::Key_M));
407  init (tr ("Select to Matching Brace"), "editor_edit:select_to_brace",
408  QKeySequence (ctrl_shift + Qt::Key_M));
409  init (tr ("Toggle Bookmark"), "editor_edit:toggle_bookmark",
410  QKeySequence (prefix + Qt::Key_F7));
411  init (tr ("Next Bookmark"), "editor_edit:next_bookmark",
412  QKeySequence (prefix + Qt::Key_F2));
413  init (tr ("Previous Bookmark"), "editor_edit:previous_bookmark",
414  QKeySequence (prefix + Qt::SHIFT + Qt::Key_F2));
415  init (tr ("Remove All Bookmark"), "editor_edit:remove_bookmark",
416  QKeySequence ());
417 
418  init (tr ("Preferences"), "editor_edit:preferences", QKeySequence ());
419  init (tr ("Styles Preferences"), "editor_edit:styles_preferences",
420  QKeySequence ());
421 
422  // view
423  init (tr ("Show Line Numbers"), "editor_view:show_line_numbers",
424  QKeySequence ());
425  init (tr ("Show Whitespace Characters"), "editor_view:show_white_spaces",
426  QKeySequence ());
427  init (tr ("Show Line Endings"), "editor_view:show_eol_chars", QKeySequence ());
428  init (tr ("Show Indentation Guides"), "editor_view:show_ind_guides",
429  QKeySequence ());
430  init (tr ("Show Long Line Marker"), "editor_view:show_long_line",
431  QKeySequence ());
432  init (tr ("Show Toolbar"), "editor_view:show_toolbar",
433  QKeySequence ());
434  init (tr ("Show Statusbar"), "editor_view:show_statusbar",
435  QKeySequence ());
436  init (tr ("Show Horizontal Scrollbar"), "editor_view:show_hscrollbar",
437  QKeySequence ());
438  init (tr ("Zoom In"), "editor_view:zoom_in", QKeySequence::ZoomIn);
439  init (tr ("Zoom Out"), "editor_view:zoom_out", QKeySequence::ZoomOut);
440 #if defined (Q_OS_MAC)
441  init (tr ("Zoom Normal"), "editor_view:zoom_normal",
442  QKeySequence (ctrl + Qt::Key_Underscore));
443 #else
444  init (tr ("Zoom Normal"), "editor_view:zoom_normal",
445  QKeySequence (ctrl + Qt::Key_Period));
446 #endif
447 
448  // debug
449  init (tr ("Toggle Breakpoint"), "editor_debug:toggle_breakpoint",
450  QKeySequence ());
451  init (tr ("Next Breakpoint"), "editor_debug:next_breakpoint",
452  QKeySequence ());
453  init (tr ("Previous Breakpoint"), "editor_debug:previous_breakpoint",
454  QKeySequence ());
455  init (tr ("Remove All Breakpoints"), "editor_debug:remove_breakpoints",
456  QKeySequence ());
457 
458  // run
459  init (tr ("Run File"), "editor_run:run_file",
460  QKeySequence (prefix + Qt::Key_F5));
461  init (tr ("Run Selection"), "editor_run:run_selection",
462  QKeySequence (prefix + Qt::Key_F9));
463 
464  // help
465  init (tr ("Help on Keyword"), "editor_help:help_keyword",
466  QKeySequence::HelpContents);
467  init (tr ("Document on Keyword"), "editor_help:doc_keyword",
468  QKeySequence (Qt::SHIFT + Qt::Key_F1));
469 
470  }
471 
472  // write one or all actual shortcut set(s) into a settings file
473  void shortcut_manager::do_write_shortcuts (QSettings *settings,
474  bool closing)
475  {
476  bool sc_ctrld = false;
477 
478  for (int i = 0; i < m_sc.count (); i++) // loop over all shortcuts
479  {
480  settings->setValue ("shortcuts/" + m_sc.at (i).m_settings_key,
481  m_sc.at (i).m_actual_sc.toString ());
482  // special: check main-window for Ctrl-D (Terminal)
483  if (m_sc.at (i).m_settings_key.startsWith ("main_")
484  && m_sc.at (i).m_actual_sc == QKeySequence (Qt::ControlModifier+Qt::Key_D))
485  sc_ctrld = true;
486  }
487 
488  settings->setValue ("shortcuts/main_ctrld",sc_ctrld);
489 
490  if (closing)
491  {
492  delete m_dialog; // the dialog for key sequences can be removed now
493  m_dialog = nullptr; // make sure it is zero again
494  }
495 
496  settings->sync (); // sync the settings file
497  }
498 
499  void shortcut_manager::do_set_shortcut (QAction *action, const QString& key)
500  {
501  int index;
502 
503  index = m_action_hash[key] - 1;
504 
505  if (index > -1 && index < m_sc.count ())
506  action->setShortcut (QKeySequence (
507  m_settings->value ("shortcuts/" + key, m_sc.at (index).m_default_sc).toString ()));
508  else
509  qDebug () << "Key: " << key << " not found in m_action_hash";
510  }
511 
512  void shortcut_manager::do_fill_treewidget (QTreeWidget *tree_view)
513  {
514  m_dialog = nullptr;
515  m_level_hash.clear ();
516 
517 #if defined (HAVE_QHEADERVIEW_SETSECTIONRESIZEMODE)
518  tree_view->header ()->setSectionResizeMode (QHeaderView::ResizeToContents);
519 #else
520  tree_view->header ()->setResizeMode (QHeaderView::ResizeToContents);
521 #endif
522 
523  QTreeWidgetItem *main = new QTreeWidgetItem (tree_view);
524  main->setText (0, tr ("Global"));
525  main->setExpanded (true);
526  QTreeWidgetItem *main_file = new QTreeWidgetItem (main);
527  main_file->setText (0, tr ("File Menu"));
528  QTreeWidgetItem *main_edit = new QTreeWidgetItem (main);
529  main_edit->setText (0, tr ("Edit Menu"));
530  QTreeWidgetItem *main_debug = new QTreeWidgetItem (main);
531  main_debug->setText (0, tr ("Debug Menu"));
532  QTreeWidgetItem *main_window = new QTreeWidgetItem (main);
533  main_window->setText (0, tr ("Window Menu"));
534  QTreeWidgetItem *main_help = new QTreeWidgetItem (main);
535  main_help->setText (0, tr ("Help Menu"));
536  QTreeWidgetItem *main_news = new QTreeWidgetItem (main);
537  main_news->setText (0, tr ("News Menu"));
538  QTreeWidgetItem *main_tabs = new QTreeWidgetItem (main);
539  main_tabs->setText (0, tr ("Tab Handling in Dock Widgets"));
540 
541  m_level_hash["main_file"] = main_file;
542  m_level_hash["main_edit"] = main_edit;
543  m_level_hash["main_debug"] = main_debug;
544  m_level_hash["main_window"] = main_window;
545  m_level_hash["main_help"] = main_help;
546  m_level_hash["main_news"] = main_news;
547  m_level_hash["main_tabs"] = main_tabs;
548  m_level_hash["editor_tabs"] = main_tabs;
549 
550  QTreeWidgetItem *editor = new QTreeWidgetItem (tree_view);
551  editor->setText (0, tr ("Editor"));
552  editor->setExpanded (true);
553  QTreeWidgetItem *editor_file = new QTreeWidgetItem (editor);
554  editor_file->setText (0, tr ("File Menu"));
555  QTreeWidgetItem *editor_edit = new QTreeWidgetItem (editor);
556  editor_edit->setText (0, tr ("Edit Menu"));
557  QTreeWidgetItem *editor_view = new QTreeWidgetItem (editor);
558  editor_view->setText (0, tr ("View Menu"));
559  QTreeWidgetItem *editor_debug = new QTreeWidgetItem (editor);
560  editor_debug->setText (0, tr ("Debug Menu"));
561  QTreeWidgetItem *editor_run = new QTreeWidgetItem (editor);
562  editor_run->setText (0, tr ("Run Menu"));
563  QTreeWidgetItem *editor_help = new QTreeWidgetItem (editor);
564  editor_help->setText (0, tr ("Help Menu"));
565 
566  m_level_hash["editor_file"] = editor_file;
567  m_level_hash["editor_edit"] = editor_edit;
568  m_level_hash["editor_view"] = editor_view;
569  m_level_hash["editor_debug"] = editor_debug;
570  m_level_hash["editor_run"] = editor_run;
571  m_level_hash["editor_help"] = editor_help;
572 
573  connect (tree_view, SIGNAL (itemDoubleClicked (QTreeWidgetItem*, int)),
574  this, SLOT (handle_double_clicked (QTreeWidgetItem*, int)));
575 
576  for (int i = 0; i < m_sc.count (); i++)
577  {
578  shortcut_t sc = m_sc.at (i);
579 
580  QTreeWidgetItem *section = m_level_hash[sc.m_settings_key.section (':',0,0)];
581 
582  // handle sections which have changed and do not correspond to the
583  // previously defined keyname
584  if (section == editor_file)
585  {
586  // Closing tabs now in global tab handling section
587  if (sc.m_settings_key.contains ("editor_file:close"))
588  section = main_tabs;
589  }
590 
591  QTreeWidgetItem *tree_item = new QTreeWidgetItem (section);
592 
593  // set a slightly transparent foreground for default columns
594  QColor fg = QColor (tree_item->foreground (1).color ());
595  fg.setAlpha (128);
596  tree_item->setForeground (1, QBrush (fg));
597 
598  // write the shortcuts
599  tree_item->setText (0, sc.m_description);
600  tree_item->setText (1, sc.m_default_sc.toString ());
601  tree_item->setText (2, sc.m_actual_sc.toString ());
602 
603  m_item_index_hash[tree_item] = i + 1; // index+1 to avoid 0
604  m_index_item_hash[i] = tree_item;
605  }
606 
607  }
608 
609  // import or export of shortcut sets,
610  // called from settings dialog when related buttons are clicked;
611  // returns true on success, false otherwise
612  bool
614  {
615  // ask to save the current shortcuts, maybe abort import
616  if (action == OSC_DEFAULT || action == OSC_IMPORT)
617  {
618  if (! overwrite_all_shortcuts ())
619  return false;
620  }
621 
622  // get the filename to read or write the shortcuts,
623  // the default extension is .osc (octave shortcuts)
624  if (action != OSC_DEFAULT)
625  {
626  QString file;
627 
628  if (action == OSC_IMPORT)
629  file = QFileDialog::getOpenFileName (this,
630  tr ("Import shortcuts from file ..."), QString (),
631  tr ("Octave Shortcut Files (*.osc);;All Files (*)"),
632  nullptr, QFileDialog::DontUseNativeDialog);
633  else if (action == OSC_EXPORT)
634  file = QFileDialog::getSaveFileName (this,
635  tr ("Export shortcuts into file ..."), QString (),
636  tr ("Octave Shortcut Files (*.osc);;All Files (*)"),
637  nullptr, QFileDialog::DontUseNativeDialog);
638 
639  if (file.isEmpty ())
640  return false;
641 
642  QSettings *osc_settings = new QSettings (file, QSettings::IniFormat);
643 
644  if (! osc_settings)
645  {
646  qWarning () << tr ("Failed to open %1 as octave shortcut file")
647  .arg (file);
648  return false;
649  }
650  else
651  {
652  if (action == OSC_IMPORT)
653  import_shortcuts (osc_settings); // import (special action)
654  else if (action == OSC_EXPORT)
655  do_write_shortcuts (osc_settings, false); // export, (save settings)
656  }
657  }
658  else
659  {
660  import_shortcuts (nullptr);
661  }
662 
663  return true;
664  }
665 
667  {
668  if (! m_dialog)
669  {
670  m_dialog = new QDialog (this);
671 
672  m_dialog->setWindowTitle (tr ("Enter new Shortcut"));
673 
674  QVBoxLayout *box = new QVBoxLayout (m_dialog);
675 
676  QLabel *help = new QLabel (tr ("Apply the desired shortcut or click "
677  "on the right button to reset the "
678  "shortcut to its default."));
679  help->setWordWrap (true);
680  box->addWidget (help);
681 
682  QCheckBox *direct = new QCheckBox (
683  tr ("Enter shortcut directly by performing it"));
684  direct->setCheckState (Qt::Checked);
685  box->addWidget (direct);
686 
687  QGridLayout *grid = new QGridLayout ();
688 
689  QLabel *actual = new QLabel (tr ("Actual shortcut"));
691  m_edit_actual->setAlignment (Qt::AlignHCenter);
692  grid->addWidget (actual, 0, 0);
693  grid->addWidget (m_edit_actual, 0, 1);
694 
695  QLabel *def = new QLabel (tr ("Default shortcut"));
696  m_label_default = new QLabel (m_dialog);
697  m_label_default->setAlignment (Qt::AlignHCenter);
698  grid->addWidget (def, 1, 0);
699  grid->addWidget (m_label_default, 1, 1);
700 
701  QPushButton *set_default = new QPushButton (tr ("Set to default"));
702  grid->addWidget (set_default, 0, 2);
703  connect (set_default, SIGNAL (clicked ()),
704  this, SLOT (shortcut_dialog_set_default ()));
705 
706  box->addLayout (grid);
707 
708  QDialogButtonBox *button_box = new QDialogButtonBox (QDialogButtonBox::Ok
709  | QDialogButtonBox::Cancel);
710  QList<QAbstractButton *> buttons = button_box->buttons ();
711  for (int i = 0; i < buttons.count (); i++)
712  buttons.at (i)->setShortcut (QKeySequence ());
713  connect (button_box, SIGNAL (accepted ()), m_dialog, SLOT (accept ()));
714  connect (button_box, SIGNAL (rejected ()), m_dialog, SLOT (reject ()));
715  box->addWidget (button_box);
716 
717  m_dialog->setLayout (box);
718 
719  connect (direct, SIGNAL (stateChanged (int)),
720  m_edit_actual, SLOT (handle_direct_shortcut (int)));
721  connect (m_dialog, SIGNAL (finished (int)),
722  this, SLOT (shortcut_dialog_finished (int)));
723 
724  }
725 
726  m_edit_actual->setText (m_sc.at (index).m_actual_sc.toString ());
727  m_label_default->setText (m_sc.at (index).m_default_sc.toString ());
728  m_handled_index = index;
729 
730  m_edit_actual->setFocus ();
731  m_dialog->setFocusProxy (m_edit_actual);
732  m_dialog->exec ();
733  }
734 
735  // import a shortcut set from a given settings file or reset to
736  // the defaults (settings = 0) and refresh the tree view
737  void shortcut_manager::import_shortcuts (QSettings *settings)
738  {
739  for (int i = 0; i < m_sc.count (); i++)
740  {
741  // update the list of all shortcuts
742  shortcut_t sc = m_sc.at (i); // make a copy
743 
744  if (settings)
745  sc.m_actual_sc = QKeySequence ( // get new shortcut from settings
746  settings->value ("shortcuts/" + sc.m_settings_key,sc.m_actual_sc).
747  toString ()); // and use the old one as default
748  else
749  sc.m_actual_sc = QKeySequence (sc.m_default_sc); // get default shortcut
750 
751  m_sc.replace (i,sc); // replace the old with the new one
752 
753  // update the tree view
754  QTreeWidgetItem *tree_item = m_index_item_hash[i]; // get related tree item
755  tree_item->setText (2, sc.m_actual_sc.toString ()); // display new shortcut
756  }
757  }
758 
759  // ask the user whether to save the current shortcut set;
760  // returns true to proceed with import action, false to abort it
762  {
763  QMessageBox msg_box;
764  msg_box.setWindowTitle (tr ("Overwriting Shortcuts"));
765  msg_box.setIcon (QMessageBox::Warning);
766  msg_box.setText (tr ("You are about to overwrite all shortcuts.\n"
767  "Would you like to save the current shortcut set or cancel the action?"));
768  msg_box.setStandardButtons (QMessageBox::Save | QMessageBox::Cancel);
769  QPushButton *discard = msg_box.addButton (tr ("Don't save"),
770  QMessageBox::DestructiveRole);
771  msg_box.setDefaultButton (QMessageBox::Save);
772 
773  int ret = msg_box.exec ();
774 
775  if (msg_box.clickedButton () == discard)
776  return true; // do not save and go ahead
777 
778  if (ret == QMessageBox::Save)
779  {
781  return true; // go ahead
782  }
783 
784  return false; // abort the import
785  }
786 }
For example cd octave end example noindent changes the current working directory to an error message is printed and the working directory is not changed sc
Definition: dirfns.cc:124
For example cd octave end example noindent changes the current working directory to file
Definition: dirfns.cc:124
int main(int argc, char **argv)
Definition: main-cli.cc:83
void do_fill_treewidget(QTreeWidget *tree_view)
#define CTRL(x)
Definition: kpty.cpp:143
void do_set_shortcut(QAction *action, const QString &key)
QHash< int, QTreeWidgetItem * > m_index_item_hash
void error(const char *fmt,...)
Definition: error.cc:578
QHash< QString, int > m_action_hash
bool do_import_export(int action)
virtual void keyPressEvent(QKeyEvent *e)
i e
Definition: data.cc:2591
octave_value arg
Definition: pr-output.cc:3244
QHash< QString, int > m_shortcut_hash
enter_shortcut * m_edit_actual
static shortcut_manager * instance
void do_write_shortcuts(QSettings *settings, bool closing)
static octave_value box(JNIEnv *jni_env, void *jobj, void *jcls_arg=nullptr)
void init(const QString &, const QString &, const QKeySequence &)
octave_value retval
Definition: data.cc:6246
void import_shortcuts(QSettings *settings)
QHash< QTreeWidgetItem *, int > m_item_index_hash
static bool instance_ok(void)
QHash< QString, QTreeWidgetItem * > m_level_hash
enter_shortcut(QWidget *p=nullptr)
Represents the main window.
Definition: main-window.h:96
With real return the complex result
Definition: data.cc:3260
static uint32_t state[624]
Definition: randmtzig.cc:183
void warning(const char *fmt,...)
Definition: error.cc:801
p
Definition: lu.cc:138
void handle_double_clicked(QTreeWidgetItem *, int)
static QSettings * get_settings(void)
for i
Definition: data.cc:5264
nd example The result of the integration is returned in the value of it is recommended to verify this value for difficult integrands and then a warning is issued and as may be less efficient for a smooth or otherwise well behaved integrand than other methods such as Article No
Definition: quadcc.cc:1567
QList< shortcut_t > m_sc