diff options
-rw-r--r-- | src/quick/items/qquicktextinput.cpp | 20 | ||||
-rw-r--r-- | src/quick/items/qquicktextinput_p_p.h | 10 |
2 files changed, 28 insertions, 2 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); diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h index cb965f2fed..b4561556aa 100644 --- a/src/quick/items/qquicktextinput_p_p.h +++ b/src/quick/items/qquicktextinput_p_p.h @@ -110,6 +110,7 @@ public: , m_cursor(0) #if QT_CONFIG(im) , m_preeditCursor(0) + , m_undoPreeditState(-1) #endif , m_blinkEnabled(false) , m_blinkTimer(0) @@ -248,6 +249,7 @@ public: int m_cursor; #if QT_CONFIG(im) int m_preeditCursor; + int m_undoPreeditState; #endif bool m_blinkEnabled; int m_blinkTimer; @@ -335,7 +337,13 @@ public: bool isUndoAvailable() const { return !m_readOnly && m_undoState; } bool isRedoAvailable() const { return !m_readOnly && m_undoState < (int)m_history.size(); } - void clearUndo() { m_history.clear(); m_undoState = 0; } + void clearUndo() { + m_history.clear(); + m_undoState = 0; +#if QT_CONFIG(im) + m_undoPreeditState = -1; +#endif + } bool allSelected() const { return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.length(); } bool hasSelectedText() const { return !m_text.isEmpty() && m_selend > m_selstart; } |