File indexing completed on 2024-11-10 04:56:52

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2023 Ismael Asensio <isma.af@gmail.com>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include "shortcutsettings.h"
0011 
0012 #include <QAction>
0013 
0014 #include <KActionCollection>
0015 #include <KGlobalAccel>
0016 #include <KLocalizedString>
0017 
0018 // Implementation of a KConfigSkeletonItem that uses KGlobalAccel to retrieve and store
0019 // shortcut settings instead of storing them in a config file
0020 class ShortcutItem : public KConfigSkeletonItem
0021 {
0022 public:
0023     ShortcutItem(QAction *action, KActionCollection *actionCollection);
0024 
0025     void readConfig(KConfig *config) override;
0026     void writeConfig(KConfig *config) override;
0027 
0028     void readDefault(KConfig *config) override;
0029     void setDefault() override;
0030     void swapDefault() override;
0031 
0032     bool isEqual(const QVariant &p) const override;
0033     QVariant property() const override;
0034     void setProperty(const QVariant &p) override;
0035 
0036 private:
0037     KActionCollection *m_actionCollection = nullptr;
0038     QAction *m_action = nullptr;
0039     QKeySequence m_savedShortcut;
0040 };
0041 
0042 ShortcutItem::ShortcutItem(QAction *action, KActionCollection *actionCollection)
0043     : KConfigSkeletonItem(actionCollection->componentName(), action->text())
0044     , m_actionCollection(actionCollection)
0045     , m_action(action)
0046 {
0047     setGetDefaultImpl([this] {
0048         return m_actionCollection->defaultShortcut(m_action);
0049     });
0050 
0051     setIsDefaultImpl([this] {
0052         return m_action->shortcut() == m_actionCollection->defaultShortcut(m_action);
0053     });
0054 
0055     setIsSaveNeededImpl([this] {
0056         return (m_action->shortcut() != m_savedShortcut);
0057     });
0058 }
0059 
0060 void ShortcutItem::readConfig(KConfig *config)
0061 {
0062     const auto shortcuts = KGlobalAccel::self()->globalShortcut(m_actionCollection->componentName(), m_action->objectName());
0063     m_savedShortcut = shortcuts.isEmpty() ? QKeySequence() : shortcuts.first();
0064     m_action->setShortcut(m_savedShortcut);
0065 }
0066 
0067 void ShortcutItem::writeConfig(KConfig *config)
0068 {
0069     m_savedShortcut = m_action->shortcut();
0070     KGlobalAccel::self()->setShortcut(m_action, {m_action->shortcut()}, KGlobalAccel::NoAutoloading);
0071 }
0072 
0073 void ShortcutItem::readDefault(KConfig *config)
0074 {
0075 }
0076 
0077 void ShortcutItem::setDefault()
0078 {
0079     m_action->setShortcut(m_actionCollection->defaultShortcut(m_action));
0080 }
0081 
0082 void ShortcutItem::swapDefault()
0083 {
0084     QKeySequence previousShortcut = m_action->shortcut();
0085     m_action->setShortcut(m_actionCollection->defaultShortcut(m_action));
0086     m_actionCollection->setDefaultShortcut(m_action, previousShortcut);
0087 }
0088 
0089 bool ShortcutItem::isEqual(const QVariant &p) const
0090 {
0091     if (!p.canConvert<QKeySequence>()) {
0092         return false;
0093     }
0094     return m_action->shortcut() == p.value<QKeySequence>();
0095 }
0096 
0097 QVariant ShortcutItem::property() const
0098 {
0099     return QVariant::fromValue<QKeySequence>(m_action->shortcut());
0100 }
0101 
0102 void ShortcutItem::setProperty(const QVariant &p)
0103 {
0104     m_action->setShortcut(p.value<QKeySequence>());
0105 }
0106 
0107 namespace KWin
0108 {
0109 namespace TabBox
0110 {
0111 
0112 ShortcutSettings::ShortcutSettings(QObject *parent)
0113     : KConfigSkeleton(nullptr, parent)
0114     , m_actionCollection(new KActionCollection(this, QStringLiteral("kwin")))
0115 {
0116     m_actionCollection->setConfigGroup("Navigation");
0117     m_actionCollection->setConfigGlobal(true);
0118 
0119     auto addShortcut = [this](const KLocalizedString &name, const QKeySequence &sequence = QKeySequence()) {
0120         const QString untranslatedName = QString::fromUtf8(name.untranslatedText());
0121         QAction *action = m_actionCollection->addAction(untranslatedName);
0122         action->setObjectName(untranslatedName);
0123         action->setProperty("isConfigurationAction", true);
0124         action->setText(name.toString());
0125 
0126         m_actionCollection->setDefaultShortcut(action, sequence);
0127 
0128         addItem(new ShortcutItem(action, m_actionCollection));
0129     };
0130 
0131     // TabboxType::Main
0132     addShortcut(ki18nd("kwin", "Walk Through Windows"), Qt::ALT | Qt::Key_Tab);
0133     addShortcut(ki18nd("kwin", "Walk Through Windows (Reverse)"), Qt::ALT | Qt::SHIFT | Qt::Key_Tab);
0134     addShortcut(ki18nd("kwin", "Walk Through Windows of Current Application"), Qt::ALT | Qt::Key_QuoteLeft);
0135     addShortcut(ki18nd("kwin", "Walk Through Windows of Current Application (Reverse)"), Qt::ALT | Qt::Key_AsciiTilde);
0136     // TabboxType::Alternative
0137     addShortcut(ki18nd("kwin", "Walk Through Windows Alternative"));
0138     addShortcut(ki18nd("kwin", "Walk Through Windows Alternative (Reverse)"));
0139     addShortcut(ki18nd("kwin", "Walk Through Windows of Current Application Alternative"));
0140     addShortcut(ki18nd("kwin", "Walk Through Windows of Current Application Alternative (Reverse)"));
0141 }
0142 
0143 KActionCollection *ShortcutSettings::actionCollection() const
0144 {
0145     return m_actionCollection;
0146 }
0147 
0148 QKeySequence ShortcutSettings::shortcut(const QString &name) const
0149 {
0150     QAction *action = m_actionCollection->action(name);
0151     Q_ASSERT(action);
0152     return action->shortcut();
0153 }
0154 
0155 void ShortcutSettings::setShortcut(const QString &name, const QKeySequence &seq)
0156 {
0157     QAction *action = m_actionCollection->action(name);
0158     Q_ASSERT(action);
0159     action->setShortcut(seq);
0160 }
0161 
0162 bool ShortcutSettings::isDefault(const QString &name) const
0163 {
0164     QAction *action = m_actionCollection->action(name);
0165     Q_ASSERT(action);
0166     return action->shortcut() == m_actionCollection->defaultShortcut(action);
0167 }
0168 
0169 } // namespace TabBox
0170 } // namespace KWin