From c79f36c51f24905c188a1a6a7e2b38960713f093 Mon Sep 17 00:00:00 2001 From: Pekka Vuorela Date: Wed, 15 Feb 2012 14:30:44 +0200 Subject: [PATCH] Have input method hints on only classes using them Removed inputMethodHints setter and getter from QQuickItem. No need to consume memory for input method hints on every item when only QQuickTextInput and QQuickTextEdit actually use them. Additionally introduced change signals on the editor hint properties. Change-Id: Ice380d4f4dd47fdde73d2468f4a44a7d1540ad45 Reviewed-by: Joona Petrell Reviewed-by: Andrew den Exter --- src/quick/items/qquickitem.cpp | 21 ------------------- src/quick/items/qquickitem.h | 2 -- src/quick/items/qquickitem_p.h | 1 - src/quick/items/qquicktextedit.cpp | 18 ++++++++++++++++ src/quick/items/qquicktextedit_p.h | 6 +++++- src/quick/items/qquicktextedit_p_p.h | 3 ++- src/quick/items/qquicktextinput.cpp | 14 ++++++++----- src/quick/items/qquicktextinput_p.h | 7 ++++--- src/quick/items/qquicktextinput_p_p.h | 2 ++ .../qquicktextedit/tst_qquicktextedit.cpp | 7 +++++++ .../qquicktextinput/tst_qquicktextinput.cpp | 20 ++++++++++++++---- 11 files changed, 63 insertions(+), 38 deletions(-) diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index c5d55cf6b3..889f0548b1 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -2309,7 +2309,6 @@ QQuickItemPrivate::QQuickItemPrivate() z(0), scale(1), rotation(0), opacity(1), attachedLayoutDirection(0), acceptedMouseButtons(0), - imHints(Qt::ImhNone), keyHandler(0), @@ -3113,24 +3112,6 @@ void QQuickItem::windowDeactivateEvent() } } -Qt::InputMethodHints QQuickItem::inputMethodHints() const -{ - Q_D(const QQuickItem); - return d->imHints; -} - -void QQuickItem::setInputMethodHints(Qt::InputMethodHints hints) -{ - Q_D(QQuickItem); - d->imHints = hints; - - if (!d->canvas || d->canvas->activeFocusItem() != this) - return; - - if (qApp->focusObject() == this) - qApp->inputMethod()->update(Qt::ImHints); -} - QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const { Q_D(const QQuickItem); @@ -3141,8 +3122,6 @@ QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const v = (bool)(flags() & ItemAcceptsInputMethod); break; case Qt::ImHints: - v = (int)inputMethodHints(); - break; case Qt::ImCursorRectangle: case Qt::ImFont: case Qt::ImCursorPosition: diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h index 16a6074354..4c733aecef 100644 --- a/src/quick/items/qquickitem.h +++ b/src/quick/items/qquickitem.h @@ -309,8 +309,6 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QDeclarativeParserStatu Q_INVOKABLE void forceActiveFocus(); Q_INVOKABLE QQuickItem *childAt(qreal x, qreal y) const; - Qt::InputMethodHints inputMethodHints() const; - void setInputMethodHints(Qt::InputMethodHints hints); virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const; struct UpdatePaintNodeData { diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index c88219f732..a5e8640b9f 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -439,7 +439,6 @@ class Q_QUICK_EXPORT QQuickItemPrivate : public QObjectPrivate QQuickLayoutMirroringAttached* attachedLayoutDirection; Qt::MouseButtons acceptedMouseButtons; - Qt::InputMethodHints imHints; void setAccessibleFlagAndListener(); diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index fba84e6fde..6f3c32db7d 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -1131,6 +1131,24 @@ void QQuickTextEdit::setTextMargin(qreal margin) \endlist */ +Qt::InputMethodHints QQuickTextEdit::inputMethodHints() const +{ + Q_D(const QQuickTextEdit); + return d->inputMethodHints; +} + +void QQuickTextEdit::setInputMethodHints(Qt::InputMethodHints hints) +{ + Q_D(QQuickTextEdit); + + if (hints == d->inputMethodHints) + return; + + d->inputMethodHints = hints; + updateInputMethod(Qt::ImHints); + emit inputMethodHintsChanged(); +} + void QQuickTextEdit::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h index 0db85bb5fa..d71759f466 100644 --- a/src/quick/items/qquicktextedit_p.h +++ b/src/quick/items/qquicktextedit_p.h @@ -88,7 +88,7 @@ class Q_AUTOTEST_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem Q_PROPERTY(bool activeFocusOnPress READ focusOnPress WRITE setFocusOnPress NOTIFY activeFocusOnPressChanged) Q_PROPERTY(bool persistentSelection READ persistentSelection WRITE setPersistentSelection NOTIFY persistentSelectionChanged) Q_PROPERTY(qreal textMargin READ textMargin WRITE setTextMargin NOTIFY textMarginChanged) - Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints) + Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints NOTIFY inputMethodHintsChanged) Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged) Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged) Q_PROPERTY(bool canPaste READ canPaste NOTIFY canPasteChanged) @@ -190,6 +190,9 @@ class Q_AUTOTEST_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem qreal textMargin() const; void setTextMargin(qreal margin); + Qt::InputMethodHints inputMethodHints() const; + void setInputMethodHints(Qt::InputMethodHints hints); + bool selectByMouse() const; void setSelectByMouse(bool); @@ -265,6 +268,7 @@ class Q_AUTOTEST_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem void inputMethodComposingChanged(); void effectiveHorizontalAlignmentChanged(); void baseUrlChanged(); + void inputMethodHintsChanged(); public Q_SLOTS: void selectAll(); diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h index 665aa02839..b30792ffaa 100644 --- a/src/quick/items/qquicktextedit_p_p.h +++ b/src/quick/items/qquicktextedit_p_p.h @@ -77,7 +77,7 @@ class QQuickTextEditPrivate : public QQuickImplicitSizeItemPrivate textMargin(0.0), lastSelectionStart(0), lastSelectionEnd(0), cursorComponent(0), cursor(0), format(QQuickTextEdit::PlainText), document(0), wrapMode(QQuickTextEdit::NoWrap), mouseSelectionMode(QQuickTextEdit::SelectCharacters), - lineCount(0), yoff(0), updateType(UpdatePaintNode) + lineCount(0), yoff(0), inputMethodHints(Qt::ImhNone), updateType(UpdatePaintNode) { } @@ -132,6 +132,7 @@ class QQuickTextEditPrivate : public QQuickImplicitSizeItemPrivate int lineCount; int yoff; QSize contentSize; + Qt::InputMethodHints inputMethodHints; enum UpdateType { UpdateNone, diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 830b875617..bcdef31ccb 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -1110,7 +1110,8 @@ void QQuickTextInputPrivate::updateInputMethodHints() hints &= ~Qt::ImhHiddenText; if (m_echoMode != QQuickTextInput::Normal) hints |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhSensitiveData); - q->setInputMethodHints(hints); + effectiveInputMethodHints = hints; + q->updateInputMethod(Qt::ImHints); } /*! \qmlproperty enumeration QtQuick2::TextInput::echoMode @@ -1190,19 +1191,22 @@ void QQuickTextInput::setEchoMode(QQuickTextInput::EchoMode echo) \endlist */ -Qt::InputMethodHints QQuickTextInput::imHints() const +Qt::InputMethodHints QQuickTextInput::inputMethodHints() const { Q_D(const QQuickTextInput); return d->inputMethodHints; } -void QQuickTextInput::setIMHints(Qt::InputMethodHints hints) +void QQuickTextInput::setInputMethodHints(Qt::InputMethodHints hints) { Q_D(QQuickTextInput); - if (d->inputMethodHints == hints) + + if (hints == d->inputMethodHints) return; + d->inputMethodHints = hints; d->updateInputMethodHints(); + emit inputMethodHintsChanged(); } /*! @@ -1781,7 +1785,7 @@ QVariant QQuickTextInput::inputMethodQuery(Qt::InputMethodQuery property) const case Qt::ImEnabled: return QVariant((bool)(flags() & ItemAcceptsInputMethod)); case Qt::ImHints: - return QVariant((int)inputMethodHints()); + return QVariant((int) d->effectiveInputMethodHints); case Qt::ImCursorRectangle: return cursorRectangle(); case Qt::ImFont: diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h index b5b3d0f430..952752205d 100644 --- a/src/quick/items/qquicktextinput_p.h +++ b/src/quick/items/qquicktextinput_p.h @@ -88,7 +88,7 @@ class Q_AUTOTEST_EXPORT QQuickTextInput : public QQuickImplicitSizeItem Q_PROPERTY(QValidator* validator READ validator WRITE setValidator NOTIFY validatorChanged) #endif Q_PROPERTY(QString inputMask READ inputMask WRITE setInputMask NOTIFY inputMaskChanged) - Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ imHints WRITE setIMHints) + Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints NOTIFY inputMethodHintsChanged) Q_PROPERTY(bool acceptableInput READ hasAcceptableInput NOTIFY acceptableInputChanged) Q_PROPERTY(EchoMode echoMode READ echoMode WRITE setEchoMode NOTIFY echoModeChanged) @@ -251,8 +251,8 @@ class Q_AUTOTEST_EXPORT QQuickTextInput : public QQuickImplicitSizeItem bool isInputMethodComposing() const; - Qt::InputMethodHints imHints() const; - void setIMHints(Qt::InputMethodHints hints); + Qt::InputMethodHints inputMethodHints() const; + void setInputMethodHints(Qt::InputMethodHints hints); Q_INVOKABLE QString getText(int start, int end) const; @@ -295,6 +295,7 @@ class Q_AUTOTEST_EXPORT QQuickTextInput : public QQuickImplicitSizeItem void inputMethodComposingChanged(); void effectiveHorizontalAlignmentChanged(); void contentSizeChanged(); + void inputMethodHintsChanged(); protected: virtual void geometryChanged(const QRectF &newGeometry, diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h index 07d73bebdf..09896c2a6e 100644 --- a/src/quick/items/qquicktextinput_p_p.h +++ b/src/quick/items/qquicktextinput_p_p.h @@ -103,6 +103,7 @@ class Q_AUTOTEST_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPr , wrapMode(QQuickTextInput::NoWrap) , mouseSelectionMode(QQuickTextInput::SelectCharacters) , inputMethodHints(Qt::ImhNone) + , effectiveInputMethodHints(Qt::ImhNone) , m_layoutDirection(Qt::LayoutDirectionAuto) , m_passwordCharacter(QLatin1Char('*')) , focused(false) @@ -228,6 +229,7 @@ class Q_AUTOTEST_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPr QQuickTextInput::WrapMode wrapMode; QQuickTextInput::SelectionMode mouseSelectionMode; Qt::InputMethodHints inputMethodHints; + Qt::InputMethodHints effectiveInputMethodHints; Qt::LayoutDirection m_layoutDirection; QChar m_blank; diff --git a/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp index eb8e711e6a..41c8546688 100644 --- a/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp +++ b/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp @@ -1715,8 +1715,15 @@ void tst_qquicktextedit::inputMethodHints() QQuickTextEdit *textEditObject = qobject_cast(canvas.rootObject()); QVERIFY(textEditObject != 0); QVERIFY(textEditObject->inputMethodHints() & Qt::ImhNoPredictiveText); + QSignalSpy inputMethodHintSpy(textEditObject, SIGNAL(inputMethodHintsChanged())); textEditObject->setInputMethodHints(Qt::ImhUppercaseOnly); QVERIFY(textEditObject->inputMethodHints() & Qt::ImhUppercaseOnly); + QCOMPARE(inputMethodHintSpy.count(), 1); + textEditObject->setInputMethodHints(Qt::ImhUppercaseOnly); + QCOMPARE(inputMethodHintSpy.count(), 1); + + QQuickTextEdit plainTextEdit; + QCOMPARE(plainTextEdit.inputMethodHints(), Qt::ImhNone); } void tst_qquicktextedit::positionAt() diff --git a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp index 16577376f0..c1768bd98a 100644 --- a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp @@ -1948,14 +1948,23 @@ void tst_qquicktextinput::inputMethods() QQuickTextInput *input = qobject_cast(canvas.rootObject()); QVERIFY(input != 0); QVERIFY(input->inputMethodHints() & Qt::ImhNoPredictiveText); + QSignalSpy inputMethodHintSpy(input, SIGNAL(inputMethodHintsChanged())); input->setInputMethodHints(Qt::ImhUppercaseOnly); QVERIFY(input->inputMethodHints() & Qt::ImhUppercaseOnly); + QCOMPARE(inputMethodHintSpy.count(), 1); + input->setInputMethodHints(Qt::ImhUppercaseOnly); + QCOMPARE(inputMethodHintSpy.count(), 1); + + // default value + QQuickTextInput plainInput; + QCOMPARE(plainInput.inputMethodHints(), Qt::ImhNone); input->setFocus(true); QVERIFY(input->hasActiveFocus() == true); // test that input method event is committed QInputMethodEvent event; event.setCommitString( "My ", -12, 0); + QTRY_COMPARE(qGuiApp->focusObject(), input); QGuiApplication::sendEvent(qGuiApp->focusObject(), &event); QCOMPARE(input->text(), QString("My Hello world!")); @@ -2589,7 +2598,7 @@ void tst_qquicktextinput::echoMode() //Normal ref &= ~Qt::ImhHiddenText; ref &= ~(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhSensitiveData); - QCOMPARE(input->inputMethodHints(), ref); + QCOMPARE((Qt::InputMethodHints) input->inputMethodQuery(Qt::ImHints).toInt(), ref); input->setEchoMode(QQuickTextInput::NoEcho); QCOMPARE(input->text(), initial); QCOMPARE(input->displayText(), QLatin1String("")); @@ -2597,14 +2606,17 @@ void tst_qquicktextinput::echoMode() //NoEcho ref |= Qt::ImhHiddenText; ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhSensitiveData); - QCOMPARE(input->inputMethodHints(), ref); + QCOMPARE((Qt::InputMethodHints) input->inputMethodQuery(Qt::ImHints).toInt(), ref); input->setEchoMode(QQuickTextInput::Password); //Password ref |= Qt::ImhHiddenText; ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhSensitiveData); QCOMPARE(input->text(), initial); QCOMPARE(input->displayText(), QLatin1String("********")); - QCOMPARE(input->inputMethodHints(), ref); + QCOMPARE((Qt::InputMethodHints) input->inputMethodQuery(Qt::ImHints).toInt(), ref); + // clearing input hints do not clear bits set by echo mode + input->setInputMethodHints(Qt::ImhNone); + QCOMPARE((Qt::InputMethodHints) input->inputMethodQuery(Qt::ImHints).toInt(), ref); input->setPasswordCharacter(QChar('Q')); QCOMPARE(input->passwordCharacter(), QLatin1String("Q")); QCOMPARE(input->text(), initial); @@ -2613,7 +2625,7 @@ void tst_qquicktextinput::echoMode() //PasswordEchoOnEdit ref &= ~Qt::ImhHiddenText; ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhSensitiveData); - QCOMPARE(input->inputMethodHints(), ref); + QCOMPARE((Qt::InputMethodHints) input->inputMethodQuery(Qt::ImHints).toInt(), ref); QCOMPARE(input->text(), initial); QCOMPARE(input->displayText(), QLatin1String("QQQQQQQQ")); QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("QQQQQQQQ"));