summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2010-09-03 08:15:01 (GMT)
committerAlan Alpert <alan.alpert@nokia.com>2010-09-03 08:15:01 (GMT)
commit1dc5853f7dc40fd18cc5674d89ebc327514449f4 (patch)
tree7a7b00f3b084086efabf8d2d6bb88f244812789a
parentadcb5f115ff768fe68883f392c00e6d2945a377c (diff)
parent9311f0554b885f6b3ab1ab77f9c65b9f89865675 (diff)
downloadQt-1dc5853f7dc40fd18cc5674d89ebc327514449f4.zip
Qt-1dc5853f7dc40fd18cc5674d89ebc327514449f4.tar.gz
Qt-1dc5853f7dc40fd18cc5674d89ebc327514449f4.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7
-rw-r--r--doc/src/declarative/extending.qdoc10
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp12
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp2
-rw-r--r--src/declarative/qml/qdeclarativeobjectscriptclass.cpp16
-rw-r--r--src/declarative/qml/qdeclarativevaluetypescriptclass.cpp2
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_p.h1
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp17
-rw-r--r--src/gui/text/qfont_s60.cpp36
-rw-r--r--tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp2
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectArg.qml9
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectRet.qml11
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/testtypes.h6
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp27
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/aliasPropertiesAndSignals.qml14
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp12
-rw-r--r--tests/auto/qinputcontext/tst_qinputcontext.cpp124
16 files changed, 280 insertions, 21 deletions
diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc
index 6388764..0cc989d 100644
--- a/doc/src/declarative/extending.qdoc
+++ b/doc/src/declarative/extending.qdoc
@@ -674,6 +674,16 @@ declaring a new property, and the corresponding C++ type.
\row \o variant \o QVariant
\endtable
+From QML you can also declare object and list properties using any element name
+like this:
+
+\code
+ property QtObject objectProperty
+ property Item itemProperty
+ property MyCustomType customProperty
+ property list<Item> listOfItemsProperty
+\endcode
+
QML supports two methods for adding a new property to a type: a new property
definition, and a property alias.
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index 7847303..61ea9c8 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -2416,13 +2416,17 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
propBuilder.setWritable(!readonly);
}
- if (mode == ResolveAliases) {
- for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
- const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
+ for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
+ const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
- if (p.type == Object::DynamicProperty::Alias) {
+ if (p.type == Object::DynamicProperty::Alias) {
+ if (mode == ResolveAliases) {
((QDeclarativeVMEMetaData *)dynamicData.data())->aliasCount++;
compileAlias(builder, dynamicData, obj, p);
+ } else {
+ // Need a fake signal so that the metaobject remains consistent across
+ // the resolve and non-resolve alias runs
+ builder.addSignal(p.name + "Changed()");
}
}
}
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 8461368..e77a53e 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -2113,7 +2113,7 @@ bool QDeclarativeEnginePrivate::isQObject(int t)
QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
{
int t = v.userType();
- if (m_compositeTypes.contains(t)) {
+ if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
if (ok) *ok = true;
return *(QObject **)(v.constData());
} else {
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
index f439151..9d74238 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
@@ -625,11 +625,12 @@ private:
char data[4 * sizeof(void *)];
int type;
+ bool isObjectType;
};
}
MetaCallArgument::MetaCallArgument()
-: type(QVariant::Invalid)
+: type(QVariant::Invalid), isObjectType(false)
{
}
@@ -744,12 +745,23 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine,
new (&data) QVariant();
type = -1;
- QVariant v = QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value);
+ QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(engine);
+ QVariant v = priv->scriptValueToVariant(value);
if (v.userType() == callType) {
*((QVariant *)&data) = v;
} else if (v.canConvert((QVariant::Type)callType)) {
*((QVariant *)&data) = v;
((QVariant *)&data)->convert((QVariant::Type)callType);
+ } else if (const QMetaObject *mo = priv->rawMetaObjectForType(callType)) {
+ QObject *obj = priv->toQObject(v);
+
+ if (obj) {
+ const QMetaObject *objMo = obj->metaObject();
+ while (objMo && objMo != mo) objMo = objMo->superClass();
+ if (!objMo) obj = 0;
+ }
+
+ *((QVariant *)&data) = QVariant(callType, &obj);
} else {
*((QVariant *)&data) = QVariant(callType, (void *)0);
}
diff --git a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
index f06d6ae..60f2cb3 100644
--- a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
+++ b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
@@ -168,7 +168,7 @@ void QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier
ref->type->read(ref->object, ref->property);
QMetaProperty p = ref->type->metaObject()->property(m_lastIndex);
- if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::QReal)
+ if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double)
v = v.toInt();
p.write(ref->type, v);
ref->type->write(ref->object, ref->property, 0);
diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h
index 2fd6d16..ac40bba 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_p.h
+++ b/src/gui/inputmethod/qcoefepinputcontext_p.h
@@ -84,6 +84,7 @@ public:
void update();
bool filterEvent(const QEvent *event);
+ bool symbianFilterEvent(QWidget *keyWidget, const QSymbianEvent *event);
void mouseHandler( int x, QMouseEvent *event);
bool isComposing() const { return !m_preeditString.isEmpty(); }
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index add3d17..b08b9a9 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -47,6 +47,7 @@
#include <qgraphicsview.h>
#include <qgraphicsscene.h>
#include <qgraphicswidget.h>
+#include <qsymbianevent.h>
#include <private/qcore_symbian_p.h>
#include <fepitfr.h>
@@ -287,6 +288,18 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
return false;
}
+bool QCoeFepInputContext::symbianFilterEvent(QWidget *keyWidget, const QSymbianEvent *event)
+{
+ Q_UNUSED(keyWidget);
+ if (event->type() == QSymbianEvent::CommandEvent)
+ // A command basically means the same as a button being pushed. With Qt buttons
+ // that would normally result in a reset of the input method due to the focus change.
+ // This should also happen for commands.
+ reset();
+
+ return false;
+}
+
void QCoeFepInputContext::timerEvent(QTimerEvent *timerEvent)
{
if (timerEvent->timerId() == m_tempPreeditStringTimeout.timerId())
@@ -651,7 +664,7 @@ void QCoeFepInputContext::UpdateFepInlineTextL(const TDesC& aNewInlineText,
QInputMethodEvent event(newPreeditString, attributes);
if (newPreeditString.isEmpty() && m_preeditString.isEmpty()) {
// In Symbian world this means "erase last character".
- event.setCommitString("", -1, 1);
+ event.setCommitString(QLatin1String(""), -1, 1);
}
m_preeditString = newPreeditString;
sendEvent(event);
@@ -823,8 +836,6 @@ void QCoeFepInputContext::DoCommitFepInlineEditL()
void QCoeFepInputContext::commitCurrentString(bool cancelFepTransaction)
{
- int longPress = 0;
-
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent event(QLatin1String(""), attributes);
event.setCommitString(m_preeditString, 0, 0);
diff --git a/src/gui/text/qfont_s60.cpp b/src/gui/text/qfont_s60.cpp
index ccd17a2..2d547a9 100644
--- a/src/gui/text/qfont_s60.cpp
+++ b/src/gui/text/qfont_s60.cpp
@@ -40,15 +40,26 @@
****************************************************************************/
#include "qfont.h"
+#include "qfont_p.h"
#include <private/qt_s60_p.h>
#include <private/qpixmap_s60_p.h>
#include "qmutex.h"
QT_BEGIN_NAMESPACE
-#if 1
#ifdef QT_NO_FREETYPE
Q_GLOBAL_STATIC(QMutex, lastResortFamilyMutex);
+Q_GLOBAL_STATIC_WITH_INITIALIZER(QStringList, fontFamiliesOnFontServer, {
+ QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
+ const int numTypeFaces = S60->screenDevice()->NumTypefaces();
+ for (int i = 0; i < numTypeFaces; i++) {
+ TTypefaceSupport typefaceSupport;
+ S60->screenDevice()->TypefaceSupport(typefaceSupport, i);
+ const QString familyName((const QChar *)typefaceSupport.iTypeface.iName.Ptr(), typefaceSupport.iTypeface.iName.Length());
+ x->append(familyName);
+ }
+ lock.relock();
+});
#endif // QT_NO_FREETYPE
QString QFont::lastResortFamily() const
@@ -70,7 +81,7 @@ QString QFont::lastResortFamily() const
lock.relock();
}
return family;
-#else
+#else // QT_NO_FREETYPE
// For the FreeType case we just hard code the face name, since otherwise on
// East Asian systems we may get a name for a stroke based (non-ttf) font.
@@ -82,15 +93,24 @@ QString QFont::lastResortFamily() const
return QLatin1String(isJapaneseOrChineseSystem?"Heisei Kaku Gothic S60":"Series 60 Sans");
#endif // QT_NO_FREETYPE
}
-#else // 0
-QString QFont::lastResortFamily() const
-{
- return QLatin1String("Series 60 Sans");
-}
-#endif // 0
QString QFont::defaultFamily() const
{
+#ifdef QT_NO_FREETYPE
+ switch(d->request.styleHint) {
+ case QFont::SansSerif: {
+ static const char* const preferredSansSerif[] = {"Nokia Sans S60", "Series 60 Sans"};
+ for (int i = 0; i < sizeof preferredSansSerif / sizeof preferredSansSerif[0]; ++i) {
+ const QString sansSerif = QLatin1String(preferredSansSerif[i]);
+ if (fontFamiliesOnFontServer()->contains(sansSerif))
+ return sansSerif;
+ }
+ }
+ // No break. Intentional fall through.
+ default:
+ return lastResortFamily();
+ }
+#endif // QT_NO_FREETYPE
return lastResortFamily();
}
diff --git a/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp b/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp
index 5028ba1..dca5205 100644
--- a/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp
+++ b/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp
@@ -480,7 +480,7 @@ void tst_qdeclarativedom::loadDynamicProperty()
DP_TEST(0, a, QVariant::Int, 25, 14, "int");
DP_TEST(1, b, QVariant::Bool, 44, 15, "bool");
- DP_TEST(2, c, QVariant::Double, 64, 17, "double");
+ DP_TEST(2, c, QMetaType::QReal, 64, 17, "double");
DP_TEST(3, d, QMetaType::QReal, 86, 15, "real");
DP_TEST(4, e, QVariant::String, 106, 17, "string");
DP_TEST(5, f, QVariant::Url, 128, 14, "url");
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectArg.qml b/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectArg.qml
new file mode 100644
index 0000000..d5d3329
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectArg.qml
@@ -0,0 +1,9 @@
+import Qt.test 1.0
+import Qt 4.7
+
+MyQmlObject {
+ id: root
+ Component.onCompleted: {
+ root.myinvokable(root);
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectRet.qml b/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectRet.qml
new file mode 100644
index 0000000..29d7d01
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectRet.qml
@@ -0,0 +1,11 @@
+import Qt.test 1.0
+import Qt 4.7
+
+MyQmlObject {
+ id: root
+ property bool test: false
+ Component.onCompleted: {
+ test = (root.returnme() == root)
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
index 7d7e3d9..220318d 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
+++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
@@ -95,7 +95,7 @@ class MyQmlObject : public QObject
Q_PROPERTY(int nonscriptable READ nonscriptable WRITE setNonscriptable SCRIPTABLE false);
public:
- MyQmlObject(): m_methodCalled(false), m_methodIntCalled(false), m_object(0), m_value(0), m_resetProperty(13) {}
+ MyQmlObject(): myinvokableObject(0), m_methodCalled(false), m_methodIntCalled(false), m_object(0), m_value(0), m_resetProperty(13) {}
enum MyEnum { EnumValue1 = 0, EnumValue2 = 1 };
enum MyEnum2 { EnumValue3 = 2, EnumValue4 = 3 };
@@ -149,6 +149,9 @@ public:
int nonscriptable() const { return 0; }
void setNonscriptable(int) {}
+ MyQmlObject *myinvokableObject;
+ Q_INVOKABLE MyQmlObject *returnme() { return this; }
+
signals:
void basicSignal();
void argumentSignal(int a, QString b, qreal c);
@@ -162,6 +165,7 @@ public slots:
void methodNoArgs() { m_methodCalled = true; }
void method(int a) { if(a == 163) m_methodIntCalled = true; }
void setString(const QString &s) { m_string = s; }
+ void myinvokable(MyQmlObject *o) { myinvokableObject = o; }
private:
friend class tst_qdeclarativeecmascript;
diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
index 76ca964..33bf7ea 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
+++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
@@ -164,6 +164,8 @@ private slots:
void include();
void callQtInvokables();
+ void invokableObjectArg();
+ void invokableObjectRet();
private:
QDeclarativeEngine engine;
};
@@ -1733,6 +1735,31 @@ void tst_qdeclarativeecmascript::callQtInvokables()
QCOMPARE(o.actuals().at(0), QVariant(9));
}
+// QTBUG-13047 (check that you can pass registered object types as args)
+void tst_qdeclarativeecmascript::invokableObjectArg()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("invokableObjectArg.qml"));
+
+ QObject *o = component.create();
+ QVERIFY(o);
+ MyQmlObject *qmlobject = qobject_cast<MyQmlObject *>(o);
+ QVERIFY(qmlobject);
+ QCOMPARE(qmlobject->myinvokableObject, qmlobject);
+
+ delete o;
+}
+
+// QTBUG-13047 (check that you can return registered object types from methods)
+void tst_qdeclarativeecmascript::invokableObjectRet()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("invokableObjectRet.qml"));
+
+ QObject *o = component.create();
+ QVERIFY(o);
+ QCOMPARE(o->property("test").toBool(), true);
+ delete o;
+}
+
// QTBUG-5675
void tst_qdeclarativeecmascript::listToVariant()
{
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/aliasPropertiesAndSignals.qml b/tests/auto/declarative/qdeclarativelanguage/data/aliasPropertiesAndSignals.qml
new file mode 100644
index 0000000..59afe58
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelanguage/data/aliasPropertiesAndSignals.qml
@@ -0,0 +1,14 @@
+import Qt 4.7
+
+QtObject {
+ id: root
+
+ property bool test: false
+ property alias myalias: root.objectName
+ signal go
+ onGo: test = true
+
+ Component.onCompleted: {
+ root.go();
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
index dc00e16..1825991 100644
--- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
+++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
@@ -118,6 +118,7 @@ private slots:
void valueTypes();
void cppnamespace();
void aliasProperties();
+ void aliasPropertiesAndSignals();
void componentCompositeType();
void i18n();
void i18n_data();
@@ -1051,6 +1052,17 @@ void tst_qdeclarativelanguage::aliasProperties()
}
}
+// QTBUG-13374 Test that alias properties and signals can coexist
+void tst_qdeclarativelanguage::aliasPropertiesAndSignals()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertiesAndSignals.qml"));
+ VERIFY_ERRORS(0);
+ QObject *o = component.create();
+ QVERIFY(o);
+ QCOMPARE(o->property("test").toBool(), true);
+ delete o;
+}
+
// Test that the root element in a composite type can be a Component
void tst_qdeclarativelanguage::componentCompositeType()
{
diff --git a/tests/auto/qinputcontext/tst_qinputcontext.cpp b/tests/auto/qinputcontext/tst_qinputcontext.cpp
index 93813f9..52e655b 100644
--- a/tests/auto/qinputcontext/tst_qinputcontext.cpp
+++ b/tests/auto/qinputcontext/tst_qinputcontext.cpp
@@ -49,6 +49,7 @@
#include <qradiobutton.h>
#include <qwindowsstyle.h>
#include <qdesktopwidget.h>
+#include <qpushbutton.h>
#ifdef Q_OS_SYMBIAN
#include <private/qt_s60_p.h>
@@ -80,6 +81,8 @@ private slots:
void focusProxy();
void symbianTestCoeFepInputContext_data();
void symbianTestCoeFepInputContext();
+ void symbianTestCoeFepAutoCommit_data();
+ void symbianTestCoeFepAutoCommit();
private:
bool m_phoneIsQwerty;
@@ -936,5 +939,126 @@ void tst_QInputContext::symbianTestCoeFepInputContext()
#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"