File indexing completed on 2023-05-30 11:30:47

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 <QButtonGroup>
0030 #include <QDialogButtonBox>
0031 #include <QGroupBox>
0032 #include <QHBoxLayout>
0033 #include <QKeySequence>
0034 #include <QList>
0035 #include <QPushButton>
0036 #include <QRadioButton>
0037 #include <QString>
0038 #include <QVBoxLayout>
0039 
0040 // Table of shortcut keys for each action, key group and three or four button modifier
0041 
0042 struct KeyDialog::KeyInfo {
0043     QString action;
0044     QKeySequence shortcut[3];
0045 };
0046 
0047 const KeyDialog::KeyInfo KeyDialog::keyInfo[] = {
0048     { "playPause",
0049       { QKeySequence(),
0050         QKeySequence(Qt::CTRL+Qt::ALT+Qt::Key_P),
0051         QKeySequence(Qt::Key_MediaPlay) } },
0052     { "stop",
0053       { QKeySequence(),
0054         QKeySequence(Qt::CTRL+Qt::ALT+Qt::Key_S),
0055         QKeySequence(Qt::Key_MediaStop) } },
0056     { "back",
0057       { QKeySequence(),
0058         QKeySequence(Qt::CTRL+Qt::ALT+Qt::Key_Left),
0059         QKeySequence(Qt::Key_MediaPrevious) } },
0060     { "forward",
0061       { QKeySequence(),
0062         QKeySequence(Qt::CTRL+Qt::ALT+Qt::Key_Right),
0063         QKeySequence(Qt::Key_MediaNext) } },
0064     { "forwardAlbum",
0065       { QKeySequence(),
0066         QKeySequence(Qt::CTRL+Qt::ALT+Qt::Key_Up),
0067         QKeySequence(Qt::CTRL+Qt::Key_MediaNext) } },
0068     { "seekBack",
0069       { QKeySequence(),
0070         QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::ALT+Qt::Key_Left),
0071         QKeySequence(Qt::SHIFT+Qt::Key_MediaPrevious) } },
0072     { "seekForward",
0073       { QKeySequence(),
0074         QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::ALT+Qt::Key_Right),
0075         QKeySequence(Qt::SHIFT+Qt::Key_MediaNext) } },
0076     { "volumeUp",
0077       { QKeySequence(),
0078         QKeySequence(Qt::CTRL+Qt::ALT+Qt::SHIFT+Qt::Key_Up),
0079         QKeySequence(Qt::Key_VolumeUp) } },
0080     { "volumeDown",
0081       { QKeySequence(),
0082         QKeySequence(Qt::CTRL+Qt::ALT+Qt::SHIFT+Qt::Key_Down),
0083         QKeySequence(Qt::Key_VolumeDown) } },
0084     { "mute",
0085       { QKeySequence(),
0086         QKeySequence(Qt::CTRL+Qt::ALT+Qt::Key_M),
0087         QKeySequence(Qt::Key_VolumeMute) } },
0088     { "showHide",
0089       { QKeySequence(),
0090         QKeySequence(),
0091         QKeySequence() } }
0092 };
0093 
0094 const uint KeyDialog::keyInfoCount = sizeof(KeyDialog::keyInfo) / sizeof(KeyDialog::keyInfo[0]);
0095 
0096 KeyDialog::KeyDialog(KActionCollection *actionCollection, QWidget *parent)
0097   : QDialog(parent)
0098   , m_actionCollection(actionCollection)
0099 {
0100     setWindowTitle(i18n("Configure Shortcuts"));
0101 
0102     // Read key group from configuration
0103 
0104     KConfigGroup config(KSharedConfig::openConfig(), "Shortcuts");
0105     int selectedButton = config.readEntry("GlobalKeys", int(StandardKeys));
0106 
0107     // Create widgets for key chooser
0108 
0109     auto vboxLayout = new QVBoxLayout(this);
0110 
0111     m_pKeyChooser = new KShortcutsEditor(actionCollection, this);
0112     vboxLayout->addWidget(m_pKeyChooser);
0113 
0114     // Create buttons to select key group
0115 
0116     QGroupBox *buttonBox = new QGroupBox(i18n("Global Shortcuts"), this);
0117     vboxLayout->addWidget(buttonBox);
0118 
0119     m_group = new QButtonGroup(buttonBox);
0120     QHBoxLayout *buttonLayout = new QHBoxLayout(buttonBox);
0121 
0122     QRadioButton *radioButton = new QRadioButton(i18n("&No keys"), buttonBox);
0123     m_group->addButton(radioButton, NoKeys);
0124     buttonLayout->addWidget(radioButton);
0125 
0126     radioButton = new QRadioButton(i18n("&Standard keys"), buttonBox);
0127     m_group->addButton(radioButton, StandardKeys);
0128     buttonLayout->addWidget(radioButton);
0129 
0130     radioButton = new QRadioButton(i18n("&Multimedia keys"), buttonBox);
0131     m_group->addButton(radioButton, MultimediaKeys);
0132     buttonLayout->addWidget(radioButton);
0133 
0134     connect(m_group, SIGNAL(buttonClicked(int)), SLOT(slotKeys(int)));
0135     buttonBox->setWhatsThis(
0136         i18n("Here you can select the keys used as global shortcuts to control the player"));
0137 
0138     m_group->button(selectedButton)->setChecked(true);
0139 
0140     auto dlgButtonBox = new QDialogButtonBox(
0141             QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults,
0142             this);
0143     vboxLayout->addWidget(dlgButtonBox);
0144 
0145     connect(dlgButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0146     connect(dlgButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0147     connect(dlgButtonBox->button(QDialogButtonBox::RestoreDefaults), &QAbstractButton::clicked,
0148             this,                                                    &KeyDialog::slotDefault);
0149 
0150     resize(400, 500); // TODO: Make it bigger!
0151 }
0152 
0153 int KeyDialog::configure()
0154 {
0155     // Show the dialog and save configuration if accepted
0156 
0157     int retcode = exec();
0158     if(retcode == Accepted) {
0159         KConfigGroup config(KSharedConfig::openConfig(), "Shortcuts");
0160 
0161         config.writeEntry("GlobalKeys", m_group->checkedId());
0162         KSharedConfig::openConfig()->sync();
0163 
0164         m_pKeyChooser->save();
0165     }
0166 
0167     return retcode;
0168 }
0169 
0170 void KeyDialog::slotKeys(int group)
0171 {
0172     // Set modifier keys according to key group and modifier keys
0173 
0174     auto globalAccel = KGlobalAccel::self();
0175 
0176     for(uint i = 0; i < keyInfoCount; i++) {
0177         QAction *a = ActionCollection::action<QAction>(keyInfo[i].action);
0178 
0179         if(a) {
0180             if (group == 0) {
0181                 globalAccel->removeAllShortcuts(a);
0182             }
0183             else {
0184                 QKeySequence shortcut(keyInfo[i].shortcut[group]);
0185                 QList<QKeySequence> shortcutList{shortcut};
0186                 globalAccel->setShortcut(a, shortcutList, KGlobalAccel::NoAutoloading);
0187             }
0188         }
0189     }
0190 
0191     // Update the key chooser widget.
0192     // TODO: When widget is fixed to note the update remove this bit so that
0193     // we don't drop user changes for no reason.
0194 
0195     m_pKeyChooser->clearCollections();
0196     m_pKeyChooser->addCollection(m_actionCollection);
0197 }
0198 
0199 void KeyDialog::slotDefault()
0200 {
0201     // Select default keys - standard key group
0202 
0203     m_group->button(StandardKeys)->setChecked(true);
0204     slotKeys(StandardKeys);
0205     m_pKeyChooser->allDefault();
0206 }
0207 
0208 void KeyDialog::setupActionShortcut(const QString &actionName)
0209 {
0210     // Find and insert a standard key
0211     QKeySequence shortcut = QKeySequence();
0212 
0213     // Find out what type is selected so we know what keys to setup.
0214     KConfigGroup config(KSharedConfig::openConfig(), "Shortcuts");
0215     int selectedKeys = config.readEntry("GlobalKeys", int(StandardKeys));
0216 
0217     for(uint i = 0; i < keyInfoCount; i++) {
0218         if(keyInfo[i].action == actionName) {
0219             shortcut = keyInfo[i].shortcut[selectedKeys];
0220             break;
0221         }
0222     }
0223 
0224     if(shortcut.isEmpty())
0225         return; // We have no shortcut to set.
0226 
0227     QAction *a = ActionCollection::action<QAction>(actionName);
0228     if(a) {
0229         KGlobalAccel::setGlobalShortcut(a, shortcut);
0230     }
0231 }
0232 
0233 // vim: set et sw=4 tw=0 sta: