diff options
-rw-r--r-- | src/widgets/widgets/qlineedit.cpp | 7 | ||||
-rw-r--r-- | src/widgets/widgets/qlineedit.h | 1 | ||||
-rw-r--r-- | src/widgets/widgets/qlineedit_p.cpp | 12 | ||||
-rw-r--r-- | src/widgets/widgets/qlineedit_p.h | 1 | ||||
-rw-r--r-- | tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp | 68 |
5 files changed, 84 insertions, 5 deletions
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 07985cf966..9f1f00ced7 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -1691,8 +1691,11 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e) /*! \fn void QLineEdit::editingFinished() - This signal is emitted when the Return or Enter key is pressed or - the line edit loses focus. Note that if there is a validator() or + This signal is emitted when the Return or Enter key is pressed, or + if the line edit loses focus and its contents have changed since the + last time this signal was emitted. + + Note that if there is a validator() or inputMask() set on the line edit and enter/return is pressed, the editingFinished() signal will only be emitted if the input follows the inputMask() and the validator() returns QValidator::Acceptable. diff --git a/src/widgets/widgets/qlineedit.h b/src/widgets/widgets/qlineedit.h index f09d62ec78..b4f6641b86 100644 --- a/src/widgets/widgets/qlineedit.h +++ b/src/widgets/widgets/qlineedit.h @@ -263,6 +263,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_updateNeeded(const QRect &)) Q_PRIVATE_SLOT(d_func(), void _q_textChanged(const QString &)) Q_PRIVATE_SLOT(d_func(), void _q_clearButtonClicked()) + Q_PRIVATE_SLOT(d_func(), void _q_controlEditingFinished()) }; QT_END_NAMESPACE diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index 9fe5b5af3f..1839941036 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -193,10 +193,8 @@ void QLineEditPrivate::init(const QString& txt) q, SLOT(_q_cursorPositionChanged(int,int))); QObject::connect(control, SIGNAL(selectionChanged()), q, SLOT(_q_selectionChanged())); - QObject::connect(control, SIGNAL(accepted()), - q, SIGNAL(returnPressed())); QObject::connect(control, SIGNAL(editingFinished()), - q, SIGNAL(editingFinished())); + q, SLOT(_q_controlEditingFinished())); #ifdef QT_KEYPAD_NAVIGATION QObject::connect(control, SIGNAL(editFocusChange(bool)), q, SLOT(_q_editFocusChange(bool))); @@ -485,6 +483,14 @@ void QLineEditPrivate::_q_clearButtonClicked() } } +void QLineEditPrivate::_q_controlEditingFinished() +{ + Q_Q(QLineEdit); + edited = false; + emit q->returnPressed(); + emit q->editingFinished(); +} + QLineEditPrivate::SideWidgetParameters QLineEditPrivate::sideWidgetParameters() const { Q_Q(const QLineEdit); diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h index 049f7a3bdf..936cf2d088 100644 --- a/src/widgets/widgets/qlineedit_p.h +++ b/src/widgets/widgets/qlineedit_p.h @@ -233,6 +233,7 @@ public: #endif void _q_textChanged(const QString &); void _q_clearButtonClicked(); + void _q_controlEditingFinished(); QMargins textMargins; // use effectiveTextMargins() in case of icon. diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index 87be592e2b..547bc49199 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -250,6 +250,8 @@ private slots: void textMargin_data(); void textMargin(); + void returnKeyClearsEditedFlag(); + // task-specific tests: void task180999_focus(); void task174640_editingFinished(); @@ -3586,6 +3588,72 @@ void tst_QLineEdit::textMargin() QTRY_COMPARE(testWidget.cursorPosition(), cursorPosition); } +void tst_QLineEdit::returnKeyClearsEditedFlag() +{ + /* Tests that pressing enter within the line edit correctly clears + the "edited" flag, preventing a redundant emission of + editingFinished() when its focus is dropped after no further + edits */ + QLineEdit testWidget; + QSignalSpy leSpy(&testWidget, &QLineEdit::editingFinished); + QVERIFY(leSpy.isValid()); + + // Prepare widget for testing + testWidget.setFocus(); + centerOnScreen(&testWidget); + testWidget.show(); + testWidget.raise(); + QVERIFY(QTest::qWaitForWindowExposed(&testWidget)); + QTRY_VERIFY(testWidget.hasFocus()); + + // Focus drop with no edits shouldn't emit signal, edited flag == false + testWidget.clearFocus(); // Signal not emitted + QVERIFY(!testWidget.hasFocus()); + QCOMPARE(leSpy.count(), 0); + + // Focus drop after edits should emit signal, edited flag == true + testWidget.setFocus(); + QTRY_VERIFY(testWidget.hasFocus()); + QTest::keyClicks(&testWidget, "edit1 "); // edited flag set + testWidget.clearFocus(); // edited flag cleared, signal emitted + QVERIFY(!testWidget.hasFocus()); + QCOMPARE(leSpy.count(), 1); + + // Only text related keys should set edited flag + testWidget.setFocus(); + QTRY_VERIFY(testWidget.hasFocus()); + QTest::keyClick(&testWidget, Qt::Key_Left); + QTest::keyClick(&testWidget, Qt::Key_Alt); + QTest::keyClick(&testWidget, Qt::Key_PageUp); + testWidget.clearFocus(); // Signal not emitted + QVERIFY(!testWidget.hasFocus()); + QCOMPARE(leSpy.count(), 1); // No change + + // Return should always emit signal + testWidget.setFocus(); + QTRY_VERIFY(testWidget.hasFocus()); + QTest::keyClick(&testWidget, Qt::Key_Return); /* Without edits, + signal emitted, + edited flag cleared */ + QCOMPARE(leSpy.count(), 2); + QTest::keyClicks(&testWidget, "edit2 "); // edited flag set + QTest::keyClick(&testWidget, Qt::Key_Return); /* With edits, + signal emitted, + edited flag cleared */ + QCOMPARE(leSpy.count(), 3); + + /* After editing the line edit following a Return key press with a + focus drop should not emit signal a second time since Return now + clears the edited flag */ + QTest::keyClicks(&testWidget, "edit3 "); // edited flag set + QTest::keyClick(&testWidget, Qt::Key_Return); /* signal emitted, + edited flag cleared */ + QCOMPARE(leSpy.count(), 4); + testWidget.clearFocus(); // Signal not emitted since edited == false + QVERIFY(!testWidget.hasFocus()); + QCOMPARE(leSpy.count(), 4); // No change +} + #ifndef QT_NO_CURSOR void tst_QLineEdit::cursor() { |