14 #include <QDialogButtonBox>
15 #include <QGridLayout>
18 #include <QMouseEvent>
19 #include <QScrollArea>
22 #include <qkeysequenceedit.h>
23 #include <qlineedit.h>
24 #include <qnamespace.h>
25 #include <qshortcut.h>
55 Qt::NoModifier,
_(
"Scroll map")},
57 Qt::NoModifier,
_(
"Center View")},
59 Qt::Key_Return | Qt::AltModifier, Qt::AllButtons, Qt::NoModifier,
62 Qt::AllButtons, Qt::NoModifier,
_(
"Show minimap")},
64 Qt::Key_W | Qt::ControlModifier, Qt::AllButtons, Qt::NoModifier,
67 Qt::AllButtons, Qt::NoModifier,
_(
"Map Grid")},
69 Qt::Key_B | Qt::ControlModifier, Qt::AllButtons, Qt::NoModifier,
70 _(
"National Borders")},
72 Qt::ControlModifier | Qt::ShiftModifier,
_(
"Quick buy from map")},
74 Qt::ControlModifier,
_(
"Quick production select from map")},
76 Qt::NoModifier,
_(
"Select button")},
78 Qt::MetaModifier | Qt::ControlModifier,
_(
"Adjust workers")},
80 Qt::ShiftModifier,
_(
"Append focus")},
82 Qt::NoModifier,
_(
"Popup tile info")},
84 Qt::MiddleButton, Qt::ControlModifier,
_(
"Wakeup sentries")},
86 Qt::ControlModifier | Qt::AltModifier,
_(
"Show link to tile")},
88 Qt::ShiftModifier | Qt::ControlModifier,
_(
"Paste production")},
90 Qt::ShiftModifier,
_(
"Copy production")},
92 Qt::ShiftModifier | Qt::AltModifier,
93 _(
"Show/hide city working area")},
95 Qt::Key_Space | Qt::ControlModifier, Qt::AllButtons, Qt::NoModifier,
96 _(
"Units selection (for tile under mouse position)")},
98 Qt::Key_D | Qt::ControlModifier, Qt::AllButtons, Qt::NoModifier,
99 _(
"City Traderoutes")},
101 Qt::AllButtons, Qt::NoModifier,
_(
"City Production Levels")},
103 Qt::AllButtons, Qt::NoModifier,
_(
"City Names")},
105 Qt::NoModifier,
_(
"Done Moving")},
107 Qt::NoModifier,
_(
"Go to/Airlift to City...")},
109 Qt::ShiftModifier,
_(
"Auto Explore")},
111 Qt::NoModifier,
_(
"Patrol")},
113 Qt::Key_D | Qt::ShiftModifier | Qt::ControlModifier, Qt::AllButtons,
114 Qt::NoModifier,
_(
"Unsentry All On Tile")},
116 Qt::NoModifier,
_(
"Do...")},
118 Qt::Key_U | Qt::ControlModifier, Qt::AllButtons, Qt::NoModifier,
121 Qt::NoModifier,
_(
"Set Home City")},
123 Qt::NoModifier,
_(
"Build Mine")},
125 Qt::AllButtons, Qt::NoModifier,
_(
"Plant")},
127 Qt::NoModifier,
_(
"Build Irrigation")},
129 Qt::AllButtons, Qt::NoModifier,
_(
"Cultivate")},
131 Qt::NoModifier,
_(
"Build Road")},
133 Qt::NoModifier,
_(
"Build City")},
135 Qt::NoModifier,
_(
"Sentry")},
137 Qt::NoModifier,
_(
"Fortify")},
139 Qt::NoModifier,
_(
"Go to Tile")},
141 Qt::NoModifier,
_(
"Wait")},
143 Qt::NoModifier,
_(
"Transform")},
145 Qt::AllButtons, Qt::NoModifier,
_(
"Explode Nuclear")},
147 Qt::NoModifier,
_(
"Load")},
149 Qt::NoModifier,
_(
"Unload")},
151 Qt::NoModifier,
_(
"Quick buy current production from map")},
153 Qt::Key_L | Qt::ControlModifier | Qt::ShiftModifier, Qt::AllButtons,
154 Qt::NoModifier,
_(
"Lock/unlock interface")},
156 Qt::NoModifier,
_(
"Auto worker")},
158 Qt::NoModifier,
_(
"Paradrop/clean pollution")},
160 Qt::Key_F1 | Qt::ControlModifier, Qt::AllButtons, Qt::NoModifier,
161 _(
"Popup combat information")},
163 Qt::Key_F5 | Qt::ControlModifier | Qt::ShiftModifier, Qt::AllButtons,
164 Qt::NoModifier,
_(
"Reload theme")},
166 Qt::Key_F6 | Qt::ControlModifier | Qt::ShiftModifier, Qt::AllButtons,
167 Qt::NoModifier,
_(
"Reload tileset")},
169 Qt::Key_F | Qt::ControlModifier, Qt::AllButtons, Qt::NoModifier,
170 _(
"Toggle city full bar visibility")},
172 Qt::NoModifier,
_(
"Zoom in")},
174 Qt::NoModifier,
_(
"Zoom out")},
176 Qt::Key_J | Qt::ControlModifier | Qt::ShiftModifier, Qt::AllButtons,
177 Qt::NoModifier,
_(
"Load Lua script")},
179 Qt::Key_K | Qt::ControlModifier | Qt::ShiftModifier, Qt::AllButtons,
180 Qt::NoModifier,
_(
"Load last loaded Lua script")},
182 Qt::Key_Backspace | Qt::ControlModifier, Qt::AllButtons,
183 Qt::NoModifier,
_(
"Reload tileset with default scale")},
185 Qt::AllButtons, Qt::NoModifier,
_(
"Go And Build City")},
187 Qt::AllButtons, Qt::NoModifier,
_(
"Go And Join City")},
189 Qt::AllButtons, Qt::NoModifier,
_(
"Pillage")},
191 Qt::NoModifier,
_(
"Clean Nuclear Fallout")}};
201 return keys.toString(QKeySequence::NativeText);
204 return QKeySequence(
modifiers).toString(QKeySequence::NativeText)
219 return !
keys.isEmpty();
221 return buttons != Qt::NoButton;
297 auto id = pair.first;
298 auto shortcut = pair.second;
301 auto qs =
new QShortcut(shortcut.keys, parent);
302 connect(qs, &QShortcut::activated, parent,
331 const auto buttons =
event->buttons();
332 const auto modifiers =
event->modifiers();
334 for (
const auto &[
id, shortcut] :
shortcuts()) {
336 && shortcut.modifiers == modifiers) {
375 for (
const auto &s : defaults) {
389 action->setShortcut(QKeySequence());
397 : QKeySequenceEdit(sc.keys), m_shortcut(sc)
400 for (
auto widget : children()) {
401 m_line = qobject_cast<QLineEdit *>(widget);
407 m_line->setContextMenuPolicy(Qt::NoContextMenu);
408 m_line->installEventFilter(
this);
411 m_line->setMinimumWidth(
m_line->sizeHint().width() * 2);
412 installEventFilter(
this);
421 if (
auto keys = keySequence(); !keys.isEmpty()) {
451 if (
event->type() == QEvent::FocusIn) {
452 auto focus_event =
static_cast<QFocusEvent *
>(
event);
453 if (focus_event->reason() == Qt::MouseFocusReason) {
466 if (watched ==
m_line &&
event->type() == QEvent::MouseButtonPress
472 auto mouse_event =
static_cast<QMouseEvent *
>(
event);
481 emit editingFinished();
482 mouse_event->accept();
486 return QKeySequenceEdit::eventFilter(watched,
event);
496 return _(
"NoButton");
498 return _(
"LeftButton");
499 case Qt::RightButton:
500 return _(
"RightButton");
501 case Qt::MiddleButton:
502 return _(
"MiddleButton");
504 return _(
"BackButton");
505 case Qt::ForwardButton:
506 return _(
"ForwardButton");
508 return _(
"TaskButton");
509 case Qt::ExtraButton4:
510 return _(
"ExtraButton4");
511 case Qt::ExtraButton5:
512 return _(
"ExtraButton5");
513 case Qt::ExtraButton6:
514 return _(
"ExtraButton6");
515 case Qt::ExtraButton7:
516 return _(
"ExtraButton7");
517 case Qt::ExtraButton8:
518 return _(
"ExtraButton8");
519 case Qt::ExtraButton9:
520 return _(
"ExtraButton9");
521 case Qt::ExtraButton10:
522 return _(
"ExtraButton10");
523 case Qt::ExtraButton11:
524 return _(
"ExtraButton11");
525 case Qt::ExtraButton12:
526 return _(
"ExtraButton12");
527 case Qt::ExtraButton13:
528 return _(
"ExtraButton13");
529 case Qt::ExtraButton14:
530 return _(
"ExtraButton14");
531 case Qt::ExtraButton15:
532 return _(
"ExtraButton15");
533 case Qt::ExtraButton16:
534 return _(
"ExtraButton16");
535 case Qt::ExtraButton17:
536 return _(
"ExtraButton17");
537 case Qt::ExtraButton18:
538 return _(
"ExtraButton18");
539 case Qt::ExtraButton19:
540 return _(
"ExtraButton19");
541 case Qt::ExtraButton20:
542 return _(
"ExtraButton20");
543 case Qt::ExtraButton21:
544 return _(
"ExtraButton21");
545 case Qt::ExtraButton22:
546 return _(
"ExtraButton22");
547 case Qt::ExtraButton23:
548 return _(
"ExtraButton23");
549 case Qt::ExtraButton24:
550 return _(
"ExtraButton24");
552 return QLatin1String(
"");
561 setWindowTitle(
_(
"Shortcuts options"));
564 auto size = sizeHint();
566 + style()->pixelMetric(QStyle::PM_ScrollBarExtent));
568 setAttribute(Qt::WA_DeleteOnClose);
586 widget =
new QWidget(
this);
587 scroll =
new QScrollArea(
this);
588 scroll->setWidgetResizable(
true);
594 widget->setProperty(
"shortcuts",
true);
596 scroll->setWidget(widget);
600 but =
new QPushButton(style()->standardIcon(QStyle::SP_DialogResetButton),
602 button_box->addButton(but, QDialogButtonBox::ResetRole);
603 QObject::connect(but, &QPushButton::clicked,
606 but =
new QPushButton(style()->standardIcon(QStyle::SP_DialogSaveButton),
608 button_box->addButton(but, QDialogButtonBox::ActionRole);
609 QObject::connect(but, &QPushButton::clicked,
612 but =
new QPushButton(style()->standardIcon(QStyle::SP_DialogCloseButton),
614 button_box->addButton(but, QDialogButtonBox::AcceptRole);
615 QObject::connect(but, &QPushButton::clicked,
627 auto l =
new QLabel(sc.
str);
628 auto hb =
new QHBoxLayout();
631 connect(fb, &shortcut_edit::editingFinished,
this,
634 hb->addWidget(l, 1, Qt::AlignLeft);
636 hb->addWidget(fb, 1, Qt::AlignRight);
646 auto edit = qobject_cast<shortcut_edit *>(sender());
647 auto shortcut = edit->shortcut();
655 edit->set_shortcut(old);
657 const auto title = QString(
_(
"Already in use"));
659 const auto text = QString(
_(
"\"%1\" is already assigned to \"%2\""))
660 .arg(shortcut.to_string())
664 scinfo->setStandardButtons(QMessageBox::Close);
665 scinfo->set_text_title(text, title);
666 scinfo->setAttribute(Qt::WA_DeleteOnClose);
675 QString &where)
const
679 qWarning(
"Trying to set a shortcut already used elsewhere");
700 while ((
item = layout->takeAt(0))) {
701 if ((sublayout =
item->layout()) != 0) {
702 }
else if ((widget =
item->widget()) != 0) {
721 king()->menuBar()->setVisible(
true);
748 QSettings s(QSettings::IniFormat, QSettings::UserScope,
749 QStringLiteral(
"freeciv21-client"));
750 s.beginWriteArray(QStringLiteral(
"ShortcutsV2"));
753 s.setValue(QStringLiteral(
"id"),
sc.id);
754 s.setValue(QStringLiteral(
"type"),
sc.type);
755 s.setValue(QStringLiteral(
"keys"),
sc.keys.toString());
756 s.setValue(QStringLiteral(
"buttons"),
sc.buttons);
757 s.setValue(QStringLiteral(
"modifiers"), QVariant(
sc.modifiers));
769 QSettings s(QSettings::IniFormat, QSettings::UserScope,
770 QStringLiteral(
"freeciv21-client"));
771 num = s.beginReadArray(QStringLiteral(
"ShortcutsV2"));
772 if (num <= defaults.size()) {
773 for (i = 0; i < num; ++i) {
777 static_cast<shortcut_id>(s.value(QStringLiteral(
"id")).toInt());
779 s.value(QStringLiteral(
"type")).toInt());
780 sc.keys = QKeySequence::fromString(
781 s.value(QStringLiteral(
"keys")).toString());
782 sc.buttons =
static_cast<Qt::MouseButton
>(
783 s.value(QStringLiteral(
"buttons")).toInt());
784 sc.modifiers =
static_cast<Qt::KeyboardModifiers
>(
785 s.value(QStringLiteral(
"modifiers")).toInt());
786 sc.str = defaults[i].str;
789 for (; i < defaults.size(); ++i) {
void init()
Inits shortcut dialog layout.
bool shortcut_exists(const fc_shortcut &shortcut, QString &where) const
Checks if a shortcut already exists.
void add_option(const fc_shortcut &sc)
Adds shortcut option for dialog.
void apply_option(int response)
Slot for buttons on bottom of shortcut dialog.
fc_shortcuts_dialog(QWidget *parent=0)
Contructor for shortcut dialog.
void edit_shortcut()
Slot for editing shortcut.
QDialogButtonBox * button_box
QVBoxLayout * scroll_layout
~fc_shortcuts_dialog() override
Destructor for shortcut dialog.
QVBoxLayout * main_layout
void refresh()
Reinitializes layout.
fc_shortcut get_shortcut(shortcut_id id) const
Returns shortcut for given id.
std::map< shortcut_id, QPointer< QAction > > m_actions
static fc_shortcuts * m_instance
static fc_shortcuts * sc()
Returns given instance.
void init_default(bool read)
Inits defaults shortcuts or reads from settings.
static void drop()
Deletes current instance.
void write() const
Writes shortcuts to file.
void create_no_action_shortcuts(map_view *parent)
Enable key bindings for all shortcuts that have no action associated with them.
std::map< shortcut_id, fc_shortcut > m_shortcuts_by_id
void set_shortcut(const fc_shortcut &sc)
Sets given shortcut.
void setup_action(const fc_shortcut &sc, QAction *action)
Sets up key bindings for the action.
std::map< shortcut_id, QPointer< QShortcut > > m_shortcuts
virtual ~fc_shortcuts()
fc_shortcuts destructor
bool read()
Reads shortcuts from file.
void link_action(shortcut_id id, QAction *action)
Links an action to a shortcut.
void invoke(shortcut_id id, map_view *mapview)
Invokes the action for a shortcut.
void maybe_route_mouse_shortcut(QMouseEvent *event, map_view *mapview)
If the mouse event corresponds to a registered shortcut, fire the corresponding action.
fc_shortcuts()
fc_shortcuts contructor
QString get_desc(shortcut_id id) const
Returns description for given shortcut.
auto shortcuts() const
Returns all existing shortcuts.
void shortcut_pressed(shortcut_id key)
Pressed mouse or keyboard.
bool eventFilter(QObject *watched, QEvent *event) override
Mouse press event for shortcut edit widget.
fc_shortcut shortcut() const
Retrieves the shortcut entered by the user.
shortcut_edit(const fc_shortcut &sc)
Constructs a shortcut edit widget.
bool event(QEvent *event) override
Reimplemented from QObject.
bool m_ignore_next_mouse_event
void set_shortcut(const fc_shortcut &shortcut)
Changes the shortcut displayed by the widget.
class fc_client * king()
Return fc_client instance.
#define fc_assert_ret(condition)
static std::vector< fc_shortcut > default_shortcuts()
Returns the list of default shrotcuts.
static QHash< int, const char * > key_map
void popup_shortcuts_dialog()
Popups shortcut dialog.
void real_menus_init()
Initialize menus (sensitivity, name, etc.) based on the current state and current ruleset,...
static QString button_name(Qt::MouseButton bt)
Returns mouse button name.
Qt::KeyboardModifiers modifiers
bool is_valid() const
Checks if the shortcut can be used.
QString to_string() const
Returns shortcut as string (eg.
bool conflicts(const fc_shortcut &other) const