mirror of https://github.com/Nheko-Reborn/nheko
parent
72410c499d
commit
56dcdd7fd4
@ -0,0 +1,241 @@ |
|||||||
|
// SPDX-FileCopyrightText: Nheko Contributors
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "KeySequenceRegistry.h" |
||||||
|
|
||||||
|
KeySequenceRegistry *KeySequenceRegistry::s_instance = nullptr; |
||||||
|
|
||||||
|
KeySequenceImpl::KeySequenceImpl(const QString &name, |
||||||
|
const QStringList &keySequences, |
||||||
|
QObject *parent) |
||||||
|
: QObject{parent} |
||||||
|
, m_name{name} |
||||||
|
, m_keySequences{keySequences} |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
KeySequenceImpl::setKeySequences(const QStringList &keySequences) |
||||||
|
{ |
||||||
|
if (keySequences == m_keySequences) |
||||||
|
return; |
||||||
|
m_keySequences = keySequences; |
||||||
|
emit keySequencesChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
EditableKeySequence::EditableKeySequence(QObject *parent) |
||||||
|
: QObject{parent} |
||||||
|
{ |
||||||
|
KeySequenceRegistry::instance()->registerKeySequence(this); |
||||||
|
} |
||||||
|
|
||||||
|
EditableKeySequence::EditableKeySequence(const QString &name, QObject *parent) |
||||||
|
: QObject{parent} |
||||||
|
, m_name{name} |
||||||
|
{ |
||||||
|
KeySequenceRegistry::instance()->registerKeySequence(this); |
||||||
|
} |
||||||
|
|
||||||
|
const QString |
||||||
|
EditableKeySequence::keySequence() const |
||||||
|
{ |
||||||
|
return (m_impl && m_impl->keySequences().size() > 0) ? m_impl->keySequences().first() |
||||||
|
: defaultKeySequence(); |
||||||
|
} |
||||||
|
|
||||||
|
const QStringList |
||||||
|
EditableKeySequence::keySequences() const |
||||||
|
{ |
||||||
|
return m_impl ? m_impl->keySequences() : defaultKeySequences(); |
||||||
|
} |
||||||
|
|
||||||
|
const QString |
||||||
|
EditableKeySequence::defaultKeySequence() const |
||||||
|
{ |
||||||
|
return m_defaultKeySequences.size() > 0 ? m_defaultKeySequences.first().toString() : QString{}; |
||||||
|
} |
||||||
|
|
||||||
|
const QStringList |
||||||
|
EditableKeySequence::defaultKeySequences() const |
||||||
|
{ |
||||||
|
QStringList dest; |
||||||
|
dest.resize(m_defaultKeySequences.size()); |
||||||
|
std::transform(m_defaultKeySequences.begin(), |
||||||
|
m_defaultKeySequences.end(), |
||||||
|
dest.begin(), |
||||||
|
[](const auto &keySequence) { return keySequence.toString(); }); |
||||||
|
return dest; |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
EditableKeySequence::setName(const QString &name) |
||||||
|
{ |
||||||
|
if (name == m_name) |
||||||
|
return; |
||||||
|
m_name = name; |
||||||
|
emit nameChanged(); |
||||||
|
KeySequenceRegistry::instance()->registerKeySequence(this); |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
EditableKeySequence::setKeySequence(const QString &keySequence) |
||||||
|
{ |
||||||
|
setKeySequences({keySequence}); |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
EditableKeySequence::setKeySequences(const QStringList &keySequences) |
||||||
|
{ |
||||||
|
m_impl->setKeySequences(keySequences); |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
EditableKeySequence::setDefaultKeySequence(const QString &keySequence) |
||||||
|
{ |
||||||
|
setDefaultKeySequences({keySequence}); |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
EditableKeySequence::setDefaultKeySequences(const QStringList &keySequences) |
||||||
|
{ |
||||||
|
QList<QKeySequence> temp; |
||||||
|
temp.resize(keySequences.size()); |
||||||
|
std::transform(keySequences.begin(), |
||||||
|
keySequences.end(), |
||||||
|
temp.begin(), |
||||||
|
[](const auto &keySequence) { return QKeySequence(keySequence); }); |
||||||
|
|
||||||
|
if (temp == m_defaultKeySequences) |
||||||
|
return; |
||||||
|
m_defaultKeySequences = temp; |
||||||
|
emit defaultKeySequencesChanged(); |
||||||
|
|
||||||
|
if (m_impl && m_impl->keySequences().isEmpty()) |
||||||
|
m_impl->setKeySequences(keySequences); |
||||||
|
} |
||||||
|
|
||||||
|
KeySequenceRegistry::KeySequenceRegistry(QObject *parent) |
||||||
|
: QAbstractListModel{parent} |
||||||
|
{ |
||||||
|
s_instance = this; |
||||||
|
} |
||||||
|
|
||||||
|
KeySequenceRegistry * |
||||||
|
KeySequenceRegistry::instance() |
||||||
|
{ |
||||||
|
if (!s_instance) |
||||||
|
s_instance = new KeySequenceRegistry; |
||||||
|
return s_instance; |
||||||
|
} |
||||||
|
|
||||||
|
KeySequenceRegistry * |
||||||
|
KeySequenceRegistry::create(QQmlEngine *qmlEngine, QJSEngine *) |
||||||
|
{ |
||||||
|
// The instance has to exist before it is used. We cannot replace it.
|
||||||
|
Q_ASSERT(s_instance); |
||||||
|
|
||||||
|
// The engine has to have the same thread affinity as the singleton.
|
||||||
|
Q_ASSERT(qmlEngine->thread() == s_instance->thread()); |
||||||
|
|
||||||
|
// There can only be one engine accessing the singleton.
|
||||||
|
static QJSEngine *s_engine = nullptr; |
||||||
|
if (s_engine) |
||||||
|
Q_ASSERT(qmlEngine == s_engine); |
||||||
|
else |
||||||
|
s_engine = qmlEngine; |
||||||
|
|
||||||
|
QJSEngine::setObjectOwnership(s_instance, QJSEngine::CppOwnership); |
||||||
|
return s_instance; |
||||||
|
} |
||||||
|
|
||||||
|
QHash<int, QByteArray> |
||||||
|
KeySequenceRegistry::roleNames() const |
||||||
|
{ |
||||||
|
return {{Roles::Name, "name"}, {Roles::KeySequence, "keySequence"}}; |
||||||
|
} |
||||||
|
|
||||||
|
QVariant |
||||||
|
KeySequenceRegistry::data(const QModelIndex &index, int role) const |
||||||
|
{ |
||||||
|
if (!index.isValid() || index.row() >= m_keySequences.size() || index.row() < 0) |
||||||
|
return {}; |
||||||
|
|
||||||
|
switch (role) { |
||||||
|
case Roles::Name: |
||||||
|
return m_keySequences.at(index.row())->name(); |
||||||
|
case Roles::KeySequence: { |
||||||
|
const auto &data = m_keySequences.at(index.row())->keySequences(); |
||||||
|
return data.size() > 0 ? data.first() : QString{}; |
||||||
|
} |
||||||
|
default: |
||||||
|
return {}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
KeySequenceRegistry::changeKeySequence(const QString &name, const QString &newKeySequence) |
||||||
|
{ |
||||||
|
for (int i = 0; i < m_keySequences.size(); ++i) { |
||||||
|
if (m_keySequences.at(i)->name() == name) { |
||||||
|
m_keySequences.at(i)->setKeySequences({newKeySequence}); |
||||||
|
emit dataChanged(index(i), index(i), {Roles::KeySequence}); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
QString |
||||||
|
KeySequenceRegistry::keycodeToChar(int keycode) const |
||||||
|
{ |
||||||
|
return QString((char)keycode); |
||||||
|
} |
||||||
|
|
||||||
|
QMap<QString, QStringList> |
||||||
|
KeySequenceRegistry::dumpBindings() const |
||||||
|
{ |
||||||
|
QMap<QString, QStringList> bindings; |
||||||
|
for (const auto sequence : m_keySequences) |
||||||
|
bindings[sequence->name()] = sequence->keySequences(); |
||||||
|
return bindings; |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
KeySequenceRegistry::restoreBindings(const QMap<QString, QStringList> &bindings) |
||||||
|
{ |
||||||
|
for (const auto &[name, keySequences] : bindings.asKeyValueRange()) { |
||||||
|
if (auto it = std::find_if(m_keySequences.begin(), |
||||||
|
m_keySequences.end(), |
||||||
|
[&name](const auto &impl) { return impl->name() == name; }); |
||||||
|
it != m_keySequences.end()) |
||||||
|
(*it)->setKeySequences(keySequences); |
||||||
|
else |
||||||
|
m_keySequences.push_back(new KeySequenceImpl{name, keySequences}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
KeySequenceRegistry::registerKeySequence(EditableKeySequence *action) |
||||||
|
{ |
||||||
|
if (action->name().isEmpty()) |
||||||
|
return; |
||||||
|
|
||||||
|
KeySequenceImpl *impl = nullptr; |
||||||
|
if (auto it = |
||||||
|
std::find_if(m_keySequences.begin(), |
||||||
|
m_keySequences.end(), |
||||||
|
[action](const auto &impl) { return impl->name() == action->name(); }); |
||||||
|
it != m_keySequences.end()) |
||||||
|
impl = *it; |
||||||
|
else { |
||||||
|
impl = new KeySequenceImpl{action->name(), action->keySequences()}; |
||||||
|
m_keySequences.push_back(impl); |
||||||
|
} |
||||||
|
|
||||||
|
action->m_impl = impl; |
||||||
|
connect(impl, |
||||||
|
&KeySequenceImpl::keySequencesChanged, |
||||||
|
action, |
||||||
|
&EditableKeySequence::keySequencesChanged); |
||||||
|
emit action->keySequencesChanged(); |
||||||
|
} |
@ -0,0 +1,116 @@ |
|||||||
|
// SPDX-FileCopyrightText: Nheko Contributors
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <QAbstractListModel> |
||||||
|
#include <QKeySequence> |
||||||
|
#include <QQmlEngine> |
||||||
|
|
||||||
|
class KeySequenceImpl : public QObject |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
|
||||||
|
public: |
||||||
|
KeySequenceImpl(const QString &name, |
||||||
|
const QStringList &keySequences, |
||||||
|
QObject *parent = nullptr); |
||||||
|
|
||||||
|
const QString &name() const { return m_name; } |
||||||
|
const QStringList &keySequences() const { return m_keySequences; } |
||||||
|
|
||||||
|
void setKeySequences(const QStringList &keySequences); |
||||||
|
|
||||||
|
signals: |
||||||
|
void keySequencesChanged(); |
||||||
|
|
||||||
|
private: |
||||||
|
const QString m_name; |
||||||
|
QStringList m_keySequences; |
||||||
|
}; |
||||||
|
|
||||||
|
class EditableKeySequence : public QObject |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
QML_ELEMENT |
||||||
|
|
||||||
|
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged FINAL) |
||||||
|
Q_PROPERTY( |
||||||
|
QString keySequence READ keySequence WRITE setKeySequence NOTIFY keySequencesChanged FINAL) |
||||||
|
Q_PROPERTY(QStringList keySequences READ keySequences WRITE setKeySequences NOTIFY |
||||||
|
keySequencesChanged FINAL) |
||||||
|
Q_PROPERTY(QString defaultKeySequence READ defaultKeySequence WRITE setDefaultKeySequence NOTIFY |
||||||
|
defaultKeySequencesChanged FINAL) |
||||||
|
Q_PROPERTY(QStringList defaultKeySequences READ defaultKeySequences WRITE setDefaultKeySequences |
||||||
|
NOTIFY defaultKeySequencesChanged FINAL) |
||||||
|
|
||||||
|
public: |
||||||
|
EditableKeySequence(QObject *parent = nullptr); |
||||||
|
EditableKeySequence(const QString &name, QObject *parent = nullptr); |
||||||
|
|
||||||
|
const QString &name() const { return m_name; } |
||||||
|
const QString keySequence() const; |
||||||
|
const QStringList keySequences() const; |
||||||
|
const QString defaultKeySequence() const; |
||||||
|
const QStringList defaultKeySequences() const; |
||||||
|
|
||||||
|
void setName(const QString &name); |
||||||
|
void setKeySequence(const QString &keySequence); |
||||||
|
void setKeySequences(const QStringList &keySequences); |
||||||
|
void setDefaultKeySequence(const QString &keySequence); |
||||||
|
void setDefaultKeySequences(const QStringList &keySequences); |
||||||
|
|
||||||
|
signals: |
||||||
|
void nameChanged(); |
||||||
|
void keySequencesChanged(); |
||||||
|
void defaultKeySequencesChanged(); |
||||||
|
|
||||||
|
private: |
||||||
|
QString m_name; |
||||||
|
QList<QKeySequence> m_defaultKeySequences; |
||||||
|
|
||||||
|
KeySequenceImpl *m_impl = nullptr; |
||||||
|
|
||||||
|
friend class KeySequenceRegistry; |
||||||
|
}; |
||||||
|
|
||||||
|
class KeySequenceRegistry : public QAbstractListModel |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
QML_ELEMENT |
||||||
|
QML_SINGLETON |
||||||
|
|
||||||
|
public: |
||||||
|
enum Roles |
||||||
|
{ |
||||||
|
Name, |
||||||
|
KeySequence, |
||||||
|
}; |
||||||
|
|
||||||
|
static KeySequenceRegistry *instance(); |
||||||
|
static KeySequenceRegistry *create(QQmlEngine *qmlEngine, QJSEngine *); |
||||||
|
|
||||||
|
QHash<int, QByteArray> roleNames() const override; |
||||||
|
int rowCount(const QModelIndex & = QModelIndex()) const override |
||||||
|
{ |
||||||
|
return m_keySequences.size(); |
||||||
|
} |
||||||
|
QVariant data(const QModelIndex &index, int role) const override; |
||||||
|
|
||||||
|
Q_INVOKABLE void changeKeySequence(const QString &name, const QString &newKeysequence); |
||||||
|
Q_INVOKABLE QString keycodeToChar(int keycode) const; |
||||||
|
|
||||||
|
QMap<QString, QStringList> dumpBindings() const; |
||||||
|
void restoreBindings(const QMap<QString, QStringList> &bindings); |
||||||
|
|
||||||
|
private: |
||||||
|
explicit KeySequenceRegistry(QObject *parent = nullptr); |
||||||
|
|
||||||
|
void registerKeySequence(EditableKeySequence *action); |
||||||
|
|
||||||
|
static KeySequenceRegistry *s_instance; |
||||||
|
QList<KeySequenceImpl *> m_keySequences; |
||||||
|
|
||||||
|
friend EditableKeySequence; |
||||||
|
}; |
@ -1,158 +0,0 @@ |
|||||||
// SPDX-FileCopyrightText: Nheko Contributors
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
#include "ShortcutRegistry.h" |
|
||||||
|
|
||||||
ShortcutRegistry *ShortcutRegistry::s_instance = nullptr; |
|
||||||
|
|
||||||
EditableShortcut::EditableShortcut(QObject *parent) |
|
||||||
: QObject{parent} |
|
||||||
{ |
|
||||||
ShortcutRegistry::instance()->registerShortcut(this); |
|
||||||
} |
|
||||||
|
|
||||||
EditableShortcut::EditableShortcut(const QString &name, const QString &description, QObject *parent) |
|
||||||
: QObject{parent} |
|
||||||
, m_name{name} |
|
||||||
, m_description{description} |
|
||||||
{ |
|
||||||
ShortcutRegistry::instance()->registerShortcut(this); |
|
||||||
} |
|
||||||
|
|
||||||
const QStringList |
|
||||||
EditableShortcut::shortcuts() const |
|
||||||
{ |
|
||||||
QStringList dest; |
|
||||||
dest.resize(m_shortcuts.size()); |
|
||||||
std::transform(m_shortcuts.begin(), m_shortcuts.end(), dest.begin(), [](const auto &shortcut) { |
|
||||||
return shortcut.toString(); |
|
||||||
}); |
|
||||||
return dest; |
|
||||||
} |
|
||||||
|
|
||||||
void |
|
||||||
EditableShortcut::setName(const QString &name) |
|
||||||
{ |
|
||||||
if (name == m_name) |
|
||||||
return; |
|
||||||
m_name = name; |
|
||||||
emit nameChanged(); |
|
||||||
} |
|
||||||
|
|
||||||
void |
|
||||||
EditableShortcut::setDescription(const QString &description) |
|
||||||
{ |
|
||||||
if (description == m_description) |
|
||||||
return; |
|
||||||
m_description = description; |
|
||||||
emit descriptionChanged(); |
|
||||||
} |
|
||||||
|
|
||||||
void |
|
||||||
EditableShortcut::setShortcut(const QString &shortcut) |
|
||||||
{ |
|
||||||
setShortcuts({shortcut}); |
|
||||||
} |
|
||||||
|
|
||||||
void |
|
||||||
EditableShortcut::setShortcuts(const QStringList &shortcuts) |
|
||||||
{ |
|
||||||
QList<QKeySequence> temp; |
|
||||||
temp.resize(shortcuts.size()); |
|
||||||
std::transform(shortcuts.begin(), shortcuts.end(), temp.begin(), [](const auto &shortcut) { |
|
||||||
return QKeySequence(shortcut); |
|
||||||
}); |
|
||||||
|
|
||||||
if (temp == m_shortcuts) |
|
||||||
return; |
|
||||||
m_shortcuts = temp; |
|
||||||
emit shortcutsChanged(); |
|
||||||
} |
|
||||||
|
|
||||||
ShortcutRegistry::ShortcutRegistry(QObject *parent) |
|
||||||
: QAbstractListModel{parent} |
|
||||||
{ |
|
||||||
if (s_instance) |
|
||||||
m_shortcuts = s_instance->m_shortcuts; |
|
||||||
|
|
||||||
s_instance = this; |
|
||||||
} |
|
||||||
|
|
||||||
ShortcutRegistry * |
|
||||||
ShortcutRegistry::instance() |
|
||||||
{ |
|
||||||
return s_instance; |
|
||||||
} |
|
||||||
|
|
||||||
ShortcutRegistry * |
|
||||||
ShortcutRegistry::create(QQmlEngine *qmlEngine, QJSEngine *) |
|
||||||
{ |
|
||||||
// The instance has to exist before it is used. We cannot replace it.
|
|
||||||
Q_ASSERT(s_instance); |
|
||||||
|
|
||||||
// The engine has to have the same thread affinity as the singleton.
|
|
||||||
Q_ASSERT(qmlEngine->thread() == s_instance->thread()); |
|
||||||
|
|
||||||
// There can only be one engine accessing the singleton.
|
|
||||||
static QJSEngine *s_engine = nullptr; |
|
||||||
if (s_engine) |
|
||||||
Q_ASSERT(qmlEngine == s_engine); |
|
||||||
else |
|
||||||
s_engine = qmlEngine; |
|
||||||
|
|
||||||
QJSEngine::setObjectOwnership(s_instance, QJSEngine::CppOwnership); |
|
||||||
return s_instance; |
|
||||||
} |
|
||||||
|
|
||||||
QHash<int, QByteArray> |
|
||||||
ShortcutRegistry::roleNames() const |
|
||||||
{ |
|
||||||
return { |
|
||||||
{Roles::Name, "name"}, {Roles::Description, "description"}, {Roles::Shortcut, "shortcut"}}; |
|
||||||
} |
|
||||||
|
|
||||||
QVariant |
|
||||||
ShortcutRegistry::data(const QModelIndex &index, int role) const |
|
||||||
{ |
|
||||||
if (!index.isValid() || index.row() >= m_shortcuts.size() || index.row() < 0) |
|
||||||
return {}; |
|
||||||
|
|
||||||
switch (role) { |
|
||||||
case Roles::Name: |
|
||||||
return m_shortcuts[index.row()]->name(); |
|
||||||
case Roles::Description: |
|
||||||
return m_shortcuts[index.row()]->description(); |
|
||||||
case Roles::Shortcut: |
|
||||||
return m_shortcuts[index.row()]->shortcut(); |
|
||||||
default: |
|
||||||
return {}; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void |
|
||||||
ShortcutRegistry::changeShortcut(const QString &name, const QString &newShortcut) |
|
||||||
{ |
|
||||||
for (int i = 0; i < m_shortcuts.size(); ++i) { |
|
||||||
if (m_shortcuts[i]->name() == name) { |
|
||||||
qDebug() << "new:" << newShortcut; |
|
||||||
m_shortcuts[i]->setShortcut(newShortcut); |
|
||||||
emit dataChanged(index(i), index(i), {Roles::Shortcut}); |
|
||||||
return; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
QString |
|
||||||
ShortcutRegistry::keycodeToChar(int keycode) const |
|
||||||
{ |
|
||||||
return QString((char)keycode); |
|
||||||
} |
|
||||||
|
|
||||||
void |
|
||||||
ShortcutRegistry::registerShortcut(EditableShortcut *action) |
|
||||||
{ |
|
||||||
beginInsertRows({}, m_shortcuts.size(), m_shortcuts.size()); |
|
||||||
m_shortcuts.push_back(action); |
|
||||||
endInsertRows(); |
|
||||||
} |
|
@ -1,84 +0,0 @@ |
|||||||
// SPDX-FileCopyrightText: Nheko Contributors
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
#pragma once |
|
||||||
|
|
||||||
#include <QAbstractListModel> |
|
||||||
#include <QKeySequence> |
|
||||||
#include <QQmlEngine> |
|
||||||
|
|
||||||
class EditableShortcut : public QObject |
|
||||||
{ |
|
||||||
Q_OBJECT |
|
||||||
QML_ELEMENT |
|
||||||
|
|
||||||
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged FINAL) |
|
||||||
Q_PROPERTY( |
|
||||||
QString description READ description WRITE setDescription NOTIFY descriptionChanged FINAL) |
|
||||||
Q_PROPERTY(QString shortcut READ shortcut WRITE setShortcut NOTIFY shortcutsChanged FINAL) |
|
||||||
Q_PROPERTY( |
|
||||||
QStringList shortcuts READ shortcuts WRITE setShortcuts NOTIFY shortcutsChanged FINAL) |
|
||||||
|
|
||||||
public: |
|
||||||
EditableShortcut(QObject *parent = nullptr); |
|
||||||
EditableShortcut(const QString &name, const QString &description, QObject *parent = nullptr); |
|
||||||
|
|
||||||
const QString &name() const { return m_name; } |
|
||||||
const QString &description() const { return m_description; } |
|
||||||
const QString shortcut() const |
|
||||||
{ |
|
||||||
return m_shortcuts.size() > 0 ? m_shortcuts.first().toString() : QString{}; |
|
||||||
} |
|
||||||
const QStringList shortcuts() const; |
|
||||||
|
|
||||||
void setName(const QString &name); |
|
||||||
void setDescription(const QString &description); |
|
||||||
void setShortcut(const QString &shortcut); |
|
||||||
void setShortcuts(const QStringList &shortcuts); |
|
||||||
|
|
||||||
signals: |
|
||||||
void nameChanged(); |
|
||||||
void descriptionChanged(); |
|
||||||
void shortcutsChanged(); |
|
||||||
|
|
||||||
private: |
|
||||||
QString m_name; |
|
||||||
QString m_description; |
|
||||||
QList<QKeySequence> m_shortcuts; |
|
||||||
}; |
|
||||||
|
|
||||||
class ShortcutRegistry : public QAbstractListModel |
|
||||||
{ |
|
||||||
Q_OBJECT |
|
||||||
QML_ELEMENT |
|
||||||
QML_SINGLETON |
|
||||||
|
|
||||||
public: |
|
||||||
enum Roles |
|
||||||
{ |
|
||||||
Name, |
|
||||||
Description, |
|
||||||
Shortcut, |
|
||||||
}; |
|
||||||
|
|
||||||
explicit ShortcutRegistry(QObject *parent = nullptr); |
|
||||||
|
|
||||||
static ShortcutRegistry *instance(); |
|
||||||
static ShortcutRegistry *create(QQmlEngine *qmlEngine, QJSEngine *); |
|
||||||
|
|
||||||
QHash<int, QByteArray> roleNames() const override; |
|
||||||
int rowCount(const QModelIndex & = QModelIndex()) const override { return m_shortcuts.size(); } |
|
||||||
QVariant data(const QModelIndex &index, int role) const override; |
|
||||||
|
|
||||||
Q_INVOKABLE void changeShortcut(const QString &name, const QString &newShortcut); |
|
||||||
Q_INVOKABLE QString keycodeToChar(int keycode) const; |
|
||||||
|
|
||||||
private: |
|
||||||
void registerShortcut(EditableShortcut *action); |
|
||||||
|
|
||||||
static ShortcutRegistry *s_instance; |
|
||||||
QList<EditableShortcut *> m_shortcuts; |
|
||||||
|
|
||||||
friend EditableShortcut; |
|
||||||
}; |
|
Loading…
Reference in new issue