summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPekka Vuorela <pekka.ta.vuorela@nokia.com>2011-10-12 11:08:00 +0300
committerQt by Nokia <qt-info@nokia.com>2011-11-05 23:47:02 +0100
commit8bd40fef0733a4796a308b3bc137a05296e142c4 (patch)
tree10ff24637ab73cd1516bda8c39bd121aac412e97
parent4b3d88a9c67402b6a234d597bab25846f039bbdb (diff)
Support tentative commit string with input method.
Tentative commit string allows input method to notify editor what is expected to be committed in the place of preedit. This commit adds such support in QLineEdit. Change-Id: If855619bc6843652db0d6254f7e7063bb8ad0936 Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
-rw-r--r--src/gui/kernel/qevent.cpp19
-rw-r--r--src/gui/kernel/qevent.h3
-rw-r--r--src/widgets/widgets/qlineedit.cpp2
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp22
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol_p.h19
-rw-r--r--tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp26
6 files changed, 86 insertions, 5 deletions
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index ba81e5512c..2c0858ae00 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -1644,6 +1644,17 @@ void QInputMethodEvent::setCommitString(const QString &commitString, int replace
}
/*!
+ Sets the tentative commit string to \a tentativeCommitString.
+
+ The tentative commit string is what the preedit string is expected to be committed as.
+ The string can be used within the editor to trigger code that reacts on text changes such as validators.
+*/
+void QInputMethodEvent::setTentativeCommitString(const QString &tentativeCommitString)
+{
+ tentativeCommit = tentativeCommitString;
+}
+
+/*!
\fn const QList<Attribute> &QInputMethodEvent::attributes() const
Returns the list of attributes passed to the QInputMethodEvent
@@ -1692,6 +1703,14 @@ void QInputMethodEvent::setCommitString(const QString &commitString, int replace
\sa replacementStart(), setCommitString()
*/
+/*!
+ \fn const QString &tentativeCommitString() const
+
+ Returns the text as which preedit string is expected to be committed as.
+ The string can be used within the editor to trigger code that reacts on text changes such as validators.
+
+ \sa setTentativeCommitString()
+*/
/*! \class QInputMethodQueryEvent
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index de888832bf..aad31a90eb 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -428,6 +428,7 @@ public:
QInputMethodEvent();
QInputMethodEvent(const QString &preeditText, const QList<Attribute> &attributes);
void setCommitString(const QString &commitString, int replaceFrom = 0, int replaceLength = 0);
+ void setTentativeCommitString(const QString &tentativeCommitString);
inline const QList<Attribute> &attributes() const { return attrs; }
inline const QString &preeditString() const { return preedit; }
@@ -435,6 +436,7 @@ public:
inline const QString &commitString() const { return commit; }
inline int replacementStart() const { return replace_from; }
inline int replacementLength() const { return replace_length; }
+ inline const QString &tentativeCommitString() const { return tentativeCommit; }
QInputMethodEvent(const QInputMethodEvent &other);
@@ -444,6 +446,7 @@ private:
QString commit;
int replace_from;
int replace_length;
+ QString tentativeCommit;
};
class Q_GUI_EXPORT QInputMethodQueryEvent : public QEvent
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index 1412bf547a..a4a54caa53 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -1631,7 +1631,7 @@ QVariant QLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const
case Qt::ImCursorPosition:
return QVariant(d->control->cursor());
case Qt::ImSurroundingText:
- return QVariant(text());
+ return QVariant(d->control->realText());
case Qt::ImCurrentSelection:
return QVariant(selectedText());
case Qt::ImMaximumTextLength:
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index 6869f56e0a..498b972045 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -429,7 +429,7 @@ void QWidgetLineControl::moveCursor(int pos, bool mark)
*/
void QWidgetLineControl::processInputMethodEvent(QInputMethodEvent *event)
{
- int priorState = 0;
+ int priorState = -1;
bool isGettingInput = !event->commitString().isEmpty()
|| event->preeditString() != preeditAreaText()
|| event->replacementLength() > 0;
@@ -514,8 +514,16 @@ void QWidgetLineControl::processInputMethodEvent(QInputMethodEvent *event)
emitCursorPositionChanged();
else if (m_preeditCursor != oldPreeditCursor)
emit updateMicroFocus();
- if (isGettingInput)
+
+ bool tentativeCommitChanged = (m_tentativeCommit != event->tentativeCommitString());
+ if (tentativeCommitChanged) {
+ m_textDirty = true;
+ m_tentativeCommit = event->tentativeCommitString();
+ }
+
+ if (isGettingInput || tentativeCommitChanged)
finishChange(priorState);
+
if (selectionChange)
emit selectionChanged();
}
@@ -612,7 +620,6 @@ bool QWidgetLineControl::finishChange(int validateFromState, bool update, bool e
m_validInput = true;
#ifndef QT_NO_VALIDATOR
if (m_validator) {
- m_validInput = false;
QString textCopy = m_text;
int cursorCopy = m_cursor;
m_validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid);
@@ -622,6 +629,15 @@ bool QWidgetLineControl::finishChange(int validateFromState, bool update, bool e
return true;
}
m_cursor = cursorCopy;
+
+ if (!m_tentativeCommit.isEmpty()) {
+ textCopy.insert(m_cursor, m_tentativeCommit);
+ bool validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid);
+ if (!validInput)
+ m_tentativeCommit.clear();
+ }
+ } else {
+ m_tentativeCommit.clear();
}
}
#endif
diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h
index 4ffa9e4b31..3bcdffbf08 100644
--- a/src/widgets/widgets/qwidgetlinecontrol_p.h
+++ b/src/widgets/widgets/qwidgetlinecontrol_p.h
@@ -215,10 +215,26 @@ public:
QString text() const
{
+ QString content = m_text;
+ if (!m_tentativeCommit.isEmpty())
+ content.insert(m_cursor, m_tentativeCommit);
+ QString res = m_maskData ? stripString(content) : content;
+ return (res.isNull() ? QString::fromLatin1("") : res);
+ }
+ // like text() but doesn't include preedit
+ QString realText() const
+ {
QString res = m_maskData ? stripString(m_text) : m_text;
return (res.isNull() ? QString::fromLatin1("") : res);
}
- void setText(const QString &txt) { internalSetText(txt, -1, false); }
+ void setText(const QString &txt)
+ {
+ if (composeMode())
+ qApp->inputPanel()->reset();
+ m_tentativeCommit.clear();
+ internalSetText(txt, -1, false);
+ }
+
QString displayText() const { return m_textLayout.text(); }
void backspace();
@@ -379,6 +395,7 @@ private:
int m_cursor;
int m_preeditCursor;
int m_cursorWidth;
+ QString m_tentativeCommit;
Qt::LayoutDirection m_layoutDirection;
uint m_hideCursor : 1; // used to hide the m_cursor inside preedit areas
uint m_separator : 1;
diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
index 841fbbd955..0804f1241c 100644
--- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
+++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
@@ -279,6 +279,7 @@ private slots:
void selectAndCursorPosition();
void inputMethodSelection();
+ void inputMethodTentativeCommit();
protected slots:
void editingFinished();
@@ -3831,5 +3832,30 @@ void tst_QLineEdit::inputMethodSelection()
QCOMPARE(testWidget->selectionStart(), 12);
}
+void tst_QLineEdit::inputMethodTentativeCommit()
+{
+ // test that basic tentative commit gets to text property on preedit state
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("test", attributes);
+ event.setTentativeCommitString("test");
+ QApplication::sendEvent(testWidget, &event);
+ QCOMPARE(testWidget->text(), QString("test"));
+
+ // tentative commit not allowed present in surrounding text
+ QInputMethodQueryEvent queryEvent(Qt::ImSurroundingText);
+ QApplication::sendEvent(testWidget, &queryEvent);
+ QCOMPARE(queryEvent.value(Qt::ImSurroundingText).toString(), QString(""));
+
+ // if text with tentative commit does not validate, not allowed to be part of text property
+ testWidget->setText(""); // ensure input state is reset
+ QValidator *validator = new QIntValidator(0, 100);
+ testWidget->setValidator(validator);
+ QApplication::sendEvent(testWidget, &event);
+ QCOMPARE(testWidget->text(), QString(""));
+ testWidget->setValidator(0);
+ delete validator;
+}
+
+
QTEST_MAIN(tst_QLineEdit)
#include "tst_qlineedit.moc"