File indexing completed on 2021-12-21 13:27:55

0001 /**
0002  * Copyright (C) 2003 Stefan Asserhall <stefan.asserhall@telia.com>
0003  * Copyright (C) 2007, 2008 Michael Pyne <mpyne@kde.org>
0004  *
0005  * This program is free software; you can redistribute it and/or modify it under
0006  * the terms of the GNU General Public License as published by the Free Software
0007  * Foundation; either version 2 of the License, or (at your option) any later
0008  * version.
0009  *
0010  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0011  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0012  * PARTICULAR PURPOSE. See the GNU General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU General Public License along with
0015  * this program.  If not, see <http://www.gnu.org/licenses/>.
0016  */
0017 
0018 #include "keydialog.h"
0019 #include "actioncollection.h"
0020 
0021 #include <KConfig>
0022 #include <KShortcutsEditor>
0023 #include <KConfigGroup>
0024 #include <KSharedConfig>
0025 #include <KGlobalAccel>
0026 #include <KLocalizedString>
0027 
0028 #include <QAction>
0029 #include <QKeySequence>
0030 #include <QList>
0031 #include <QHBoxLayout>
0032 #include <QVBoxLayout>
0033 #include <QTimer>
0034 #include <QDialogButtonBox>
0035 #include <QButtonGroup>
0036 #include <QRadioButton>
0037 #include <QPushButton>
0038 #include <QGroupBox>
0039 #include <QString>
0040 
0041 // Table of shortcut keys for each action, key group and three or four button modifier
0042 
0043 struct KeyDialog::KeyInfo {
0044     QString action;
0045     QKeySequence shortcut[3];
0046 };
0047 
0048 const KeyDialog::KeyInfo KeyDialog::keyInfo[] = {
0049     { "playPause",
0050       { QKeySequence(),
0051         QKeySequence(Qt::CTRL+Qt::ALT+Qt::Key_P),
0052         QKeySequence(Qt::Key_MediaPlay) } },
0053     { "stop",
0054       { QKeySequence(),
0055         QKeySequence(Qt::CTRL+Qt::ALT+Qt::Key_S),
0056         QKeySequence(Qt::Key_MediaStop) } },
0057     { "back",
0058       { QKeySequence(),
0059         QKeySequence(Qt::CTRL+Qt::ALT+Qt::Key_Left),
0060         QKeySequence(Qt::Key_MediaPrevious) } },
0061     { "forward",
0062       { QKeySequence(),
0063         QKeySequence(Qt::CTRL+Qt::ALT+Qt::Key_Right),
0064         QKeySequence(Qt::Key_MediaNext) } },
0065     { "forwardAlbum",
0066       { QKeySequence(),
0067         QKeySequence(Qt::CTRL+Qt::ALT+Qt::Key_Up),
0068         QKeySequence(Qt::CTRL+Qt::Key_MediaNext) } },
0069     { "seekBack",
0070       { QKeySequence(),
0071         QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::ALT+Qt::Key_Left),
0072         QKeySequence(Qt::SHIFT+Qt::Key_MediaPrevious) } },
0073     { "seekForward",
0074       { QKeySequence(),
0075         QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::ALT+Qt::Key_Right),
0076         QKeySequence(Qt::SHIFT+Qt::Key_MediaNext) } },
0077     { "volumeUp",
0078       { QKeySequence(),
0079         QKeySequence(Qt::CTRL+Qt::ALT+Qt::SHIFT+Qt::Key_Up),
0080         QKeySequence(Qt::Key_VolumeUp) } },
0081     { "volumeDown",
0082       { QKeySequence(),
0083         QKeySequence(Qt::CTRL+Qt::ALT+Qt::SHIFT+Qt::Key_Down),
0084         QKeySequence(Qt::Key_VolumeDown) } },
0085     { "mute",
0086       { QKeySequence(),
0087         QKeySequence(Qt::CTRL+Qt::ALT+Qt::Key_M),
0088         QKeySequence(Qt::Key_VolumeMute) } },
0089     { "showHide",
0090       { QKeySequence(),
0091         QKeySequence(),
0092         QKeySequence() } }
0093 };
0094 
0095 const uint KeyDialog::keyInfoCount = sizeof(KeyDialog::keyInfo) / sizeof(KeyDialog::keyInfo[0]);
0096 
0097 KeyDialog::KeyDialog(KActionCollection *actionCollection, QWidget *parent)
0098   : QDialog(parent)
0099   , m_actionCollection(actionCollection)
0100 {
0101     setWindowTitle(i18n("Configure Shortcuts"));
0102 
0103     // Read key group from configuration
0104 
0105     KConfigGroup config(KSharedConfig::openConfig(), "Shortcuts");
0106     int selectedButton = config.readEntry("GlobalKeys", int(StandardKeys));
0107 
0108     // Create widgets for key chooser
0109 
0110     auto vboxLayout = new QVBoxLayout(this);
0111 
0112     m_pKeyChooser = new KShortcutsEditor(actionCollection, this);
0113     vboxLayout->addWidget(m_pKeyChooser);
0114 
0115     // Create buttons to select key group
0116 
0117     QGroupBox *buttonBox = new QGroupBox(i18n("Global Shortcuts"), this);
0118     vboxLayout->addWidget(buttonBox);
0119 
0120     m_group = new QButtonGroup(buttonBox);
0121     QHBoxLayout *buttonLayout = new QHBoxLayout(buttonBox);
0122 
0123     QRadioButton *radioButton = new QRadioButton(i18n("&No keys"), buttonBox);
0124     m_group->addButton(radioButton, NoKeys);
0125     buttonLayout->addWidget(radioButton);
0126 
0127     radioButton = new QRadioButton(i18n("&Standard keys"), buttonBox);
0128     m_group->addButton(radioButton, StandardKeys);
0129     buttonLayout->addWidget(radioButton);
0130 
0131     radioButton = new QRadioButton(i18n("&Multimedia keys"), buttonBox);
0132     m_group->addButton(radioButton, MultimediaKeys);
0133     buttonLayout->addWidget(radioButton);
0134 
0135     connect(m_group, SIGNAL(buttonClicked(int)), SLOT(slotKeys(int)));
0136     buttonBox->setWhatsThis(
0137         i18n("Here you can select the keys used as global shortcuts to control the player"));
0138 
0139     m_group->button(selectedButton)->setChecked(true);
0140 
0141     auto dlgButtonBox = new QDialogButtonBox(
0142             QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults,
0143             this);
0144     vboxLayout->addWidget(dlgButtonBox);
0145 
0146     connect(dlgButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0147     connect(dlgButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0148     connect(dlgButtonBox->button(QDialogButtonBox::RestoreDefaults), &QAbstractButton::clicked,
0149             this,                                                    &KeyDialog::slotDefault);
0150 
0151     resize(400, 500); // TODO: Make it bigger!
0152 }
0153 
0154 int KeyDialog::configure()
0155 {
0156     // Show the dialog and save configuration if accepted
0157 
0158     int retcode = exec();
0159     if(retcode == Accepted) {
0160         KConfigGroup config(KSharedConfig::openConfig(), "Shortcuts");
0161 
0162         config.writeEntry("GlobalKeys", m_group->checkedId());
0163         KSharedConfig::openConfig()->sync();
0164 
0165         m_pKeyChooser->save();
0166     }
0167 
0168     return retcode;
0169 }
0170 
0171 void KeyDialog::slotKeys(int group)
0172 {
0173     // Set modifier keys according to key group and modifier keys
0174 
0175     auto globalAccel = KGlobalAccel::self();
0176 
0177     for(uint i = 0; i < keyInfoCount; i++) {
0178         QAction *a = ActionCollection::action<QAction>(keyInfo[i].action);
0179 
0180         if(a) {
0181             if (group == 0) {
0182                 globalAccel->removeAllShortcuts(a);
0183             }
0184             else {
0185                 QKeySequence shortcut(keyInfo[i].shortcut[group]);
0186                 QList<QKeySequence> shortcutList{shortcut};
0187                 globalAccel->setShortcut(a, shortcutList, KGlobalAccel::NoAutoloading);
0188             }
0189         }
0190     }
0191 
0192     // Update the key chooser widget.
0193     // TODO: When widget is fixed to note the update remove this bit so that
0194     // we don't drop user changes for no reason.
0195 
0196     m_pKeyChooser->clearCollections();
0197     m_pKeyChooser->addCollection(m_actionCollection);
0198 }
0199 
0200 void KeyDialog::slotDefault()
0201 {
0202     // Select default keys - standard key group
0203 
0204     m_group->button(StandardKeys)->setChecked(true);
0205     slotKeys(StandardKeys);
0206     m_pKeyChooser->allDefault();
0207 }
0208 
0209 void KeyDialog::setupActionShortcut(const QString &actionName)
0210 {
0211     // Find and insert a standard key
0212     QKeySequence shortcut = QKeySequence();
0213 
0214     // Find out what type is selected so we know what keys to setup.
0215     KConfigGroup config(KSharedConfig::openConfig(), "Shortcuts");
0216     int selectedKeys = config.readEntry("GlobalKeys", int(StandardKeys));
0217 
0218     for(uint i = 0; i < keyInfoCount; i++) {
0219         if(keyInfo[i].action == actionName) {
0220             shortcut = keyInfo[i].shortcut[selectedKeys];
0221             break;
0222         }
0223     }
0224 
0225     if(shortcut.isEmpty())
0226         return; // We have no shortcut to set.
0227 
0228     QAction *a = ActionCollection::action<QAction>(actionName);
0229     if(a) {
0230         KGlobalAccel::setGlobalShortcut(a, shortcut);
0231     }
0232 }
0233 
0234 // vim: set et sw=4 tw=0 sta: