From 1ea0d399b3787d486d6fc59aaaf498cbf6bd66b2 Mon Sep 17 00:00:00 2001 From: Laszlo Papp Date: Fri, 24 Jun 2022 17:57:22 +0100 Subject: [PATCH] QKeySequenceEdit: Add a finishing key combinations property Different shortcut editors seem to have different preferences. By default, QWidget seems to utilise Tab, Backtab, Return and Enter for navigation purposes. However, some shortcut editors would like to be able to record these keys as part of combinations to use in the application. Therefore, leave it with the application developers to decide what key combinations they would like to use for finishing the key sequence edit. This should provide enough flexibility for application developers to customize their shortcut editor behavior. [ChangeLog][QtWidgets][QKeySequenceEdit] Added a property to allow defining the finishing key combinations. Fixes: QTBUG-103844 Fixes: QTBUG-103843 Change-Id: Id84644086ca7a4f11618d510e59698a43735b99b Reviewed-by: Volker Hilsheimer --- src/widgets/widgets/qkeysequenceedit.cpp | 43 ++++++++++++++++++- src/widgets/widgets/qkeysequenceedit.h | 4 ++ src/widgets/widgets/qkeysequenceedit_p.h | 1 + .../qkeysequenceedit/tst_qkeysequenceedit.cpp | 40 +++++++++++++++++ 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qkeysequenceedit.cpp b/src/widgets/widgets/qkeysequenceedit.cpp index c7d82019f1..565ea08001 100644 --- a/src/widgets/widgets/qkeysequenceedit.cpp +++ b/src/widgets/widgets/qkeysequenceedit.cpp @@ -29,6 +29,7 @@ void QKeySequenceEditPrivate::init() keyNum = 0; prevKey = -1; releaseTimer = 0; + finishingKeyCombinations = {Qt::Key_Tab, Qt::Key_Backtab}; QVBoxLayout *layout = new QVBoxLayout(q); layout->setContentsMargins(0, 0, 0, 0); @@ -209,6 +210,31 @@ void QKeySequenceEdit::setMaximumSequenceLength(qsizetype count) } } +/*! + \property QKeySequenceEdit::finishingKeyCombinations + \brief The list of key combinations that finish editing the key sequences. + + Any combination in the list will finish the editing of key sequences. + All other key combinations can be recorded as part of a key sequence. By + default, Qt::Key_Tab and Qt::Key_Backtab will finish recording the key + sequence. + + \since 6.5 +*/ +void QKeySequenceEdit::setFinishingKeyCombinations(const QList &finishingKeyCombinations) +{ + Q_D(QKeySequenceEdit); + + d->finishingKeyCombinations = finishingKeyCombinations; +} + +QList QKeySequenceEdit::finishingKeyCombinations() const +{ + Q_D(const QKeySequenceEdit); + + return d->finishingKeyCombinations; +} + void QKeySequenceEdit::setKeySequence(const QKeySequence &keySequence) { Q_D(QKeySequenceEdit); @@ -260,13 +286,23 @@ void QKeySequenceEdit::clear() */ bool QKeySequenceEdit::event(QEvent *e) { + Q_D(const QKeySequenceEdit); + switch (e->type()) { case QEvent::Shortcut: return true; case QEvent::ShortcutOverride: e->accept(); return true; - default : + case QEvent::KeyPress: { + QKeyEvent *ke = static_cast(e); + if (!d->finishingKeyCombinations.contains(ke->keyCombination())) { + keyPressEvent(ke); + return true; + } + } + break; + default: break; } @@ -280,6 +316,11 @@ void QKeySequenceEdit::keyPressEvent(QKeyEvent *e) { Q_D(QKeySequenceEdit); + if (d->finishingKeyCombinations.contains(e->keyCombination())) { + d->finishEditing(); + return; + } + int nextKey = e->key(); if (d->prevKey == -1) { diff --git a/src/widgets/widgets/qkeysequenceedit.h b/src/widgets/widgets/qkeysequenceedit.h index f7ef0e00ec..15b40133b1 100644 --- a/src/widgets/widgets/qkeysequenceedit.h +++ b/src/widgets/widgets/qkeysequenceedit.h @@ -20,6 +20,7 @@ class Q_WIDGETS_EXPORT QKeySequenceEdit : public QWidget NOTIFY keySequenceChanged USER true) Q_PROPERTY(bool clearButtonEnabled READ isClearButtonEnabled WRITE setClearButtonEnabled) Q_PROPERTY(qsizetype maximumSequenceLength READ maximumSequenceLength WRITE setMaximumSequenceLength) + Q_PROPERTY(QList finishingKeyCombinations READ finishingKeyCombinations WRITE setFinishingKeyCombinations) public: explicit QKeySequenceEdit(QWidget *parent = nullptr); @@ -32,6 +33,9 @@ public: void setClearButtonEnabled(bool enable); bool isClearButtonEnabled() const; + void setFinishingKeyCombinations(const QList &inishingKeyCombinations); + QList finishingKeyCombinations() const; + public Q_SLOTS: void setKeySequence(const QKeySequence &keySequence); void clear(); diff --git a/src/widgets/widgets/qkeysequenceedit_p.h b/src/widgets/widgets/qkeysequenceedit_p.h index d654df2391..bdf3bfe788 100644 --- a/src/widgets/widgets/qkeysequenceedit_p.h +++ b/src/widgets/widgets/qkeysequenceedit_p.h @@ -46,6 +46,7 @@ public: QKeyCombination key[QKeySequencePrivate::MaxKeyCount]; int prevKey; int releaseTimer; + QList finishingKeyCombinations; }; QT_END_NAMESPACE diff --git a/tests/auto/widgets/widgets/qkeysequenceedit/tst_qkeysequenceedit.cpp b/tests/auto/widgets/widgets/qkeysequenceedit/tst_qkeysequenceedit.cpp index d372505f8c..a0a2fe023a 100644 --- a/tests/auto/widgets/widgets/qkeysequenceedit/tst_qkeysequenceedit.cpp +++ b/tests/auto/widgets/widgets/qkeysequenceedit/tst_qkeysequenceedit.cpp @@ -21,6 +21,8 @@ private slots: void testKeys(); void testLineEditContents(); void testMaximumSequenceLength(); + void testFinishingKeyCombinations_data(); + void testFinishingKeyCombinations(); }; void tst_QKeySequenceEdit::testSetters() @@ -123,5 +125,43 @@ void tst_QKeySequenceEdit::testLineEditContents() QCOMPARE(le->text(), QString()); } +void tst_QKeySequenceEdit::testFinishingKeyCombinations_data() +{ + QTest::addColumn("key"); + QTest::addColumn("modifiers"); + QTest::addColumn("keySequence"); + + QTest::newRow("1") << Qt::Key_Backtab << Qt::KeyboardModifiers(Qt::NoModifier) << QKeySequence("Backtab"); + QTest::newRow("2") << Qt::Key_Tab << Qt::KeyboardModifiers(Qt::NoModifier) << QKeySequence("Tab"); + QTest::newRow("3") << Qt::Key_Return << Qt::KeyboardModifiers(Qt::NoModifier) << QKeySequence("Return"); + QTest::newRow("4") << Qt::Key_Enter << Qt::KeyboardModifiers(Qt::NoModifier) << QKeySequence("Enter"); + QTest::newRow("5") << Qt::Key_Enter << Qt::KeyboardModifiers(Qt::ShiftModifier) << QKeySequence("Shift+Enter"); +} + +void tst_QKeySequenceEdit::testFinishingKeyCombinations() +{ + QFETCH(Qt::Key, key); + QFETCH(Qt::KeyboardModifiers, modifiers); + QFETCH(QKeySequence, keySequence); + QKeySequenceEdit edit; + + QSignalSpy spy(&edit, SIGNAL(editingFinished())); + QCOMPARE(spy.count(), 0); + + edit.setFinishingKeyCombinations({QKeyCombination(modifiers, key)}); + QTest::keyPress(&edit, key, modifiers); + QTest::keyRelease(&edit, key, modifiers); + + QCOMPARE(edit.keySequence(), QKeySequence()); + QTRY_COMPARE(spy.count(), 1); + + edit.setFinishingKeyCombinations({}); + QTest::keyPress(&edit, key, modifiers); + QTest::keyRelease(&edit, key, modifiers); + + QCOMPARE(edit.keySequence(), keySequence); + QTRY_COMPARE(spy.count(), 2); +} + QTEST_MAIN(tst_QKeySequenceEdit) #include "tst_qkeysequenceedit.moc"