git repos / SagoImageBrowser

blame: src/shortcutmanager.cpp

normal view · raw

83f0e0bc Poul Sander 2026-05-30 17:59 1
#include "shortcutmanager.h"
83f0e0bc Poul Sander 2026-05-30 17:59 2
83f0e0bc Poul Sander 2026-05-30 17:59 3
#include <QKeyEvent>
83f0e0bc Poul Sander 2026-05-30 17:59 4
#include <QSettings>
83f0e0bc Poul Sander 2026-05-30 17:59 5
83f0e0bc Poul Sander 2026-05-30 17:59 6
namespace {
83f0e0bc Poul Sander 2026-05-30 17:59 7
83f0e0bc Poul Sander 2026-05-30 17:59 8
struct ActionInfo {
83f0e0bc Poul Sander 2026-05-30 17:59 9
    const char *name;        // settings key
83f0e0bc Poul Sander 2026-05-30 17:59 10
    const char *description; // human-readable for help overlay / prefs table
83f0e0bc Poul Sander 2026-05-30 17:59 11
    QKeySequence defaultKey;
83f0e0bc Poul Sander 2026-05-30 17:59 12
    ShortcutManager::Category category;
83f0e0bc Poul Sander 2026-05-30 17:59 13
};
83f0e0bc Poul Sander 2026-05-30 17:59 14
83f0e0bc Poul Sander 2026-05-30 17:59 15
// Order must match ShortcutManager::Action enum
83f0e0bc Poul Sander 2026-05-30 17:59 16
static const ActionInfo kDefaults[ShortcutManager::ActionCount] = {
83f0e0bc Poul Sander 2026-05-30 17:59 17
    {"ToggleHelp",      "Show/hide keyboard shortcuts", QKeySequence(Qt::Key_F1),       ShortcutManager::CatNotConfigurable},
83f0e0bc Poul Sander 2026-05-30 17:59 18
    {"CloseViewer",     "Close viewer",                 QKeySequence(Qt::Key_Escape),   ShortcutManager::CatImageViewer},
83f0e0bc Poul Sander 2026-05-30 17:59 19
    {"CloseViewerAlt",  "Close viewer (alt)",           QKeySequence(Qt::Key_Return),   ShortcutManager::CatImageViewer},
83f0e0bc Poul Sander 2026-05-30 17:59 20
    {"NextImage",       "Next image",                   QKeySequence(Qt::Key_PageDown), ShortcutManager::CatImageViewer},
83f0e0bc Poul Sander 2026-05-30 17:59 21
    {"PrevImage",       "Previous image",               QKeySequence(Qt::Key_PageUp),   ShortcutManager::CatImageViewer},
83f0e0bc Poul Sander 2026-05-30 17:59 22
    {"PanLeft",         "Pan left",                     QKeySequence(Qt::Key_Left),     ShortcutManager::CatImageViewer},
83f0e0bc Poul Sander 2026-05-30 17:59 23
    {"PanRight",        "Pan right",                    QKeySequence(Qt::Key_Right),    ShortcutManager::CatImageViewer},
83f0e0bc Poul Sander 2026-05-30 17:59 24
    {"PanUp",           "Pan up",                       QKeySequence(Qt::Key_Up),       ShortcutManager::CatImageViewer},
83f0e0bc Poul Sander 2026-05-30 17:59 25
    {"PanDown",         "Pan down",                     QKeySequence(Qt::Key_Down),     ShortcutManager::CatImageViewer},
83f0e0bc Poul Sander 2026-05-30 17:59 26
    {"ZoomOriginal",    "Zoom to original size",        QKeySequence(Qt::Key_Slash),    ShortcutManager::CatImageViewer},
83f0e0bc Poul Sander 2026-05-30 17:59 27
    {"ZoomFit",         "Zoom to fit screen",           QKeySequence(Qt::Key_Asterisk), ShortcutManager::CatImageViewer},
83f0e0bc Poul Sander 2026-05-30 17:59 28
    {"ZoomIn",          "Zoom in",                      QKeySequence(Qt::Key_Plus),     ShortcutManager::CatImageViewer},
83f0e0bc Poul Sander 2026-05-30 17:59 29
    {"ZoomOut",         "Zoom out",                     QKeySequence(Qt::Key_Minus),    ShortcutManager::CatImageViewer},
83f0e0bc Poul Sander 2026-05-30 17:59 30
    {"ToggleExif",      "Toggle EXIF info",             QKeySequence(Qt::Key_I),        ShortcutManager::CatImageViewer},
83f0e0bc Poul Sander 2026-05-30 17:59 31
    {"EditCaption",     "Edit caption",                 QKeySequence(Qt::Key_E),        ShortcutManager::CatImageViewer},
83f0e0bc Poul Sander 2026-05-30 17:59 32
    {"ToggleFullscreen","Toggle fullscreen",            QKeySequence(Qt::Key_F11),      ShortcutManager::CatImageViewer},
83f0e0bc Poul Sander 2026-05-30 17:59 33
    {"ActivateEntry",   "Open folder / image",          QKeySequence(Qt::Key_Return),   ShortcutManager::CatBrowser},
83f0e0bc Poul Sander 2026-05-30 17:59 34
};
83f0e0bc Poul Sander 2026-05-30 17:59 35
83f0e0bc Poul Sander 2026-05-30 17:59 36
} // namespace
83f0e0bc Poul Sander 2026-05-30 17:59 37
83f0e0bc Poul Sander 2026-05-30 17:59 38
ShortcutManager::ShortcutManager()
83f0e0bc Poul Sander 2026-05-30 17:59 39
{
83f0e0bc Poul Sander 2026-05-30 17:59 40
    resetToDefaults();
83f0e0bc Poul Sander 2026-05-30 17:59 41
}
83f0e0bc Poul Sander 2026-05-30 17:59 42
83f0e0bc Poul Sander 2026-05-30 17:59 43
ShortcutManager &ShortcutManager::instance()
83f0e0bc Poul Sander 2026-05-30 17:59 44
{
83f0e0bc Poul Sander 2026-05-30 17:59 45
    static ShortcutManager mgr;
83f0e0bc Poul Sander 2026-05-30 17:59 46
    return mgr;
83f0e0bc Poul Sander 2026-05-30 17:59 47
}
83f0e0bc Poul Sander 2026-05-30 17:59 48
83f0e0bc Poul Sander 2026-05-30 17:59 49
QKeySequence ShortcutManager::shortcut(Action action) const
83f0e0bc Poul Sander 2026-05-30 17:59 50
{
83f0e0bc Poul Sander 2026-05-30 17:59 51
    if (action < 0 || action >= ActionCount)
83f0e0bc Poul Sander 2026-05-30 17:59 52
        return {};
83f0e0bc Poul Sander 2026-05-30 17:59 53
    return m_bindings[action].key;
83f0e0bc Poul Sander 2026-05-30 17:59 54
}
83f0e0bc Poul Sander 2026-05-30 17:59 55
83f0e0bc Poul Sander 2026-05-30 17:59 56
QString ShortcutManager::displayKey(Action action) const
83f0e0bc Poul Sander 2026-05-30 17:59 57
{
83f0e0bc Poul Sander 2026-05-30 17:59 58
    if (action < 0 || action >= ActionCount)
83f0e0bc Poul Sander 2026-05-30 17:59 59
        return {};
83f0e0bc Poul Sander 2026-05-30 17:59 60
    return m_bindings[action].key.toString(QKeySequence::NativeText);
83f0e0bc Poul Sander 2026-05-30 17:59 61
}
83f0e0bc Poul Sander 2026-05-30 17:59 62
83f0e0bc Poul Sander 2026-05-30 17:59 63
QString ShortcutManager::description(Action action) const
83f0e0bc Poul Sander 2026-05-30 17:59 64
{
83f0e0bc Poul Sander 2026-05-30 17:59 65
    return actionDescription(action);
83f0e0bc Poul Sander 2026-05-30 17:59 66
}
83f0e0bc Poul Sander 2026-05-30 17:59 67
83f0e0bc Poul Sander 2026-05-30 17:59 68
void ShortcutManager::setShortcut(Action action, const QKeySequence &seq)
83f0e0bc Poul Sander 2026-05-30 17:59 69
{
83f0e0bc Poul Sander 2026-05-30 17:59 70
    if (action >= 0 && action < ActionCount)
83f0e0bc Poul Sander 2026-05-30 17:59 71
        m_bindings[action].key = seq;
83f0e0bc Poul Sander 2026-05-30 17:59 72
}
83f0e0bc Poul Sander 2026-05-30 17:59 73
83f0e0bc Poul Sander 2026-05-30 17:59 74
void ShortcutManager::resetToDefaults()
83f0e0bc Poul Sander 2026-05-30 17:59 75
{
83f0e0bc Poul Sander 2026-05-30 17:59 76
    for (int i = 0; i < ActionCount; ++i)
83f0e0bc Poul Sander 2026-05-30 17:59 77
        m_bindings[i].key = kDefaults[i].defaultKey;
83f0e0bc Poul Sander 2026-05-30 17:59 78
}
83f0e0bc Poul Sander 2026-05-30 17:59 79
83f0e0bc Poul Sander 2026-05-30 17:59 80
void ShortcutManager::load(QSettings &settings)
83f0e0bc Poul Sander 2026-05-30 17:59 81
{
83f0e0bc Poul Sander 2026-05-30 17:59 82
    settings.beginGroup("shortcuts");
83f0e0bc Poul Sander 2026-05-30 17:59 83
    for (int i = 0; i < ActionCount; ++i) {
83f0e0bc Poul Sander 2026-05-30 17:59 84
        if (kDefaults[i].category == CatNotConfigurable) {
83f0e0bc Poul Sander 2026-05-30 17:59 85
            m_bindings[i].key = kDefaults[i].defaultKey;
83f0e0bc Poul Sander 2026-05-30 17:59 86
            continue;
83f0e0bc Poul Sander 2026-05-30 17:59 87
        }
83f0e0bc Poul Sander 2026-05-30 17:59 88
        const QString key = QString::fromLatin1(kDefaults[i].name);
83f0e0bc Poul Sander 2026-05-30 17:59 89
        if (settings.contains(key))
83f0e0bc Poul Sander 2026-05-30 17:59 90
            m_bindings[i].key = QKeySequence(settings.value(key).toString());
83f0e0bc Poul Sander 2026-05-30 17:59 91
        else
83f0e0bc Poul Sander 2026-05-30 17:59 92
            m_bindings[i].key = kDefaults[i].defaultKey;
83f0e0bc Poul Sander 2026-05-30 17:59 93
    }
83f0e0bc Poul Sander 2026-05-30 17:59 94
    settings.endGroup();
83f0e0bc Poul Sander 2026-05-30 17:59 95
}
83f0e0bc Poul Sander 2026-05-30 17:59 96
83f0e0bc Poul Sander 2026-05-30 17:59 97
void ShortcutManager::save(QSettings &settings) const
83f0e0bc Poul Sander 2026-05-30 17:59 98
{
83f0e0bc Poul Sander 2026-05-30 17:59 99
    settings.beginGroup("shortcuts");
83f0e0bc Poul Sander 2026-05-30 17:59 100
    for (int i = 0; i < ActionCount; ++i) {
83f0e0bc Poul Sander 2026-05-30 17:59 101
        if (kDefaults[i].category == CatNotConfigurable)
83f0e0bc Poul Sander 2026-05-30 17:59 102
            continue;
83f0e0bc Poul Sander 2026-05-30 17:59 103
        const QString key = QString::fromLatin1(kDefaults[i].name);
83f0e0bc Poul Sander 2026-05-30 17:59 104
        if (m_bindings[i].key == kDefaults[i].defaultKey)
83f0e0bc Poul Sander 2026-05-30 17:59 105
            settings.remove(key); // only store non-defaults
83f0e0bc Poul Sander 2026-05-30 17:59 106
        else
83f0e0bc Poul Sander 2026-05-30 17:59 107
            settings.setValue(key, m_bindings[i].key.toString());
83f0e0bc Poul Sander 2026-05-30 17:59 108
    }
83f0e0bc Poul Sander 2026-05-30 17:59 109
    settings.endGroup();
83f0e0bc Poul Sander 2026-05-30 17:59 110
}
83f0e0bc Poul Sander 2026-05-30 17:59 111
83f0e0bc Poul Sander 2026-05-30 17:59 112
QKeySequence ShortcutManager::defaultShortcut(Action action)
83f0e0bc Poul Sander 2026-05-30 17:59 113
{
83f0e0bc Poul Sander 2026-05-30 17:59 114
    if (action < 0 || action >= ActionCount)
83f0e0bc Poul Sander 2026-05-30 17:59 115
        return {};
83f0e0bc Poul Sander 2026-05-30 17:59 116
    return kDefaults[action].defaultKey;
83f0e0bc Poul Sander 2026-05-30 17:59 117
}
83f0e0bc Poul Sander 2026-05-30 17:59 118
83f0e0bc Poul Sander 2026-05-30 17:59 119
QString ShortcutManager::actionName(Action action)
83f0e0bc Poul Sander 2026-05-30 17:59 120
{
83f0e0bc Poul Sander 2026-05-30 17:59 121
    if (action < 0 || action >= ActionCount)
83f0e0bc Poul Sander 2026-05-30 17:59 122
        return {};
83f0e0bc Poul Sander 2026-05-30 17:59 123
    return QString::fromLatin1(kDefaults[action].name);
83f0e0bc Poul Sander 2026-05-30 17:59 124
}
83f0e0bc Poul Sander 2026-05-30 17:59 125
83f0e0bc Poul Sander 2026-05-30 17:59 126
QString ShortcutManager::actionDescription(Action action)
83f0e0bc Poul Sander 2026-05-30 17:59 127
{
83f0e0bc Poul Sander 2026-05-30 17:59 128
    if (action < 0 || action >= ActionCount)
83f0e0bc Poul Sander 2026-05-30 17:59 129
        return {};
83f0e0bc Poul Sander 2026-05-30 17:59 130
    return QString::fromLatin1(kDefaults[action].description);
83f0e0bc Poul Sander 2026-05-30 17:59 131
}
83f0e0bc Poul Sander 2026-05-30 17:59 132
83f0e0bc Poul Sander 2026-05-30 17:59 133
ShortcutManager::Category ShortcutManager::actionCategory(Action action)
83f0e0bc Poul Sander 2026-05-30 17:59 134
{
83f0e0bc Poul Sander 2026-05-30 17:59 135
    if (action < 0 || action >= ActionCount)
83f0e0bc Poul Sander 2026-05-30 17:59 136
        return CatNotConfigurable;
83f0e0bc Poul Sander 2026-05-30 17:59 137
    return kDefaults[action].category;
83f0e0bc Poul Sander 2026-05-30 17:59 138
}
83f0e0bc Poul Sander 2026-05-30 17:59 139
83f0e0bc Poul Sander 2026-05-30 17:59 140
bool ShortcutManager::matches(const QKeyEvent *event, Action action) const
83f0e0bc Poul Sander 2026-05-30 17:59 141
{
83f0e0bc Poul Sander 2026-05-30 17:59 142
    if (action < 0 || action >= ActionCount)
83f0e0bc Poul Sander 2026-05-30 17:59 143
        return false;
83f0e0bc Poul Sander 2026-05-30 17:59 144
    const QKeySequence &seq = m_bindings[action].key;
83f0e0bc Poul Sander 2026-05-30 17:59 145
    if (seq.isEmpty())
83f0e0bc Poul Sander 2026-05-30 17:59 146
        return false;
83f0e0bc Poul Sander 2026-05-30 17:59 147
    // Compare the first key in the sequence against the event's key + modifiers.
83f0e0bc Poul Sander 2026-05-30 17:59 148
    int eventKey = event->key();
83f0e0bc Poul Sander 2026-05-30 17:59 149
    Qt::KeyboardModifiers mods = event->modifiers() & ~Qt::KeypadModifier;
83f0e0bc Poul Sander 2026-05-30 17:59 150
    if (mods != Qt::NoModifier)
83f0e0bc Poul Sander 2026-05-30 17:59 151
        eventKey |= mods;
83f0e0bc Poul Sander 2026-05-30 17:59 152
    return seq[0] == QKeyCombination::fromCombined(eventKey);
83f0e0bc Poul Sander 2026-05-30 17:59 153
}
1970-01-01 00:00 154