Skip to content

Commit

Permalink
Made TextInput mouse events commit preedit
Browse files Browse the repository at this point in the history
Similar to what was earlier done on QWidgets editors.
Additionally updated tests to check QInputPanel::invokeAction instead
of the obsolete QInputContext mouse handler.

Change-Id: Ia2bd22eebdeed79cff7a4925129b28dd1500b1ad
Reviewed-by: Joona Petrell <joona.t.petrell@nokia.com>
  • Loading branch information
Pekka Vuorela authored and Qt by Nokia committed Dec 1, 2011
1 parent ca00a4a commit b5f206e
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 140 deletions.
42 changes: 29 additions & 13 deletions src/declarative/items/qquicktextinput.cpp
Expand Up @@ -1084,9 +1084,9 @@ void QQuickTextInput::inputMethodEvent(QInputMethodEvent *ev)
void QQuickTextInput::mouseDoubleClickEvent(QMouseEvent *event)
{
Q_D(QQuickTextInput);
if (d->sendMouseEventToInputContext(event))
return;
if (d->selectByMouse) {

if (d->selectByMouse && event->button() == Qt::LeftButton) {
d->control->commitPreedit();
int cursor = d->xToPos(event->localPos().x());
d->control->selectWordAtPos(cursor);
event->setAccepted(true);
Expand All @@ -1095,15 +1095,18 @@ void QQuickTextInput::mouseDoubleClickEvent(QMouseEvent *event)
d->tripleClickTimer.start();
}
} else {
if (d->sendMouseEventToInputContext(event))
return;
QQuickImplicitSizeItem::mouseDoubleClickEvent(event);
}
}

void QQuickTextInput::mousePressEvent(QMouseEvent *event)
{
Q_D(QQuickTextInput);
if (d->sendMouseEventToInputContext(event))
return;

d->pressPos = event->localPos();

if (d->focusOnPress) {
bool hadActiveFocus = hasActiveFocus();
forceActiveFocus();
Expand All @@ -1114,7 +1117,6 @@ void QQuickTextInput::mousePressEvent(QMouseEvent *event)
if (d->selectByMouse) {
setKeepMouseGrab(false);
d->selectPressed = true;
d->pressPos = event->localPos();
QPoint distanceVector = d->pressPos.toPoint() - d->tripleClickStartPoint;
if (d->hasPendingTripleClick()
&& distanceVector.manhattanLength() < qApp->styleHints()->startDragDistance()) {
Expand All @@ -1123,6 +1125,10 @@ void QQuickTextInput::mousePressEvent(QMouseEvent *event)
return;
}
}

if (d->sendMouseEventToInputContext(event))
return;

bool mark = (event->modifiers() & Qt::ShiftModifier) && d->selectByMouse;
int cursor = d->xToPos(event->localPos().x());
d->control->moveCursor(cursor, mark);
Expand All @@ -1132,12 +1138,20 @@ void QQuickTextInput::mousePressEvent(QMouseEvent *event)
void QQuickTextInput::mouseMoveEvent(QMouseEvent *event)
{
Q_D(QQuickTextInput);
if (d->sendMouseEventToInputContext(event))
return;

if (d->selectPressed) {
if (qAbs(int(event->localPos().x() - d->pressPos.x())) > qApp->styleHints()->startDragDistance())
setKeepMouseGrab(true);
moveCursorSelection(d->xToPos(event->localPos().x()), d->mouseSelectionMode);

if (d->control->composeMode()) {
// start selection
int startPos = d->xToPos(d->pressPos.x());
int currentPos = d->xToPos(event->localPos().x());
if (startPos != currentPos)
d->control->setSelection(startPos, currentPos - startPos);
} else {
moveCursorSelection(d->xToPos(event->localPos().x()), d->mouseSelectionMode);
}
event->setAccepted(true);
} else {
QQuickImplicitSizeItem::mouseMoveEvent(event);
Expand All @@ -1161,13 +1175,15 @@ void QQuickTextInput::mouseReleaseEvent(QMouseEvent *event)
bool QQuickTextInputPrivate::sendMouseEventToInputContext(QMouseEvent *event)
{
#if !defined QT_NO_IM
if (control->composeMode() && event->type() == QEvent::MouseButtonRelease) {
if (control->composeMode()) {
int tmp_cursor = xToPos(event->localPos().x());
int mousePos = tmp_cursor - control->cursor();
// may be causing reset() in some input methods
qApp->inputPanel()->invokeAction(QInputPanel::Click, mousePos);
if (!control->preeditAreaText().isEmpty())
if (mousePos >= 0 && mousePos <= control->preeditAreaText().length()) {
if (event->type() == QEvent::MouseButtonRelease) {
qApp->inputPanel()->invokeAction(QInputPanel::Click, mousePos);
}
return true;
}
}
#else
Q_UNUSED(event);
Expand Down
55 changes: 25 additions & 30 deletions src/qtquick1/graphicsitems/qdeclarativetextinput.cpp
Expand Up @@ -1124,22 +1124,23 @@ Handles the given mouse \a event.
void QDeclarative1TextInput::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
Q_D(QDeclarative1TextInput);
if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonDblClick))
return;
if (d->selectByMouse) {
if (d->selectByMouse && event->button() == Qt::LeftButton) {
int cursor = d->xToPos(event->pos().x());
d->control->selectWordAtPos(cursor);
event->setAccepted(true);
} else {
if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonDblClick))
return;
QDeclarative1PaintedItem::mouseDoubleClickEvent(event);
}
}

void QDeclarative1TextInput::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
Q_D(QDeclarative1TextInput);
if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonPress))
return;

d->pressPos = event->pos();

if(d->focusOnPress){
bool hadActiveFocus = hasActiveFocus();
forceActiveFocus();
Expand All @@ -1157,8 +1158,10 @@ void QDeclarative1TextInput::mousePressEvent(QGraphicsSceneMouseEvent *event)
if (d->selectByMouse) {
setKeepMouseGrab(false);
d->selectPressed = true;
d->pressPos = event->pos();
}
if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonPress))
return;

bool mark = (event->modifiers() & Qt::ShiftModifier) && d->selectByMouse;
int cursor = d->xToPos(event->pos().x());
d->control->moveCursor(cursor, mark);
Expand All @@ -1168,12 +1171,20 @@ void QDeclarative1TextInput::mousePressEvent(QGraphicsSceneMouseEvent *event)
void QDeclarative1TextInput::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
Q_D(QDeclarative1TextInput);
if (d->sendMouseEventToInputContext(event, QEvent::MouseMove))
return;

if (d->selectPressed) {
if (qAbs(int(event->pos().x() - d->pressPos.x())) > QApplication::startDragDistance())
setKeepMouseGrab(true);
moveCursorSelection(d->xToPos(event->pos().x()), d->mouseSelectionMode);

if (d->control->composeMode()) {
// start selection
int startPos = d->xToPos(d->pressPos.x());
int currentPos = d->xToPos(event->pos().x());
if (startPos != currentPos)
d->control->setSelection(startPos, currentPos - startPos);
} else {
moveCursorSelection(d->xToPos(event->pos().x()), d->mouseSelectionMode);
}
event->setAccepted(true);
} else {
QDeclarative1PaintedItem::mouseMoveEvent(event);
Expand Down Expand Up @@ -1215,28 +1226,12 @@ bool QDeclarative1TextInputPrivate::sendMouseEventToInputContext(
if (event->widget() && control->composeMode()) {
int tmp_cursor = xToPos(event->pos().x());
int mousePos = tmp_cursor - control->cursor();
if (mousePos < 0 || mousePos > control->preeditAreaText().length()) {
mousePos = -1;
// don't send move events outside the preedit area
if (eventType == QEvent::MouseMove)
return true;
}

QInputContext *qic = event->widget()->inputContext();
if (qic) {
QMouseEvent mouseEvent(
eventType,
event->widget()->mapFromGlobal(event->screenPos()),
event->screenPos(),
event->button(),
event->buttons(),
event->modifiers());
// may be causing reset() in some input methods
qic->mouseHandler(mousePos, &mouseEvent);
event->setAccepted(mouseEvent.isAccepted());
}
if (!control->preeditAreaText().isEmpty())
if (mousePos >= 0 && mousePos <= control->preeditAreaText().length()) {
if (eventType == QEvent::MouseButtonRelease) {
qApp->inputPanel()->invokeAction(QInputPanel::Click, mousePos);
}
return true;
}
}
#else
Q_UNUSED(event);
Expand Down
64 changes: 60 additions & 4 deletions tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp
Expand Up @@ -41,6 +41,7 @@
#include <qtest.h>
#include <QtTest/QSignalSpy>
#include "../shared/util.h"
#include <private/qinputpanel_p.h>
#include <QtDeclarative/qdeclarativeengine.h>
#include <QFile>
#include <QtDeclarative/qquickview.h>
Expand Down Expand Up @@ -94,6 +95,7 @@ class tst_qquicktextinput : public QObject
private slots:
void initTestCase();
void cleanupTestCase();
void cleanup();
void text();
void width();
void font();
Expand Down Expand Up @@ -147,6 +149,7 @@ private slots:

void preeditAutoScroll();
void preeditCursorRectangle();
void inputContextMouseHandler();
void inputMethodComposing();
void cursorRectangleSize();

Expand Down Expand Up @@ -208,7 +211,7 @@ void tst_qquicktextinput::simulateKeys(QWindow *window, const QKeySequence &sequ

QList<Key> &operator <<(QList<Key> &keys, const QKeySequence &sequence)
{
for (int i = 0; i < sequence.count(); ++i)
for (uint i = 0; i < sequence.count(); ++i)
keys << Key(sequence[i], QChar());
return keys;
}
Expand All @@ -235,8 +238,15 @@ void tst_qquicktextinput::initTestCase()

void tst_qquicktextinput::cleanupTestCase()
{
}

void tst_qquicktextinput::cleanup()
{
// ensure not even skipped tests with custom input context leave it dangling
QInputPanelPrivate *inputPanelPrivate = QInputPanelPrivate::get(qApp->inputPanel());
inputPanelPrivate->testContext = 0;
}

tst_qquicktextinput::tst_qquicktextinput()
{
standard << "the quick brown fox jumped over the lazy dog"
Expand Down Expand Up @@ -2185,7 +2195,11 @@ void tst_qquicktextinput::simulateKey(QQuickView *view, int key)
class PlatformInputContext : public QPlatformInputContext
{
public:
PlatformInputContext() : m_visible(false) {}
PlatformInputContext()
: m_visible(false), m_action(QInputPanel::Click), m_cursorPosition(0),
m_invokeActionCallCount(0)
{
}

virtual void showInputPanel()
{
Expand All @@ -2199,8 +2213,17 @@ class PlatformInputContext : public QPlatformInputContext
{
return m_visible;
}
virtual void invokeAction(QInputPanel::Action action, int cursorPosition)
{
m_invokeActionCallCount++;
m_action = action;
m_cursorPosition = cursorPosition;
}

bool m_visible;
QInputPanel::Action m_action;
int m_cursorPosition;
int m_invokeActionCallCount;
};

void tst_qquicktextinput::openInputPanel()
Expand Down Expand Up @@ -2292,8 +2315,6 @@ void tst_qquicktextinput::openInputPanel()
// input panel should close when closeSoftwareInputPanel is called
input->closeSoftwareInputPanel();
QCOMPARE(qApp->inputPanel()->visible(), false);

inputPanelPrivate->testContext = 0;
}

class MyTextInput : public QQuickTextInput
Expand Down Expand Up @@ -2545,6 +2566,41 @@ void tst_qquicktextinput::preeditCursorRectangle()
QVERIFY(panelSpy.count() > 0);
}

void tst_qquicktextinput::inputContextMouseHandler()
{
PlatformInputContext platformInputContext;
QInputPanelPrivate *inputPanelPrivate = QInputPanelPrivate::get(qApp->inputPanel());
inputPanelPrivate->testContext = &platformInputContext;

QString text = "supercalifragisiticexpialidocious!";
QQuickView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml")));
QQuickTextInput *input = qobject_cast<QQuickTextInput *>(view.rootObject());
QVERIFY(input);

input->setFocus(true);
input->setText("");

view.show();
view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
QTRY_COMPARE(&view, qGuiApp->focusWindow());

QFontMetricsF fm(input->font());
const qreal y = fm.height() / 2;
QPoint position = QPointF(fm.width(text.mid(0, 2)), y).toPoint();

QInputMethodEvent inputEvent(text.mid(0, 5), QList<QInputMethodEvent::Attribute>());
QApplication::sendEvent(input, &inputEvent);

QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, position);
QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, position);
QGuiApplication::processEvents();

QCOMPARE(platformInputContext.m_action, QInputPanel::Click);
QCOMPARE(platformInputContext.m_invokeActionCallCount, 1);
QCOMPARE(platformInputContext.m_cursorPosition, 2);
}

void tst_qquicktextinput::inputMethodComposing()
{
QString text = "supercalifragisiticexpialidocious!";
Expand Down

0 comments on commit b5f206e

Please sign in to comment.