diff options
author | Bartlomiej Moskal <bartlomiej.moskal@qt.io> | 2021-01-19 11:47:54 +0100 |
---|---|---|
committer | Bartlomiej Moskal <bartlomiej.moskal@qt.io> | 2021-02-19 07:50:42 +0000 |
commit | b1ae151acc80254ab0ec2937c55b99223205875c (patch) | |
tree | 54027207bdf404d7766eb678c60a47b1bd2e5d56 /src/quick/items/qquicktextinput.cpp | |
parent | f34ecc8f99522b69d1aaa3d5d233add9ed9b6da9 (diff) |
qquicktextinput: Fix validation for IM event
If validation did not pass after text pre-editing is finished, it need
to be roll back to state before pre-editing started.
Before this change, if validation did not pass, text was always rolled
back to previous state. In pre-editing text case, it means back to the
state in which part of the text was removed (and later changed to
pre-edited text). It may cause a situation of removing part of the text
that was already validated
Pick-to: 5.15 6.0 6.1
Fixes: QTBUG-90239
Change-Id: I3ec39e0f6b8a93d4e6fd190af30d4c80a0e495eb
Reviewed-by: Rami Potinkara <rami.potinkara@qt.io>
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
Diffstat (limited to 'src/quick/items/qquicktextinput.cpp')
-rw-r--r-- | src/quick/items/qquicktextinput.cpp | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 6aec9e8c42..5707fe8b92 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -3471,8 +3471,12 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event) } QString oldPreeditString = m_textLayout.preeditAreaText(); m_textLayout.setPreeditArea(m_cursor, event->preeditString()); - if (oldPreeditString != m_textLayout.preeditAreaText()) + if (oldPreeditString != m_textLayout.preeditAreaText()) { emit q->preeditTextChanged(); + if (!event->preeditString().isEmpty() && m_undoPreeditState == -1) + // Pre-edit text started. Remember state for undo purpose. + m_undoPreeditState = priorState; + } const int oldPreeditCursor = m_preeditCursor; m_preeditCursor = event->preeditString().length(); hasImState = !event->preeditString().isEmpty(); @@ -3514,6 +3518,11 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event) q->updateInputMethod(Qt::ImCursorRectangle | Qt::ImAnchorRectangle | Qt::ImCurrentSelection); } + + // Empty pre-edit text handled. Clean m_undoPreeditState + if (event->preeditString().isEmpty()) + m_undoPreeditState = -1; + } #endif // im @@ -3590,6 +3599,12 @@ bool QQuickTextInputPrivate::finishChange(int validateFromState, bool update, bo if (m_maskData) checkIsValid(); +#if QT_CONFIG(im) + // If we were during pre-edit, validateFromState should point to the state before pre-edit + // has been started. Choose the correct oldest remembered state + if (m_undoPreeditState >= 0 && (m_undoPreeditState < validateFromState || validateFromState < 0)) + validateFromState = m_undoPreeditState; +#endif if (validateFromState >= 0 && wasValidInput && !m_validInput) { if (m_transactions.count()) return false; @@ -3662,6 +3677,9 @@ void QQuickTextInputPrivate::internalSetText(const QString &txt, int pos, bool e } m_history.clear(); m_undoState = 0; +#if QT_CONFIG(im) + m_undoPreeditState = -1; +#endif m_cursor = (pos < 0 || pos > m_text.length()) ? m_text.length() : pos; m_textDirty = (oldText != m_text); |