diff options
author | Yuntaek Rim <yuntaek.rim@myscript.com> | 2018-01-17 22:59:43 +0200 |
---|---|---|
committer | Mitch Curtis <mitch.curtis@qt.io> | 2018-08-16 08:44:47 +0000 |
commit | 00408414e38dd69186b7b39b3879a057079b6bb6 (patch) | |
tree | dfee460b2172b8c5fb7de098fa62174ff9be2a6e /src/virtualkeyboard/inputcontext.cpp | |
parent | 61385be34a2d4b09fd77f780295adb37d931a88d (diff) |
Allow InputMethod to process pre-edit click
We already have InputMethod::reselect, but it is
limited to case where the current pre-edit is
discarded and new range is made active.
However, if an input method wants to move the
cursor within pre-edit, it is not possible with
the current implementation.
This change adds the new API for the InputMethod
which allows to handle pre-edit click before
reselect happens. If the input method handles
the event, reselect will not be done.
This change also improves the cursor handling
within pre-edit text. Previously if the cursor
attribute was added to pre-edit text and the
input was committed, the cursor would jump to
position after pre-edit text. This is now taken
into account when committing text and cursor
location will be preserved.
Change-Id: I0a32f75eb4e454c86dd8d4f4016ac02fc1bc6c60
Reviewed-by: Jarkko Koivikko <jarkko.koivikko@code-q.fi>
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src/virtualkeyboard/inputcontext.cpp')
-rw-r--r-- | src/virtualkeyboard/inputcontext.cpp | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/src/virtualkeyboard/inputcontext.cpp b/src/virtualkeyboard/inputcontext.cpp index dd937966..8635e514 100644 --- a/src/virtualkeyboard/inputcontext.cpp +++ b/src/virtualkeyboard/inputcontext.cpp @@ -252,6 +252,7 @@ QString InputContext::preeditText() const void InputContext::setPreeditText(const QString &text, QList<QInputMethodEvent::Attribute> attributes, int replaceFrom, int replaceLength) { + Q_D(InputContext); // Add default attributes if (!text.isEmpty()) { if (!testAttribute(attributes, QInputMethodEvent::TextFormat)) { @@ -259,7 +260,7 @@ void InputContext::setPreeditText(const QString &text, QList<QInputMethodEvent:: textFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline); attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, text.length(), textFormat)); } - } else { + } else if (d->forceCursorPosition != -1) { addSelectionAttribute(attributes); } @@ -492,17 +493,20 @@ void InputContext::commit(const QString &text, int replaceFrom, int replaceLengt Q_D(InputContext); VIRTUALKEYBOARD_DEBUG() << "InputContext::commit():" << text << replaceFrom << replaceLength; bool preeditChanged = !d->preeditText.isEmpty(); - d->preeditText.clear(); - d->preeditTextAttributes.clear(); if (d->inputContext) { QList<QInputMethodEvent::Attribute> attributes; addSelectionAttribute(attributes); + d->preeditText.clear(); + d->preeditTextAttributes.clear(); QInputMethodEvent inputEvent(QString(), attributes); inputEvent.setCommitString(text, replaceFrom, replaceLength); d->stateFlags |= InputContextPrivate::InputMethodEventState; d->inputContext->sendEvent(&inputEvent); d->stateFlags &= ~InputContextPrivate::InputMethodEventState; + } else { + d->preeditText.clear(); + d->preeditTextAttributes.clear(); } if (preeditChanged) @@ -831,6 +835,9 @@ void InputContext::invokeAction(QInputMethod::Action action, int cursorPosition) switch (action) { case QInputMethod::Click: if ((int)d->stateFlags == 0) { + if (d->inputEngine->clickPreeditText(cursorPosition)) + break; + bool reselect = !d->inputMethodHints.testFlag(Qt::ImhNoPredictiveText) && d->selectedText.isEmpty() && cursorPosition < d->preeditText.length(); if (reselect) { d->stateFlags |= InputContextPrivate::ReselectEventState; @@ -893,11 +900,23 @@ bool InputContext::filterEvent(const QEvent *event) void InputContext::addSelectionAttribute(QList<QInputMethodEvent::Attribute> &attributes) { Q_D(InputContext); - if (!testAttribute(attributes, QInputMethodEvent::Selection) && d->forceCursorPosition != -1) { - if (d->forceAnchorPosition != -1) - attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, d->forceAnchorPosition, d->forceCursorPosition - d->forceAnchorPosition, QVariant())); - else - attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, d->forceCursorPosition, 0, QVariant())); + if (!testAttribute(attributes, QInputMethodEvent::Selection)) { + // Convert Cursor attribute to Selection attribute. + // In this case the cursor is set in pre-edit text, but + // the cursor is not being forced to specific location. + if (d->forceCursorPosition == -1) { + int cursorAttributeIndex = findAttribute(d->preeditTextAttributes, QInputMethodEvent::Cursor); + if (cursorAttributeIndex != -1 && d->preeditTextAttributes[cursorAttributeIndex].length > 0) + d->forceCursorPosition = d->cursorPosition + d->preeditTextAttributes[cursorAttributeIndex].start; + d->forceAnchorPosition = -1; + } + + if (d->forceCursorPosition != -1) { + if (d->forceAnchorPosition != -1) + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, d->forceAnchorPosition, d->forceCursorPosition - d->forceAnchorPosition, QVariant())); + else + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, d->forceCursorPosition, 0, QVariant())); + } } d->forceAnchorPosition = -1; d->forceCursorPosition = -1; @@ -912,6 +931,16 @@ bool InputContext::testAttribute(const QList<QInputMethodEvent::Attribute> &attr return false; } +int InputContext::findAttribute(const QList<QInputMethodEvent::Attribute> &attributes, QInputMethodEvent::AttributeType attributeType) const +{ + const int count = attributes.count(); + for (int i = 0; i < count; ++i) { + if (attributes.at(i).type == attributeType) + return i; + } + return -1; +} + /*! \qmlproperty bool InputContext::focus |