JSON protocol: fix field_addr memory leak.
[freeciv.git] / client / gui-qt / shortcuts.cpp
blob37e645b9bc0e1c3a535e5ded7afeb05f146ddefc
1 /***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
19 //Qt
20 #include <QDialog>
21 #include <QDialogButtonBox>
22 #include <QGridLayout>
23 #include <QLabel>
24 #include <QMouseEvent>
25 #include <QLineEdit>
26 #include <QScrollArea>
27 #include <QSettings>
28 #include <QSignalMapper>
29 #include <QVBoxLayout>
30 #include <QWidget>
32 // client
33 #include "options.h"
35 // gui-qt
36 #include "fc_client.h"
37 #include "shortcuts.h"
39 extern "C" void real_menus_init();
41 static QHash<int, const char *> key_map;
42 static QString button_name(Qt::MouseButton bt);
43 static QMap<shortcut_id, fc_shortcut*>* hash_copy(QMap<shortcut_id, fc_shortcut*> *h);
44 fc_shortcuts *fc_shortcuts::m_instance = 0;
45 QMap<shortcut_id, fc_shortcut*> fc_shortcuts::hash = QMap<shortcut_id, fc_shortcut*>();
47 enum {
48 RESPONSE_CANCEL,
49 RESPONSE_OK,
50 RESPONSE_APPLY,
51 RESPONSE_RESET,
52 RESPONSE_SAVE
55 static int num_shortcuts = 52;
56 fc_shortcut default_shortcuts[] = {
57 {SC_SCROLL_MAP, 0, Qt::RightButton, Qt::NoModifier, "Scroll map" },
58 {SC_CENTER_VIEW, Qt::Key_C, Qt::AllButtons, Qt::NoModifier,
59 _("Center View") },
60 {SC_FULLSCREEN, Qt::Key_Return, Qt::AllButtons, Qt::AltModifier,
61 _("Fullscreen") },
62 {SC_MINIMAP, Qt::Key_M, Qt::AllButtons, Qt::ControlModifier,
63 _("Show minimap") },
64 {SC_CITY_OUTPUT, Qt::Key_W, Qt::AllButtons, Qt::ControlModifier,
65 _("City Output") },
66 {SC_MAP_GRID, Qt::Key_G, Qt::AllButtons, Qt::ControlModifier,
67 _("Map Grid") },
68 {SC_NAT_BORDERS, Qt::Key_B, Qt::AllButtons, Qt::ControlModifier,
69 _("National Borders") },
70 {SC_QUICK_BUY, 0, Qt::LeftButton, Qt::ControlModifier | Qt::ShiftModifier,
71 _("Quick buy from map") },
72 {SC_QUICK_SELECT, 0, Qt::LeftButton, Qt::ControlModifier,
73 _("Quick production select from map") },
74 {SC_SELECT_BUTTON, 0, Qt::LeftButton, Qt::NoModifier,
75 _("Select button") },
76 {SC_ADJUST_WORKERS, 0, Qt::LeftButton,
77 Qt::MetaModifier | Qt::ControlModifier, _("Adjust workers") },
78 {SC_APPEND_FOCUS, 0, Qt::LeftButton, Qt::MetaModifier,
79 _("Append focus") },
80 {SC_POPUP_INFO, 0, Qt::MiddleButton, Qt::NoModifier,
81 _("Popup tile info") },
82 {SC_WAKEUP_SENTRIES, 0, Qt::MiddleButton, Qt::ControlModifier,
83 _("Wakeup sentries") },
84 {SC_MAKE_LINK, 0, Qt::RightButton, Qt::ControlModifier | Qt::AltModifier,
85 _("Show link to tile") },
86 {SC_PASTE_PROD, 0, Qt::RightButton,
87 Qt::ShiftModifier | Qt::ControlModifier, _("Paste production") },
88 {SC_COPY_PROD, 0, Qt::RightButton,
89 Qt::ShiftModifier, _("Copy production") },
90 {SC_HIDE_WORKERS, 0, Qt::RightButton,
91 Qt::ShiftModifier | Qt::AltModifier, _("Show/hide workers") },
92 {SC_SHOW_UNITS, Qt::Key_Space, Qt::AllButtons, Qt::ControlModifier,
93 _("Units selection(for tile under mouse position)") },
94 {SC_TRADE_ROUTES, Qt::Key_D, Qt::AllButtons, Qt::ControlModifier,
95 _("City Traderoutes") },
96 {SC_CITY_PROD, Qt::Key_P, Qt::AllButtons, Qt::ControlModifier,
97 _("City Production Levels") },
98 {SC_CITY_NAMES, Qt::Key_N, Qt::AllButtons, Qt::ControlModifier,
99 _("City Names") },
100 {SC_DONE_MOVING, Qt::Key_Space, Qt::AllButtons, Qt::NoModifier,
101 _("Done Moving") },
102 {SC_GOTOAIRLIFT, Qt::Key_T, Qt::AllButtons, Qt::NoModifier,
103 _("Go to/Airlift to City...") },
104 {SC_AUTOEXPLORE, Qt::Key_X, Qt::AllButtons, Qt::NoModifier,
105 _("Auto Explore") },
106 {SC_PATROL, Qt::Key_E, Qt::AllButtons, Qt::ShiftModifier,
107 _("Patrol") },
108 {SC_UNSENTRY_TILE, Qt::Key_D, Qt::AllButtons,
109 Qt::ShiftModifier | Qt::ControlModifier, _("Unsentry All On Tile") },
110 {SC_DO, Qt::Key_D, Qt::AllButtons, Qt::NoModifier, _("Do...") },
111 {SC_UPGRADE_UNIT, Qt::Key_U, Qt::AllButtons, Qt::ControlModifier,
112 _("Upgrade") },
113 {SC_SETHOME, Qt::Key_H, Qt::AllButtons, Qt::NoModifier,
114 _("Set Home City") },
115 {SC_BUILDMINE, Qt::Key_M, Qt::AllButtons, Qt::NoModifier,
116 _("Build Mine") },
117 {SC_BUILDIRRIGATION, Qt::Key_I, Qt::AllButtons, Qt::NoModifier,
118 _("Build Irrigation") },
119 {SC_BUILDROAD, Qt::Key_R, Qt::AllButtons, Qt::NoModifier,
120 _("Build Road") },
121 {SC_BUILDCITY, Qt::Key_B, Qt::AllButtons, Qt::NoModifier,
122 _("Build City") },
123 {SC_SENTRY, Qt::Key_S, Qt::AllButtons, Qt::NoModifier,
124 _("Sentry") },
125 {SC_FORTIFY, Qt::Key_F, Qt::AllButtons, Qt::NoModifier,
126 _("Fortify") },
127 {SC_GOTO, Qt::Key_G, Qt::AllButtons, Qt::NoModifier,
128 _("Go to Tile") },
129 {SC_WAIT, Qt::Key_W, Qt::AllButtons, Qt::NoModifier,
130 _("Wait") },
131 {SC_TRANSFORM, Qt::Key_O, Qt::AllButtons, Qt::NoModifier,
132 _("Transform") },
133 {SC_NUKE, Qt::Key_N, Qt::AllButtons, Qt::ShiftModifier,
134 _("Explode Nuclear") },
135 {SC_LOAD, Qt::Key_L, Qt::AllButtons, Qt::NoModifier,
136 _("Load") },
137 {SC_UNLOAD, Qt::Key_U, Qt::AllButtons, Qt::NoModifier,
138 _("Unload") },
139 {SC_BUY_MAP, 0, Qt::BackButton, Qt::NoModifier,
140 _("Quick buy current production from map") },
141 {SC_IFACE_LOCK, Qt::Key_L, Qt::AllButtons, Qt::ControlModifier
142 | Qt::ShiftModifier, _("Lock/unlock interface") },
143 {SC_AUTOMATE, Qt::Key_A, Qt::AllButtons, Qt::NoModifier,
144 _("Auto worker") },
145 {SC_PARADROP, Qt::Key_P, Qt::AllButtons, Qt::NoModifier,
146 _("Paradrop/clean pollution") },
147 {SC_POPUP_COMB_INF, Qt::Key_F1, Qt::AllButtons, Qt::ControlModifier,
148 _("Popup combat information") },
149 {SC_RELOAD_THEME, Qt::Key_F5, Qt::AllButtons, Qt::ControlModifier
150 | Qt::ShiftModifier, _("Reload theme") },
151 {SC_RELOAD_TILESET, Qt::Key_F6, Qt::AllButtons, Qt::ControlModifier
152 | Qt::ShiftModifier, _("Reload tileset") },
153 {SC_SHOW_FULLBAR, Qt::Key_F, Qt::AllButtons, Qt::ControlModifier,
154 _("Toggle city full bar visiblity") },
155 {SC_ZOOM_IN, Qt::Key_Plus, Qt::AllButtons, Qt::NoModifier,
156 _("Reload zoomed in tileset") },
157 {SC_ZOOM_OUT, Qt::Key_Minus, Qt::AllButtons, Qt::NoModifier,
158 _("Reload zoomed out tileset") }
162 /**************************************************************************
163 Returns shortcut as string (eg. for menu)
164 **************************************************************************/
165 QString shortcut_to_string(fc_shortcut *sc)
167 QString ret, m, bn, k;
169 if (sc == nullptr) {
170 return "";
172 if (sc->mod != Qt::NoModifier) {
173 m = QKeySequence(sc->mod).toString(QKeySequence::NativeText);
175 if (sc->mouse != Qt::AllButtons) {
176 bn = button_name(sc->mouse);
178 if (sc->key != 0) {
179 k = QKeySequence(sc->key).toString(QKeySequence::NativeText);
181 ret = m + bn + k;
183 return ret;
186 /**************************************************************************
187 fc_shortcuts contructor
188 **************************************************************************/
189 fc_shortcuts::fc_shortcuts()
191 init_default(true);
194 /**************************************************************************
195 Returns description for given shortcut
196 **************************************************************************/
197 QString fc_shortcuts::get_desc(shortcut_id id)
199 fc_shortcut *s;
200 s = hash.value(id);
201 return s->str;
204 /**************************************************************************
205 Returns shortcut for given id
206 **************************************************************************/
207 fc_shortcut *fc_shortcuts::get_shortcut(shortcut_id id)
209 fc_shortcut *s;
210 s = hash.value(id);
211 return s;
214 /**************************************************************************
215 Returns id for given shortcut
216 **************************************************************************/
217 shortcut_id fc_shortcuts::get_id(fc_shortcut *sc)
219 return hash.key(sc);
222 /**************************************************************************
223 Sets given shortcut
224 **************************************************************************/
225 void fc_shortcuts::set_shortcut(fc_shortcut *s)
227 fc_shortcut *sc;
228 sc = hash.value(s->id);
229 sc->key = s->key;
230 sc->mod = s->mod;
231 sc->mouse = s->mouse;
234 /**************************************************************************
235 Deletes current instance
236 **************************************************************************/
237 void fc_shortcuts::drop()
239 if (m_instance) {
240 delete m_instance;
241 m_instance = 0;
245 /**************************************************************************
246 Returns given instance
247 **************************************************************************/
248 fc_shortcuts *fc_shortcuts::sc()
250 if (!m_instance)
251 m_instance = new fc_shortcuts;
252 return m_instance;
255 /**************************************************************************
256 Inits defaults shortcuts or reads from settings
257 **************************************************************************/
258 void fc_shortcuts::init_default(bool read)
260 int i;
261 fc_shortcut *s;
262 bool suc = false;
263 hash.clear();
265 if (read) {
266 suc = read_shortcuts();
268 if (suc == false) {
269 for (i = 0 ; i < num_shortcuts; i++) {
270 s = new fc_shortcut();
271 s->id = default_shortcuts[i].id;
272 s->key = default_shortcuts[i].key;
273 s->mouse = default_shortcuts[i].mouse;
274 s->mod = default_shortcuts[i].mod;
275 s->str = default_shortcuts[i].str;
276 hash.insert(default_shortcuts[i].id, s);
281 /**************************************************************************
282 Constructor for setting shortcuts
283 **************************************************************************/
284 fc_shortcut_popup::fc_shortcut_popup(QWidget *parent): QDialog()
286 QVBoxLayout *vb = new QVBoxLayout;
287 setParent(parent);
288 setAttribute(Qt::WA_DeleteOnClose);
289 setWindowFlags(Qt::Popup);
290 vb->addWidget(&edit);
291 setLayout(vb);
292 sc = nullptr;
295 /**************************************************************************
296 Custom line edit contructor
297 **************************************************************************/
298 line_edit::line_edit(): QLineEdit()
300 setContextMenuPolicy(Qt::NoContextMenu);
301 setWindowModality(Qt::WindowModal);
304 /**************************************************************************
305 Mouse press event for line edit
306 **************************************************************************/
307 void line_edit::mousePressEvent(QMouseEvent *event)
309 fc_shortcut_popup *fcp;
310 shc.mouse = event->button();
311 shc.mod = event->modifiers();
312 fcp = reinterpret_cast<fc_shortcut_popup *>(parentWidget());
313 fcp->sc->mouse = shc.mouse;
314 fcp->sc->mod = shc.mod;
315 fcp->sc->key = 0;
316 parentWidget()->close();
319 /**************************************************************************
320 Key release event for line edit
321 **************************************************************************/
322 void line_edit::keyReleaseEvent(QKeyEvent *event)
324 fc_shortcut_popup *fcp;
326 shc.key = event->key();
327 shc.mod = event->modifiers();
328 fcp = reinterpret_cast<fc_shortcut_popup *>(parentWidget());
329 fcp->sc->mouse = Qt::AllButtons;
330 fcp->sc->key = shc.key;
331 fcp->sc->mod = shc.mod;
332 parentWidget()->close();
335 /**************************************************************************
336 Popups line edit for setting shortcut
337 **************************************************************************/
338 void fc_shortcut_popup::run(fc_shortcut *s)
340 QPoint p(50, 20);
341 edit.setReadOnly(true);
342 edit.setFocus();
343 setWindowModality(Qt::WindowModal);
344 sc = s;
345 move(QCursor::pos() - p);
346 show();
349 /**************************************************************************
350 Closes given popup and sets shortcut
351 **************************************************************************/
352 void fc_shortcut_popup::closeEvent(QCloseEvent *ev)
354 fc_sc_button *scp;
355 if (sc != nullptr) {
356 if (check_if_exist() == false) {
357 scp = reinterpret_cast<fc_sc_button *>(parentWidget());
358 scp->setText(shortcut_to_string(scp->sc));
359 fc_shortcuts::sc()->set_shortcut(sc);
363 QDialog::closeEvent(ev);
366 /**************************************************************************
367 Checks is shortcut is already assigned and popups hud box then
368 or return false if is not assigned
369 **************************************************************************/
370 bool fc_shortcut_popup::check_if_exist()
372 fc_shortcut *fsc;
373 QString desc;
374 int id = 0;
376 desc = "";
377 if (sc != nullptr) {
378 foreach (fsc, fc_shortcuts::sc()->hash) {
379 if (id == 0) {
380 id++;
381 continue;
383 if (*sc == *fsc) {
384 desc = fc_shortcuts::sc()->get_desc(static_cast<shortcut_id>(id + 1));
386 id++;
388 if (desc.isEmpty() == true) {
389 desc = gui()->menu_bar->shortcut_exist(sc);
391 if (desc.isEmpty() == false) {
392 fc_sc_button *fsb;
393 fsb = qobject_cast<fc_sc_button*>(parentWidget());
394 fsb->show_info(desc);
395 return true;
399 return false;
403 /**************************************************************************
404 Returns mouse button name
405 **************************************************************************/
406 QString button_name(Qt::MouseButton bt)
408 QString button_name = "";
409 switch (bt) {
410 case Qt::NoButton:
411 return _("NoButton");
412 case Qt::LeftButton:
413 return _("LeftButton");
414 case Qt::RightButton:
415 return _("RightButton");
416 case Qt::MiddleButton:
417 return _("MiddleButton");
418 case Qt::BackButton:
419 return _("BackButton");
420 case Qt::ForwardButton:
421 return _("ForwardButton");
422 case Qt::TaskButton:
423 return _("TaskButton");
424 case Qt::ExtraButton4:
425 return _("ExtraButton4");
426 case Qt::ExtraButton5:
427 return _("ExtraButton5");
428 case Qt::ExtraButton6:
429 return _("ExtraButton6");
430 case Qt::ExtraButton7:
431 return _("ExtraButton7");
432 case Qt::ExtraButton8:
433 return _("ExtraButton8");
434 case Qt::ExtraButton9:
435 return _("ExtraButton9");
436 case Qt::ExtraButton10:
437 return _("ExtraButton10");
438 case Qt::ExtraButton11:
439 return _("ExtraButton11");
440 case Qt::ExtraButton12:
441 return _("ExtraButton12");
442 case Qt::ExtraButton13:
443 return _("ExtraButton13");
444 case Qt::ExtraButton14:
445 return _("ExtraButton14");
446 case Qt::ExtraButton15:
447 return _("ExtraButton15");
448 case Qt::ExtraButton16:
449 return _("ExtraButton16");
450 case Qt::ExtraButton17:
451 return _("ExtraButton17");
452 case Qt::ExtraButton18:
453 return _("ExtraButton18");
454 case Qt::ExtraButton19:
455 return _("ExtraButton19");
456 case Qt::ExtraButton20:
457 return _("ExtraButton20");
458 case Qt::ExtraButton21:
459 return _("ExtraButton21");
460 case Qt::ExtraButton22:
461 return _("ExtraButton22");
462 case Qt::ExtraButton23:
463 return _("ExtraButton23");
464 case Qt::ExtraButton24:
465 return _("ExtraButton24");
466 default:
467 return "";
471 /**************************************************************************
472 Constructor for button setting shortcut
473 **************************************************************************/
474 fc_sc_button::fc_sc_button(): QPushButton()
476 sc = new fc_shortcut;
479 /**************************************************************************
480 Constructor setting given shortcut
481 **************************************************************************/
482 fc_sc_button::fc_sc_button(fc_shortcut *s): QPushButton()
484 sc_orig = s;
485 sc = new fc_shortcut;
486 sc->id = sc_orig->id;
487 sc->key = sc_orig->key;
488 sc->mouse = sc_orig->mouse;
489 sc->mod = sc_orig->mod;
490 sc->str = sc_orig->str;
491 setText(shortcut_to_string(sc));
494 /**************************************************************************
495 Executes slot to show information about assigned shortcut
496 **************************************************************************/
497 void fc_sc_button::show_info(QString str)
499 err_message = str;
500 popup_error();
503 /**************************************************************************
504 Shows information about assigned shortcut
505 **************************************************************************/
506 void fc_sc_button::popup_error()
508 hud_message_box scinfo(gui()->central_wdg);
509 QList<fc_shortcut_popup *> fsb_list;
510 QString title;
511 /* wait until shortcut popup is destroyed */
512 fsb_list = findChildren<fc_shortcut_popup *>();
513 if (fsb_list.count() > 0) {
514 QTimer::singleShot(20, this, SLOT(popup_error()));
515 return;
518 /* TRANS: Given shortcut(%1) is already assigned */
519 title = QString(_("%1 is already assigned to"))
520 .arg(shortcut_to_string(sc));
521 scinfo.setStandardButtons(QMessageBox::Ok);
522 scinfo.setDefaultButton(QMessageBox::Ok);
523 scinfo.set_text_title(err_message, title);
524 scinfo.exec();
526 /**************************************************************************
527 Contructor for shortcut dialog
528 **************************************************************************/
529 fc_shortcuts_dialog::fc_shortcuts_dialog(QWidget *parent)
530 : QDialog(parent)
532 setWindowTitle(_("Shortcuts options"));
533 hashcopy = hash_copy(&fc_shortcuts::hash);
534 init();
537 /**************************************************************************
538 DEstructor for shortcut dialog
539 **************************************************************************/
540 fc_shortcuts_dialog::~fc_shortcuts_dialog()
545 /**************************************************************************
546 Inits shortut dialog layout
547 **************************************************************************/
548 void fc_shortcuts_dialog::init()
550 fc_shortcut *sc;
551 QPushButton *but;
552 QScrollArea *scroll;
553 QSize size;
554 QString desc;
555 QWidget *widget;
556 shortcut_id id;
558 widget = new QWidget(this);
559 scroll = new QScrollArea(this);
560 scroll->setWidgetResizable(true);
561 scroll_layout = new QVBoxLayout;
562 main_layout = new QVBoxLayout;
563 foreach (sc, fc_shortcuts::sc()->hash) {
564 id = fc_shortcuts::sc()->get_id(sc);
565 desc = fc_shortcuts::sc()->get_desc(id);
566 add_option(sc);
568 widget->setProperty("doomed", true);
569 widget->setLayout(scroll_layout);
570 scroll->setWidget(widget);
571 main_layout->addWidget(scroll);
573 signal_map = new QSignalMapper;
574 button_box = new QDialogButtonBox();
575 but = new QPushButton(style()->standardIcon(QStyle::SP_DialogCancelButton),
576 _("Cancel"));
577 button_box->addButton(but, QDialogButtonBox::ActionRole);
578 connect(but, SIGNAL(clicked()), signal_map, SLOT(map()));
579 signal_map->setMapping(but, RESPONSE_CANCEL);
581 but = new QPushButton(style()->standardIcon(QStyle::SP_DialogResetButton),
582 _("Reset"));
583 button_box->addButton(but, QDialogButtonBox::ResetRole);
584 connect(but, SIGNAL(clicked()), signal_map, SLOT(map()));
585 signal_map->setMapping(but, RESPONSE_RESET);
587 but = new QPushButton(style()->standardIcon(QStyle::SP_DialogApplyButton),
588 _("Apply"));
589 button_box->addButton(but, QDialogButtonBox::ActionRole);
590 connect(but, SIGNAL(clicked()), signal_map, SLOT(map()));
591 signal_map->setMapping(but, RESPONSE_APPLY);
593 but = new QPushButton(style()->standardIcon(QStyle::SP_DialogSaveButton),
594 _("Save"));
595 button_box->addButton(but, QDialogButtonBox::ActionRole);
596 connect(but, SIGNAL(clicked()), signal_map, SLOT(map()));
597 signal_map->setMapping(but, RESPONSE_SAVE);
599 but = new QPushButton(style()->standardIcon(QStyle::SP_DialogOkButton),
600 _("Ok"));
601 button_box->addButton(but, QDialogButtonBox::ActionRole);
602 connect(but, SIGNAL(clicked()), signal_map, SLOT(map()));
603 signal_map->setMapping(but, RESPONSE_OK);
605 main_layout->addWidget(button_box);
606 setLayout(main_layout);
607 size = sizeHint();
608 size.setWidth(size.width() + 10
609 + style()->pixelMetric(QStyle::PM_ScrollBarExtent));
610 resize(size);
611 connect(signal_map, SIGNAL(mapped(int)), this, SLOT(apply_option(int)));
612 setAttribute(Qt::WA_DeleteOnClose);
615 /**************************************************************************
616 Adds shortcut option for dialog
617 **************************************************************************/
618 void fc_shortcuts_dialog::add_option(fc_shortcut *sc)
620 QHBoxLayout *hb;
621 QLabel *l;
623 l = new QLabel(sc->str);
624 hb = new QHBoxLayout();
626 fc_sc_button *fb = new fc_sc_button(sc);
627 connect(fb, SIGNAL(clicked()), this, SLOT(edit_shortcut()));
629 hb->addWidget(l, 1, Qt::AlignLeft);
630 hb->addStretch();
631 hb->addWidget(fb, 1, Qt::AlignRight);
633 scroll_layout->addLayout(hb);
637 /**************************************************************************
638 Slot for editing shortcut
639 **************************************************************************/
640 void fc_shortcuts_dialog::edit_shortcut()
642 fc_sc_button *pb;
643 pb = qobject_cast<fc_sc_button *>(sender());
644 fc_shortcut_popup *sb = new fc_shortcut_popup(pb);
645 sb->run(pb->sc);
648 /**************************************************************************
649 Reinitializes layout
650 **************************************************************************/
651 void fc_shortcuts_dialog::refresh()
653 QLayout *layout;
654 QLayout *sublayout;
655 QLayoutItem *item;
656 QWidget *widget;
658 layout = main_layout;
659 while ((item = layout->takeAt(0))) {
660 if ((sublayout = item->layout()) != 0) {
661 } else if ((widget = item->widget()) != 0) {
662 widget->hide();
663 delete widget;
664 } else {
665 delete item;
668 delete main_layout;
669 init();
672 /**************************************************************************
673 Slot for buttons on bottom of shortcut dialog
674 **************************************************************************/
675 void fc_shortcuts_dialog::apply_option(int response)
677 switch (response) {
678 case RESPONSE_APPLY:
679 real_menus_init();
680 gui()->menuBar()->setVisible(true);
681 break;
682 case RESPONSE_CANCEL:
683 fc_shortcuts::hash = *hashcopy;
684 fc_shortcuts::hash.detach();
685 close();
686 break;
687 case RESPONSE_OK:
688 real_menus_init();
689 gui()->menuBar()->setVisible(true);
690 close();
691 break;
692 case RESPONSE_SAVE:
693 write_shortcuts();
694 break;
695 case RESPONSE_RESET:
696 fc_shortcuts::sc()->init_default(false);
697 refresh();
698 break;
702 /**************************************************************************
703 Popups shortcut dialog
704 **************************************************************************/
705 void popup_shortcuts_dialog()
707 fc_shortcuts_dialog *sh = new fc_shortcuts_dialog(gui());
708 sh->show();
711 /**************************************************************************
712 Make deep copy of shortcut map
713 **************************************************************************/
714 QMap<shortcut_id, fc_shortcut *> *hash_copy(QMap<shortcut_id, fc_shortcut *> *h)
716 QMap<shortcut_id, fc_shortcut*> *new_hash;
717 fc_shortcut *s;
718 fc_shortcut *sc;
719 int i;
720 shortcut_id id;
721 new_hash = new QMap<shortcut_id, fc_shortcut*>;
723 for (i = 1 ; i < num_shortcuts + 1; i++) {
724 sc = new fc_shortcut();
725 id = static_cast<shortcut_id>(i);
726 s = h->value(id);
727 sc->id = id;
728 sc->key = s->key;
729 sc->mouse = s->mouse;
730 sc->mod = s->mod;
731 sc->str = s->str;
732 new_hash->insert(sc->id, sc);
735 return new_hash;
739 /**************************************************************************
740 Writes shortcuts to file
741 **************************************************************************/
742 void write_shortcuts()
744 fc_shortcut *sc;
745 QMap<shortcut_id, fc_shortcut*> h = fc_shortcuts::hash;
746 QSettings s(QSettings::IniFormat, QSettings::UserScope,
747 "freeciv-qt-client");
748 s.beginWriteArray("Shortcuts");
749 for (int i = 0; i < num_shortcuts; ++i) {
750 s.setArrayIndex(i);
751 sc = h.value(static_cast<shortcut_id>(i + 1));
752 s.setValue("id", sc->id);
753 s.setValue("key", sc->key);
754 s.setValue("mouse", sc->mouse);
755 s.setValue("mod", QVariant(sc->mod));
757 s.endArray();
760 /**************************************************************************
761 Reads shortcuts from file. Returns false if failed.
762 **************************************************************************/
763 bool read_shortcuts()
765 int num, i;
766 fc_shortcut *sc;
767 QSettings s(QSettings::IniFormat, QSettings::UserScope,
768 "freeciv-qt-client");
769 num = s.beginReadArray("Shortcuts");
770 if (num == num_shortcuts) {
771 for (i = 0; i < num_shortcuts; ++i) {
772 s.setArrayIndex(i);
773 sc = new fc_shortcut();
774 sc->id = static_cast<shortcut_id>(s.value("id").toInt());
775 sc->key = s.value("key").toInt();
776 sc->mouse = static_cast<Qt::MouseButton>(s.value("mouse").toInt());
777 sc->mod = static_cast<Qt::KeyboardModifiers>(s.value("mod").toInt());
778 sc->str = default_shortcuts[i].str;
779 fc_shortcuts::hash.insert(sc->id, sc);
781 } else {
782 s.endArray();
783 return false;
785 s.endArray();
786 return true;