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: