QKeySequenceEdit: add a maximumSquenceLength property

At the very least, it would be important to have a single combination
key sequence. This is commonly seen in keyboard shortcut editors where
QKeySequenceEdit is very much applicable.

[ChangeLog][QtWidgets][QKeySequenceEdit] Added a maximumSquenceLength
property.

Done-with: Marc Mutz <marc.mutz@qt.io>
Change-Id: Id7fa5a8593eb150fa67d7e89308492c0a200ac36
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Laszlo Papp 2022-05-18 12:06:53 +02:00 committed by Marc Mutz
parent 4d60ba61dc
commit 9521a07af2
4 changed files with 97 additions and 8 deletions

View File

@ -136,6 +136,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 +172,43 @@ bool QKeySequenceEdit::isClearButtonEnabled() const
return d->lineEdit->isClearButtonEnabled();
}
/*!
\property QKeySequenceEdit::maximumSequenceLength
\brief The maximum sequence length.
The value is clamped to [1-4] inclusive, i.e. the maximum value of the
maximum sequence length is 4 driven by QKeySequence. The minimum value is
1, which can be useful for single sequence, like a typical shortcut.
The QKeySequence stored in QKeySequenceEdit is truncated if longer than the
value of this property.
\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();
}
}
void QKeySequenceEdit::setKeySequence(const QKeySequence &keySequence)
{
Q_D(QKeySequenceEdit);
@ -178,16 +218,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);
}
/*!
@ -255,7 +303,7 @@ void QKeySequenceEdit::keyPressEvent(QKeyEvent *e)
return;
}
if (d->keyNum >= QKeySequencePrivate::MaxKeyCount)
if (d->keyNum >= d->maximumSequenceLength)
return;
if (e->modifiers() & Qt::ShiftModifier) {
@ -285,7 +333,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 +349,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();

View File

@ -19,6 +19,7 @@ class Q_WIDGETS_EXPORT QKeySequenceEdit : public QWidget
Q_PROPERTY(QKeySequence keySequence READ keySequence WRITE setKeySequence
NOTIFY keySequenceChanged USER true)
Q_PROPERTY(bool clearButtonEnabled READ isClearButtonEnabled WRITE setClearButtonEnabled)
Q_PROPERTY(qsizetype maximumSequenceLength READ maximumSequenceLength WRITE setMaximumSequenceLength)
public:
explicit QKeySequenceEdit(QWidget *parent = nullptr);
@ -26,6 +27,7 @@ public:
~QKeySequenceEdit();
QKeySequence keySequence() const;
qsizetype maximumSequenceLength() const;
void setClearButtonEnabled(bool enable);
bool isClearButtonEnabled() const;
@ -33,6 +35,7 @@ public:
public Q_SLOTS:
void setKeySequence(const QKeySequence &keySequence);
void clear();
void setMaximumSequenceLength(qsizetype count);
Q_SIGNALS:
void editingFinished();

View File

@ -42,6 +42,7 @@ public:
QLineEdit *lineEdit;
QKeySequence keySequence;
int keyNum;
int maximumSequenceLength = QKeySequencePrivate::MaxKeyCount;
QKeyCombination key[QKeySequencePrivate::MaxKeyCount];
int prevKey;
int releaseTimer;

View File

@ -20,6 +20,7 @@ private slots:
void testKeys_data();
void testKeys();
void testLineEditContents();
void testMaximumSequenceLength();
};
void tst_QKeySequenceEdit::testSetters()
@ -49,6 +50,42 @@ void tst_QKeySequenceEdit::testKeys_data()
QTest::newRow("4") << Qt::Key_N << Qt::KeyboardModifiers(Qt::ControlModifier | Qt::ShiftModifier) << QKeySequence("Ctrl+Shift+N");
}
void tst_QKeySequenceEdit::testMaximumSequenceLength()
{
//
// GIVEN:
// - A QKeySequenceEdit with maxKeyCount == 1
// - A QKeySequence with more than one key
//
QKeySequenceEdit edit;
edit.setMaximumSequenceLength(1);
QCOMPARE(edit.maximumSequenceLength(), 1);
QKeySequence multi("Ctrl+X, S");
QCOMPARE(multi.count(), 2);
//
// WHEN: setting the key sequence on the edit
//
QTest::ignoreMessage(QtWarningMsg,
"QKeySequenceEdit: setting a key sequence of length 2 when "
"maximumSequenceLength is 1, truncating.");
edit.setKeySequence(multi);
//
// THEN:
// - the maxKeyCount property doesn't change
// - the key sequence is truncated to maxKeyCount
// - and won't un-truncate by increasing maxKeyCount
//
QCOMPARE(edit.maximumSequenceLength(), 1);
const auto edited = edit.keySequence();
QCOMPARE(edited.count(), 1);
QCOMPARE(edited, QKeySequence("Ctrl+X"));
edit.setMaximumSequenceLength(2);
QCOMPARE(edit.keySequence(), edited);
}
void tst_QKeySequenceEdit::testKeys()
{
QFETCH(Qt::Key, key);