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