Mercurial > octave-libgccjit
comparison libgui/src/shortcut-manager.cc @ 18611:086093fbdc1a gui-release
first implementation of a shortcut manager (bug #41217)
* file-editor.cc (set_shortcuts): use shortcut-manager to set some shortcuts
* main_window.cc (set_global_shortcuts): use shortcut-manager to set some
shortcuts;
(construct_file_menu): all actions as class variables;
(construct_edit_menu): all actions as class variables;
* main_window.h: actions as class variables
* module.mk: new files shortcut_manager.cc, shortcut_manager.h
* octave-gui.cc (octave_start_gui): initialize the shortcut_manager
* settings-dialog.cc (constructor): call shortcut-manager for shortcut table
(write_changed_settings): call shortcut-manager for writing shortcuts
* settings-dialog.ui: new tab with a tree widget for the shortcuts
* shortcut_manager.cc (constructor, destructor): new class;
(instance_ok): checks if instance is valid, creates a new one otherwise;
(do_init_data): initialize the list with all shortcut's data;
(init): internal function for initializing the data list;
(do_fill_treewidget): fills the tree widget in the settings dialog;
(do_write_shortcuts): writes shortcuts from settings dialog into file;
(do_set_shortcut): setting the shortcut for an action;
(handle_double_clicked): slot for double clicking into the tree widget;
(shortcut_dialog): dialog for entering a new shortcut;
(shortcut_dialog_finished): processing the dialog's result;
(shortcut_dialog_set_default): setting the shortcut to it's default;
(enter_shortcut::enter_shortcut): new class derived from QLineEdit;
(enter_shortcut::handle_direct_shortcut): switch between normal editing and
directly entering a shortcut;
(enter_shortcut::keyPressEvent): event handler filtering the shortcuts;
* shortcut_manager.h (init_data): static function calling do_init_data;
(write_shortcuts): static function calling do_write_shortcuts;
(fill_treewidget): static function calling do_fill_treewidget;
(set_shortcut): static function calling do_set_shortcut;
author | Torsten <ttl@justmail.de> |
---|---|
date | Tue, 01 Apr 2014 21:29:48 +0200 |
parents | |
children | a827fc5fe59d |
comparison
equal
deleted
inserted
replaced
18610:6e81b59d657c | 18611:086093fbdc1a |
---|---|
1 /* | |
2 | |
3 Copyright (C) 2014 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 #ifdef HAVE_CONFIG_H | |
24 #include <config.h> | |
25 #endif | |
26 | |
27 #include <QMessageBox> | |
28 #include <QDebug> | |
29 #include <QGridLayout> | |
30 #include <QVBoxLayout> | |
31 #include <QDialogButtonBox> | |
32 #include <QPushButton> | |
33 #include <QLineEdit> | |
34 #include <QCheckBox> | |
35 #include <QHeaderView> | |
36 #include <QAction> | |
37 | |
38 #include "error.h" | |
39 #include "resource-manager.h" | |
40 #include "shortcut-manager.h" | |
41 #include "singleton-cleanup.h" | |
42 | |
43 shortcut_manager *shortcut_manager::instance = 0; | |
44 | |
45 shortcut_manager::shortcut_manager () | |
46 { | |
47 setObjectName ("Shortcut_Manager"); | |
48 } | |
49 | |
50 shortcut_manager::~shortcut_manager () | |
51 { | |
52 } | |
53 | |
54 bool | |
55 shortcut_manager::instance_ok (void) | |
56 { | |
57 bool retval = true; | |
58 | |
59 if (! instance) | |
60 { | |
61 instance = new shortcut_manager (); | |
62 | |
63 if (instance) | |
64 singleton_cleanup_list::add (cleanup_instance); | |
65 } | |
66 | |
67 if (! instance) | |
68 { | |
69 ::error ("unable to create shortcut_manager object!"); | |
70 | |
71 retval = false; | |
72 } | |
73 | |
74 return retval; | |
75 } | |
76 | |
77 void | |
78 shortcut_manager::do_init_data () | |
79 { | |
80 // actions of the main window | |
81 init (tr ("New File"), "main_file:new_file", QKeySequence::New ); | |
82 init (tr ("New Function"), "main_file:new_function", QKeySequence ("Ctrl+Shift+N") ); | |
83 init (tr ("New Figure"), "main_file:new_figure", QKeySequence () ); | |
84 init (tr ("Open File"), "main_file:open_file", QKeySequence::Open ); | |
85 init (tr ("Load Workspace"), "main_file:load_workspace", QKeySequence () ); | |
86 init (tr ("Save Workspace As"), "main_file:save_workspace", QKeySequence () ); | |
87 init (tr ("Preferences"), "main_file:preferences", QKeySequence () ); | |
88 init (tr ("Exit Octave"), "main_file:exit", QKeySequence::Quit ); | |
89 | |
90 init (tr ("Copy"), "main_edit:copy", QKeySequence::Copy); | |
91 init (tr ("Paste"), "main_edit:paste", QKeySequence::Paste); | |
92 init (tr ("Undo"), "main_edit:undo", QKeySequence::Undo); | |
93 init (tr ("Select All"), "main_edit:select_all", QKeySequence () ); | |
94 init (tr ("Clear Clipboard"), "main_edit:clear_clipboard", QKeySequence () ); | |
95 init (tr ("Find in Files"), "main_edit:find_in_files", QKeySequence (Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_F) ); | |
96 init (tr ("Clear Command Window"), "main_edit:clear_command_window", QKeySequence () ); | |
97 init (tr ("Clear Command History"), "main_edit:clear_history", QKeySequence () ); | |
98 init (tr ("Clear Workspace"), "main_edit:clear_workspace", QKeySequence () ); | |
99 | |
100 // actions of the editor | |
101 init (tr ("Save File"), "editor_file:save", QKeySequence::Save ); | |
102 init (tr ("Save File As"), "editor_file:save_as", QKeySequence::SaveAs ); | |
103 } | |
104 | |
105 void | |
106 shortcut_manager::init (QString description, QString key, QKeySequence def_sc) | |
107 { | |
108 QSettings *settings = resource_manager::get_settings (); | |
109 | |
110 settings->beginGroup ("shortcuts"); | |
111 QKeySequence actual = QKeySequence (settings->value (key, def_sc).toString ()); | |
112 settings->endGroup (); | |
113 | |
114 shortcut_t shortcut_info; | |
115 shortcut_info.description = description; | |
116 shortcut_info.settings_key = key; | |
117 shortcut_info.actual_sc = actual; | |
118 shortcut_info.default_sc = def_sc; | |
119 _sc << shortcut_info; | |
120 | |
121 if (! actual.isEmpty ()) | |
122 _shortcut_hash[actual] = _sc.count (); // offset of 1 to avoid 0 | |
123 _action_hash[key] = _sc.count (); // offset of 1 to avoid 0 | |
124 } | |
125 | |
126 void | |
127 shortcut_manager::do_fill_treewidget (QTreeWidget *tree_view) | |
128 { | |
129 _dialog = 0; | |
130 _level_hash.clear (); | |
131 | |
132 tree_view->header ()->setResizeMode (QHeaderView::ResizeToContents); | |
133 | |
134 QTreeWidgetItem *main = new QTreeWidgetItem (tree_view); | |
135 main->setText (0, tr ("Main")); | |
136 main->setExpanded (true); | |
137 QTreeWidgetItem *main_file = new QTreeWidgetItem (main); | |
138 main_file->setText (0, tr ("File")); | |
139 QTreeWidgetItem *main_edit = new QTreeWidgetItem (main); | |
140 main_edit->setText (0, tr ("Edit")); | |
141 QTreeWidgetItem *main_debug = new QTreeWidgetItem (main); | |
142 main_debug->setText (0, tr ("Debug")); | |
143 QTreeWidgetItem *main_window = new QTreeWidgetItem (main); | |
144 main_window->setText (0, tr ("Window")); | |
145 QTreeWidgetItem *main_help = new QTreeWidgetItem (main); | |
146 main_help->setText (0, tr ("Help")); | |
147 QTreeWidgetItem *main_news = new QTreeWidgetItem (main); | |
148 main_news->setText (0, tr ("News")); | |
149 | |
150 _level_hash["main_file"] = main_file; | |
151 _level_hash["main_edit"] = main_edit; | |
152 _level_hash["main_debug"] = main_debug; | |
153 _level_hash["main_window"] = main_window; | |
154 _level_hash["main_help"] = main_help; | |
155 _level_hash["main_news"] = main_news; | |
156 | |
157 QTreeWidgetItem *editor = new QTreeWidgetItem (tree_view); | |
158 editor->setText (0, tr ("Editor")); | |
159 editor->setExpanded (true); | |
160 QTreeWidgetItem *editor_file = new QTreeWidgetItem (editor); | |
161 editor_file->setText (0, tr ("File")); | |
162 QTreeWidgetItem *editor_edit = new QTreeWidgetItem (editor); | |
163 editor_edit->setText (0, tr ("Edit")); | |
164 QTreeWidgetItem *editor_view = new QTreeWidgetItem (editor); | |
165 editor_view->setText (0, tr ("View")); | |
166 QTreeWidgetItem *editor_debug = new QTreeWidgetItem (editor); | |
167 editor_debug->setText (0, tr ("Debug")); | |
168 QTreeWidgetItem *editor_run = new QTreeWidgetItem (editor); | |
169 editor_run->setText (0, tr ("Run")); | |
170 QTreeWidgetItem *editor_help = new QTreeWidgetItem (editor); | |
171 editor_help->setText (0, tr ("Help")); | |
172 | |
173 _level_hash["editor_file"] = editor_file; | |
174 _level_hash["editor_edit"] = editor_edit; | |
175 _level_hash["editor_view"] = editor_view; | |
176 _level_hash["editor_debug"] = editor_debug; | |
177 _level_hash["editor_run"] = editor_run; | |
178 _level_hash["editor_help"] = editor_help; | |
179 | |
180 connect (tree_view, SIGNAL (itemDoubleClicked (QTreeWidgetItem*, int)), | |
181 this, SLOT (handle_double_clicked (QTreeWidgetItem*, int))); | |
182 | |
183 for (int i = 0; i < _sc.count (); i++) | |
184 { | |
185 shortcut_t shortcut_info = _sc.at (i); | |
186 | |
187 QTreeWidgetItem* section = _level_hash[shortcut_info.settings_key.section(':',0,0)]; | |
188 QTreeWidgetItem* tree_item = new QTreeWidgetItem (section); | |
189 | |
190 tree_item->setText (0, shortcut_info.description); | |
191 tree_item->setText (1, shortcut_info.default_sc); | |
192 tree_item->setText (2, shortcut_info.actual_sc); | |
193 | |
194 _item_index_hash[tree_item] = i + 1; // index+1 to avoid 0 | |
195 _index_item_hash[i] = tree_item; | |
196 } | |
197 } | |
198 | |
199 void | |
200 shortcut_manager::do_write_shortcuts () | |
201 { | |
202 QSettings *settings = resource_manager::get_settings (); | |
203 | |
204 settings->beginGroup ("shortcuts"); | |
205 for (int i = 0; i < _sc.count (); i++) | |
206 settings->setValue(_sc.at (i).settings_key, _sc.at (i).actual_sc.toString ()); | |
207 settings->endGroup (); | |
208 | |
209 settings->sync (); | |
210 | |
211 delete _dialog; | |
212 } | |
213 | |
214 void | |
215 shortcut_manager::do_set_shortcut (QAction* action, const QString& key) | |
216 { | |
217 QSettings *settings = resource_manager::get_settings (); | |
218 | |
219 int index = _action_hash[key] - 1; | |
220 | |
221 action->setShortcut ( | |
222 settings->value ("shortcuts/" + key, _sc.at (index).default_sc).toString ()); | |
223 } | |
224 | |
225 void | |
226 shortcut_manager::handle_double_clicked (QTreeWidgetItem* item, int) | |
227 { | |
228 int i = _item_index_hash[item]; | |
229 if (i == 0) | |
230 return; // top-level-item clicked | |
231 | |
232 shortcut_dialog (i-1); // correct to index starting at 0 | |
233 } | |
234 | |
235 void | |
236 shortcut_manager::shortcut_dialog (int index) | |
237 { | |
238 if (! _dialog) | |
239 { | |
240 _dialog = new QDialog (this); | |
241 | |
242 _dialog->setWindowTitle (tr ("Enter new Shortcut")); | |
243 | |
244 QVBoxLayout *box = new QVBoxLayout(_dialog); | |
245 | |
246 QLabel *help = new QLabel (tr ("Apply the desired shortcut or click " | |
247 "on the right button to reset the " | |
248 "shortcut to its default.")); | |
249 help->setWordWrap (true); | |
250 box->addWidget (help); | |
251 | |
252 QCheckBox *direct = new QCheckBox (tr ("Enter shortcut directly by performing it")); | |
253 direct->setCheckState (Qt::Checked); | |
254 box->addWidget (direct); | |
255 | |
256 QGridLayout *grid = new QGridLayout(); | |
257 | |
258 QLabel *actual = new QLabel (tr ("Actual shortcut")); | |
259 _edit_actual = new enter_shortcut (_dialog); | |
260 _edit_actual->setAlignment (Qt::AlignHCenter); | |
261 grid->addWidget (actual, 0, 0); | |
262 grid->addWidget (_edit_actual, 0, 1); | |
263 | |
264 QLabel *def = new QLabel (tr ("Default shortcut")); | |
265 _label_default = new QLabel (_dialog); | |
266 _label_default->setAlignment (Qt::AlignHCenter); | |
267 grid->addWidget (def, 1, 0); | |
268 grid->addWidget (_label_default, 1, 1); | |
269 | |
270 QPushButton *set_default = new QPushButton (tr ("Set to default")); | |
271 grid->addWidget (set_default, 0, 2); | |
272 connect (set_default, SIGNAL (clicked ()), | |
273 this, SLOT (shortcut_dialog_set_default ())); | |
274 | |
275 box->addLayout (grid); | |
276 | |
277 QDialogButtonBox *button_box = new QDialogButtonBox (QDialogButtonBox::Ok | |
278 | QDialogButtonBox::Cancel); | |
279 QList<QAbstractButton *> buttons = button_box->buttons (); | |
280 for (int i = 0; i < buttons.count (); i++) | |
281 buttons.at (i)->setShortcut (QKeySequence ()); | |
282 connect(button_box, SIGNAL (accepted ()), _dialog, SLOT (accept ())); | |
283 connect(button_box, SIGNAL (rejected ()), _dialog, SLOT (reject ())); | |
284 box->addWidget (button_box); | |
285 | |
286 _dialog->setLayout (box); | |
287 | |
288 connect (direct, SIGNAL (stateChanged (int)), | |
289 _edit_actual, SLOT (handle_direct_shortcut (int))); | |
290 connect (_dialog, SIGNAL (finished (int)), | |
291 this, SLOT (shortcut_dialog_finished (int))); | |
292 | |
293 } | |
294 | |
295 _edit_actual->setText (_sc.at (index).actual_sc); | |
296 _label_default->setText (_sc.at (index).default_sc); | |
297 _handled_index = index; | |
298 | |
299 _edit_actual->setFocus (); | |
300 _dialog->setFocusProxy (_edit_actual); | |
301 _dialog->exec (); | |
302 } | |
303 | |
304 void | |
305 shortcut_manager::shortcut_dialog_finished (int result) | |
306 { | |
307 if (result == QDialog::Rejected) | |
308 return; | |
309 | |
310 int double_index = _shortcut_hash[_edit_actual->text()] - 1; | |
311 | |
312 if (double_index >= 0 && double_index != _handled_index) | |
313 { | |
314 int ret = QMessageBox::warning(this, tr("Double Shortcut"), | |
315 tr ("The chosen shortcut\n \"%1\"\n" | |
316 "is already used for the action\n \"%2\".\n" | |
317 "Do you want to use the shortcut anyhow removing it " | |
318 "from the previous action?") | |
319 .arg (_edit_actual->text()) | |
320 .arg (_sc.at (double_index).description), | |
321 QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); | |
322 | |
323 if (ret == QMessageBox::Yes) | |
324 { | |
325 shortcut_t double_shortcut = _sc.at (double_index); | |
326 double_shortcut.actual_sc = QKeySequence (); | |
327 _sc.replace (double_index, double_shortcut); | |
328 _index_item_hash[double_index]->setText (1, QKeySequence ()); | |
329 } | |
330 else | |
331 return; | |
332 } | |
333 | |
334 shortcut_t shortcut = _sc.at (_handled_index); | |
335 if (! shortcut.actual_sc.isEmpty ()) | |
336 _shortcut_hash.remove (shortcut.actual_sc); | |
337 shortcut.actual_sc = _edit_actual->text(); | |
338 _sc.replace (_handled_index, shortcut); | |
339 | |
340 _index_item_hash[_handled_index]->setText (2, shortcut.actual_sc); | |
341 | |
342 if (! shortcut.actual_sc.isEmpty ()) | |
343 _shortcut_hash[shortcut.actual_sc] = _handled_index + 1; // index+1 to avoid 0 | |
344 } | |
345 | |
346 void | |
347 shortcut_manager::shortcut_dialog_set_default () | |
348 { | |
349 _edit_actual->setText (_label_default->text ()); | |
350 } | |
351 | |
352 | |
353 | |
354 enter_shortcut::enter_shortcut (QWidget *p) : QLineEdit (p) | |
355 { | |
356 _direct_shortcut = true; | |
357 } | |
358 | |
359 enter_shortcut::~enter_shortcut () | |
360 { | |
361 } | |
362 | |
363 void | |
364 enter_shortcut::handle_direct_shortcut (int state) | |
365 { | |
366 if (state) | |
367 _direct_shortcut = true; | |
368 else | |
369 _direct_shortcut = false; | |
370 } | |
371 | |
372 void | |
373 enter_shortcut::keyPressEvent (QKeyEvent *e) | |
374 { | |
375 if (! _direct_shortcut) | |
376 { | |
377 QLineEdit::keyPressEvent (e); | |
378 return; | |
379 } | |
380 | |
381 if (e->type () == QEvent::KeyPress) | |
382 { | |
383 int key = e->key (); | |
384 | |
385 if (key == Qt::Key_unknown || key == 0 || key >= 16777248) | |
386 return; | |
387 | |
388 Qt::KeyboardModifiers modifiers = e->modifiers (); | |
389 | |
390 if(modifiers & Qt::ShiftModifier) | |
391 key += Qt::SHIFT; | |
392 if(modifiers & Qt::ControlModifier) | |
393 key += Qt::CTRL; | |
394 if(modifiers & Qt::AltModifier) | |
395 key += Qt::ALT; | |
396 if(modifiers & Qt::MetaModifier) | |
397 key += Qt::META; | |
398 | |
399 setText (QKeySequence(key)); | |
400 } | |
401 } | |
402 |