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