summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
authorPekka Vuorela <pekka.ta.vuorela@nokia.com>2011-10-04 17:44:35 +0300
committerQt by Nokia <qt-info@nokia.com>2011-11-05 23:47:02 +0100
commit7851568c65e0560056c6fa541039543d43a63e20 (patch)
tree75eef36925198b1e21d60ae1916b1cca8f634ee6 /src/widgets
parent10dc2171cf004705f8212f5100b99bfde04c8d54 (diff)
QLineEdit - made mouse interactions commit preedit
Simplifying input context mouse handling rules by making the editor in charge when text gets committed and selected. This includes: - Allowing selection to start on top of preedit. Commits once a single character gets selected - Double click to commit preedit before selecting a word. - Only sending events to input context that happen on top of preedit. - Committing preedit when a mouse press happens outside of it, allowing to move cursor to click position. Change-Id: I9dab00ea3445055ffd0d7cae540a1197c5748509 Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/widgets/qlineedit.cpp57
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp10
-rw-r--r--src/widgets/widgets/qlineedit_p.h2
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp29
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol_p.h1
5 files changed, 83 insertions, 16 deletions
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index a4a54caa53..43030289ff 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -1388,6 +1388,9 @@ bool QLineEdit::event(QEvent * e)
void QLineEdit::mousePressEvent(QMouseEvent* e)
{
Q_D(QLineEdit);
+
+ d->mousePressPos = e->pos();
+
if (d->sendMouseEventToInputContext(e))
return;
if (e->button() == Qt::RightButton)
@@ -1410,7 +1413,6 @@ void QLineEdit::mousePressEvent(QMouseEvent* e)
#ifndef QT_NO_DRAGANDDROP
if (!mark && d->dragEnabled && d->control->echoMode() == Normal &&
e->button() == Qt::LeftButton && d->control->inSelection(e->pos().x())) {
- d->dndPos = e->pos();
if (!d->dndTimer.isActive())
d->dndTimer.start(QApplication::startDragTime(), this);
} else
@@ -1425,20 +1427,28 @@ void QLineEdit::mousePressEvent(QMouseEvent* e)
void QLineEdit::mouseMoveEvent(QMouseEvent * e)
{
Q_D(QLineEdit);
- if (d->sendMouseEventToInputContext(e))
- return;
if (e->buttons() & Qt::LeftButton) {
#ifndef QT_NO_DRAGANDDROP
if (d->dndTimer.isActive()) {
- if ((d->dndPos - e->pos()).manhattanLength() > QApplication::startDragDistance())
+ if ((d->mousePressPos - e->pos()).manhattanLength() > QApplication::startDragDistance())
d->drag();
} else
#endif
{
- d->control->moveCursor(d->xToPos(e->pos().x()), true);
+ if (d->control->composeMode()) {
+ int startPos = d->xToPos(d->mousePressPos.x());
+ int currentPos = d->xToPos(e->pos().x());
+ if (startPos != currentPos)
+ d->control->setSelection(startPos, currentPos - startPos);
+
+ } else {
+ d->control->moveCursor(d->xToPos(e->pos().x()), true);
+ }
}
}
+
+ d->sendMouseEventToInputContext(e);
}
/*! \reimp
@@ -1478,12 +1488,43 @@ void QLineEdit::mouseReleaseEvent(QMouseEvent* e)
void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
{
Q_D(QLineEdit);
- if (d->sendMouseEventToInputContext(e))
- return;
+
if (e->button() == Qt::LeftButton) {
- d->control->selectWordAtPos(d->xToPos(e->pos().x()));
+ int position = d->xToPos(e->pos().x());
+
+ // exit composition mode
+ if (d->control->composeMode()) {
+ int preeditPos = d->control->cursor();
+ int posInPreedit = position - d->control->cursor();
+ int preeditLength = d->control->preeditAreaText().length();
+ bool positionOnPreedit = false;
+
+ if (posInPreedit >= 0 && posInPreedit <= preeditLength)
+ positionOnPreedit = true;
+
+ int textLength = d->control->end();
+ d->control->commitPreedit();
+ int sizeChange = d->control->end() - textLength;
+
+ if (positionOnPreedit) {
+ if (sizeChange == 0)
+ position = -1; // cancel selection, word disappeared
+ else
+ // ensure not selecting after preedit if event happened there
+ position = qBound(preeditPos, position, preeditPos + sizeChange);
+ } else if (position > preeditPos) {
+ // adjust positions after former preedit by how much text changed
+ position += (sizeChange - preeditLength);
+ }
+ }
+
+ if (position >= 0)
+ d->control->selectWordAtPos(position);
+
d->tripleClickTimer.start(QApplication::doubleClickInterval(), this);
d->tripleClick = e->pos();
+ } else {
+ d->sendMouseEventToInputContext(e);
}
}
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
index 247d0afb0b..b17651e1d3 100644
--- a/src/widgets/widgets/qlineedit_p.cpp
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -259,19 +259,15 @@ bool QLineEditPrivate::sendMouseEventToInputContext( QMouseEvent *e )
if ( control->composeMode() ) {
int tmp_cursor = xToPos(e->pos().x());
int mousePos = tmp_cursor - control->cursor();
- if ( mousePos < 0 || mousePos > control->preeditAreaText().length() ) {
+ if ( mousePos < 0 || mousePos > control->preeditAreaText().length() )
mousePos = -1;
- // don't send move events outside the preedit area
- if ( e->type() == QEvent::MouseMove )
- return true;
- }
QInputContext *qic = q->inputContext();
- if ( qic )
+ if (qic && mousePos >= 0) {
// may be causing reset() in some input methods
qic->mouseHandler(mousePos, e);
- if (!control->preeditAreaText().isEmpty())
return true;
+ }
}
#else
Q_UNUSED(e);
diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h
index d916ae3185..076f2fcf11 100644
--- a/src/widgets/widgets/qlineedit_p.h
+++ b/src/widgets/widgets/qlineedit_p.h
@@ -137,8 +137,8 @@ public:
#ifndef QT_NO_COMPLETER
void _q_completionHighlighted(QString);
#endif
+ QPoint mousePressPos;
#ifndef QT_NO_DRAGANDDROP
- QPoint dndPos;
QBasicTimer dndTimer;
void drag();
#endif
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index 498b972045..027512b6ae 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -167,6 +167,31 @@ void QWidgetLineControl::paste(QClipboard::Mode clipboardMode)
/*!
\internal
+ Exits preedit mode and commits parts marked as tentative commit
+*/
+void QWidgetLineControl::commitPreedit()
+{
+ if (!composeMode())
+ return;
+
+ qApp->inputPanel()->reset();
+
+ if (!m_tentativeCommit.isEmpty()) {
+ internalInsert(m_tentativeCommit);
+ m_tentativeCommit.clear();
+ finishChange(-1, true/*not used, not documented*/, false);
+ }
+
+ m_preeditCursor = 0;
+ setPreeditArea(-1, QString());
+ m_textLayout.clearAdditionalFormats();
+ updateDisplayText(/*force*/ true);
+}
+
+
+/*!
+ \internal
+
Handles the behavior for the backspace key or function.
Removes the current selection if there is a selection, otherwise
removes the character prior to the cursor position.
@@ -259,6 +284,8 @@ void QWidgetLineControl::clear()
*/
void QWidgetLineControl::setSelection(int start, int length)
{
+ commitPreedit();
+
if(start < 0 || start > (int)m_text.length()){
qWarning("QWidgetLineControl::setSelection: Invalid start position");
return;
@@ -394,6 +421,8 @@ bool QWidgetLineControl::fixup() // this function assumes that validate currentl
*/
void QWidgetLineControl::moveCursor(int pos, bool mark)
{
+ commitPreedit();
+
if (pos != m_cursor) {
separate();
if (m_maskData)
diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h
index 3bcdffbf08..e0c304279e 100644
--- a/src/widgets/widgets/qwidgetlinecontrol_p.h
+++ b/src/widgets/widgets/qwidgetlinecontrol_p.h
@@ -234,6 +234,7 @@ public:
m_tentativeCommit.clear();
internalSetText(txt, -1, false);
}
+ void commitPreedit();
QString displayText() const { return m_textLayout.text(); }