summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@digia.com>2014-01-20 12:30:35 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-15 10:38:35 +0100
commitf8dbed12266c42785c1e4758eed05833ec035f33 (patch)
tree85067c8722cfc3854d9e22845fcd633f06cb4422 /src
parent25e7fe16504ad4784ea2d75204ffa855ca6d3e1b (diff)
Extending the inputMethodQuery API
Currently, inputMethodQuery() only provides information about the current paragraph. On some platforms, such as Android, the input method needs information about the global cursor position, and more of the surrounding text. Some queries need to pass parameters. The current inputmethodQuery() implementation does not allow parameters to be passed. Changing this would require new or modified virtual functions, which is not possible until Qt 6. Therefore, a completely new mechanism is needed. Change-Id: Ic64fd90198ade70aa0fa6fa5ad3867dfa7ed763c Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qnamespace.h4
-rw-r--r--src/corelib/global/qnamespace.qdoc5
-rw-r--r--src/gui/kernel/qinputmethod.cpp25
-rw-r--r--src/gui/kernel/qinputmethod.h3
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp2
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp2
-rw-r--r--src/widgets/widgets/qtextedit.cpp13
-rw-r--r--src/widgets/widgets/qtextedit.h1
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp43
-rw-r--r--src/widgets/widgets/qwidgettextcontrol_p.h2
10 files changed, 93 insertions, 7 deletions
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 9d9972f7d1..d7ae97e911 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -1332,6 +1332,10 @@ public:
ImHints = 0x100,
ImPreferredLanguage = 0x200,
+ ImAbsolutePosition = 0x400,
+ ImTextBeforeCursor = 0x800,
+ ImTextAfterCursor = 0x1000,
+
ImPlatformData = 0x80000000,
ImQueryInput = ImCursorRectangle | ImCursorPosition | ImSurroundingText |
ImCurrentSelection | ImAnchorPosition,
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index dc5552d848..31bc18749b 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -2446,6 +2446,11 @@
\value ImHints The hints for input method on expected input. (See Qt::InputMethodHints)
\value ImPreferredLanguage The preferred input language.
\value ImPlatformData Platform specific data for input method.
+ \value ImAbsolutePosition The logical position of the cursor within the entire document.
+ \value ImTextBeforeCursor The plain text before the cursor. The widget can decide how much text to return,
+ but \b{must} not return an empty string unless the cursor is at the start of the document.
+ \value ImTextAfterCursor The plain text after the cursor. The widget can decide how much text to return,
+ but \b{must} not return an empty string unless the cursor is at the end of the document.
Masks:
diff --git a/src/gui/kernel/qinputmethod.cpp b/src/gui/kernel/qinputmethod.cpp
index 438c169f71..495ea8f6e7 100644
--- a/src/gui/kernel/qinputmethod.cpp
+++ b/src/gui/kernel/qinputmethod.cpp
@@ -45,6 +45,8 @@
#include <qtimer.h>
#include <qpa/qplatforminputcontext_p.h>
+#include <QDebug>
+
QT_BEGIN_NAMESPACE
/*!
@@ -365,6 +367,29 @@ bool QInputMethodPrivate::objectAcceptsInputMethod(QObject *object)
return enabled;
}
+/*!
+ Send \a query to the current focus object with parameters \a argument and return the result.
+ */
+QVariant QInputMethod::queryFocusObject(Qt::InputMethodQuery query, QVariant argument)
+{
+ QVariant retval;
+ QObject *focusObject = qGuiApp->focusObject();
+ if (!focusObject)
+ return retval;
+
+ bool newMethodWorks = QMetaObject::invokeMethod(focusObject, "inputMethodQuery",
+ Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, retval),
+ Q_ARG(Qt::InputMethodQuery, query),
+ Q_ARG(QVariant, argument));
+ if (newMethodWorks)
+ return retval;
+
+ QInputMethodQueryEvent queryEvent(query);
+ QCoreApplication::sendEvent(focusObject, &queryEvent);
+ return queryEvent.value(query);
+}
+
QT_END_NAMESPACE
#include "moc_qinputmethod.cpp"
diff --git a/src/gui/kernel/qinputmethod.h b/src/gui/kernel/qinputmethod.h
index fe6cc3f331..b155b5c0ca 100644
--- a/src/gui/kernel/qinputmethod.h
+++ b/src/gui/kernel/qinputmethod.h
@@ -50,6 +50,7 @@ class QInputMethodPrivate;
class QWindow;
class QRectF;
class QTransform;
+class QInputMethodQueryEvent;
class Q_GUI_EXPORT QInputMethod : public QObject
{
@@ -89,6 +90,8 @@ public:
QLocale locale() const;
Qt::LayoutDirection inputDirection() const;
+ static QVariant queryFocusObject(Qt::InputMethodQuery query, QVariant argument);
+
public Q_SLOTS:
void show();
void hide();
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index 2d07e545c8..ae2423400a 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -10316,7 +10316,7 @@ QVariant QGraphicsTextItem::inputMethodQuery(Qt::InputMethodQuery query) const
if (query == Qt::ImHints)
v = int(inputMethodHints());
else if (dd->control)
- v = dd->control->inputMethodQuery(query);
+ v = dd->control->inputMethodQuery(query, QVariant());
if (v.type() == QVariant::RectF)
v = v.toRectF().translated(-dd->controlOffset());
else if (v.type() == QVariant::PointF)
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index 89374b1c41..d51dce4765 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -2192,7 +2192,7 @@ QVariant QPlainTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
v = QWidget::inputMethodQuery(property);
break;
default:
- v = d->control->inputMethodQuery(property);
+ v = d->control->inputMethodQuery(property, QVariant());
const QPoint offset(-d->horizontalOffset(), -0);
if (v.type() == QVariant::RectF)
v = v.toRectF().toRect().translated(offset);
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index cc7b44d082..a33ac0817f 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -1717,14 +1717,21 @@ void QTextEdit::scrollContentsBy(int dx, int dy)
*/
QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
{
+ return inputMethodQuery(property, QVariant());
+}
+
+/*!\internal
+ */
+QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const
+{
Q_D(const QTextEdit);
QVariant v;
- switch (property) {
+ switch (query) {
case Qt::ImHints:
- v = QWidget::inputMethodQuery(property);
+ v = QWidget::inputMethodQuery(query);
break;
default:
- v = d->control->inputMethodQuery(property);
+ v = d->control->inputMethodQuery(query, argument);
const QPoint offset(-d->horizontalOffset(), -d->verticalOffset());
if (v.type() == QVariant::RectF)
v = v.toRectF().toRect().translated(offset);
diff --git a/src/widgets/widgets/qtextedit.h b/src/widgets/widgets/qtextedit.h
index 406d8b2c4b..a283a51b90 100644
--- a/src/widgets/widgets/qtextedit.h
+++ b/src/widgets/widgets/qtextedit.h
@@ -212,6 +212,7 @@ public:
void print(QPagedPaintDevice *printer) const;
QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
+ Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const;
public Q_SLOTS:
void setFontPointSize(qreal s);
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index 06b513f3e0..98f85e681b 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -2024,7 +2024,7 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
emit q->microFocusChanged();
}
-QVariant QWidgetTextControl::inputMethodQuery(Qt::InputMethodQuery property) const
+QVariant QWidgetTextControl::inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const
{
Q_D(const QWidgetTextControl);
QTextBlock block = d->cursor.block();
@@ -2043,6 +2043,47 @@ QVariant QWidgetTextControl::inputMethodQuery(Qt::InputMethodQuery property) con
return QVariant(); // No limit.
case Qt::ImAnchorPosition:
return QVariant(d->cursor.anchor() - block.position());
+ case Qt::ImAbsolutePosition:
+ return QVariant(d->cursor.position());
+ case Qt::ImTextAfterCursor:
+ {
+ int maxLength = argument.isValid() ? argument.toInt() : 1024;
+ QTextCursor tmpCursor = d->cursor;
+ int localPos = d->cursor.position() - block.position();
+ QString result = block.text().mid(localPos);
+ while (result.length() < maxLength) {
+ int currentBlock = tmpCursor.blockNumber();
+ tmpCursor.movePosition(QTextCursor::NextBlock);
+ if (tmpCursor.blockNumber() == currentBlock)
+ break;
+ result += QLatin1Char('\n') + tmpCursor.block().text();
+ }
+ return QVariant(result);
+ }
+ case Qt::ImTextBeforeCursor:
+ {
+ int maxLength = argument.isValid() ? argument.toInt() : 1024;
+ QTextCursor tmpCursor = d->cursor;
+ int localPos = d->cursor.position() - block.position();
+ int numBlocks = 0;
+ int resultLen = localPos;
+ while (resultLen < maxLength) {
+ int currentBlock = tmpCursor.blockNumber();
+ tmpCursor.movePosition(QTextCursor::PreviousBlock);
+ if (tmpCursor.blockNumber() == currentBlock)
+ break;
+ numBlocks++;
+ resultLen += tmpCursor.block().length();
+ }
+ QString result;
+ while (numBlocks) {
+ result += tmpCursor.block().text() + QLatin1Char('\n');
+ tmpCursor.movePosition(QTextCursor::NextBlock);
+ --numBlocks;
+ }
+ result += block.text().mid(0,localPos);
+ return QVariant(result);
+ }
default:
return QVariant();
}
diff --git a/src/widgets/widgets/qwidgettextcontrol_p.h b/src/widgets/widgets/qwidgettextcontrol_p.h
index 847371e194..0c76355ca1 100644
--- a/src/widgets/widgets/qwidgettextcontrol_p.h
+++ b/src/widgets/widgets/qwidgettextcontrol_p.h
@@ -239,7 +239,7 @@ public:
void setFocus(bool focus, Qt::FocusReason = Qt::OtherFocusReason);
- virtual QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
+ virtual QVariant inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const;
virtual QMimeData *createMimeDataFromSelection() const;
virtual bool canInsertFromMimeData(const QMimeData *source) const;