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