summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets/qwidgettextcontrol.cpp
diff options
context:
space:
mode:
authorPekka Vuorela <pekka.ta.vuorela@nokia.com>2011-10-07 13:48:29 +0300
committerQt by Nokia <qt-info@nokia.com>2011-11-05 22:10:52 +0100
commit4b3d88a9c67402b6a234d597bab25846f039bbdb (patch)
tree143f07bd13d06f06ae1fb2c6100c91f0c61becee /src/widgets/widgets/qwidgettextcontrol.cpp
parent15d25dc6763427414b96a5ecd739d0e9ee047456 (diff)
QTextEdit - mouse events to override input context
- Selection can start on top of preedit - Mouse press outside preedit commits - Double click to commit on top of preedit Change-Id: Ia2698d97d354a677d935de1a8fd9ed53a161ca5e Reviewed-by: Joona Petrell <joona.t.petrell@nokia.com> Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Diffstat (limited to 'src/widgets/widgets/qwidgettextcontrol.cpp')
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp217
1 files changed, 118 insertions, 99 deletions
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index c645955a8c..d48ee9a2ae 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -1506,6 +1506,13 @@ void QWidgetTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton butto
{
Q_Q(QWidgetTextControl);
+ mousePressed = (interactionFlags & Qt::TextSelectableByMouse);
+ mousePressPos = pos.toPoint();
+
+#ifndef QT_NO_DRAGANDDROP
+ mightStartDrag = false;
+#endif
+
if (sendMouseEventToInputContext(
e, QEvent::MouseButtonPress, button, pos, modifiers, buttons, globalPos)) {
return;
@@ -1530,10 +1537,8 @@ void QWidgetTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton butto
const QTextCursor oldSelection = cursor;
const int oldCursorPos = cursor.position();
- mousePressed = (interactionFlags & Qt::TextSelectableByMouse);
-#ifndef QT_NO_DRAGANDDROP
- mightStartDrag = false;
-#endif
+ if (isPreediting())
+ qApp->inputPanel()->commit();
if (trippleClickTimer.isActive()
&& ((pos - trippleClickPoint).toPoint().manhattanLength() < QApplication::startDragDistance())) {
@@ -1575,7 +1580,6 @@ void QWidgetTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton butto
&& q->hitTest(pos, Qt::ExactHit) != -1) {
#ifndef QT_NO_DRAGANDDROP
mightStartDrag = true;
- dragStartPos = pos.toPoint();
#endif
return;
}
@@ -1605,11 +1609,6 @@ void QWidgetTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button
{
Q_Q(QWidgetTextControl);
- if (sendMouseEventToInputContext(
- e, QEvent::MouseMove, button, mousePos, modifiers, buttons, globalPos)) {
- return;
- }
-
if (interactionFlags & Qt::LinksAccessibleByMouse) {
QString anchor = q->anchorAt(mousePos);
if (anchor != highlightedAnchor) {
@@ -1618,69 +1617,84 @@ void QWidgetTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button
}
}
- if (!(buttons & Qt::LeftButton))
- return;
+ if (buttons & Qt::LeftButton) {
+ const bool editable = interactionFlags & Qt::TextEditable;
- const bool editable = interactionFlags & Qt::TextEditable;
+ if (!(mousePressed
+ || editable
+ || mightStartDrag
+ || selectedWordOnDoubleClick.hasSelection()
+ || selectedBlockOnTrippleClick.hasSelection()))
+ return;
- if (!(mousePressed
- || editable
- || mightStartDrag
- || selectedWordOnDoubleClick.hasSelection()
- || selectedBlockOnTrippleClick.hasSelection()))
- return;
+ const QTextCursor oldSelection = cursor;
+ const int oldCursorPos = cursor.position();
- const QTextCursor oldSelection = cursor;
- const int oldCursorPos = cursor.position();
+ if (mightStartDrag) {
+ if ((mousePos.toPoint() - mousePressPos).manhattanLength() > QApplication::startDragDistance())
+ startDrag();
+ return;
+ }
- if (mightStartDrag) {
- if ((mousePos.toPoint() - dragStartPos).manhattanLength() > QApplication::startDragDistance())
- startDrag();
- return;
- }
+ if (!mousePressed)
+ return;
- if (!mousePressed)
- return;
+ const qreal mouseX = qreal(mousePos.x());
- const qreal mouseX = qreal(mousePos.x());
+ int newCursorPos = q->hitTest(mousePos, Qt::FuzzyHit);
- int newCursorPos = q->hitTest(mousePos, Qt::FuzzyHit);
- if (newCursorPos == -1)
- return;
+ if (isPreediting()) {
+ // note: oldCursorPos not including preedit
+ int selectionStartPos = q->hitTest(mousePressPos, Qt::FuzzyHit);
- if (wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) {
- selectedWordOnDoubleClick = cursor;
- selectedWordOnDoubleClick.select(QTextCursor::WordUnderCursor);
- }
+ if (newCursorPos != selectionStartPos) {
+ qApp->inputPanel()->commit();
+ // commit invalidates positions
+ newCursorPos = q->hitTest(mousePos, Qt::FuzzyHit);
+ selectionStartPos = q->hitTest(mousePressPos, Qt::FuzzyHit);
+ setCursorPosition(selectionStartPos);
+ }
+ }
- if (selectedBlockOnTrippleClick.hasSelection())
- extendBlockwiseSelection(newCursorPos);
- else if (selectedWordOnDoubleClick.hasSelection())
- extendWordwiseSelection(newCursorPos, mouseX);
- else
- setCursorPosition(newCursorPos, QTextCursor::KeepAnchor);
+ if (newCursorPos == -1)
+ return;
- if (interactionFlags & Qt::TextEditable) {
- // don't call ensureVisible for the visible cursor to avoid jumping
- // scrollbars. the autoscrolling ensures smooth scrolling if necessary.
- //q->ensureCursorVisible();
- if (cursor.position() != oldCursorPos)
- emit q->cursorPositionChanged();
- _q_updateCurrentCharFormatAndSelection();
+ if (wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) {
+ selectedWordOnDoubleClick = cursor;
+ selectedWordOnDoubleClick.select(QTextCursor::WordUnderCursor);
+ }
+
+ if (selectedBlockOnTrippleClick.hasSelection())
+ extendBlockwiseSelection(newCursorPos);
+ else if (selectedWordOnDoubleClick.hasSelection())
+ extendWordwiseSelection(newCursorPos, mouseX);
+ else if (!isPreediting())
+ setCursorPosition(newCursorPos, QTextCursor::KeepAnchor);
+
+ if (interactionFlags & Qt::TextEditable) {
+ // don't call ensureVisible for the visible cursor to avoid jumping
+ // scrollbars. the autoscrolling ensures smooth scrolling if necessary.
+ //q->ensureCursorVisible();
+ if (cursor.position() != oldCursorPos)
+ emit q->cursorPositionChanged();
+ _q_updateCurrentCharFormatAndSelection();
#ifndef QT_NO_IM
- if (contextWidget) {
- if (QInputContext *ic = qApp->inputContext()) {
- ic->update();
+ if (contextWidget) {
+ if (QInputContext *ic = qApp->inputContext()) {
+ ic->update();
+ }
}
- }
#endif //QT_NO_IM
- } else {
- //emit q->visibilityRequest(QRectF(mousePos, QSizeF(1, 1)));
- if (cursor.position() != oldCursorPos)
- emit q->cursorPositionChanged();
+ } else {
+ //emit q->visibilityRequest(QRectF(mousePos, QSizeF(1, 1)));
+ if (cursor.position() != oldCursorPos)
+ emit q->cursorPositionChanged();
+ }
+ selectionChanged(true);
+ repaintOldAndNewSelection(oldSelection);
}
- selectionChanged(true);
- repaintOldAndNewSelection(oldSelection);
+
+ sendMouseEventToInputContext(e, QEvent::MouseMove, button, mousePos, modifiers, buttons, globalPos);
}
void QWidgetTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers,
@@ -1748,46 +1762,46 @@ void QWidgetTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton but
}
}
-void QWidgetTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers,
- Qt::MouseButtons buttons, const QPoint &globalPos)
+void QWidgetTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos,
+ Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons,
+ const QPoint &globalPos)
{
Q_Q(QWidgetTextControl);
- if (sendMouseEventToInputContext(
- e, QEvent::MouseButtonDblClick, button, pos, modifiers, buttons, globalPos)) {
- return;
- }
-
- if (button != Qt::LeftButton
- || !(interactionFlags & Qt::TextSelectableByMouse)) {
- e->ignore();
- return;
- }
+ if (button == Qt::LeftButton
+ && (interactionFlags & Qt::TextSelectableByMouse)) {
#ifndef QT_NO_DRAGANDDROP
- mightStartDrag = false;
+ mightStartDrag = false;
#endif
- const QTextCursor oldSelection = cursor;
- setCursorPosition(pos);
- QTextLine line = currentTextLine(cursor);
- bool doEmit = false;
- if (line.isValid() && line.textLength()) {
- cursor.select(QTextCursor::WordUnderCursor);
- doEmit = true;
- }
- repaintOldAndNewSelection(oldSelection);
+ if (isPreediting())
+ qApp->inputPanel()->commit();
- cursorIsFocusIndicator = false;
- selectedWordOnDoubleClick = cursor;
+ const QTextCursor oldSelection = cursor;
+ setCursorPosition(pos);
+ QTextLine line = currentTextLine(cursor);
+ bool doEmit = false;
+ if (line.isValid() && line.textLength()) {
+ cursor.select(QTextCursor::WordUnderCursor);
+ doEmit = true;
+ }
+ repaintOldAndNewSelection(oldSelection);
- trippleClickPoint = pos;
- trippleClickTimer.start(QApplication::doubleClickInterval(), q);
- if (doEmit) {
- selectionChanged();
+ cursorIsFocusIndicator = false;
+ selectedWordOnDoubleClick = cursor;
+
+ trippleClickPoint = pos;
+ trippleClickTimer.start(QApplication::doubleClickInterval(), q);
+ if (doEmit) {
+ selectionChanged();
#ifndef QT_NO_CLIPBOARD
- setClipboardSelection();
+ setClipboardSelection();
#endif
- emit q->cursorPositionChanged();
+ emit q->cursorPositionChanged();
+ }
+ } else if (!sendMouseEventToInputContext(e, QEvent::MouseButtonDblClick, button, pos,
+ modifiers, buttons, globalPos)) {
+ e->ignore();
}
}
@@ -1798,26 +1812,22 @@ bool QWidgetTextControlPrivate::sendMouseEventToInputContext(
#if !defined(QT_NO_IM)
Q_Q(QWidgetTextControl);
- QTextLayout *layout = cursor.block().layout();
- if (contextWidget && layout && !layout->preeditAreaText().isEmpty()) {
+ if (contextWidget && isPreediting()) {
+ QTextLayout *layout = cursor.block().layout();
QInputContext *ctx = qApp->inputContext();
int cursorPos = q->hitTest(pos, Qt::FuzzyHit) - cursor.position();
- if (cursorPos < 0 || cursorPos > layout->preeditAreaText().length()) {
+ 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) {
+
+ if (ctx && cursorPos >= 0) {
QMouseEvent ev(eventType, contextWidget->mapFromGlobal(globalPos),
contextWidget->topLevelWidget()->mapFromGlobal(globalPos), globalPos,
button, buttons, modifiers);
ctx->mouseHandler(cursorPos, &ev);
e->setAccepted(ev.isAccepted());
- }
- if (!layout->preeditAreaText().isEmpty())
return true;
+ }
}
#else
Q_UNUSED(e);
@@ -2730,6 +2740,15 @@ void QWidgetTextControlPrivate::showToolTip(const QPoint &globalPos, const QPoin
}
#endif // QT_NO_TOOLTIP
+bool QWidgetTextControlPrivate::isPreediting() const
+{
+ QTextLayout *layout = cursor.block().layout();
+ if (layout && !layout->preeditAreaText().isEmpty())
+ return true;
+
+ return false;
+}
+
bool QWidgetTextControl::setFocusToNextOrPreviousAnchor(bool next)
{
Q_D(QWidgetTextControl);