diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2015-12-08 20:35:11 +0100 |
---|---|---|
committer | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2015-12-09 19:04:59 +0000 |
commit | 872b9b231ef966ce7b2b40785ee92a0d4a8d2851 (patch) | |
tree | 9eba2013979f957848f3f6af924966fa64b5430f | |
parent | 410aa20f073b5e45e73366773b7d173f840a9cfe (diff) |
QLineEdit: fix the shortcut override events on a readonly line edit
When a QLineEdit is readonly there's a discrepancy between key press
events and shortcut override events. For instance, presses Ctrl+C
copies the text unless there's also a shortcut for the same key sequence.
In this case, the shortcut override event is not handled, and no text
is copied. Fix it by splitting the handling of shortcut override
events between "read only" access (copy, select, etc.), which still
makes sense on a read only line edit, and write access (paste, ...)
which doesn't.
[ChangeLog][Important Behavior Changes][QLineEdit] QLineEdit will
now accept certain shortcut override events even if it is read only.
Change-Id: Ie5b048259b99a1eff0581129e3ad97f27a88fe86
Task-number: QTBUG-21217
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@theqtcompany.com>
-rw-r--r-- | src/widgets/widgets/qwidgetlinecontrol.cpp | 28 | ||||
-rw-r--r-- | tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp | 60 |
2 files changed, 77 insertions, 11 deletions
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp index e2893d9496..42cd51eca7 100644 --- a/src/widgets/widgets/qwidgetlinecontrol.cpp +++ b/src/widgets/widgets/qwidgetlinecontrol.cpp @@ -1516,14 +1516,7 @@ void QWidgetLineControl::timerEvent(QTimerEvent *event) #ifndef QT_NO_SHORTCUT void QWidgetLineControl::processShortcutOverrideEvent(QKeyEvent *ke) { - if (isReadOnly()) - return; - if (ke == QKeySequence::Copy - || ke == QKeySequence::Paste - || ke == QKeySequence::Cut - || ke == QKeySequence::Redo - || ke == QKeySequence::Undo || ke == QKeySequence::MoveToNextWord || ke == QKeySequence::MoveToPreviousWord || ke == QKeySequence::MoveToEndOfLine @@ -1537,22 +1530,35 @@ void QWidgetLineControl::processShortcutOverrideEvent(QKeyEvent *ke) || ke == QKeySequence::SelectEndOfBlock || ke == QKeySequence::SelectStartOfDocument || ke == QKeySequence::SelectAll - || ke == QKeySequence::SelectEndOfDocument - || ke == QKeySequence::DeleteCompleteLine) { + || ke == QKeySequence::SelectEndOfDocument) { ke->accept(); + } else if (ke == QKeySequence::Paste + || ke == QKeySequence::Cut + || ke == QKeySequence::Redo + || ke == QKeySequence::Undo + || ke == QKeySequence::DeleteCompleteLine) { + if (!isReadOnly()) + ke->accept(); } else if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier || ke->modifiers() == Qt::KeypadModifier) { if (ke->key() < Qt::Key_Escape) { - ke->accept(); + if (!isReadOnly()) + ke->accept(); } else { switch (ke->key()) { case Qt::Key_Delete: + case Qt::Key_Backspace: + if (!isReadOnly()) + ke->accept(); + break; + case Qt::Key_Home: case Qt::Key_End: - case Qt::Key_Backspace: case Qt::Key_Left: case Qt::Key_Right: ke->accept(); + break; + default: break; } diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index ba700ed58d..de896ea273 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -64,6 +64,7 @@ #include <qsortfilterproxymodel.h> #include <qdebug.h> #include <qscreen.h> +#include <qshortcut.h> #include "qcommonstyle.h" #include "qstyleoption.h" @@ -312,6 +313,9 @@ private slots: void shouldShowPlaceholderText(); void QTBUG1266_setInputMaskEmittingTextEdited(); + void shortcutOverrideOnReadonlyLineEdit_data(); + void shortcutOverrideOnReadonlyLineEdit(); + protected slots: void editingFinished(); @@ -4487,5 +4491,61 @@ void tst_QLineEdit::QTBUG1266_setInputMaskEmittingTextEdited() QCOMPARE(spy.count(), 0); } +void tst_QLineEdit::shortcutOverrideOnReadonlyLineEdit_data() +{ + QTest::addColumn<QKeySequence>("keySequence"); + QTest::addColumn<bool>("shouldBeHandledByQLineEdit"); + + QTest::newRow("Copy") << QKeySequence(QKeySequence::Copy) << true; + QTest::newRow("MoveToNextChar") << QKeySequence(QKeySequence::MoveToNextChar) << true; + QTest::newRow("SelectAll") << QKeySequence(QKeySequence::SelectAll) << true; + QTest::newRow("Right press") << QKeySequence(Qt::Key_Right) << true; + QTest::newRow("Left press") << QKeySequence(Qt::Key_Left) << true; + + QTest::newRow("Paste") << QKeySequence(QKeySequence::Paste) << false; + QTest::newRow("Paste") << QKeySequence(QKeySequence::Cut) << false; + QTest::newRow("Undo") << QKeySequence(QKeySequence::Undo) << false; + QTest::newRow("Redo") << QKeySequence(QKeySequence::Redo) << false; + + QTest::newRow("a") << QKeySequence(Qt::Key_A) << false; + QTest::newRow("b") << QKeySequence(Qt::Key_B) << false; + QTest::newRow("c") << QKeySequence(Qt::Key_C) << false; + QTest::newRow("x") << QKeySequence(Qt::Key_X) << false; + QTest::newRow("X") << QKeySequence(Qt::ShiftModifier + Qt::Key_X) << false; + + QTest::newRow("Alt+Home") << QKeySequence(Qt::AltModifier + Qt::Key_Home) << false; +} + +void tst_QLineEdit::shortcutOverrideOnReadonlyLineEdit() +{ + QFETCH(QKeySequence, keySequence); + QFETCH(bool, shouldBeHandledByQLineEdit); + + QWidget widget; + + QShortcut *shortcut = new QShortcut(keySequence, &widget); + QSignalSpy spy(shortcut, &QShortcut::activated); + QVERIFY(spy.isValid()); + + QLineEdit *lineEdit = new QLineEdit(QStringLiteral("Test"), &widget); + lineEdit->setReadOnly(true); + lineEdit->setFocus(); + + widget.show(); + + QVERIFY(QTest::qWaitForWindowActive(&widget)); + + const int keySequenceCount = keySequence.count(); + for (int i = 0; i < keySequenceCount; ++i) { + const uint key = keySequence[i]; + QTest::keyClick(lineEdit, + Qt::Key(key & ~Qt::KeyboardModifierMask), + Qt::KeyboardModifier(key & Qt::KeyboardModifierMask)); + } + + const int activationCount = shouldBeHandledByQLineEdit ? 0 : 1; + QCOMPARE(spy.count(), activationCount); +} + QTEST_MAIN(tst_QLineEdit) #include "tst_qlineedit.moc" |