aboutsummaryrefslogtreecommitdiffstats
path: root/src/virtualkeyboard/inputcontext.cpp
diff options
context:
space:
mode:
authorYuntaek Rim <yuntaek.rim@myscript.com>2018-01-17 22:59:43 +0200
committerMitch Curtis <mitch.curtis@qt.io>2018-08-16 08:44:47 +0000
commit00408414e38dd69186b7b39b3879a057079b6bb6 (patch)
treedfee460b2172b8c5fb7de098fa62174ff9be2a6e /src/virtualkeyboard/inputcontext.cpp
parent61385be34a2d4b09fd77f780295adb37d931a88d (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.cpp45
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