summaryrefslogtreecommitdiffstats
path: root/tests/auto/qinputcontext/tst_qinputcontext.cpp
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /tests/auto/qinputcontext/tst_qinputcontext.cpp
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'tests/auto/qinputcontext/tst_qinputcontext.cpp')
-rw-r--r--tests/auto/qinputcontext/tst_qinputcontext.cpp1405
1 files changed, 1405 insertions, 0 deletions
diff --git a/tests/auto/qinputcontext/tst_qinputcontext.cpp b/tests/auto/qinputcontext/tst_qinputcontext.cpp
new file mode 100644
index 0000000000..6a047f2208
--- /dev/null
+++ b/tests/auto/qinputcontext/tst_qinputcontext.cpp
@@ -0,0 +1,1405 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../../shared/util.h"
+
+#include <qinputcontext.h>
+#include <qlineedit.h>
+#include <qplaintextedit.h>
+#include <qlayout.h>
+#include <qradiobutton.h>
+#include <qwindowsstyle.h>
+#include <qdesktopwidget.h>
+#include <qpushbutton.h>
+#include <qgraphicsview.h>
+#include <qgraphicsscene.h>
+
+#ifdef QT_WEBKIT_LIB
+#include <qwebview.h>
+#include <qgraphicswebview.h>
+#endif
+
+#ifdef Q_OS_SYMBIAN
+#include <private/qt_s60_p.h>
+#include <private/qcoefepinputcontext_p.h>
+
+#include <w32std.h>
+#include <coecntrl.h>
+#endif
+
+class tst_QInputContext : public QObject
+{
+Q_OBJECT
+
+public:
+ tst_QInputContext() : m_phoneIsQwerty(false) {}
+ virtual ~tst_QInputContext() {}
+
+ template <class WidgetType> void symbianTestCoeFepInputContext_addData();
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase() {}
+ void init() {}
+ void cleanup() {}
+private slots:
+ void maximumTextLength();
+ void filterMouseEvents();
+ void requestSoftwareInputPanel();
+ void closeSoftwareInputPanel();
+ void selections();
+ void focusProxy();
+ void contextInheritance();
+ void symbianTestCoeFepInputContext_data();
+ void symbianTestCoeFepInputContext();
+ void symbianTestCoeFepAutoCommit_data();
+ void symbianTestCoeFepAutoCommit();
+
+private:
+ bool m_phoneIsQwerty;
+};
+
+#ifdef Q_OS_SYMBIAN
+class KeyEvent : public TWsEvent
+{
+public:
+ KeyEvent(QWidget *w, TInt type, TInt scanCode, TUint code, TUint modifiers, TInt repeats) {
+ iHandle = w->effectiveWinId()->DrawableWindow()->WindowGroupId();
+ iType = type;
+ SetTimeNow();
+ TKeyEvent *keyEvent = reinterpret_cast<TKeyEvent *>(iEventData);
+ keyEvent->iScanCode = scanCode;
+ keyEvent->iCode = code;
+ keyEvent->iModifiers = modifiers;
+ keyEvent->iRepeats = repeats;
+ }
+};
+
+class FepReplayEvent
+{
+public:
+ enum Type {
+ Pause,
+ Key,
+ CompleteKey
+ };
+
+ FepReplayEvent(int msecsToPause)
+ : m_type(Pause)
+ , m_msecsToPause(msecsToPause)
+ {
+ }
+
+ FepReplayEvent(TInt keyType, TInt scanCode, TUint code, TUint modifiers, TInt repeats)
+ : m_type(Key)
+ , m_keyType(keyType)
+ , m_scanCode(scanCode)
+ , m_code(code)
+ , m_modifiers(modifiers)
+ , m_repeats(repeats)
+ {
+ }
+
+ FepReplayEvent(TInt scanCode, TUint code, TUint modifiers, TInt repeats)
+ : m_type(CompleteKey)
+ , m_scanCode(scanCode)
+ , m_code(code)
+ , m_modifiers(modifiers)
+ , m_repeats(repeats)
+ {
+ }
+
+ void sendEvent(QWidget *w, TInt type, TInt scanCode, TUint code, TUint modifiers, TInt repeats)
+ {
+ KeyEvent event(w, type, scanCode, code, modifiers, repeats);
+ S60->wsSession().SendEventToWindowGroup(w->effectiveWinId()->DrawableWindow()->WindowGroupId(), event);
+ }
+
+ void pause(int msecs)
+ {
+ // Don't use qWait here. The polling nature of that function screws up the test.
+ QTimer timer;
+ QEventLoop loop;
+ QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
+ timer.setSingleShot(true);
+ timer.start(msecs);
+ loop.exec();
+ }
+
+ // For some reason, the test fails if using processEvents instead of an event loop
+ // with a timer to quit it, so use the timer.
+#define KEY_WAIT 10
+
+ void replay(QWidget *w)
+ {
+ if (m_type == Pause) {
+ pause(m_msecsToPause);
+ } else if (m_type == Key) {
+ sendEvent(w, m_keyType, m_scanCode, m_code, m_modifiers, m_repeats);
+ if (m_keyType != EEventKeyDown)
+ // EEventKeyDown events should have no pause before the EEventKey event.
+ pause(KEY_WAIT);
+ } else if (m_type == CompleteKey) {
+ sendEvent(w, EEventKeyDown, m_scanCode, 0, m_modifiers, m_repeats);
+ // EEventKeyDown events should have no pause before the EEventKey event.
+ sendEvent(w, EEventKey, m_scanCode, m_code, m_modifiers, m_repeats);
+ pause(KEY_WAIT);
+ sendEvent(w, EEventKeyUp, m_scanCode, 0, m_modifiers, m_repeats);
+ pause(KEY_WAIT);
+ }
+ }
+
+private:
+ Type m_type;
+ int m_msecsToPause;
+ TInt m_keyType;
+ TInt m_scanCode;
+ TUint m_code;
+ TUint m_modifiers;
+ TInt m_repeats;
+};
+
+Q_DECLARE_METATYPE(QList<FepReplayEvent>)
+Q_DECLARE_METATYPE(Qt::InputMethodHints)
+Q_DECLARE_METATYPE(QLineEdit::EchoMode);
+
+#endif // Q_OS_SYMBIAN
+
+void tst_QInputContext::initTestCase()
+{
+#ifdef Q_OS_SYMBIAN
+ // Sanity test. Checks FEP for:
+ // - T9 mode is default (it will attempt to fix this)
+ // - Language is English (it cannot fix this; bail out if not correct)
+ QWidget w;
+ QLayout *layout = new QVBoxLayout;
+ w.setLayout(layout);
+ QLineEdit *lineedit = new QLineEdit;
+ layout->addWidget(lineedit);
+ lineedit->setFocus();
+#ifdef QT_KEYPAD_NAVIGATION
+ lineedit->setEditFocus(true);
+#endif
+ w.show();
+
+ QDesktopWidget desktop;
+ QRect screenSize = desktop.screenGeometry(&w);
+ if (screenSize.width() > screenSize.height()) {
+ // Crude way of finding out we are running on a qwerty phone.
+ m_phoneIsQwerty = true;
+ return;
+ }
+
+ for (int iterations = 0; iterations < 16; iterations++) {
+ QTest::qWait(500);
+
+ QList<FepReplayEvent> keyEvents;
+
+ keyEvents << FepReplayEvent('9', '9', 0, 0);
+ keyEvents << FepReplayEvent('6', '6', 0, 0);
+ keyEvents << FepReplayEvent('8', '8', 0, 0);
+ keyEvents << FepReplayEvent(EStdKeyRightArrow, EKeyRightArrow, 0, 0);
+
+ foreach(FepReplayEvent event, keyEvents) {
+ event.replay(lineedit);
+ }
+
+ QApplication::processEvents();
+
+ if (lineedit->text().endsWith("you", Qt::CaseInsensitive)) {
+ // Success!
+ return;
+ }
+
+ // Try changing modes.
+ // After 8 iterations, try to press the mode switch twice before typing.
+ for (int c = 0; c <= iterations / 8; c++) {
+ FepReplayEvent(EStdKeyHash, '#', 0, 0).replay(lineedit);
+ }
+ }
+
+ QFAIL("FEP sanity test failed. Either the phone is not set to English, or the test was unable to enable T9");
+#endif
+}
+
+void tst_QInputContext::maximumTextLength()
+{
+ QLineEdit le;
+
+ le.setMaxLength(15);
+ QVariant variant = le.inputMethodQuery(Qt::ImMaximumTextLength);
+ QVERIFY(variant.isValid());
+ QCOMPARE(variant.toInt(), 15);
+
+ QPlainTextEdit pte;
+ // For BC/historical reasons, QPlainTextEdit::inputMethodQuery is protected.
+ variant = static_cast<QWidget *>(&pte)->inputMethodQuery(Qt::ImMaximumTextLength);
+ QVERIFY(!variant.isValid());
+}
+
+class QFilterInputContext : public QInputContext
+{
+public:
+ QFilterInputContext() {}
+ ~QFilterInputContext() {}
+
+ QString identifierName() { return QString(); }
+ QString language() { return QString(); }
+
+ void reset() {}
+
+ bool isComposing() const { return false; }
+
+ bool filterEvent( const QEvent *event )
+ {
+ lastTypes.append(event->type());
+ return false;
+ }
+
+public:
+ QList<QEvent::Type> lastTypes;
+};
+
+void tst_QInputContext::filterMouseEvents()
+{
+ QLineEdit le;
+ le.show();
+ QApplication::setActiveWindow(&le);
+
+ QFilterInputContext *ic = new QFilterInputContext;
+ le.setInputContext(ic);
+ QTest::mouseClick(&le, Qt::LeftButton);
+
+ QVERIFY(ic->lastTypes.indexOf(QEvent::MouseButtonRelease) >= 0);
+
+ le.setInputContext(0);
+}
+
+class RequestSoftwareInputPanelStyle : public QWindowsStyle
+{
+public:
+ RequestSoftwareInputPanelStyle()
+ : m_rsipBehavior(RSIP_OnMouseClickAndAlreadyFocused)
+ {
+#ifdef Q_OS_WINCE
+ qApp->setAutoSipEnabled(true);
+#endif
+ }
+ ~RequestSoftwareInputPanelStyle()
+ {
+ }
+
+ int styleHint(StyleHint hint, const QStyleOption *opt = 0,
+ const QWidget *widget = 0, QStyleHintReturn* returnData = 0) const
+ {
+ if (hint == SH_RequestSoftwareInputPanel) {
+ return m_rsipBehavior;
+ } else {
+ return QWindowsStyle::styleHint(hint, opt, widget, returnData);
+ }
+ }
+
+ RequestSoftwareInputPanel m_rsipBehavior;
+};
+
+void tst_QInputContext::requestSoftwareInputPanel()
+{
+ QStyle *oldStyle = qApp->style();
+ oldStyle->setParent(this); // Prevent it being deleted.
+ RequestSoftwareInputPanelStyle *newStyle = new RequestSoftwareInputPanelStyle;
+ qApp->setStyle(newStyle);
+
+ QWidget w;
+ QLayout *layout = new QVBoxLayout;
+ QLineEdit *le1, *le2;
+ le1 = new QLineEdit;
+ le2 = new QLineEdit;
+ layout->addWidget(le1);
+ layout->addWidget(le2);
+ w.setLayout(layout);
+
+ QFilterInputContext *ic1, *ic2;
+ ic1 = new QFilterInputContext;
+ ic2 = new QFilterInputContext;
+ le1->setInputContext(ic1);
+ le2->setInputContext(ic2);
+
+ w.show();
+ QApplication::setActiveWindow(&w);
+
+ // Testing single click panel activation.
+ newStyle->m_rsipBehavior = QStyle::RSIP_OnMouseClick;
+ QTest::mouseClick(le2, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
+ QVERIFY(ic2->lastTypes.indexOf(QEvent::RequestSoftwareInputPanel) >= 0);
+ ic2->lastTypes.clear();
+
+ // Testing double click panel activation.
+ newStyle->m_rsipBehavior = QStyle::RSIP_OnMouseClickAndAlreadyFocused;
+ QTest::mouseClick(le1, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
+ QVERIFY(ic1->lastTypes.indexOf(QEvent::RequestSoftwareInputPanel) < 0);
+ QTest::mouseClick(le1, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
+ QVERIFY(ic1->lastTypes.indexOf(QEvent::RequestSoftwareInputPanel) >= 0);
+ ic1->lastTypes.clear();
+
+ // Testing right mouse button
+ QTest::mouseClick(le1, Qt::RightButton, Qt::NoModifier, QPoint(5, 5));
+ QVERIFY(ic1->lastTypes.indexOf(QEvent::RequestSoftwareInputPanel) < 0);
+
+ qApp->setStyle(oldStyle);
+ oldStyle->setParent(qApp);
+}
+
+void tst_QInputContext::closeSoftwareInputPanel()
+{
+ QWidget w;
+ QLayout *layout = new QVBoxLayout;
+ QLineEdit *le1, *le2;
+ QRadioButton *rb;
+ le1 = new QLineEdit;
+ le2 = new QLineEdit;
+ rb = new QRadioButton;
+ layout->addWidget(le1);
+ layout->addWidget(le2);
+ layout->addWidget(rb);
+ w.setLayout(layout);
+
+ QFilterInputContext *ic1, *ic2;
+ ic1 = new QFilterInputContext;
+ ic2 = new QFilterInputContext;
+ le1->setInputContext(ic1);
+ le2->setInputContext(ic2);
+
+ w.show();
+ QApplication::setActiveWindow(&w);
+
+ // Testing that panel doesn't close between two input methods aware widgets.
+ QTest::mouseClick(le1, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
+ QTest::mouseClick(le2, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
+ QVERIFY(ic2->lastTypes.indexOf(QEvent::CloseSoftwareInputPanel) < 0);
+
+ // Testing that panel closes when focusing non-aware widget.
+ QTest::mouseClick(rb, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
+ QVERIFY(ic2->lastTypes.indexOf(QEvent::CloseSoftwareInputPanel) >= 0);
+}
+
+void tst_QInputContext::selections()
+{
+ QLineEdit le;
+ le.setText("Test text");
+ le.setSelection(2, 2);
+ QCOMPARE(le.inputMethodQuery(Qt::ImCursorPosition).toInt(), 4);
+ QCOMPARE(le.inputMethodQuery(Qt::ImAnchorPosition).toInt(), 2);
+
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 5, 3, QVariant()));
+ QInputMethodEvent event("", attributes);
+ QApplication::sendEvent(&le, &event);
+ QCOMPARE(le.cursorPosition(), 8);
+ QCOMPARE(le.selectionStart(), 5);
+ QCOMPARE(le.inputMethodQuery(Qt::ImCursorPosition).toInt(), 8);
+ QCOMPARE(le.inputMethodQuery(Qt::ImAnchorPosition).toInt(), 5);
+}
+
+void tst_QInputContext::focusProxy()
+{
+ QWidget toplevel(0, Qt::X11BypassWindowManagerHint); toplevel.setObjectName("toplevel");
+ QWidget w(&toplevel); w.setObjectName("w");
+ QWidget proxy(&w); proxy.setObjectName("proxy");
+ QWidget proxy2(&w); proxy2.setObjectName("proxy2");
+ w.setFocusProxy(&proxy);
+ w.setAttribute(Qt::WA_InputMethodEnabled);
+ toplevel.show();
+ QApplication::setActiveWindow(&toplevel);
+ QTest::qWaitForWindowShown(&toplevel);
+ w.setFocus();
+ w.setAttribute(Qt::WA_NativeWindow); // we shouldn't crash!
+
+ proxy.setAttribute(Qt::WA_InputMethodEnabled);
+ proxy2.setAttribute(Qt::WA_InputMethodEnabled);
+
+ proxy2.setFocus();
+ w.setFocus();
+
+ QInputContext *gic = qApp->inputContext();
+ QVERIFY(gic);
+ QCOMPARE(gic->focusWidget(), &proxy);
+
+ // then change the focus proxy and check that input context is valid
+ QVERIFY(w.hasFocus());
+ QVERIFY(proxy.hasFocus());
+ QVERIFY(!proxy2.hasFocus());
+ w.setFocusProxy(&proxy2);
+ QVERIFY(!w.hasFocus());
+ QVERIFY(proxy.hasFocus());
+ QVERIFY(!proxy2.hasFocus());
+ QCOMPARE(gic->focusWidget(), &proxy);
+}
+
+void tst_QInputContext::contextInheritance()
+{
+ QWidget parent;
+ QWidget child(&parent);
+
+ parent.setAttribute(Qt::WA_InputMethodEnabled, true);
+ child.setAttribute(Qt::WA_InputMethodEnabled, true);
+
+ QCOMPARE(parent.inputContext(), qApp->inputContext());
+ QCOMPARE(child.inputContext(), qApp->inputContext());
+
+ QInputContext *qic = new QFilterInputContext;
+ parent.setInputContext(qic);
+ QCOMPARE(parent.inputContext(), qic);
+ QCOMPARE(child.inputContext(), qic);
+
+ parent.setAttribute(Qt::WA_InputMethodEnabled, false);
+ QVERIFY(!parent.inputContext());
+ QCOMPARE(child.inputContext(), qic);
+ parent.setAttribute(Qt::WA_InputMethodEnabled, true);
+
+ parent.setInputContext(0);
+ QCOMPARE(parent.inputContext(), qApp->inputContext());
+ QCOMPARE(child.inputContext(), qApp->inputContext());
+
+ qic = new QFilterInputContext;
+ qApp->setInputContext(qic);
+ QCOMPARE(parent.inputContext(), qic);
+ QCOMPARE(child.inputContext(), qic);
+}
+
+#ifdef QT_WEBKIT_LIB
+class AutoWebView : public QWebView
+{
+ Q_OBJECT
+
+public:
+ AutoWebView()
+ : m_length(0)
+ , m_mode(QLineEdit::Normal)
+ {
+ updatePage();
+ }
+ ~AutoWebView() {}
+
+ void updatePage()
+ {
+ // The update might reset the input method parameters.
+ bool imEnabled = testAttribute(Qt::WA_InputMethodEnabled);
+ Qt::InputMethodHints hints = inputMethodHints();
+
+ QString page = "<html><body onLoad=\"document.forms.testform.testinput.focus()\">"
+ "<form name=\"testform\"><input name=\"testinput\" type=\"%1\" %2></form></body></html>";
+ if (m_mode == QLineEdit::Password)
+ page = page.arg("password");
+ else
+ page = page.arg("text");
+
+ if (m_length == 0)
+ page = page.arg("");
+ else
+ page = page.arg("maxlength=\"" + QString::number(m_length) + "\"");
+
+ setHtml(page);
+
+ setAttribute(Qt::WA_InputMethodEnabled, imEnabled);
+ setInputMethodHints(hints);
+ }
+ void setMaxLength(int length)
+ {
+ m_length = length;
+ updatePage();
+ }
+ void setEchoMode(QLineEdit::EchoMode mode)
+ {
+ m_mode = mode;
+ updatePage();
+ }
+
+ int m_length;
+ QLineEdit::EchoMode m_mode;
+};
+
+class AutoGraphicsWebView : public QGraphicsView
+{
+ Q_OBJECT
+
+public:
+ AutoGraphicsWebView()
+ : m_length(0)
+ , m_mode(QLineEdit::Normal)
+ {
+ m_scene.addItem(&m_view);
+ setScene(&m_scene);
+ m_view.setFocus();
+ updatePage();
+ }
+ ~AutoGraphicsWebView() {}
+
+ void updatePage()
+ {
+ // The update might reset the input method parameters.
+ bool imEnabled = testAttribute(Qt::WA_InputMethodEnabled);
+ Qt::InputMethodHints hints = inputMethodHints();
+
+ QString page = "<html><body onLoad=\"document.forms.testform.testinput.focus()\">"
+ "<form name=\"testform\"><input name=\"testinput\" type=\"%1\" %2></form></body></html>";
+ if (m_mode == QLineEdit::Password)
+ page = page.arg("password");
+ else
+ page = page.arg("text");
+
+ if (m_length == 0)
+ page = page.arg("");
+ else
+ page = page.arg("maxlength=\"" + QString::number(m_length) + "\"");
+
+ m_view.setHtml(page);
+
+ setAttribute(Qt::WA_InputMethodEnabled, imEnabled);
+ setInputMethodHints(hints);
+ }
+ void setMaxLength(int length)
+ {
+ m_length = length;
+ updatePage();
+ }
+ void setEchoMode(QLineEdit::EchoMode mode)
+ {
+ m_mode = mode;
+ updatePage();
+ }
+
+ int m_length;
+ QLineEdit::EchoMode m_mode;
+ QGraphicsScene m_scene;
+ QGraphicsWebView m_view;
+};
+#endif // QT_WEBKIT_LIB
+
+void tst_QInputContext::symbianTestCoeFepInputContext_data()
+{
+#ifdef Q_OS_SYMBIAN
+ QTest::addColumn<QWidget *> ("editwidget");
+ QTest::addColumn<bool> ("inputMethodEnabled");
+ QTest::addColumn<Qt::InputMethodHints> ("inputMethodHints");
+ QTest::addColumn<int> ("maxLength"); // Zero for no limit
+ QTest::addColumn<QLineEdit::EchoMode> ("echoMode");
+ QTest::addColumn<QList<FepReplayEvent> > ("keyEvents");
+ QTest::addColumn<QString> ("finalString");
+ QTest::addColumn<QString> ("preeditString");
+
+ symbianTestCoeFepInputContext_addData<QLineEdit>();
+ symbianTestCoeFepInputContext_addData<QPlainTextEdit>();
+ symbianTestCoeFepInputContext_addData<QTextEdit>();
+# ifdef QT_WEBKIT_LIB
+ symbianTestCoeFepInputContext_addData<AutoWebView>();
+ symbianTestCoeFepInputContext_addData<AutoGraphicsWebView>();
+# endif
+#endif
+}
+
+Q_DECLARE_METATYPE(QWidget *)
+Q_DECLARE_METATYPE(QLineEdit *)
+Q_DECLARE_METATYPE(QPlainTextEdit *)
+Q_DECLARE_METATYPE(QTextEdit *)
+
+template <class WidgetType>
+void tst_QInputContext::symbianTestCoeFepInputContext_addData()
+{
+#ifdef Q_OS_SYMBIAN
+ QList<FepReplayEvent> events;
+ QWidget *editwidget;
+
+ events << FepReplayEvent(EStdKeyBackspace, EKeyBackspace, 0, 0);
+ events << FepReplayEvent(EStdKeyBackspace, EKeyBackspace, 0, 0);
+ events << FepReplayEvent('5', '5', 0, 0);
+ events << FepReplayEvent('4', '4', 0, 0);
+ events << FepReplayEvent('6', '6', 0, 0);
+ events << FepReplayEvent(EStdKeyBackspace, EKeyBackspace, 0, 0);
+ events << FepReplayEvent(EStdKeyBackspace, EKeyBackspace, 0, 0);
+ events << FepReplayEvent('1', '1', 0, 0);
+ events << FepReplayEvent(EStdKeyBackspace, EKeyBackspace, 0, 0);
+ events << FepReplayEvent('2', '2', 0, 0);
+ events << FepReplayEvent('1', '1', 0, 0);
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Numbers (no FEP)").toLocal8Bit())
+ << editwidget
+ << false
+ << Qt::InputMethodHints(Qt::ImhNone)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("521")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Numbers and password mode (no FEP)").toLocal8Bit())
+ << editwidget
+ << false
+ << Qt::InputMethodHints(Qt::ImhNone)
+ << 0
+ << QLineEdit::Password
+ << events
+ << QString("521")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Numbers").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhDigitsOnly)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("521")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Numbers max length (no FEP)").toLocal8Bit())
+ << editwidget
+ << false
+ << Qt::InputMethodHints(Qt::ImhNone)
+ << 2
+ << QLineEdit::Normal
+ << events
+ << QString("21")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Numbers max length").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhDigitsOnly)
+ << 2
+ << QLineEdit::Normal
+ << events
+ << QString("21")
+ << QString("");
+ events.clear();
+
+ events << FepReplayEvent(EEventKeyDown, '5', 0, 0, 0);
+ events << FepReplayEvent(EEventKey, '5', '5', 0, 0);
+ events << FepReplayEvent(EEventKey, '5', '5', 0, 1);
+ events << FepReplayEvent(EEventKey, '5', '5', 0, 1);
+ events << FepReplayEvent(EEventKeyUp, '5', 0, 0, 0);
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Numbers and autorepeat (no FEP)").toLocal8Bit())
+ << editwidget
+ << false
+ << Qt::InputMethodHints(Qt::ImhNone)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("555")
+ << QString("");
+ events.clear();
+
+ events << FepReplayEvent(EStdKeyBackspace, EKeyBackspace, 0, 0);
+ events << FepReplayEvent('2', '2', 0, 0);
+ events << FepReplayEvent('3', '3', 0, 0);
+ events << FepReplayEvent('4', '4', 0, 0);
+ events << FepReplayEvent('4', '4', 0, 0);
+ events << FepReplayEvent('5', '5', 0, 0);
+ events << FepReplayEvent('5', '5', 0, 0);
+ events << FepReplayEvent(EStdKeyBackspace, EKeyBackspace, 0, 0);
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Multitap").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhNoPredictiveText)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("Adh")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Multitap with no auto uppercase").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("adh")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Multitap with uppercase").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhPreferUppercase)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("ADH")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Multitap with lowercase").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhPreferLowercase)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("adh")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Multitap with forced uppercase").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhUppercaseOnly)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("ADH")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Multitap with forced lowercase").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhLowercaseOnly)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("adh")
+ << QString("");
+ events.clear();
+
+ events << FepReplayEvent(EStdKeyHash, '#', 0, 0);
+ events << FepReplayEvent('2', '2', 0, 0);
+ events << FepReplayEvent('2', '2', 0, 0);
+ events << FepReplayEvent('3', '3', 0, 0);
+ events << FepReplayEvent('4', '4', 0, 0);
+ events << FepReplayEvent('4', '4', 0, 0);
+ events << FepReplayEvent('5', '5', 0, 0);
+ events << FepReplayEvent('5', '5', 0, 0);
+ events << FepReplayEvent(EStdKeyBackspace, EKeyBackspace, 0, 0);
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Multitap with mode switch").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhNoPredictiveText)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("bdh")
+ << QString("");
+ events.clear();
+
+ events << FepReplayEvent('7', '7', 0, 0);
+ events << FepReplayEvent('7', '7', 0, 0);
+ events << FepReplayEvent('8', '8', 0, 0);
+ events << FepReplayEvent('9', '9', 0, 0);
+ events << FepReplayEvent('9', '9', 0, 0);
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Multitap with unfinished text").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhNoPredictiveText)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("Qt")
+ << QString("x");
+ events << FepReplayEvent(2000);
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Multitap with committed text").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhNoPredictiveText)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("Qtx")
+ << QString("");
+ events.clear();
+
+ events << FepReplayEvent('4', '4', 0, 0);
+ events << FepReplayEvent('4', '4', 0, 0);
+ // Simulate holding down hash key.
+ events << FepReplayEvent(EEventKeyDown, EStdKeyHash, 0, 0, 0);
+ events << FepReplayEvent(EEventKey, EStdKeyHash, '#', 0, 0);
+ events << FepReplayEvent(500);
+ events << FepReplayEvent(EEventKey, EStdKeyHash, '#', 0, 1);
+ events << FepReplayEvent(EEventKey, EStdKeyHash, '#', 0, 1);
+ events << FepReplayEvent(EEventKey, EStdKeyHash, '#', 0, 1);
+ events << FepReplayEvent(EEventKeyUp, EStdKeyHash, 0, 0, 0);
+ events << FepReplayEvent('7', '7', 0, 0);
+ events << FepReplayEvent('7', '7', 0, 0);
+ events << FepReplayEvent('8', '8', 0, 0);
+ // QTBUG-9867: Switch back as well to make sure we don't get extra symbols
+ events << FepReplayEvent(EEventKeyDown, EStdKeyHash, 0, 0, 0);
+ events << FepReplayEvent(EEventKey, EStdKeyHash, '#', 0, 0);
+ events << FepReplayEvent(500);
+ events << FepReplayEvent(EEventKey, EStdKeyHash, '#', 0, 1);
+ events << FepReplayEvent(EEventKey, EStdKeyHash, '#', 0, 1);
+ events << FepReplayEvent(EEventKey, EStdKeyHash, '#', 0, 1);
+ events << FepReplayEvent(EEventKeyUp, EStdKeyHash, 0, 0, 0);
+ events << FepReplayEvent('9', '9', 0, 0);
+ events << FepReplayEvent('6', '6', 0, 0);
+ events << FepReplayEvent('8', '8', 0, 0);
+ events << FepReplayEvent(2000);
+ events << FepReplayEvent(EStdKeyDevice3, EKeyDevice3, 0, 0); // Select key
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Multitap and numbers").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhNoPredictiveText)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("H778wmt")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": T9 and numbers").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhPreferLowercase)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("hi778you")
+ << QString("");
+ events.clear();
+
+ events << FepReplayEvent('4', '4', 0, 0);
+ events << FepReplayEvent('4', '4', 0, 0);
+ events << FepReplayEvent(EStdKeyDevice3, EKeyDevice3, 0, 0); // Select key
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": T9").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhPreferLowercase)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("hi")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": T9 with uppercase").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhPreferUppercase)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("HI")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": T9 with forced lowercase").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhLowercaseOnly)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("hi")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": T9 with forced uppercase").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhUppercaseOnly)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("HI")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": T9 with maxlength").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhLowercaseOnly)
+ << 1
+ << QLineEdit::Normal
+ << events
+ << QString("i")
+ << QString("");
+ events.clear();
+
+ events << FepReplayEvent('4', '4', 0, 0);
+ events << FepReplayEvent('4', '4', 0, 0);
+ events << FepReplayEvent(EStdKeyLeftArrow, EKeyLeftArrow, 0, 0);
+ events << FepReplayEvent(EStdKeyLeftArrow, EKeyLeftArrow, 0, 0);
+ events << FepReplayEvent('9', '9', 0, 0);
+ events << FepReplayEvent('6', '6', 0, 0);
+ events << FepReplayEvent('8', '8', 0, 0);
+ events << FepReplayEvent('0', '0', 0, 0);
+ events << FepReplayEvent(EStdKeyRightArrow, EKeyRightArrow, 0, 0);
+ events << FepReplayEvent(EStdKeyRightArrow, EKeyRightArrow, 0, 0);
+ events << FepReplayEvent('8', '8', 0, 0);
+ events << FepReplayEvent('8', '8', 0, 0);
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": T9 with movement and unfinished text").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhPreferLowercase)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("you hi")
+ << QString("tv");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": T9 with movement, password and unfinished text").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhPreferLowercase)
+ << 0
+ << QLineEdit::Password
+ << events
+ << QString("wmt h")
+ << QString("u");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": T9 with movement, maxlength, password and unfinished text").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhPreferLowercase)
+ << 2
+ << QLineEdit::Password
+ << events
+ << QString("wh")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": T9 with movement, maxlength and unfinished text").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhPreferLowercase)
+ << 2
+ << QLineEdit::Normal
+ << events
+ << QString("hi")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Multitap with movement and unfinished text").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhPreferLowercase)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("wmt h")
+ << QString("u");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Multitap with movement, maxlength and unfinished text").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhPreferLowercase)
+ << 2
+ << QLineEdit::Normal
+ << events
+ << QString("wh")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Numbers with movement").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhDigitsOnly)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("96804488")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Numbers with movement and maxlength").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhDigitsOnly)
+ << 2
+ << QLineEdit::Normal
+ << events
+ << QString("44")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Numbers with movement, password and unfinished text").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhDigitsOnly)
+ << 0
+ << QLineEdit::Password
+ << events
+ << QString("9680448")
+ << QString("8");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Numbers with movement, maxlength, password and unfinished text").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhDigitsOnly)
+ << 2
+ << QLineEdit::Password
+ << events
+ << QString("44")
+ << QString("");
+ events << FepReplayEvent(EStdKeyRightArrow, EKeyRightArrow, 0, 0);
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": T9 with movement").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhPreferLowercase)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("you htvi")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": T9 with movement and password").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhPreferLowercase)
+ << 0
+ << QLineEdit::Password
+ << events
+ << QString("wmt hu")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": T9 with movement, maxlength and password").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhPreferLowercase)
+ << 2
+ << QLineEdit::Password
+ << events
+ << QString("wh")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Multitap with movement").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhPreferLowercase)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("wmt hu")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Multitap with movement and maxlength").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhPreferLowercase)
+ << 2
+ << QLineEdit::Normal
+ << events
+ << QString("wh")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Numbers with movement and password").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhDigitsOnly)
+ << 0
+ << QLineEdit::Password
+ << events
+ << QString("96804488")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Numbers with movement, maxlength and password").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhDigitsOnly)
+ << 2
+ << QLineEdit::Password
+ << events
+ << QString("44")
+ << QString("");
+ events.clear();
+
+ // Test that the symbol key successfully does nothing when in number-only mode.
+ events << FepReplayEvent(EEventKeyDown, EStdKeyLeftFunc, 0, 0, 0);
+ events << FepReplayEvent(EEventKeyUp, EStdKeyLeftFunc, 0, 0, 0);
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Dead symbols key").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhDigitsOnly)
+ << 0
+ << QLineEdit::Normal
+ << events
+ << QString("")
+ << QString("");
+ editwidget = new WidgetType;
+ QTest::newRow(QString(QString::fromLatin1(editwidget->metaObject()->className())
+ + ": Dead symbols key and password").toLocal8Bit())
+ << editwidget
+ << true
+ << Qt::InputMethodHints(Qt::ImhDigitsOnly)
+ << 0
+ << QLineEdit::Password
+ << events
+ << QString("")
+ << QString("");
+ events.clear();
+#endif
+}
+
+void tst_QInputContext::symbianTestCoeFepInputContext()
+{
+#ifndef Q_OS_SYMBIAN
+ QSKIP("This is a Symbian-only test", SkipAll);
+#else
+ QCoeFepInputContext *ic = qobject_cast<QCoeFepInputContext *>(qApp->inputContext());
+ if (!ic) {
+ QSKIP("coefep is not the active input context; skipping test", SkipAll);
+ }
+
+ QFETCH(QWidget *, editwidget);
+ QFETCH(bool, inputMethodEnabled);
+ QFETCH(Qt::InputMethodHints, inputMethodHints);
+ QFETCH(int, maxLength);
+ QFETCH(QLineEdit::EchoMode, echoMode);
+ QFETCH(QList<FepReplayEvent>, keyEvents);
+ QFETCH(QString, finalString);
+ QFETCH(QString, preeditString);
+
+ if (inputMethodEnabled && m_phoneIsQwerty) {
+ QSKIP("Skipping advanced input method tests on QWERTY phones", SkipSingle);
+ }
+
+ QWidget w;
+ QLayout *layout = new QVBoxLayout;
+ w.setLayout(layout);
+
+ layout->addWidget(editwidget);
+ editwidget->setFocus();
+#ifdef QT_KEYPAD_NAVIGATION
+ editwidget->setEditFocus(true);
+#endif
+ w.show();
+
+ editwidget->setAttribute(Qt::WA_InputMethodEnabled, inputMethodEnabled);
+ editwidget->setInputMethodHints(inputMethodHints);
+ if (QLineEdit *lineedit = qobject_cast<QLineEdit *>(editwidget)) {
+ if (maxLength > 0)
+ lineedit->setMaxLength(maxLength);
+ lineedit->setEchoMode(echoMode);
+#ifdef QT_WEBKIT_LIB
+ } else if (AutoWebView *webView = qobject_cast<AutoWebView *>(editwidget)) {
+ if (maxLength > 0)
+ webView->setMaxLength(maxLength);
+ webView->setEchoMode(echoMode);
+ // WebKit disables T9 everywhere.
+ if (inputMethodEnabled && !(inputMethodHints & Qt::ImhNoPredictiveText))
+ return;
+ } else if (AutoGraphicsWebView *webView = qobject_cast<AutoGraphicsWebView *>(editwidget)) {
+ if (maxLength > 0)
+ webView->setMaxLength(maxLength);
+ webView->setEchoMode(echoMode);
+ // WebKit disables T9 everywhere.
+ if (inputMethodEnabled && !(inputMethodHints & Qt::ImhNoPredictiveText))
+ return;
+#endif
+ } else if (maxLength > 0 || echoMode != QLineEdit::Normal) {
+ // Only some widgets support these features so don't attempt any tests using those
+ // on other widgets.
+ return;
+ }
+
+ QTest::qWait(200);
+
+ foreach(FepReplayEvent event, keyEvents) {
+ event.replay(editwidget);
+ }
+
+ QApplication::processEvents();
+
+ QCOMPARE(editwidget->inputMethodQuery(Qt::ImSurroundingText).toString(), finalString);
+ QCOMPARE(ic->m_preeditString, preeditString);
+
+ delete editwidget;
+#endif
+}
+
+void tst_QInputContext::symbianTestCoeFepAutoCommit_data()
+{
+#ifdef Q_OS_SYMBIAN
+ QTest::addColumn<Qt::InputMethodHints> ("inputMethodHints");
+ QTest::addColumn<QLineEdit::EchoMode> ("echoMode");
+ QTest::addColumn<QList<FepReplayEvent> > ("keyEvents");
+ QTest::addColumn<QString> ("finalString");
+
+ QList<FepReplayEvent> events;
+
+ events << FepReplayEvent('4', '4', 0, 0);
+ events << FepReplayEvent('4', '4', 0, 0);
+ events << FepReplayEvent('0', '0', 0, 0);
+ events << FepReplayEvent('9', '9', 0, 0);
+ events << FepReplayEvent('6', '6', 0, 0);
+ events << FepReplayEvent('8', '8', 0, 0);
+ QTest::newRow("Numbers")
+ << Qt::InputMethodHints(Qt::ImhDigitsOnly)
+ << QLineEdit::Normal
+ << events
+ << QString("440968");
+ QTest::newRow("Numbers and password")
+ << Qt::InputMethodHints(Qt::ImhDigitsOnly)
+ << QLineEdit::Password
+ << events
+ << QString("440968");
+ QTest::newRow("Multitap")
+ << Qt::InputMethodHints(Qt::ImhPreferLowercase | Qt::ImhNoPredictiveText)
+ << QLineEdit::Normal
+ << events
+ << QString("h wmt");
+ QTest::newRow("T9")
+ << Qt::InputMethodHints(Qt::ImhPreferLowercase)
+ << QLineEdit::Normal
+ << events
+ << QString("hi you");
+ QTest::newRow("Multitap with password")
+ << Qt::InputMethodHints(Qt::ImhPreferLowercase | Qt::ImhNoPredictiveText)
+ << QLineEdit::Password
+ << events
+ << QString("h wmt");
+ QTest::newRow("T9 with password")
+ << Qt::InputMethodHints(Qt::ImhPreferLowercase)
+ << QLineEdit::Password
+ << events
+ << QString("h wmt");
+#endif
+}
+
+void tst_QInputContext::symbianTestCoeFepAutoCommit()
+{
+#ifndef Q_OS_SYMBIAN
+ QSKIP("This is a Symbian-only test", SkipAll);
+#else
+ QCoeFepInputContext *ic = qobject_cast<QCoeFepInputContext *>(qApp->inputContext());
+ if (!ic) {
+ QSKIP("coefep is not the active input context; skipping test", SkipAll);
+ }
+
+ QFETCH(Qt::InputMethodHints, inputMethodHints);
+ QFETCH(QLineEdit::EchoMode, echoMode);
+ QFETCH(QList<FepReplayEvent>, keyEvents);
+ QFETCH(QString, finalString);
+
+ if (m_phoneIsQwerty) {
+ QSKIP("Skipping advanced input method tests on QWERTY phones", SkipSingle);
+ }
+
+ QWidget w;
+ QLayout *layout = new QVBoxLayout;
+ w.setLayout(layout);
+ QLineEdit *lineedit = new QLineEdit;
+ layout->addWidget(lineedit);
+ lineedit->setFocus();
+#ifdef QT_KEYPAD_NAVIGATION
+ lineedit->setEditFocus(true);
+#endif
+ QPushButton *pushButton = new QPushButton("Done");
+ layout->addWidget(pushButton);
+ QAction softkey("Done", &w);
+ softkey.setSoftKeyRole(QAction::PositiveSoftKey);
+ w.addAction(&softkey);
+ w.show();
+
+ lineedit->setInputMethodHints(inputMethodHints);
+ lineedit->setEchoMode(echoMode);
+
+ QTest::qWait(200);
+ foreach(FepReplayEvent event, keyEvents) {
+ event.replay(lineedit);
+ }
+ QApplication::processEvents();
+
+ QTest::mouseClick(pushButton, Qt::LeftButton);
+
+ QCOMPARE(lineedit->text(), finalString);
+ QVERIFY(ic->m_preeditString.isEmpty());
+
+#ifdef Q_WS_S60
+ lineedit->inputContext()->reset();
+ lineedit->clear();
+ lineedit->setFocus();
+#ifdef QT_KEYPAD_NAVIGATION
+ lineedit->setEditFocus(true);
+#endif
+
+ QTest::qWait(200);
+ foreach(FepReplayEvent event, keyEvents) {
+ event.replay(lineedit);
+ }
+ QApplication::processEvents();
+
+ FepReplayEvent(EStdKeyDevice0, EKeyDevice0, 0, 0).replay(lineedit); // Left softkey
+
+ QCOMPARE(lineedit->text(), finalString);
+ QVERIFY(ic->m_preeditString.isEmpty());
+
+#endif // Q_WS_S60
+#endif // Q_OS_SYMBIAN
+}
+
+QTEST_MAIN(tst_QInputContext)
+#include "tst_qinputcontext.moc"