diff options
author | Andrew den Exter <andrew.den-exter@nokia.com> | 2011-02-14 08:00:15 (GMT) |
---|---|---|
committer | Andrew den Exter <andrew.den-exter@nokia.com> | 2011-02-21 03:02:21 (GMT) |
commit | 521a9bba59fe198ec7b1afe9bb25a9d3334675cf (patch) | |
tree | 146e3433f401bf642ae29e773ceec50c4203c3ea /src | |
parent | f141b42b87e0835552c85dbfd1ccce950da5aee3 (diff) | |
download | Qt-521a9bba59fe198ec7b1afe9bb25a9d3334675cf.zip Qt-521a9bba59fe198ec7b1afe9bb25a9d3334675cf.tar.gz Qt-521a9bba59fe198ec7b1afe9bb25a9d3334675cf.tar.bz2 |
Forward mouse events from TextInput and TextEdit to QInputContext.
This brings TextInput in line with QLineEdit. The fix for TextEdit
applies equally to QTextEdit.
Change-Id: I5c47e5c8e951ee53cb1fe45d9c302050cd19deef
Task-number: QTBUG-15705
Reviewed-by: axis
Diffstat (limited to 'src')
-rw-r--r-- | src/declarative/graphicsitems/qdeclarativetextedit.cpp | 36 | ||||
-rw-r--r-- | src/declarative/graphicsitems/qdeclarativetextinput.cpp | 47 | ||||
-rw-r--r-- | src/declarative/graphicsitems/qdeclarativetextinput_p_p.h | 1 | ||||
-rw-r--r-- | src/gui/text/qtextcontrol.cpp | 120 | ||||
-rw-r--r-- | src/gui/text/qtextcontrol_p_p.h | 20 |
5 files changed, 163 insertions, 61 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index 87a49bd..2946f6e 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -975,6 +975,10 @@ void QDeclarativeTextEdit::setSelectByMouse(bool on) if (d->selectByMouse != on) { d->selectByMouse = on; setKeepMouseGrab(on); + if (on) + setTextInteractionFlags(d->control->textInteractionFlags() | Qt::TextSelectableByMouse); + else + setTextInteractionFlags(d->control->textInteractionFlags() & ~Qt::TextSelectableByMouse); emit selectByMouseChanged(on); } } @@ -1027,11 +1031,10 @@ void QDeclarativeTextEdit::setReadOnly(bool r) setFlag(QGraphicsItem::ItemAcceptsInputMethod, !r); Qt::TextInteractionFlags flags = Qt::LinksAccessibleByMouse; - if (r) { + if (d->selectByMouse) flags = flags | Qt::TextSelectableByMouse; - } else { - flags = flags | Qt::TextEditorInteraction; - } + if (!r) + flags = flags | Qt::TextSelectableByKeyboard | Qt::TextEditable; d->control->setTextInteractionFlags(flags); if (!r) d->control->moveCursor(QTextCursor::End); @@ -1249,8 +1252,8 @@ void QDeclarativeTextEdit::mousePressEvent(QGraphicsSceneMouseEvent *event) } } } - if (event->type() != QEvent::GraphicsSceneMouseDoubleClick || d->selectByMouse) - d->control->processEvent(event, QPointF(0, -d->yoff)); + + d->control->processEvent(event, QPointF(0, -d->yoff)); if (!event->isAccepted()) QDeclarativePaintedItem::mousePressEvent(event); } @@ -1285,13 +1288,11 @@ Handles the given mouse \a event. void QDeclarativeTextEdit::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextEdit); - if (d->selectByMouse) { - d->control->processEvent(event, QPointF(0, -d->yoff)); - if (!event->isAccepted()) - QDeclarativePaintedItem::mouseDoubleClickEvent(event); - } else { + + d->control->processEvent(event, QPointF(0, -d->yoff)); + if (!event->isAccepted()) QDeclarativePaintedItem::mouseDoubleClickEvent(event); - } + } /*! @@ -1301,14 +1302,9 @@ Handles the given mouse \a event. void QDeclarativeTextEdit::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextEdit); - if (d->selectByMouse) { - d->control->processEvent(event, QPointF(0, -d->yoff)); - if (!event->isAccepted()) - QDeclarativePaintedItem::mouseMoveEvent(event); - event->setAccepted(true); - } else { + d->control->processEvent(event, QPointF(0, -d->yoff)); + if (!event->isAccepted()) QDeclarativePaintedItem::mouseMoveEvent(event); - } } /*! @@ -1407,7 +1403,7 @@ void QDeclarativeTextEditPrivate::init() control = new QTextControl(q); control->setIgnoreUnusedNavigationEvents(true); - control->setTextInteractionFlags(control->textInteractionFlags() | Qt::LinksAccessibleByMouse); + control->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard | Qt::TextEditable); control->setDragEnabled(false); // QTextControl follows the default text color diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index e7c2ac7..bfcd715 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -51,6 +51,7 @@ #include <QFontMetrics> #include <QPainter> #include <QTextBoundaryFinder> +#include <QInputContext> #include <qstyle.h> #ifndef QT_NO_LINEEDIT @@ -1002,6 +1003,8 @@ Handles the given mouse \a event. void QDeclarativeTextInput::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextInput); + if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonDblClick)) + return; if (d->selectByMouse) { int cursor = d->xToPos(event->pos().x()); d->control->selectWordAtPos(cursor); @@ -1014,6 +1017,8 @@ void QDeclarativeTextInput::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *even void QDeclarativeTextInput::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextInput); + if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonPress)) + return; if(d->focusOnPress){ bool hadActiveFocus = hasActiveFocus(); forceActiveFocus(); @@ -1041,6 +1046,8 @@ void QDeclarativeTextInput::mousePressEvent(QGraphicsSceneMouseEvent *event) void QDeclarativeTextInput::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextInput); + if (d->sendMouseEventToInputContext(event, QEvent::MouseMove)) + event->setAccepted(true); if (d->selectByMouse) { if (qAbs(int(event->pos().x() - d->pressPos.x())) > QApplication::startDragDistance()) setKeepMouseGrab(true); @@ -1058,6 +1065,8 @@ Handles the given mouse \a event. void QDeclarativeTextInput::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextInput); + if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonRelease)) + return; if (d->selectByMouse) setKeepMouseGrab(false); if (!d->showInputPanelOnFocus) { // input panel on click @@ -1075,6 +1084,44 @@ void QDeclarativeTextInput::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QDeclarativePaintedItem::mouseReleaseEvent(event); } +bool QDeclarativeTextInputPrivate::sendMouseEventToInputContext( + QGraphicsSceneMouseEvent *event, QEvent::Type eventType) +{ +#if !defined QT_NO_IM + 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()) + return true; + } +#else + Q_UNUSED(event); + Q_UNUSED(eventType) +#endif + + return false; +} + bool QDeclarativeTextInput::sceneEvent(QEvent *event) { bool rv = QDeclarativeItem::sceneEvent(event); diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h index f7446b4..ab2838b 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h @@ -104,6 +104,7 @@ public: void focusChanged(bool hasFocus); void updateHorizontalScroll(); int calculateTextWidth(); + bool sendMouseEventToInputContext(QGraphicsSceneMouseEvent *event, QEvent::Type eventType); QLineControl* control; diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index e380b37..b25588d 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -932,15 +932,18 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte break; } case QEvent::MouseMove: { QMouseEvent *ev = static_cast<QMouseEvent *>(e); - d->mouseMoveEvent(ev->buttons(), matrix.map(ev->pos())); + d->mouseMoveEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), + ev->buttons(), ev->globalPos()); break; } case QEvent::MouseButtonRelease: { QMouseEvent *ev = static_cast<QMouseEvent *>(e); - d->mouseReleaseEvent(ev->button(), matrix.map(ev->pos())); + d->mouseReleaseEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), + ev->buttons(), ev->globalPos()); break; } case QEvent::MouseButtonDblClick: { QMouseEvent *ev = static_cast<QMouseEvent *>(e); - d->mouseDoubleClickEvent(e, ev->button(), matrix.map(ev->pos())); + d->mouseDoubleClickEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), + ev->buttons(), ev->globalPos()); break; } case QEvent::InputMethod: d->inputMethodEvent(static_cast<QInputMethodEvent *>(e)); @@ -1000,15 +1003,18 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte break; } case QEvent::GraphicsSceneMouseMove: { QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e); - d->mouseMoveEvent(ev->buttons(), matrix.map(ev->pos())); + d->mouseMoveEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(), + ev->screenPos()); break; } case QEvent::GraphicsSceneMouseRelease: { QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e); - d->mouseReleaseEvent(ev->button(), matrix.map(ev->pos())); + d->mouseReleaseEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(), + ev->screenPos()); break; } case QEvent::GraphicsSceneMouseDoubleClick: { QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e); - d->mouseDoubleClickEvent(e, ev->button(), matrix.map(ev->pos())); + d->mouseDoubleClickEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(), + ev->screenPos()); break; } case QEvent::GraphicsSceneContextMenu: { QGraphicsSceneContextMenuEvent *ev = static_cast<QGraphicsSceneContextMenuEvent *>(e); @@ -1017,7 +1023,8 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte case QEvent::GraphicsSceneHoverMove: { QGraphicsSceneHoverEvent *ev = static_cast<QGraphicsSceneHoverEvent *>(e); - d->mouseMoveEvent(Qt::NoButton, matrix.map(ev->pos())); + d->mouseMoveEvent(ev, Qt::NoButton, matrix.map(ev->pos()), ev->modifiers(),Qt::NoButton, + ev->screenPos()); break; } case QEvent::GraphicsSceneDragEnter: { @@ -1487,6 +1494,11 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con { Q_Q(QTextControl); + if (sendMouseEventToInputContext( + e, QEvent::MouseButtonPress, button, pos, modifiers, buttons, globalPos)) { + return; + } + if (interactionFlags & Qt::LinksAccessibleByMouse) { anchorOnMousePress = q->anchorAt(pos); @@ -1529,22 +1541,7 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con return; } -#if !defined(QT_NO_IM) - QTextLayout *layout = cursor.block().layout(); - if (contextWidget && layout && !layout->preeditAreaText().isEmpty()) { - QInputContext *ctx = inputContext(); - if (ctx) { - QMouseEvent ev(QEvent::MouseButtonPress, contextWidget->mapFromGlobal(globalPos), globalPos, - button, buttons, modifiers); - ctx->mouseHandler(cursorPos - cursor.position(), &ev); - } - if (!layout->preeditAreaText().isEmpty()) { - e->ignore(); - return; - } - } -#endif - if (modifiers == Qt::ShiftModifier) { + if (modifiers == Qt::ShiftModifier && (interactionFlags & Qt::TextSelectableByMouse)) { if (wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) { selectedWordOnDoubleClick = cursor; selectedWordOnDoubleClick.select(QTextCursor::WordUnderCursor); @@ -1589,10 +1586,16 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con hadSelectionOnMousePress = cursor.hasSelection(); } -void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF &mousePos) +void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, const QPointF &mousePos, Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, const QPoint &globalPos) { Q_Q(QTextControl); + if (sendMouseEventToInputContext( + e, QEvent::MouseMove, button, mousePos, modifiers, buttons, globalPos)) { + return; + } + if (interactionFlags & Qt::LinksAccessibleByMouse) { QString anchor = q->anchorAt(mousePos); if (anchor != highlightedAnchor) { @@ -1622,12 +1625,6 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF } const qreal mouseX = qreal(mousePos.x()); -#if !defined(QT_NO_IM) - QTextLayout *layout = cursor.block().layout(); - if (layout && !layout->preeditAreaText().isEmpty()) - return; -#endif - int newCursorPos = q->hitTest(mousePos, Qt::FuzzyHit); if (newCursorPos == -1) return; @@ -1641,7 +1638,7 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF extendBlockwiseSelection(newCursorPos); else if (selectedWordOnDoubleClick.hasSelection()) extendWordwiseSelection(newCursorPos, mouseX); - else + else if (interactionFlags & Qt::TextSelectableByMouse) setCursorPosition(newCursorPos, QTextCursor::KeepAnchor); if (interactionFlags & Qt::TextEditable) { @@ -1665,10 +1662,16 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF repaintOldAndNewSelection(oldSelection); } -void QTextControlPrivate::mouseReleaseEvent(Qt::MouseButton button, const QPointF &pos) +void QTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, const QPoint &globalPos) { Q_Q(QTextControl); + if (sendMouseEventToInputContext( + e, QEvent::MouseButtonRelease, button, pos, modifiers, buttons, globalPos)) { + return; + } + const QTextCursor oldSelection = cursor; const int oldCursorPos = cursor.position(); @@ -1726,19 +1729,21 @@ void QTextControlPrivate::mouseReleaseEvent(Qt::MouseButton button, const QPoint } } -void QTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos) +void QTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, const QPoint &globalPos) { Q_Q(QTextControl); + + if (sendMouseEventToInputContext( + e, QEvent::MouseButtonDblClick, button, pos, modifiers, buttons, globalPos)) { + return; + } + if (button != Qt::LeftButton || !(interactionFlags & Qt::TextSelectableByMouse)) { e->ignore(); return; } -#if !defined(QT_NO_IM) - QTextLayout *layout = cursor.block().layout(); - if (layout && !layout->preeditAreaText().isEmpty()) - return; -#endif #ifndef QT_NO_DRAGANDDROP mightStartDrag = false; @@ -1767,6 +1772,45 @@ void QTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton butto } } +bool QTextControlPrivate::sendMouseEventToInputContext( + QEvent *e, QEvent::Type eventType, Qt::MouseButton button, const QPointF &pos, + Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, const QPoint &globalPos) +{ +#if !defined(QT_NO_IM) + Q_Q(QTextControl); + + QTextLayout *layout = cursor.block().layout(); + if (contextWidget && layout && !layout->preeditAreaText().isEmpty()) { + QInputContext *ctx = inputContext(); + int cursorPos = q->hitTest(pos, Qt::FuzzyHit) - cursor.position(); + + if (cursorPos < 0 || cursorPos > layout->preeditAreaText().length()) { + cursorPos = -1; + // don't send move events outside the preedit area + if (eventType == QEvent::MouseMove) + return true; + } + if (ctx) { + QMouseEvent ev(eventType, contextWidget->mapFromGlobal(globalPos), globalPos, + button, buttons, modifiers); + ctx->mouseHandler(cursorPos, &ev); + e->setAccepted(ev.isAccepted()); + } + if (!layout->preeditAreaText().isEmpty()) + return true; + } +#else + Q_UNUSED(e); + Q_UNUSED(eventType); + Q_UNUSED(button); + Q_UNUSED(pos); + Q_UNUSED(modifiers); + Q_UNUSED(buttons); + Q_UNUSED(globalPos); +#endif + return false; +} + void QTextControlPrivate::contextMenuEvent(const QPoint &screenPos, const QPointF &docPos, QWidget *contextWidget) { #ifdef QT_NO_CONTEXTMENU diff --git a/src/gui/text/qtextcontrol_p_p.h b/src/gui/text/qtextcontrol_p_p.h index ecd13ea..94670e2 100644 --- a/src/gui/text/qtextcontrol_p_p.h +++ b/src/gui/text/qtextcontrol_p_p.h @@ -135,9 +135,23 @@ public: Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, const QPoint &globalPos); - void mouseMoveEvent(Qt::MouseButtons buttons, const QPointF &pos); - void mouseReleaseEvent(Qt::MouseButton button, const QPointF &pos); - void mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos); + void mouseMoveEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, + Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, + const QPoint &globalPos); + void mouseReleaseEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, + Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, + const QPoint &globalPos); + void mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, + Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, + const QPoint &globalPos); + bool sendMouseEventToInputContext(QEvent *e, QEvent::Type eventType, Qt::MouseButton button, + const QPointF &pos, + Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, + const QPoint &globalPos); void contextMenuEvent(const QPoint &screenPos, const QPointF &docPos, QWidget *contextWidget); void focusEvent(QFocusEvent *e); #ifdef QT_KEYPAD_NAVIGATION |