From ed1ee0b3624d5bd3ae279f7e9171cb615e77cbbf Mon Sep 17 00:00:00 2001 From: Martin Rotter <rotter@praktik.cz> Date: Thu, 6 Aug 2020 08:08:46 +0200 Subject: [PATCH] Greatly simplified code for keyboard shortcuts. --- .../dynamicshortcutswidget.cpp | 2 +- .../dynamic-shortcuts/shortcutbutton.cpp | 122 ------------------ .../dynamic-shortcuts/shortcutbutton.h | 55 -------- .../dynamic-shortcuts/shortcutcatcher.cpp | 112 ++-------------- .../dynamic-shortcuts/shortcutcatcher.h | 50 +------ src/librssguard/librssguard.pro | 2 - 6 files changed, 15 insertions(+), 328 deletions(-) delete mode 100644 src/librssguard/dynamic-shortcuts/shortcutbutton.cpp delete mode 100644 src/librssguard/dynamic-shortcuts/shortcutbutton.h diff --git a/src/librssguard/dynamic-shortcuts/dynamicshortcutswidget.cpp b/src/librssguard/dynamic-shortcuts/dynamicshortcutswidget.cpp index 5b65f5be3..789de61c1 100644 --- a/src/librssguard/dynamic-shortcuts/dynamicshortcutswidget.cpp +++ b/src/librssguard/dynamic-shortcuts/dynamicshortcutswidget.cpp @@ -3,7 +3,6 @@ #include "dynamic-shortcuts/dynamicshortcutswidget.h" #include "definitions/definitions.h" -#include "dynamic-shortcuts/shortcutbutton.h" #include "dynamic-shortcuts/shortcutcatcher.h" #include <QAction> @@ -69,6 +68,7 @@ void DynamicShortcutsWidget::populate(QList<QAction*> actions) { // Store information for re-initialization of shortcuts // of actions when widget gets "confirmed". QPair<QAction*, ShortcutCatcher*> new_binding; + new_binding.first = action; new_binding.second = catcher; m_actionBindings << new_binding; diff --git a/src/librssguard/dynamic-shortcuts/shortcutbutton.cpp b/src/librssguard/dynamic-shortcuts/shortcutbutton.cpp deleted file mode 100644 index 89b4dafc3..000000000 --- a/src/librssguard/dynamic-shortcuts/shortcutbutton.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// For license of this file, see <project-root-folder>/LICENSE.md. - -/****************************************************************************** - Copyright (c) 2010, Artem Galichkin <doomer3d@gmail.com> - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the <organization> nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *******************************************************************************/ - -#include "dynamic-shortcuts/shortcutbutton.h" - -#include "dynamic-shortcuts/shortcutcatcher.h" - -#include <QKeyEvent> - -ShortcutButton::ShortcutButton(ShortcutCatcher* catcher, QWidget* parent) - : QPushButton(parent), m_catcher(catcher) { - setMinimumWidth(100); -} - -void ShortcutButton::keyPressEvent(QKeyEvent* event) { - int pressed_key = event->key(); - - if (pressed_key == -1) { - m_catcher->doneRecording(); - } - - const int new_modifiers = event->modifiers() & (Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META); - - if (!m_catcher->m_isRecording && (pressed_key == Qt::Key_Return || pressed_key == Qt::Key_Space)) { - return; - } - - if (!m_catcher->m_isRecording) { - QPushButton::keyPressEvent(event); - return; - } - - event->accept(); - m_catcher->m_modifierKeys = new_modifiers; - - switch (pressed_key) { - case Qt::Key_AltGr: - return; - - case Qt::Key_Shift: - case Qt::Key_Control: - case Qt::Key_Alt: - case Qt::Key_Meta: - case Qt::Key_Menu: - m_catcher->controlModifierlessTimout(); - m_catcher->updateDisplayShortcut(); - break; - - default: - - // We now have a valid key press. - if (pressed_key != 0) { - if ((pressed_key == Qt::Key_Backtab) && (m_catcher->m_modifierKeys & Qt::SHIFT) > 0) { - pressed_key = Qt::Key_Tab | m_catcher->m_modifierKeys; - } - else { - pressed_key |= m_catcher->m_modifierKeys; - } - - if (m_catcher->m_numKey == 0) { - m_catcher->m_currentSequence = QKeySequence(pressed_key); - } - - m_catcher->m_numKey++; - - if (m_catcher->m_numKey >= 4) { - m_catcher->doneRecording(); - return; - } - - m_catcher->controlModifierlessTimout(); - m_catcher->updateDisplayShortcut(); - } - } -} - -void ShortcutButton::keyReleaseEvent(QKeyEvent* event) { - if (event->key() == -1) { - return; - } - - if (!m_catcher->m_isRecording) { - QPushButton::keyReleaseEvent(event); - return; - } - - event->accept(); - const int new_modifiers = event->modifiers() & (Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META); - - if ((new_modifiers & m_catcher->m_modifierKeys) < m_catcher->m_modifierKeys) { - m_catcher->m_modifierKeys = new_modifiers; - m_catcher->controlModifierlessTimout(); - m_catcher->updateDisplayShortcut(); - } -} diff --git a/src/librssguard/dynamic-shortcuts/shortcutbutton.h b/src/librssguard/dynamic-shortcuts/shortcutbutton.h deleted file mode 100644 index 9c65777fb..000000000 --- a/src/librssguard/dynamic-shortcuts/shortcutbutton.h +++ /dev/null @@ -1,55 +0,0 @@ -// For license of this file, see <project-root-folder>/LICENSE.md. - -/****************************************************************************** - Copyright (c) 2010, Artem Galichkin <doomer3d@gmail.com> - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the <organization> nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *******************************************************************************/ - -#ifndef SHORTCUTBUTTON_H -#define SHORTCUTBUTTON_H - -#include <QPushButton> - -class ShortcutCatcher; - -class ShortcutButton : public QPushButton { - Q_OBJECT - - public: - - // Constructors and destructors. - explicit ShortcutButton(ShortcutCatcher* catcher, QWidget* parent = nullptr); - virtual ~ShortcutButton() = default; - - protected: - void keyPressEvent(QKeyEvent* event); - void keyReleaseEvent(QKeyEvent* event); - - private: - ShortcutCatcher* m_catcher; -}; - -#endif // SHORTCUTBUTTON_H diff --git a/src/librssguard/dynamic-shortcuts/shortcutcatcher.cpp b/src/librssguard/dynamic-shortcuts/shortcutcatcher.cpp index e6511c959..8021afdf7 100644 --- a/src/librssguard/dynamic-shortcuts/shortcutcatcher.cpp +++ b/src/librssguard/dynamic-shortcuts/shortcutcatcher.cpp @@ -1,40 +1,12 @@ // For license of this file, see <project-root-folder>/LICENSE.md. -/****************************************************************************** - Copyright (c) 2010, Artem Galichkin <doomer3d@gmail.com> - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the <organization> nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *******************************************************************************/ - #include "dynamic-shortcuts/shortcutcatcher.h" -#include "dynamic-shortcuts/shortcutbutton.h" #include "gui/plaintoolbutton.h" #include "miscellaneous/iconfactory.h" #include <QHBoxLayout> +#include <QKeySequenceEdit> ShortcutCatcher::ShortcutCatcher(QWidget* parent) : QWidget(parent), m_isRecording(false), m_numKey(0), m_modifierKeys(0U) { @@ -56,89 +28,24 @@ ShortcutCatcher::ShortcutCatcher(QWidget* parent) m_btnClear->setToolTip(tr("Clear current shortcut.")); // Clear main shortcut catching button. - m_btnChange = new ShortcutButton(this); - m_btnChange->setFocusPolicy(Qt::StrongFocus); - m_btnChange->setToolTip(tr("Click and hit new shortcut.")); + m_shortcutBox = new QKeySequenceEdit(this); + m_shortcutBox->setFocusPolicy(Qt::StrongFocus); + m_shortcutBox->setMinimumWidth(170); + m_shortcutBox->setToolTip(tr("Click and hit new shortcut.")); // Add both buttons to the layout. - m_layout->addWidget(m_btnChange); + m_layout->addWidget(m_shortcutBox); m_layout->addWidget(m_btnReset); m_layout->addWidget(m_btnClear); // Establish needed connections. connect(m_btnReset, &QToolButton::clicked, this, &ShortcutCatcher::resetShortcut); connect(m_btnClear, &QToolButton::clicked, this, &ShortcutCatcher::clearShortcut); - connect(m_btnChange, &QToolButton::clicked, this, &ShortcutCatcher::startRecording); - - // Prepare initial state of the control. - updateDisplayShortcut(); -} - -ShortcutCatcher::~ShortcutCatcher() { - delete m_btnReset; - delete m_btnChange; - delete m_btnClear; - delete m_layout; -} - -void ShortcutCatcher::startRecording() { - m_numKey = 0; - m_modifierKeys = 0; - m_currentSequence = QKeySequence(); - m_isRecording = true; - m_btnChange->setDown(true); - m_btnChange->grabKeyboard(); - updateDisplayShortcut(); -} - -void ShortcutCatcher::doneRecording() { - m_isRecording = false; - m_btnChange->releaseKeyboard(); - m_btnChange->setDown(false); - updateDisplayShortcut(); - emit shortcutChanged(m_currentSequence); -} - -void ShortcutCatcher::controlModifierlessTimout() { - if (m_numKey != 0 && m_modifierKeys == 0) { - doneRecording(); - } -} - -void ShortcutCatcher::updateDisplayShortcut() { - QString str = m_currentSequence.toString(QKeySequence::NativeText); - - str.replace(QL1S("&"), QL1S("&&")); - - if (m_isRecording) { - if (m_modifierKeys != 0) { - if (!str.isEmpty()) { - str.append(QSL(",")); - } - - if ((m_modifierKeys& Qt::META) > 0) { - str += QL1S("Meta + "); - } - - if ((m_modifierKeys& Qt::CTRL) > 0) { - str += QL1S("Ctrl + "); - } - - if ((m_modifierKeys& Qt::ALT) > 0) { - str += QL1S("Alt + "); - } - - if ((m_modifierKeys& Qt::SHIFT) > 0) { - str += QL1S("Shift + "); - } - } - } - - m_btnChange->setText(str); + connect(m_shortcutBox, &QKeySequenceEdit::keySequenceChanged, this, &ShortcutCatcher::shortcutChanged); } QKeySequence ShortcutCatcher::shortcut() const { - return m_currentSequence; + return m_shortcutBox->keySequence(); } void ShortcutCatcher::setDefaultShortcut(const QKeySequence& key) { @@ -147,8 +54,7 @@ void ShortcutCatcher::setDefaultShortcut(const QKeySequence& key) { } void ShortcutCatcher::setShortcut(const QKeySequence& key) { - m_currentSequence = key; - doneRecording(); + m_shortcutBox->setKeySequence(key); } void ShortcutCatcher::resetShortcut() { diff --git a/src/librssguard/dynamic-shortcuts/shortcutcatcher.h b/src/librssguard/dynamic-shortcuts/shortcutcatcher.h index d05ea2f27..ecc0483a6 100644 --- a/src/librssguard/dynamic-shortcuts/shortcutcatcher.h +++ b/src/librssguard/dynamic-shortcuts/shortcutcatcher.h @@ -1,55 +1,19 @@ // For license of this file, see <project-root-folder>/LICENSE.md. -/****************************************************************************** - Copyright (c) 2010, Artem Galichkin <doomer3d@gmail.com> - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the <organization> nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *******************************************************************************/ - #ifndef SHORTCUTCATCHER_H #define SHORTCUTCATCHER_H #include <QWidget> class QHBoxLayout; -class QToolButton; -class ShortcutButton; +class PlainToolButton; +class QKeySequenceEdit; class ShortcutCatcher : public QWidget { Q_OBJECT - friend class ShortcutButton; - public: - - // Constructors and destructors. explicit ShortcutCatcher(QWidget* parent = nullptr); - virtual ~ShortcutCatcher(); - - void controlModifierlessTimout(); - void updateDisplayShortcut(); QKeySequence shortcut() const; void setDefaultShortcut(const QKeySequence& key); @@ -59,17 +23,13 @@ class ShortcutCatcher : public QWidget { void resetShortcut(); void clearShortcut(); - private slots: - void startRecording(); - void doneRecording(); - signals: void shortcutChanged(const QKeySequence& seguence); private: - QToolButton* m_btnReset; - QToolButton* m_btnClear; - ShortcutButton* m_btnChange; + PlainToolButton* m_btnReset; + PlainToolButton* m_btnClear; + QKeySequenceEdit* m_shortcutBox; QHBoxLayout* m_layout; QKeySequence m_currentSequence; QKeySequence m_defaultSequence; diff --git a/src/librssguard/librssguard.pro b/src/librssguard/librssguard.pro index 7e60d0bf9..941e52649 100644 --- a/src/librssguard/librssguard.pro +++ b/src/librssguard/librssguard.pro @@ -41,7 +41,6 @@ HEADERS += core/feeddownloader.h \ definitions/definitions.h \ dynamic-shortcuts/dynamicshortcuts.h \ dynamic-shortcuts/dynamicshortcutswidget.h \ - dynamic-shortcuts/shortcutbutton.h \ dynamic-shortcuts/shortcutcatcher.h \ exceptions/applicationexception.h \ exceptions/filteringexception.h \ @@ -187,7 +186,6 @@ SOURCES += core/feeddownloader.cpp \ core/messagesproxymodel.cpp \ dynamic-shortcuts/dynamicshortcuts.cpp \ dynamic-shortcuts/dynamicshortcutswidget.cpp \ - dynamic-shortcuts/shortcutbutton.cpp \ dynamic-shortcuts/shortcutcatcher.cpp \ exceptions/applicationexception.cpp \ exceptions/filteringexception.cpp \