Redesign ShortcutsEditor to take an obj list and refactor config to reflect that
This commit is contained in:
parent
f5964fbe7f
commit
2fb3bf4e26
8 changed files with 356 additions and 365 deletions
|
@ -1,47 +1,88 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>ShortcutsEditor</class>
|
<class>ShortcutsEditor</class>
|
||||||
<widget class="QDialog" name="ShortcutsEditor">
|
<widget class="QMainWindow" name="ShortcutsEditor">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>540</width>
|
<width>800</width>
|
||||||
<height>640</height>
|
<height>700</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Shortcuts Editor</string>
|
<string>Shortcuts Editor</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<item>
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<widget class="QScrollArea" name="scrollArea_Shortcuts">
|
<property name="spacing">
|
||||||
<property name="widgetResizable">
|
<number>0</number>
|
||||||
<bool>true</bool>
|
</property>
|
||||||
</property>
|
<property name="leftMargin">
|
||||||
<widget class="QWidget" name="scrollAreaWidgetContents_Shortcuts">
|
<number>0</number>
|
||||||
<property name="geometry">
|
</property>
|
||||||
<rect>
|
<property name="topMargin">
|
||||||
<x>0</x>
|
<number>0</number>
|
||||||
<y>0</y>
|
</property>
|
||||||
<width>516</width>
|
<property name="rightMargin">
|
||||||
<height>580</height>
|
<number>0</number>
|
||||||
</rect>
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QScrollArea" name="scrollArea_Shortcuts">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Plain</enum>
|
||||||
|
</property>
|
||||||
|
<property name="lineWidth">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="widgetResizable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="scrollAreaWidgetContents_Shortcuts">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>794</width>
|
||||||
|
<height>642</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</item>
|
||||||
</item>
|
<item>
|
||||||
<item>
|
<widget class="QFrame" name="frame">
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<property name="frameShape">
|
||||||
<property name="standardButtons">
|
<enum>QFrame::Box</enum>
|
||||||
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
|
</property>
|
||||||
</property>
|
<property name="frameShadow">
|
||||||
<property name="centerButtons">
|
<enum>QFrame::Raised</enum>
|
||||||
<bool>false</bool>
|
</property>
|
||||||
</property>
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
</widget>
|
<item>
|
||||||
</item>
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
</layout>
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
|
||||||
|
</property>
|
||||||
|
<property name="centerButtons">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|
|
@ -201,53 +201,49 @@ class ShortcutsConfig : public KeyValueConfigBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShortcutsConfig() :
|
ShortcutsConfig() :
|
||||||
userShortcuts(QMultiMap<QString, QKeySequence>()),
|
user_shortcuts({ }),
|
||||||
defaultShortcuts(QMultiMap<QString, QKeySequence>())
|
default_shortcuts({ })
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void reset() override { userShortcuts.clear(); }
|
|
||||||
|
|
||||||
void setDefaultShortcuts(const QList<QAction *> &actions);
|
virtual void reset() override { user_shortcuts.clear(); }
|
||||||
void setDefaultShortcuts(const QList<Shortcut *> &shortcuts);
|
|
||||||
void setDefaultShortcuts(const QList<QAction *> &actions, const QList<Shortcut *> &shortcuts);
|
|
||||||
QList<QKeySequence> getDefaultShortcuts(QAction *action) const;
|
|
||||||
QList<QKeySequence> getDefaultShortcuts(Shortcut *shortcut) const;
|
|
||||||
|
|
||||||
void setUserShortcuts(const QList<QAction *> &actions);
|
void setDefaultShortcuts(const QObjectList &objects);
|
||||||
void setUserShortcuts(const QList<Shortcut *> &shortcuts);
|
void setDefaultShortcuts(const QMultiMap<const QObject *, QKeySequence> &objects_keySequences);
|
||||||
void setUserShortcuts(const QList<QAction *> &actions, const QList<Shortcut *> &shortcuts);
|
QList<QKeySequence> defaultShortcuts(const QObject *object) const;
|
||||||
QList<QKeySequence> getUserShortcuts(QAction *action) const;
|
|
||||||
QList<QKeySequence> getUserShortcuts(Shortcut *shortcut) const;
|
void setUserShortcuts(const QObjectList &objects);
|
||||||
|
void setUserShortcuts(const QMultiMap<const QObject *, QKeySequence> &objects_keySequences);
|
||||||
|
QList<QKeySequence> userShortcuts(const QObject *object) const;
|
||||||
|
|
||||||
|
static bool objectNameIsValid(const QObject *object);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual QString getConfigFilepath() override;
|
virtual QString getConfigFilepath() override;
|
||||||
virtual void parseConfigKeyValue(QString key, QString value) override;
|
virtual void parseConfigKeyValue(QString key, QString value) override;
|
||||||
virtual QMap<QString, QString> getKeyValueMap() override;
|
virtual QMap<QString, QString> getKeyValueMap() override;
|
||||||
virtual void onNewConfigFileCreated() override {};
|
virtual void onNewConfigFileCreated() override { };
|
||||||
virtual void setUnreadKeys() override {};
|
virtual void setUnreadKeys() override { };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMultiMap<QString, QKeySequence> userShortcuts;
|
QMultiMap<QString, QKeySequence> user_shortcuts;
|
||||||
QMultiMap<QString, QKeySequence> defaultShortcuts;
|
QMultiMap<QString, QKeySequence> default_shortcuts;
|
||||||
|
|
||||||
enum StoreType {
|
enum StoreType {
|
||||||
User,
|
User,
|
||||||
Default
|
Default
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QString cfgKey(const QObject *object) const;
|
||||||
|
QList<QKeySequence> currentShortcuts(const QObject *object) const;
|
||||||
|
|
||||||
|
void storeShortcutsFromList(StoreType storeType, const QObjectList &objects);
|
||||||
void storeShortcuts(
|
void storeShortcuts(
|
||||||
StoreType storeType,
|
|
||||||
const QList<QAction *> &actions);
|
|
||||||
void storeShortcuts(
|
|
||||||
StoreType storeType,
|
|
||||||
const QList<Shortcut *> &shortcuts);
|
|
||||||
void storeShortcut(
|
|
||||||
StoreType storeType,
|
StoreType storeType,
|
||||||
const QString &cfgKey,
|
const QString &cfgKey,
|
||||||
const QList<QKeySequence> &keySequences);
|
const QList<QKeySequence> &keySequences);
|
||||||
QString cfgKey(QObject *object) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Call setDefaultShortcuts() prior to applying user shortcuts.
|
||||||
extern ShortcutsConfig shortcutsConfig;
|
extern ShortcutsConfig shortcutsConfig;
|
||||||
|
|
||||||
#endif // CONFIG_H
|
#endif // CONFIG_H
|
||||||
|
|
|
@ -129,6 +129,7 @@ private slots:
|
||||||
void openNewMapPopupWindow(int, QVariant);
|
void openNewMapPopupWindow(int, QVariant);
|
||||||
void onNewMapCreated();
|
void onNewMapCreated();
|
||||||
void onMapCacheCleared();
|
void onMapCacheCleared();
|
||||||
|
void applyUserShortcuts();
|
||||||
|
|
||||||
void on_action_NewMap_triggered();
|
void on_action_NewMap_triggered();
|
||||||
void on_actionNew_Tileset_triggered();
|
void on_actionNew_Tileset_triggered();
|
||||||
|
@ -292,12 +293,12 @@ private:
|
||||||
|
|
||||||
void initWindow();
|
void initWindow();
|
||||||
void initCustomUI();
|
void initCustomUI();
|
||||||
void initExtraShortcuts();
|
|
||||||
void initExtraSignals();
|
void initExtraSignals();
|
||||||
void initEditor();
|
void initEditor();
|
||||||
void initMiscHeapObjects();
|
void initMiscHeapObjects();
|
||||||
void initMapSortOrder();
|
void initMapSortOrder();
|
||||||
void initUserShortcuts();
|
void initShortcuts();
|
||||||
|
void initExtraShortcuts();
|
||||||
void setProjectSpecificUIVisibility();
|
void setProjectSpecificUIVisibility();
|
||||||
void loadUserSettings();
|
void loadUserSettings();
|
||||||
void applyMapListFilter(QString filterText);
|
void applyMapListFilter(QString filterText);
|
||||||
|
@ -312,6 +313,8 @@ private:
|
||||||
bool isProjectOpen();
|
bool isProjectOpen();
|
||||||
void showExportMapImageWindow(bool stitchMode);
|
void showExportMapImageWindow(bool stitchMode);
|
||||||
void redrawMetatileSelection();
|
void redrawMetatileSelection();
|
||||||
|
|
||||||
|
QObjectList shortcutableObjects() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MapListUserRoles {
|
enum MapListUserRoles {
|
||||||
|
|
|
@ -6,11 +6,17 @@
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
|
|
||||||
|
|
||||||
// Alternative to QShortcut that adds support for multiple QKeySequences.
|
// Alternative to QShortcut that adds support for multiple key sequences.
|
||||||
// Use this to allow the shortcut to be editable in ShortcutsEditor.
|
// Use this to allow the shortcut to be editable in ShortcutsEditor.
|
||||||
class Shortcut : public QObject
|
class Shortcut : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_DECLARE_PRIVATE(QShortcut)
|
||||||
|
Q_PROPERTY(QKeySequence key READ key WRITE setKey)
|
||||||
|
Q_PROPERTY(QString whatsThis READ whatsThis WRITE setWhatsThis)
|
||||||
|
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
|
||||||
|
Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat)
|
||||||
|
Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Shortcut(QWidget *parent);
|
explicit Shortcut(QWidget *parent);
|
||||||
|
|
|
@ -1,80 +1,57 @@
|
||||||
#ifndef SHORTCUTSEDITOR_H
|
#ifndef SHORTCUTSEDITOR_H
|
||||||
#define SHORTCUTSEDITOR_H
|
#define SHORTCUTSEDITOR_H
|
||||||
|
|
||||||
|
#include "shortcut.h"
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QAction>
|
||||||
|
|
||||||
|
class QFormLayout;
|
||||||
|
class MultiKeyEdit;
|
||||||
class QAbstractButton;
|
class QAbstractButton;
|
||||||
class QAction;
|
|
||||||
class QKeySequenceEdit;
|
|
||||||
class ActionShortcutEdit;
|
|
||||||
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ShortcutsEditor;
|
class ShortcutsEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ShortcutsEditor : public QDialog
|
class ShortcutsEditor : public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ShortcutsEditor(QWidget *parent = nullptr);
|
explicit ShortcutsEditor(const QObjectList &objectList, QWidget *parent = nullptr);
|
||||||
~ShortcutsEditor();
|
~ShortcutsEditor();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void shortcutsSaved();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ShortcutsEditor *ui;
|
Ui::ShortcutsEditor *ui;
|
||||||
QMap<QString, QAction *> actions;
|
QWidget *main_container;
|
||||||
QWidget *ase_container;
|
QMultiMap<QString, const QObject *> labels_objects;
|
||||||
|
QHash<QString, QFormLayout *> contexts_layouts;
|
||||||
|
QHash<MultiKeyEdit *, const QObject *> multiKeyEdits_objects;
|
||||||
|
|
||||||
void populateShortcuts();
|
void parseObjectList(const QObjectList &objectList);
|
||||||
|
QString getLabel(const QObject *object) const;
|
||||||
|
bool stringPropertyIsNotEmpty(const QObject *object, const char *name) const;
|
||||||
|
void populateMainContainer();
|
||||||
|
QString getShortcutContext(const QObject *object) const;
|
||||||
|
void addNewContextGroup(const QString &shortcutContext);
|
||||||
|
void addNewMultiKeyEdit(const QObject *object, const QString &shortcutContext);
|
||||||
|
QList<MultiKeyEdit *> siblings(MultiKeyEdit *multiKeyEdit) const;
|
||||||
|
void promptUserOnDuplicateFound(MultiKeyEdit *current, MultiKeyEdit *sender);
|
||||||
|
void removeKeySequence(const QKeySequence &keySequence, MultiKeyEdit *multiKeyEdit);
|
||||||
void saveShortcuts();
|
void saveShortcuts();
|
||||||
void resetShortcuts();
|
void resetShortcuts();
|
||||||
void promptUser(ActionShortcutEdit *current, ActionShortcutEdit *sender);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void checkForDuplicates();
|
void checkForDuplicates(const QKeySequence &keySequence);
|
||||||
void dialogButtonClicked(QAbstractButton *button);
|
void dialogButtonClicked(QAbstractButton *button);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// A collection of QKeySequenceEdit's in a QHBoxLayout with a cooresponding QAction
|
|
||||||
class ActionShortcutEdit : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ActionShortcutEdit(QWidget *parent = nullptr, QAction *action = nullptr, int count = 1);
|
|
||||||
|
|
||||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
|
||||||
|
|
||||||
int count() const { return kse_children.count(); }
|
|
||||||
void setCount(int count);
|
|
||||||
QList<QKeySequence> shortcuts() const;
|
|
||||||
void setShortcuts(const QList<QKeySequence> &keySequences);
|
|
||||||
void applyShortcuts();
|
|
||||||
bool removeOne(const QKeySequence &keySequence);
|
|
||||||
bool contains(const QKeySequence &keySequence);
|
|
||||||
bool contains(QKeySequenceEdit *keySequenceEdit);
|
|
||||||
QKeySequence last() const { return shortcuts().last(); }
|
|
||||||
|
|
||||||
QAction *action;
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void editingFinished();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QVector<QKeySequenceEdit *> kse_children;
|
|
||||||
QList<QKeySequence> ks_list;
|
|
||||||
|
|
||||||
void updateShortcuts() { setShortcuts(shortcuts()); }
|
|
||||||
void focusLast();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onEditingFinished();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SHORTCUTSEDITOR_H
|
#endif // SHORTCUTSEDITOR_H
|
||||||
|
|
121
src/config.cpp
121
src/config.cpp
|
@ -13,6 +13,7 @@
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
#include <QAbstractButton>
|
||||||
|
|
||||||
KeyValueConfigBase::~KeyValueConfigBase() {
|
KeyValueConfigBase::~KeyValueConfigBase() {
|
||||||
|
|
||||||
|
@ -722,13 +723,13 @@ QString ShortcutsConfig::getConfigFilepath() {
|
||||||
void ShortcutsConfig::parseConfigKeyValue(QString key, QString value) {
|
void ShortcutsConfig::parseConfigKeyValue(QString key, QString value) {
|
||||||
QStringList keySequences = value.split(' ');
|
QStringList keySequences = value.split(' ');
|
||||||
for (auto keySequence : keySequences)
|
for (auto keySequence : keySequences)
|
||||||
userShortcuts.insert(key, keySequence);
|
user_shortcuts.insert(key, keySequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString, QString> ShortcutsConfig::getKeyValueMap() {
|
QMap<QString, QString> ShortcutsConfig::getKeyValueMap() {
|
||||||
QMap<QString, QString> map;
|
QMap<QString, QString> map;
|
||||||
for (auto cfg_key : userShortcuts.uniqueKeys()) {
|
for (auto cfg_key : user_shortcuts.uniqueKeys()) {
|
||||||
auto keySequences = userShortcuts.values(cfg_key);
|
auto keySequences = user_shortcuts.values(cfg_key);
|
||||||
QStringList values;
|
QStringList values;
|
||||||
for (auto keySequence : keySequences)
|
for (auto keySequence : keySequences)
|
||||||
values.append(keySequence.toString());
|
values.append(keySequence.toString());
|
||||||
|
@ -738,99 +739,77 @@ QMap<QString, QString> ShortcutsConfig::getKeyValueMap() {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call this before applying user shortcuts to be able to restore default shortcuts.
|
void ShortcutsConfig::setDefaultShortcuts(const QObjectList &objects) {
|
||||||
void ShortcutsConfig::setDefaultShortcuts(const QList<QAction *> &actions) {
|
storeShortcutsFromList(StoreType::Default, objects);
|
||||||
storeShortcuts(StoreType::Default, actions);
|
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call this before applying user shortcuts to be able to restore default shortcuts.
|
void ShortcutsConfig::setDefaultShortcuts(const QMultiMap<const QObject *, QKeySequence> &objects_keySequences) {
|
||||||
void ShortcutsConfig::setDefaultShortcuts(const QList<Shortcut *> &shortcuts) {
|
for (auto *object : objects_keySequences.uniqueKeys())
|
||||||
storeShortcuts(StoreType::Default, shortcuts);
|
storeShortcuts(StoreType::Default, cfgKey(object), objects_keySequences.values(object));
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call this before applying user shortcuts to be able to restore default shortcuts.
|
QList<QKeySequence> ShortcutsConfig::defaultShortcuts(const QObject *object) const {
|
||||||
void ShortcutsConfig::setDefaultShortcuts(const QList<QAction *> &actions, const QList<Shortcut *> &shortcuts) {
|
return default_shortcuts.values(cfgKey(object));
|
||||||
storeShortcuts(StoreType::Default, actions);
|
}
|
||||||
storeShortcuts(StoreType::Default, shortcuts);
|
|
||||||
|
void ShortcutsConfig::setUserShortcuts(const QObjectList &objects) {
|
||||||
|
storeShortcutsFromList(StoreType::User, objects);
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QKeySequence> ShortcutsConfig::getDefaultShortcuts(QAction *action) const {
|
void ShortcutsConfig::setUserShortcuts(const QMultiMap<const QObject *, QKeySequence> &objects_keySequences) {
|
||||||
return defaultShortcuts.values(cfgKey(action));
|
for (auto *object : objects_keySequences.uniqueKeys())
|
||||||
}
|
storeShortcuts(StoreType::User, cfgKey(object), objects_keySequences.values(object));
|
||||||
|
|
||||||
QList<QKeySequence> ShortcutsConfig::getDefaultShortcuts(Shortcut *shortcut) const {
|
|
||||||
return defaultShortcuts.values(cfgKey(shortcut));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShortcutsConfig::setUserShortcuts(const QList<QAction *> &actions) {
|
|
||||||
storeShortcuts(StoreType::User, actions);
|
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutsConfig::setUserShortcuts(const QList<Shortcut *> &shortcuts) {
|
QList<QKeySequence> ShortcutsConfig::userShortcuts(const QObject *object) const {
|
||||||
storeShortcuts(StoreType::User, shortcuts);
|
return user_shortcuts.values(cfgKey(object));
|
||||||
save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutsConfig::setUserShortcuts(const QList<QAction *> &actions, const QList<Shortcut *> &shortcuts) {
|
void ShortcutsConfig::storeShortcutsFromList(StoreType storeType, const QObjectList &objects) {
|
||||||
storeShortcuts(StoreType::User, actions);
|
for (const auto *object : objects)
|
||||||
storeShortcuts(StoreType::User, shortcuts);
|
if (objectNameIsValid(object))
|
||||||
save();
|
storeShortcuts(storeType, cfgKey(object), currentShortcuts(object));
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QKeySequence> ShortcutsConfig::getUserShortcuts(QAction *action) const {
|
void ShortcutsConfig::storeShortcuts(
|
||||||
return userShortcuts.values(cfgKey(action));
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QKeySequence> ShortcutsConfig::getUserShortcuts(Shortcut *shortcut) const {
|
|
||||||
return userShortcuts.values(cfgKey(shortcut));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShortcutsConfig::storeShortcuts(StoreType storeType, const QList<QAction *> &actions) {
|
|
||||||
for (auto *action : actions)
|
|
||||||
if (!action->text().isEmpty() && !action->objectName().isEmpty())
|
|
||||||
storeShortcut(storeType, cfgKey(action), action->shortcuts());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShortcutsConfig::storeShortcuts(StoreType storeType, const QList<Shortcut *> &shortcuts) {
|
|
||||||
for (auto *shortcut : shortcuts)
|
|
||||||
if (!shortcut->whatsThis().isEmpty() && !shortcut->objectName().isEmpty())
|
|
||||||
storeShortcut(storeType, cfgKey(shortcut), shortcut->keys());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShortcutsConfig::storeShortcut(
|
|
||||||
StoreType storeType,
|
StoreType storeType,
|
||||||
const QString &cfgKey,
|
const QString &cfgKey,
|
||||||
const QList<QKeySequence> &keySequences)
|
const QList<QKeySequence> &keySequences)
|
||||||
{
|
{
|
||||||
bool storeUser = (storeType == User) || !userShortcuts.contains(cfgKey);
|
bool storeUser = (storeType == User) || !user_shortcuts.contains(cfgKey);
|
||||||
|
|
||||||
if (storeType == Default)
|
if (storeType == Default)
|
||||||
defaultShortcuts.remove(cfgKey);
|
default_shortcuts.remove(cfgKey);
|
||||||
if (storeUser)
|
if (storeUser)
|
||||||
userShortcuts.remove(cfgKey);
|
user_shortcuts.remove(cfgKey);
|
||||||
|
|
||||||
if (keySequences.isEmpty()) {
|
if (keySequences.isEmpty()) {
|
||||||
if (storeType == Default)
|
if (storeType == Default)
|
||||||
defaultShortcuts.insert(cfgKey, QKeySequence());
|
default_shortcuts.insert(cfgKey, QKeySequence());
|
||||||
if (storeUser)
|
if (storeUser)
|
||||||
userShortcuts.insert(cfgKey, QKeySequence());
|
user_shortcuts.insert(cfgKey, QKeySequence());
|
||||||
} else {
|
} else {
|
||||||
for (auto keySequence : keySequences) {
|
for (auto keySequence : keySequences) {
|
||||||
if (storeType == Default)
|
if (storeType == Default)
|
||||||
defaultShortcuts.insert(cfgKey, keySequence);
|
default_shortcuts.insert(cfgKey, keySequence);
|
||||||
if (storeUser)
|
if (storeUser)
|
||||||
userShortcuts.insert(cfgKey, keySequence);
|
user_shortcuts.insert(cfgKey, keySequence);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ShortcutsConfig::objectNameIsValid(const QObject *object) {
|
||||||
|
// Qt internal action names start with "_q_" so we filter those out.
|
||||||
|
return !object->objectName().isEmpty() && !object->objectName().startsWith("_q_");
|
||||||
|
}
|
||||||
|
|
||||||
/* Creates a config key from the object's name prepended with the parent
|
/* Creates a config key from the object's name prepended with the parent
|
||||||
* window's object name, and converts camelCase to snake_case. */
|
* window's object name, and converts camelCase to snake_case. */
|
||||||
QString ShortcutsConfig::cfgKey(QObject *object) const {
|
QString ShortcutsConfig::cfgKey(const QObject *object) const {
|
||||||
auto cfg_key = QString();
|
auto cfg_key = QString();
|
||||||
auto *parentWidget = static_cast<QWidget *>(object->parent());
|
auto *parentWidget = static_cast<QWidget *>(object->parent());
|
||||||
if (parentWidget)
|
if (parentWidget)
|
||||||
|
@ -838,11 +817,31 @@ QString ShortcutsConfig::cfgKey(QObject *object) const {
|
||||||
cfg_key += object->objectName();
|
cfg_key += object->objectName();
|
||||||
|
|
||||||
QRegularExpression re("[A-Z]");
|
QRegularExpression re("[A-Z]");
|
||||||
int i = cfg_key.indexOf(re);
|
int i = cfg_key.indexOf(re, 1);
|
||||||
while (i != -1) {
|
while (i != -1) {
|
||||||
if (i != 0 && cfg_key.at(i - 1) != '_')
|
if (cfg_key.at(i - 1) != '_')
|
||||||
cfg_key.insert(i++, '_');
|
cfg_key.insert(i++, '_');
|
||||||
i = cfg_key.indexOf(re, i + 1);
|
i = cfg_key.indexOf(re, i + 1);
|
||||||
}
|
}
|
||||||
return cfg_key.toLower();
|
return cfg_key.toLower();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QKeySequence> ShortcutsConfig::currentShortcuts(const QObject *object) const {
|
||||||
|
if (object->inherits("QAction")) {
|
||||||
|
const auto *action = qobject_cast<const QAction *>(object);
|
||||||
|
return action->shortcuts();
|
||||||
|
} else if (object->inherits("QAbstractButton")) {
|
||||||
|
const auto *button = qobject_cast<const QAbstractButton *>(object);
|
||||||
|
return { button->shortcut() };
|
||||||
|
} else if (object->inherits("Shortcut")) {
|
||||||
|
const auto *shortcut = qobject_cast<const Shortcut *>(object);
|
||||||
|
return shortcut->keys();
|
||||||
|
} else if (object->inherits("QShortcut")) {
|
||||||
|
const auto *qshortcut = qobject_cast<const QShortcut *>(object);
|
||||||
|
return { qshortcut->key() };
|
||||||
|
} else if (object->property("shortcut").isValid()) {
|
||||||
|
return { object->property("shortcut").value<QKeySequence>() };
|
||||||
|
} else {
|
||||||
|
return { };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -88,40 +88,63 @@ void MainWindow::initWindow() {
|
||||||
porymapConfig.load();
|
porymapConfig.load();
|
||||||
this->initCustomUI();
|
this->initCustomUI();
|
||||||
this->initExtraSignals();
|
this->initExtraSignals();
|
||||||
this->initExtraShortcuts();
|
|
||||||
this->initEditor();
|
this->initEditor();
|
||||||
this->initMiscHeapObjects();
|
this->initMiscHeapObjects();
|
||||||
this->initMapSortOrder();
|
this->initMapSortOrder();
|
||||||
this->initUserShortcuts();
|
this->initShortcuts();
|
||||||
this->restoreWindowState();
|
this->restoreWindowState();
|
||||||
|
|
||||||
setWindowDisabled(true);
|
setWindowDisabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::initShortcuts() {
|
||||||
|
initExtraShortcuts();
|
||||||
|
|
||||||
|
shortcutsConfig.load();
|
||||||
|
shortcutsConfig.setDefaultShortcuts(shortcutableObjects());
|
||||||
|
applyUserShortcuts();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::initExtraShortcuts() {
|
void MainWindow::initExtraShortcuts() {
|
||||||
auto *shortcutReset_Zoom = new Shortcut(QKeySequence("Ctrl+0"), this, SLOT(resetMapViewScale()));
|
auto *shortcutReset_Zoom = new Shortcut(QKeySequence("Ctrl+0"), this, SLOT(resetMapViewScale()));
|
||||||
shortcutReset_Zoom->setObjectName("shortcutReset_Zoom");
|
shortcutReset_Zoom->setObjectName("shortcutZoom_Reset");
|
||||||
|
shortcutReset_Zoom->setWhatsThis("Zoom Reset");
|
||||||
|
|
||||||
auto *shortcutToggle_Grid = new Shortcut(QKeySequence("Ctrl+G"), ui->checkBox_ToggleGrid, SLOT(toggle()));
|
auto *shortcutToggle_Grid = new Shortcut(QKeySequence("Ctrl+G"), ui->checkBox_ToggleGrid, SLOT(toggle()));
|
||||||
shortcutToggle_Grid->setObjectName("shortcutToggle_Grid");
|
shortcutToggle_Grid->setObjectName("shortcutToggle_Grid");
|
||||||
|
shortcutToggle_Grid->setWhatsThis("Toggle Grid");
|
||||||
|
|
||||||
auto *shortcutDuplicate_Events = new Shortcut(QKeySequence("Ctrl+D"), this, SLOT(duplicate()));
|
auto *shortcutDuplicate_Events = new Shortcut(QKeySequence("Ctrl+D"), this, SLOT(duplicate()));
|
||||||
shortcutDuplicate_Events->setObjectName("shortcutDuplicate_Events");
|
shortcutDuplicate_Events->setObjectName("shortcutDuplicate_Events");
|
||||||
|
shortcutDuplicate_Events->setWhatsThis("Duplicate Selected Event(s)");
|
||||||
|
|
||||||
auto *shortcutDelete_Object = new Shortcut(
|
auto *shortcutDelete_Object = new Shortcut(
|
||||||
{QKeySequence("Del"), QKeySequence("Backspace")}, this, SLOT(on_toolButton_deleteObject_clicked()));
|
{QKeySequence("Del"), QKeySequence("Backspace")}, this, SLOT(on_toolButton_deleteObject_clicked()));
|
||||||
shortcutDelete_Object->setObjectName("shortcutDelete_Object");
|
shortcutDelete_Object->setObjectName("shortcutDelete_Object");
|
||||||
|
shortcutDelete_Object->setWhatsThis("Delete Selected Event(s)");
|
||||||
|
|
||||||
ui->actionZoom_In->setShortcuts({ui->actionZoom_In->shortcut(), QKeySequence("Ctrl+=")});
|
ui->actionZoom_In->setShortcuts({ui->actionZoom_In->shortcut(), QKeySequence("Ctrl+=")});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::initUserShortcuts() {
|
QObjectList MainWindow::shortcutableObjects() const {
|
||||||
shortcutsConfig.load();
|
QObjectList shortcutable_objects;
|
||||||
shortcutsConfig.setDefaultShortcuts(findChildren<QAction *>(), findChildren<Shortcut *>());
|
|
||||||
for (auto *action : findChildren<QAction *>())
|
for (auto *action : findChildren<QAction *>())
|
||||||
action->setShortcuts(shortcutsConfig.getUserShortcuts(action));
|
if (!action->objectName().isEmpty())
|
||||||
|
shortcutable_objects.append(qobject_cast<QObject *>(action));
|
||||||
for (auto *shortcut : findChildren<Shortcut *>())
|
for (auto *shortcut : findChildren<Shortcut *>())
|
||||||
shortcut->setKeys(shortcutsConfig.getUserShortcuts(shortcut));
|
if (!shortcut->objectName().isEmpty())
|
||||||
|
shortcutable_objects.append(qobject_cast<QObject *>(shortcut));
|
||||||
|
|
||||||
|
return shortcutable_objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::applyUserShortcuts() {
|
||||||
|
for (auto *action : findChildren<QAction *>())
|
||||||
|
if (!action->objectName().isEmpty())
|
||||||
|
action->setShortcuts(shortcutsConfig.userShortcuts(action));
|
||||||
|
for (auto *shortcut : findChildren<Shortcut *>())
|
||||||
|
if (!shortcut->objectName().isEmpty())
|
||||||
|
shortcut->setKeys(shortcutsConfig.userShortcuts(shortcut));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::initCustomUI() {
|
void MainWindow::initCustomUI() {
|
||||||
|
@ -1426,8 +1449,12 @@ void MainWindow::on_actionUse_Poryscript_triggered(bool checked)
|
||||||
|
|
||||||
void MainWindow::on_actionEdit_Shortcuts_triggered()
|
void MainWindow::on_actionEdit_Shortcuts_triggered()
|
||||||
{
|
{
|
||||||
if (!shortcutsEditor)
|
if (!shortcutsEditor) {
|
||||||
shortcutsEditor = new ShortcutsEditor(this);
|
shortcutsEditor = new ShortcutsEditor(shortcutableObjects(), this);
|
||||||
|
connect(shortcutsEditor, &QObject::destroyed, [=](QObject *) { shortcutsEditor = nullptr; });
|
||||||
|
connect(shortcutsEditor, &ShortcutsEditor::shortcutsSaved,
|
||||||
|
this, &MainWindow::applyUserShortcuts);
|
||||||
|
}
|
||||||
|
|
||||||
if (shortcutsEditor->isHidden())
|
if (shortcutsEditor->isHidden())
|
||||||
shortcutsEditor->show();
|
shortcutsEditor->show();
|
||||||
|
|
|
@ -1,26 +1,32 @@
|
||||||
#include "shortcutseditor.h"
|
#include "shortcutseditor.h"
|
||||||
#include "ui_shortcutseditor.h"
|
#include "ui_shortcutseditor.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "multikeyedit.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
#include <QGroupBox>
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#include <QAbstractButton>
|
#include <QAbstractButton>
|
||||||
#include <QtEvents>
|
#include <QtEvents>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QKeySequenceEdit>
|
#include <QRegularExpression>
|
||||||
#include <QAction>
|
#include <QLabel>
|
||||||
|
|
||||||
|
|
||||||
ShortcutsEditor::ShortcutsEditor(QWidget *parent) :
|
ShortcutsEditor::ShortcutsEditor(const QObjectList &objectList, QWidget *parent) :
|
||||||
QDialog(parent),
|
QMainWindow(parent),
|
||||||
ui(new Ui::ShortcutsEditor),
|
ui(new Ui::ShortcutsEditor),
|
||||||
actions(QMap<QString, QAction *>())
|
main_container(nullptr)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ase_container = ui->scrollAreaWidgetContents_Shortcuts;
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
main_container = ui->scrollAreaWidgetContents_Shortcuts;
|
||||||
|
main_container->setLayout(new QVBoxLayout(main_container));
|
||||||
connect(ui->buttonBox, &QDialogButtonBox::clicked,
|
connect(ui->buttonBox, &QDialogButtonBox::clicked,
|
||||||
this, &ShortcutsEditor::dialogButtonClicked);
|
this, &ShortcutsEditor::dialogButtonClicked);
|
||||||
populateShortcuts();
|
|
||||||
|
parseObjectList(objectList);
|
||||||
|
populateMainContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
ShortcutsEditor::~ShortcutsEditor()
|
ShortcutsEditor::~ShortcutsEditor()
|
||||||
|
@ -28,207 +34,143 @@ ShortcutsEditor::~ShortcutsEditor()
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutsEditor::populateShortcuts() {
|
void ShortcutsEditor::saveShortcuts() {
|
||||||
if (!parent())
|
QMultiMap<const QObject *, QKeySequence> objects_keySequences;
|
||||||
return;
|
for (auto it = multiKeyEdits_objects.cbegin(); it != multiKeyEdits_objects.cend(); ++it)
|
||||||
|
for (auto keySequence : it.key()->keySequences())
|
||||||
|
objects_keySequences.insert(it.value(), keySequence);
|
||||||
|
|
||||||
for (auto action : parent()->findChildren<QAction *>())
|
shortcutsConfig.setUserShortcuts(objects_keySequences);
|
||||||
if (!action->text().isEmpty() && !action->objectName().isEmpty())
|
emit shortcutsSaved();
|
||||||
actions.insert(action->text().remove('&'), action);
|
}
|
||||||
|
|
||||||
auto *formLayout = new QFormLayout(ase_container);
|
// Restores default shortcuts but doesn't save until Apply or OK is clicked.
|
||||||
for (auto *action : actions) {
|
void ShortcutsEditor::resetShortcuts() {
|
||||||
auto userShortcuts = shortcutsConfig.getUserShortcuts(action);
|
for (auto it = multiKeyEdits_objects.begin(); it != multiKeyEdits_objects.end(); ++it) {
|
||||||
auto *ase = new ActionShortcutEdit(ase_container, action, 2);
|
it.key()->blockSignals(true);
|
||||||
connect(ase, &ActionShortcutEdit::editingFinished,
|
const auto defaults = shortcutsConfig.defaultShortcuts(it.value());
|
||||||
this, &ShortcutsEditor::checkForDuplicates);
|
it.key()->setKeySequences(defaults);
|
||||||
ase->setShortcuts(userShortcuts);
|
it.key()->blockSignals(false);
|
||||||
formLayout->addRow(action->text(), ase);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutsEditor::saveShortcuts() {
|
void ShortcutsEditor::parseObjectList(const QObjectList &objectList) {
|
||||||
auto ase_children = ase_container->findChildren<ActionShortcutEdit *>(QString(), Qt::FindDirectChildrenOnly);
|
for (auto *object : objectList) {
|
||||||
for (auto *ase : ase_children)
|
const auto label = getLabel(object);
|
||||||
ase->applyShortcuts();
|
if (!label.isEmpty() && ShortcutsConfig::objectNameIsValid(object))
|
||||||
shortcutsConfig.setUserShortcuts(actions.values());
|
labels_objects.insert(label, object);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutsEditor::resetShortcuts() {
|
QString ShortcutsEditor::getLabel(const QObject *object) const {
|
||||||
auto ase_children = ase_container->findChildren<ActionShortcutEdit *>(QString(), Qt::FindDirectChildrenOnly);
|
if (stringPropertyIsNotEmpty(object, "text"))
|
||||||
for (auto *ase : ase_children)
|
return object->property("text").toString().remove('&');
|
||||||
ase->setShortcuts(shortcutsConfig.getDefaultShortcuts(ase->action));
|
else if (stringPropertyIsNotEmpty(object, "whatsThis"))
|
||||||
|
return object->property("whatsThis").toString().remove('&');
|
||||||
|
else
|
||||||
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutsEditor::promptUser(ActionShortcutEdit *current, ActionShortcutEdit *sender) {
|
bool ShortcutsEditor::stringPropertyIsNotEmpty(const QObject *object, const char *name) const {
|
||||||
auto result = QMessageBox::question(
|
return object->property(name).isValid() && !object->property(name).toString().isEmpty();
|
||||||
this,
|
}
|
||||||
"porymap",
|
|
||||||
QString("Shortcut \"%1\" is already used by \"%2\", would you like to replace it?")
|
void ShortcutsEditor::populateMainContainer() {
|
||||||
.arg(sender->last().toString()).arg(current->action->text()),
|
for (auto object : labels_objects) {
|
||||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
const auto shortcutContext = getShortcutContext(object);
|
||||||
|
if (!contexts_layouts.contains(shortcutContext))
|
||||||
|
addNewContextGroup(shortcutContext);
|
||||||
|
|
||||||
|
addNewMultiKeyEdit(object, shortcutContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The context for which the object's shortcut is active (Displayed in group box title).
|
||||||
|
// Uses the parent window's objectName and adds spaces between words.
|
||||||
|
QString ShortcutsEditor::getShortcutContext(const QObject *object) const {
|
||||||
|
auto objectParentWidget = static_cast<QWidget *>(object->parent());
|
||||||
|
auto context = objectParentWidget->window()->objectName();
|
||||||
|
QRegularExpression re("[A-Z]");
|
||||||
|
int i = context.indexOf(re, 1);
|
||||||
|
while (i != -1) {
|
||||||
|
if (context.at(i - 1) != ' ')
|
||||||
|
context.insert(i++, ' ');
|
||||||
|
i = context.indexOf(re, i + 1);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seperate shortcuts into context groups for duplicate checking.
|
||||||
|
void ShortcutsEditor::addNewContextGroup(const QString &shortcutContext) {
|
||||||
|
auto *groupBox = new QGroupBox(shortcutContext, main_container);
|
||||||
|
main_container->layout()->addWidget(groupBox);
|
||||||
|
auto *formLayout = new QFormLayout(groupBox);
|
||||||
|
contexts_layouts.insert(shortcutContext, formLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutsEditor::addNewMultiKeyEdit(const QObject *object, const QString &shortcutContext) {
|
||||||
|
auto *container = contexts_layouts.value(shortcutContext)->parentWidget();
|
||||||
|
auto *multiKeyEdit = new MultiKeyEdit(container);
|
||||||
|
multiKeyEdit->setKeySequences(shortcutsConfig.userShortcuts(object));
|
||||||
|
connect(multiKeyEdit, &MultiKeyEdit::keySequenceChanged,
|
||||||
|
this, &ShortcutsEditor::checkForDuplicates);
|
||||||
|
contexts_layouts.value(shortcutContext)->addRow(labels_objects.key(object), multiKeyEdit);
|
||||||
|
multiKeyEdits_objects.insert(multiKeyEdit, object);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutsEditor::checkForDuplicates(const QKeySequence &keySequence) {
|
||||||
|
if (keySequence.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto *sender_multiKeyEdit = qobject_cast<MultiKeyEdit *>(sender());
|
||||||
|
if (!sender_multiKeyEdit)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto *sibling_multiKeyEdit : siblings(sender_multiKeyEdit))
|
||||||
|
if (sibling_multiKeyEdit->contains(keySequence))
|
||||||
|
promptUserOnDuplicateFound(sender_multiKeyEdit, sibling_multiKeyEdit);
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<MultiKeyEdit *> ShortcutsEditor::siblings(MultiKeyEdit *multiKeyEdit) const {
|
||||||
|
auto list = multiKeyEdit->parent()->findChildren<MultiKeyEdit *>(QString(), Qt::FindDirectChildrenOnly);
|
||||||
|
list.removeOne(multiKeyEdit);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutsEditor::promptUserOnDuplicateFound(MultiKeyEdit *sender, MultiKeyEdit *sibling) {
|
||||||
|
const auto duplicateKeySequence = sender->keySequences().last();
|
||||||
|
const auto siblingLabel = getLabel(multiKeyEdits_objects.value(sibling));
|
||||||
|
const auto message = QString(
|
||||||
|
"Shortcut '%1' is already used by '%2', would you like to replace it?")
|
||||||
|
.arg(duplicateKeySequence.toString()).arg(siblingLabel);
|
||||||
|
|
||||||
|
const auto result = QMessageBox::question(
|
||||||
|
this, "porymap", message, QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
||||||
|
|
||||||
if (result == QMessageBox::Yes)
|
if (result == QMessageBox::Yes)
|
||||||
current->removeOne(sender->last());
|
removeKeySequence(duplicateKeySequence, sibling);
|
||||||
else if (result == QMessageBox::No)
|
else
|
||||||
sender->removeOne(sender->last());
|
removeKeySequence(duplicateKeySequence, sender);
|
||||||
|
|
||||||
|
activateWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutsEditor::checkForDuplicates() {
|
void ShortcutsEditor::removeKeySequence(const QKeySequence &keySequence, MultiKeyEdit *multiKeyEdit) {
|
||||||
auto *sender_ase = qobject_cast<ActionShortcutEdit *>(sender());
|
multiKeyEdit->blockSignals(true);
|
||||||
if (!sender_ase)
|
multiKeyEdit->removeOne(keySequence);
|
||||||
return;
|
multiKeyEdit->blockSignals(false);
|
||||||
|
|
||||||
for (auto *child_kse : findChildren<QKeySequenceEdit *>()) {
|
|
||||||
if (child_kse->keySequence().isEmpty() || child_kse->parent() == sender())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (sender_ase->contains(child_kse->keySequence())) {
|
|
||||||
auto *current_ase = qobject_cast<ActionShortcutEdit *>(child_kse->parent());
|
|
||||||
if (!current_ase)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
promptUser(current_ase, sender_ase);
|
|
||||||
activateWindow();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutsEditor::dialogButtonClicked(QAbstractButton *button) {
|
void ShortcutsEditor::dialogButtonClicked(QAbstractButton *button) {
|
||||||
auto buttonRole = ui->buttonBox->buttonRole(button);
|
auto buttonRole = ui->buttonBox->buttonRole(button);
|
||||||
if (buttonRole == QDialogButtonBox::AcceptRole) {
|
if (buttonRole == QDialogButtonBox::AcceptRole) {
|
||||||
saveShortcuts();
|
saveShortcuts();
|
||||||
hide();
|
close();
|
||||||
} else if (buttonRole == QDialogButtonBox::ApplyRole) {
|
} else if (buttonRole == QDialogButtonBox::ApplyRole) {
|
||||||
saveShortcuts();
|
saveShortcuts();
|
||||||
} else if (buttonRole == QDialogButtonBox::RejectRole) {
|
} else if (buttonRole == QDialogButtonBox::RejectRole) {
|
||||||
hide();
|
close();
|
||||||
} else if (buttonRole == QDialogButtonBox::ResetRole) {
|
} else if (buttonRole == QDialogButtonBox::ResetRole) {
|
||||||
resetShortcuts();
|
resetShortcuts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ActionShortcutEdit::ActionShortcutEdit(QWidget *parent, QAction *action, int count) :
|
|
||||||
QWidget(parent),
|
|
||||||
action(action),
|
|
||||||
kse_children(QVector<QKeySequenceEdit *>()),
|
|
||||||
ks_list(QList<QKeySequence>())
|
|
||||||
{
|
|
||||||
setLayout(new QHBoxLayout(this));
|
|
||||||
layout()->setContentsMargins(0, 0, 0, 0);
|
|
||||||
setCount(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ActionShortcutEdit::eventFilter(QObject *watched, QEvent *event) {
|
|
||||||
auto *watched_kse = qobject_cast<QKeySequenceEdit *>(watched);
|
|
||||||
if (!watched_kse)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (event->type() == QEvent::KeyPress) {
|
|
||||||
auto *keyEvent = static_cast<QKeyEvent *>(event);
|
|
||||||
if (keyEvent->key() == Qt::Key_Escape) {
|
|
||||||
watched_kse->clearFocus();
|
|
||||||
return true;
|
|
||||||
} else if (keyEvent->key() == Qt::Key_Backspace) {
|
|
||||||
removeOne(watched_kse->keySequence());
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
watched_kse->clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionShortcutEdit::setCount(int count) {
|
|
||||||
if (count < 1)
|
|
||||||
count = 1;
|
|
||||||
|
|
||||||
while (kse_children.count() > count) {
|
|
||||||
layout()->removeWidget(kse_children.last());
|
|
||||||
delete kse_children.last();
|
|
||||||
kse_children.removeLast();
|
|
||||||
}
|
|
||||||
|
|
||||||
while (kse_children.count() < count) {
|
|
||||||
auto *kse = new QKeySequenceEdit(this);
|
|
||||||
connect(kse, &QKeySequenceEdit::editingFinished,
|
|
||||||
this, &ActionShortcutEdit::onEditingFinished);
|
|
||||||
kse->installEventFilter(this);
|
|
||||||
layout()->addWidget(kse);
|
|
||||||
kse_children.append(kse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QKeySequence> ActionShortcutEdit::shortcuts() const {
|
|
||||||
QList<QKeySequence> current_ks_list;
|
|
||||||
for (auto *kse : kse_children)
|
|
||||||
if (!kse->keySequence().isEmpty())
|
|
||||||
current_ks_list.append(kse->keySequence());
|
|
||||||
return current_ks_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionShortcutEdit::setShortcuts(const QList<QKeySequence> &keySequences) {
|
|
||||||
clear();
|
|
||||||
ks_list = keySequences;
|
|
||||||
int minCount = qMin(kse_children.count(), ks_list.count());
|
|
||||||
for (int i = 0; i < minCount; ++i)
|
|
||||||
kse_children[i]->setKeySequence(ks_list[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionShortcutEdit::applyShortcuts() {
|
|
||||||
action->setShortcuts(shortcuts());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ActionShortcutEdit::removeOne(const QKeySequence &keySequence) {
|
|
||||||
for (auto *kse : kse_children) {
|
|
||||||
if (kse->keySequence() == keySequence) {
|
|
||||||
ks_list.removeOne(keySequence);
|
|
||||||
kse->clear();
|
|
||||||
updateShortcuts();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ActionShortcutEdit::contains(const QKeySequence &keySequence) {
|
|
||||||
for (auto ks : shortcuts())
|
|
||||||
if (ks == keySequence)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ActionShortcutEdit::contains(QKeySequenceEdit *keySequenceEdit) {
|
|
||||||
for (auto *kse : kse_children)
|
|
||||||
if (kse == keySequenceEdit)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionShortcutEdit::clear() {
|
|
||||||
for (auto *kse : kse_children)
|
|
||||||
kse->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionShortcutEdit::focusLast() {
|
|
||||||
for (int i = count() - 1; i >= 0; --i) {
|
|
||||||
if (!kse_children[i]->keySequence().isEmpty()) {
|
|
||||||
kse_children[i]->setFocus();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionShortcutEdit::onEditingFinished() {
|
|
||||||
auto *kse = qobject_cast<QKeySequenceEdit *>(sender());
|
|
||||||
if (!kse)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ks_list.contains(kse->keySequence()))
|
|
||||||
removeOne(kse->keySequence());
|
|
||||||
updateShortcuts();
|
|
||||||
focusLast();
|
|
||||||
emit editingFinished();
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue