diff options
Diffstat (limited to 'src/widgets/widgets/qkeysequenceedit.cpp')
-rw-r--r-- | src/widgets/widgets/qkeysequenceedit.cpp | 129 |
1 files changed, 113 insertions, 16 deletions
diff --git a/src/widgets/widgets/qkeysequenceedit.cpp b/src/widgets/widgets/qkeysequenceedit.cpp index 3dafb9396b..65ed7a465a 100644 --- a/src/widgets/widgets/qkeysequenceedit.cpp +++ b/src/widgets/widgets/qkeysequenceedit.cpp @@ -20,7 +20,7 @@ void QKeySequenceEditPrivate::init() lineEdit = new QLineEdit(q); lineEdit->setObjectName(QStringLiteral("qt_keysequenceedit_lineedit")); lineEdit->setClearButtonEnabled(false); - q->connect(lineEdit, &QLineEdit::textChanged, [q](const QString& text) { + q->connect(lineEdit, &QLineEdit::textChanged, q, [q](const QString& text) { // Clear the shortcut if the user clicked on the clear icon if (text.isEmpty()) q->clear(); @@ -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); @@ -136,6 +137,9 @@ QKeySequenceEdit::~QKeySequenceEdit() \brief This property contains the currently chosen key sequence. The shortcut can be changed by the user or via setter function. + + \note If the QKeySequence is longer than the maximumSequenceLength + property, the key sequence is truncated. */ QKeySequence QKeySequenceEdit::keySequence() const { @@ -169,6 +173,64 @@ bool QKeySequenceEdit::isClearButtonEnabled() const return d->lineEdit->isClearButtonEnabled(); } +/*! + \property QKeySequenceEdit::maximumSequenceLength + \brief The maximum sequence length. + + The maximum number of key sequences a user can enter. The value needs to + be between 1 and 4, with 4 being the default. + + \since 6.5 +*/ +qsizetype QKeySequenceEdit::maximumSequenceLength() const +{ + Q_D(const QKeySequenceEdit); + return d->maximumSequenceLength; +} + +void QKeySequenceEdit::setMaximumSequenceLength(qsizetype count) +{ + Q_D(QKeySequenceEdit); + + if (count < 1 || count > QKeySequencePrivate::MaxKeyCount) { + qWarning("QKeySequenceEdit: maximumSequenceLength %lld is out of range (1..%d)", + qlonglong(count), QKeySequencePrivate::MaxKeyCount); + return; + } + d->maximumSequenceLength = int(count); + if (d->keyNum > count) { + for (qsizetype i = d->keyNum; i < count; ++i) + d->key[i] = QKeyCombination::fromCombined(0); + d->keyNum = count; + d->rebuildKeySequence(); + } +} + +/*! + \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<QKeyCombination> &finishingKeyCombinations) +{ + Q_D(QKeySequenceEdit); + + d->finishingKeyCombinations = finishingKeyCombinations; +} + +QList<QKeyCombination> QKeySequenceEdit::finishingKeyCombinations() const +{ + Q_D(const QKeySequenceEdit); + + return d->finishingKeyCombinations; +} + void QKeySequenceEdit::setKeySequence(const QKeySequence &keySequence) { Q_D(QKeySequenceEdit); @@ -178,16 +240,24 @@ void QKeySequenceEdit::setKeySequence(const QKeySequence &keySequence) if (d->keySequence == keySequence) return; - d->keySequence = keySequence; + const auto desiredCount = keySequence.count(); + if (desiredCount > d->maximumSequenceLength) { + qWarning("QKeySequenceEdit: setting a key sequence of length %d " + "when maximumSequenceLength is %d, truncating.", + desiredCount, d->maximumSequenceLength); + } - d->key[0] = d->key[1] = d->key[2] = d->key[3] = QKeyCombination::fromCombined(0); - d->keyNum = keySequence.count(); + d->keyNum = std::min(desiredCount, d->maximumSequenceLength); for (int i = 0; i < d->keyNum; ++i) d->key[i] = keySequence[i]; + for (int i = d->keyNum; i < QKeySequencePrivate::MaxKeyCount; ++i) + d->key[i] = QKeyCombination::fromCombined(0); - d->lineEdit->setText(keySequence.toString(QKeySequence::NativeText)); + d->rebuildKeySequence(); - emit keySequenceChanged(keySequence); + d->lineEdit->setText(d->keySequence.toString(QKeySequence::NativeText)); + + emit keySequenceChanged(d->keySequence); } /*! @@ -212,13 +282,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<QKeyEvent *>(e); + if (!d->finishingKeyCombinations.contains(ke->keyCombination())) { + keyPressEvent(ke); + return true; + } + } + break; + default: break; } @@ -232,6 +312,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) { @@ -255,26 +340,27 @@ void QKeySequenceEdit::keyPressEvent(QKeyEvent *e) return; } - if (d->keyNum >= QKeySequencePrivate::MaxKeyCount) + if (d->keyNum >= d->maximumSequenceLength) return; if (e->modifiers() & Qt::ShiftModifier) { - QList<int> possibleKeys = QKeyMapper::possibleKeys(e); - int pkTotal = possibleKeys.count(); + const QList<QKeyCombination> possibleKeys = QKeyMapper::possibleKeys(e); + int pkTotal = possibleKeys.size(); if (!pkTotal) return; bool found = false; for (int i = 0; i < possibleKeys.size(); ++i) { - if (possibleKeys.at(i) - nextKey == int(e->modifiers()) - || (possibleKeys.at(i) == nextKey && e->modifiers() == Qt::ShiftModifier)) { - nextKey = possibleKeys.at(i); + const int key = possibleKeys.at(i).toCombined(); + if (key - nextKey == int(e->modifiers()) + || (key == nextKey && e->modifiers() == Qt::ShiftModifier)) { + nextKey = key; found = true; break; } } // Use as fallback if (!found) - nextKey = possibleKeys.first(); + nextKey = possibleKeys.first().toCombined(); } else { nextKey |= d->translateModifiers(e->modifiers(), e->text()); } @@ -285,7 +371,7 @@ void QKeySequenceEdit::keyPressEvent(QKeyEvent *e) d->rebuildKeySequence(); QString text = d->keySequence.toString(QKeySequence::NativeText); - if (d->keyNum < QKeySequencePrivate::MaxKeyCount) { + if (d->keyNum < d->maximumSequenceLength) { //: This text is an "unfinished" shortcut, expands like "Ctrl+A, ..." text = tr("%1, ...").arg(text); } @@ -301,7 +387,7 @@ void QKeySequenceEdit::keyReleaseEvent(QKeyEvent *e) Q_D(QKeySequenceEdit); if (d->prevKey == e->key()) { - if (d->keyNum < QKeySequencePrivate::MaxKeyCount) + if (d->keyNum < d->maximumSequenceLength) d->releaseTimer = startTimer(1000); else d->finishEditing(); @@ -323,6 +409,17 @@ void QKeySequenceEdit::timerEvent(QTimerEvent *e) QWidget::timerEvent(e); } +/*! + \reimp +*/ +void QKeySequenceEdit::focusOutEvent(QFocusEvent *e) +{ + Q_D(QKeySequenceEdit); + if (e->reason() != Qt::PopupFocusReason) + d->finishEditing(); + QWidget::focusOutEvent(e); +} + QT_END_NAMESPACE #include "moc_qkeysequenceedit.cpp" |