diff options
author | Paul Olav Tvete <paul.tvete@digia.com> | 2014-05-06 18:13:45 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-05-08 13:50:22 +0200 |
commit | eed30131e168d12ed44e9ed469bef70cd4a80f4e (patch) | |
tree | 5f982a019f38387bfd862fae1564e2d3e4d7b377 /src/plugins/platforms/android/qandroidinputcontext.cpp | |
parent | 36caeadb4db9fab1cf581f9a3bb3c4a2e14de49a (diff) |
Android: text cursor position fixes
The Android input method protocol specifies that finishComposingText()
should not move the cursor. Since Qt likes to move the cursor to the
end of the newly committed text, we have to explicitly move the cursor
to where the preedit cursor used to be. Fortunately we already keep
track of that.
Also implement support for the newCursorPosition argument to commitText()
since the function needed to be rewritten anyway. (It was calling
finishComposingText().)
Task-number: QTBUG-38794
Change-Id: Iff2c43bdbd3dda812ccdc71da63f3fa730474eef
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Diffstat (limited to 'src/plugins/platforms/android/qandroidinputcontext.cpp')
-rw-r--r-- | src/plugins/platforms/android/qandroidinputcontext.cpp | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index e255a49ac7..c2e5f83639 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -591,19 +591,37 @@ jboolean QAndroidInputContext::endBatchEdit() return JNI_TRUE; } -jboolean QAndroidInputContext::commitText(const QString &text, jint /*newCursorPosition*/) +/* + Android docs say: If composing, replace compose text with \a text. + Otherwise insert \a text at current cursor position. + + The cursor should then be moved to newCursorPosition. If > 0, this is + relative to the end of the text - 1; if <= 0, this is relative to the start + of the text. updateSelection() needs to be called. +*/ +jboolean QAndroidInputContext::commitText(const QString &text, jint newCursorPosition) { - QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery(); - if (query.isNull()) - return JNI_FALSE; + QInputMethodEvent event; + event.setCommitString(text); + sendInputMethodEvent(&event); + clear(); + // Qt has now put the cursor at the end of the text, corresponding to newCursorPosition == 1 + if (newCursorPosition != 1) { + QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery(); + if (!query.isNull()) { + QList<QInputMethodEvent::Attribute> attributes; + const int localPos = query->value(Qt::ImCursorPosition).toInt(); + const int newLocalPos = newCursorPosition > 0 + ? localPos + newCursorPosition - 1 + : localPos - text.length() + newCursorPosition; + //move the cursor + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, + newLocalPos, 0, QVariant())); + } + } - const int cursorPos = getAbsoluteCursorPosition(query); - m_composingText = text; - m_composingTextStart = cursorPos; - m_composingCursor = cursorPos + text.length(); - finishComposingText(); - //### move cursor to newCursorPosition and call updateCursorPosition() + updateCursorPosition(); return JNI_TRUE; } @@ -624,9 +642,24 @@ jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint right return JNI_TRUE; } +// Android docs say the cursor must not move jboolean QAndroidInputContext::finishComposingText() { - QInputMethodEvent event; + QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery(); + if (query.isNull()) + return JNI_FALSE; + + if (m_composingText.isEmpty()) + return JNI_TRUE; // not composing + + const int blockPos = getBlockPosition(query); + const int localCursorPos = m_composingCursor - blockPos; + + // Moving Qt's cursor to where the preedit cursor used to be + QList<QInputMethodEvent::Attribute> attributes; + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, localCursorPos, 0, QVariant())); + + QInputMethodEvent event(QString(), attributes); event.setCommitString(m_composingText); sendInputMethodEvent(&event); clear(); |