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>
This commit is contained in:
parent
15d25dc676
commit
4b3d88a9c6
@ -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 (selectedBlockOnTrippleClick.hasSelection())
|
||||
extendBlockwiseSelection(newCursorPos);
|
||||
else if (selectedWordOnDoubleClick.hasSelection())
|
||||
extendWordwiseSelection(newCursorPos, mouseX);
|
||||
else
|
||||
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 (newCursorPos != selectionStartPos) {
|
||||
qApp->inputPanel()->commit();
|
||||
// commit invalidates positions
|
||||
newCursorPos = q->hitTest(mousePos, Qt::FuzzyHit);
|
||||
selectionStartPos = q->hitTest(mousePressPos, Qt::FuzzyHit);
|
||||
setCursorPosition(selectionStartPos);
|
||||
}
|
||||
}
|
||||
|
||||
if (newCursorPos == -1)
|
||||
return;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
#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);
|
||||
|
@ -169,6 +169,8 @@ public:
|
||||
void showToolTip(const QPoint &globalPos, const QPointF &pos, QWidget *contextWidget);
|
||||
#endif
|
||||
|
||||
bool isPreediting() const;
|
||||
|
||||
void append(const QString &text, Qt::TextFormat format = Qt::AutoText);
|
||||
|
||||
QTextDocument *doc;
|
||||
@ -190,7 +192,7 @@ public:
|
||||
bool mousePressed;
|
||||
|
||||
bool mightStartDrag;
|
||||
QPoint dragStartPos;
|
||||
QPoint mousePressPos;
|
||||
QPointer<QWidget> contextWidget;
|
||||
|
||||
int lastSelectionPosition;
|
||||
|
Loading…
Reference in New Issue
Block a user