aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquicktextinput.cpp
diff options
context:
space:
mode:
authorBartlomiej Moskal <bartlomiej.moskal@qt.io>2021-01-19 11:47:54 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-02-19 11:18:57 +0000
commitf839f2f3d6bcdc1a9b87a35b8f308ec5bc6c583d (patch)
tree9562338d0fef84caaab2d30d5b3e0aaf487df701 /src/quick/items/qquicktextinput.cpp
parentdae0fe461b26b6db85586db1979bc1d9fb05670b (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 Fixes: QTBUG-90239 Change-Id: I3ec39e0f6b8a93d4e6fd190af30d4c80a0e495eb Reviewed-by: Rami Potinkara <rami.potinkara@qt.io> Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io> (cherry picked from commit b1ae151acc80254ab0ec2937c55b99223205875c) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/quick/items/qquicktextinput.cpp')
-rw-r--r--src/quick/items/qquicktextinput.cpp20
1 files changed, 19 insertions, 1 deletions
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index b1945e9eb8..419ac4a2bb 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();
@@ -3515,6 +3519,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
@@ -3591,6 +3600,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;
@@ -3663,6 +3678,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);