summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2011-02-18 23:32:56 +1000
committerQt Continuous Integration System <qt-info@nokia.com>2011-02-18 23:32:56 +1000
commit5981173f0451736bf2b53e7bf36dbbd02d8f3904 (patch)
tree221c1fa02b03c939ce0023653f96c45145b10a85
parent177131d06d0d7a39d5de210ac8ed5dff9ca4999f (diff)
parent9e063f7e4790cc15b279a44807ff59c620d53ce6 (diff)
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/qt-qml: Fix TextEdit auto test failure on windows. Fix FocusScope example. Fix compilation on old Symbian platforms Export symbols from qtestlib required for QtQuickTest Allow MouseArea to prevent mouse grab begin stolen by Flickable. Fix QTBUG-17008 XmlListModel blocks Windows system events Fix TextInput, TextEdit auto test failure on windows and mac. QDeclarativeDebug: Fix crash when serializing list of QObjects Update the input context when the pre-edit cursor position changes.
-rw-r--r--examples/declarative/keyinteraction/focus/focus.qml2
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp1
-rw-r--r--src/declarative/graphicsitems/qdeclarativemousearea.cpp38
-rw-r--r--src/declarative/graphicsitems/qdeclarativemousearea_p.h5
-rw-r--r--src/declarative/graphicsitems/qdeclarativemousearea_p_p.h3
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput.cpp2
-rw-r--r--src/declarative/qml/qdeclarativeenginedebug.cpp18
-rw-r--r--src/declarative/util/qdeclarativexmllistmodel.cpp170
-rw-r--r--src/gui/widgets/qlinecontrol.cpp3
-rw-r--r--src/gui/widgets/qlinecontrol_p.h1
-rw-r--r--src/testlib/qbenchmark_p.h4
-rw-r--r--src/testlib/qtestcase.cpp42
-rw-r--r--src/testlib/qtestlog_p.h2
-rw-r--r--src/testlib/qtestresult_p.h2
-rw-r--r--src/testlib/qtesttable_p.h2
-rw-r--r--tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp16
-rw-r--r--tests/auto/declarative/qdeclarativemousearea/data/preventstealing.qml24
-rw-r--r--tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp135
-rw-r--r--tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp75
-rw-r--r--tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp61
-rw-r--r--tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp23
-rw-r--r--tools/qml/qmlruntime.cpp2
22 files changed, 514 insertions, 117 deletions
diff --git a/examples/declarative/keyinteraction/focus/focus.qml b/examples/declarative/keyinteraction/focus/focus.qml
index 9cb1fefa30..935db2505c 100644
--- a/examples/declarative/keyinteraction/focus/focus.qml
+++ b/examples/declarative/keyinteraction/focus/focus.qml
@@ -91,7 +91,7 @@ Rectangle {
MouseArea {
anchors.fill: parent; anchors.margins: -10
- onClicked: window.state = "contextMenuOpen"
+ onClicked: contextMenu.focus = true
}
}
diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
index bc4a2d0129..3c8f64e982 100644
--- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
@@ -180,6 +180,7 @@ void QDeclarativeItemModule::defineModule()
qmlRegisterType<QDeclarativePinch>("QtQuick",1,1,"Pinch");
qmlRegisterType<QDeclarativePinchEvent>();
qmlRegisterType<QDeclarativeItem,1>("QtQuick",1,1,"Item");
+ qmlRegisterType<QDeclarativeMouseArea,1>("QtQuick",1,1,"MouseArea");
qmlRegisterType<QDeclarativeFlickable,1>("QtQuick",1,1,"Flickable");
qmlRegisterType<QDeclarativeListView,1>("QtQuick",1,1,"ListView");
qmlRegisterType<QDeclarativeGridView,1>("QtQuick",1,1,"GridView");
diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
index 5b73a29447..da11b007ad 100644
--- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp
+++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
@@ -416,6 +416,40 @@ void QDeclarativeMouseArea::setEnabled(bool a)
emit enabledChanged();
}
}
+
+/*!
+ \qmlproperty bool MouseArea::preventStealing
+ \since Quick 1.1
+ This property holds whether the mouse events may be stolen from this
+ MouseArea.
+
+ If a MouseArea is placed within an item that filters child mouse
+ events, such as Flickable, the mouse
+ events may be stolen from the MouseArea if a gesture is recognized
+ by the parent element, e.g. a flick gesture. If preventStealing is
+ set to true, no element will steal the mouse events.
+
+ Note that setting preventStealing to true once an element has started
+ stealing events will have no effect until the next press event.
+
+ By default this property is false.
+*/
+bool QDeclarativeMouseArea::preventStealing() const
+{
+ Q_D(const QDeclarativeMouseArea);
+ return d->preventStealing;
+}
+
+void QDeclarativeMouseArea::setPreventStealing(bool prevent)
+{
+ Q_D(QDeclarativeMouseArea);
+ if (prevent != d->preventStealing) {
+ d->preventStealing = prevent;
+ setKeepMouseGrab(d->preventStealing && d->absorb);
+ emit preventStealingChanged();
+ }
+}
+
/*!
\qmlproperty MouseButtons MouseArea::pressedButtons
This property holds the mouse buttons currently pressed.
@@ -443,7 +477,7 @@ void QDeclarativeMouseArea::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
Q_D(QDeclarativeMouseArea);
d->moved = false;
- d->stealMouse = false;
+ d->stealMouse = d->preventStealing;
if (!d->absorb)
QDeclarativeItem::mousePressEvent(event);
else {
@@ -460,7 +494,7 @@ void QDeclarativeMouseArea::mousePressEvent(QGraphicsSceneMouseEvent *event)
// we should only start timer if pressAndHold is connected to.
if (d->isPressAndHoldConnected())
d->pressAndHoldTimer.start(PressAndHoldDelay, this);
- setKeepMouseGrab(false);
+ setKeepMouseGrab(d->stealMouse);
event->setAccepted(setPressed(true));
}
}
diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p.h
index 937ac78db0..985f27e480 100644
--- a/src/declarative/graphicsitems/qdeclarativemousearea_p.h
+++ b/src/declarative/graphicsitems/qdeclarativemousearea_p.h
@@ -129,6 +129,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeMouseArea : public QDeclarativeItem
Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons WRITE setAcceptedButtons NOTIFY acceptedButtonsChanged)
Q_PROPERTY(bool hoverEnabled READ hoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged)
Q_PROPERTY(QDeclarativeDrag *drag READ drag CONSTANT) //### add flicking to QDeclarativeDrag or add a QDeclarativeFlick ???
+ Q_PROPERTY(bool preventStealing READ preventStealing WRITE setPreventStealing NOTIFY preventStealingChanged REVISION 1)
public:
QDeclarativeMouseArea(QDeclarativeItem *parent=0);
@@ -153,6 +154,9 @@ public:
QDeclarativeDrag *drag();
+ bool preventStealing() const;
+ void setPreventStealing(bool prevent);
+
Q_SIGNALS:
void hoveredChanged();
void pressedChanged();
@@ -161,6 +165,7 @@ Q_SIGNALS:
void hoverEnabledChanged();
void positionChanged(QDeclarativeMouseEvent *mouse);
void mousePositionChanged(QDeclarativeMouseEvent *mouse);
+ Q_REVISION(1) void preventStealingChanged();
void pressed(QDeclarativeMouseEvent *mouse);
void pressAndHold(QDeclarativeMouseEvent *mouse);
diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h
index 2a327af3ba..67694fb7ae 100644
--- a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h
@@ -68,7 +68,7 @@ class QDeclarativeMouseAreaPrivate : public QDeclarativeItemPrivate
public:
QDeclarativeMouseAreaPrivate()
: absorb(true), hovered(false), pressed(false), longPress(false),
- moved(false), stealMouse(false), doubleClick(false), drag(0)
+ moved(false), stealMouse(false), doubleClick(false), preventStealing(false), drag(0)
{
}
@@ -110,6 +110,7 @@ public:
bool dragY : 1;
bool stealMouse : 1;
bool doubleClick : 1;
+ bool preventStealing : 1;
QDeclarativeDrag *drag;
QPointF startScene;
qreal startX;
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index 3c95ab8ecf..7cf25ba934 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
@@ -1662,6 +1662,8 @@ void QDeclarativeTextInputPrivate::init()
q->connect(QApplication::clipboard(), SIGNAL(dataChanged()),
q, SLOT(q_canPasteChanged()));
#endif // QT_NO_CLIPBOARD
+ q->connect(control, SIGNAL(updateMicroFocus()),
+ q, SLOT(updateMicroFocus()));
q->updateSize();
oldValidity = control->hasAcceptableInput();
lastSelectionStart = 0;
diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp
index 8c7f3adab6..31fd516b80 100644
--- a/src/declarative/qml/qdeclarativeenginedebug.cpp
+++ b/src/declarative/qml/qdeclarativeenginedebug.cpp
@@ -167,17 +167,19 @@ QDeclarativeEngineDebugServer::propertyData(QObject *obj, int propIdx)
QVariant QDeclarativeEngineDebugServer::valueContents(const QVariant &value) const
{
int userType = value.userType();
- if (QDeclarativeValueTypeFactory::isValueType(userType))
- return value;
- /*
- if (QDeclarativeMetaType::isList(userType)) {
- int count = QDeclarativeMetaType::listCount(value);
+ if (value.type() == QVariant::List) {
QVariantList contents;
- for (int i=0; i<count; i++)
- contents << valueContents(QDeclarativeMetaType::listAt(value, i));
+ QVariantList list = value.toList();
+ int count = list.size();
+ for (int i = 0; i < count; i++)
+ contents << valueContents(list.at(i));
return contents;
- } else */
+ }
+
+ if (QDeclarativeValueTypeFactory::isValueType(userType))
+ return value;
+
if (QDeclarativeMetaType::isQObject(userType)) {
QObject *o = QDeclarativeMetaType::toQObject(value);
if (o) {
diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp
index cf3696b44a..5af53e6279 100644
--- a/src/declarative/util/qdeclarativexmllistmodel.cpp
+++ b/src/declarative/util/qdeclarativexmllistmodel.cpp
@@ -46,11 +46,9 @@
#include <QDebug>
#include <QStringList>
-#include <QQueue>
+#include <QMap>
#include <QApplication>
#include <QThread>
-#include <QMutex>
-#include <QWaitCondition>
#include <QXmlQuery>
#include <QXmlResultItems>
#include <QXmlNodeModelIndex>
@@ -58,6 +56,7 @@
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QTimer>
+#include <QMutex>
#include <private/qobject_p.h>
@@ -147,39 +146,32 @@ struct XmlQueryJob
QStringList keyRoleResultsCache;
};
-class QDeclarativeXmlQuery : public QThread
+class QDeclarativeXmlQuery : public QObject
{
Q_OBJECT
public:
QDeclarativeXmlQuery(QObject *parent=0)
- : QThread(parent), m_quit(false), m_abortQueryId(-1), m_queryIds(XMLLISTMODEL_CLEAR_ID + 1) {
+ : QObject(parent), m_queryIds(XMLLISTMODEL_CLEAR_ID + 1) {
qRegisterMetaType<QDeclarativeXmlQueryResult>("QDeclarativeXmlQueryResult");
- m_currentJob.queryId = -1;
+ moveToThread(&m_thread);
+ m_thread.start(QThread::IdlePriority);
}
~QDeclarativeXmlQuery() {
- m_mutex.lock();
- m_quit = true;
- m_condition.wakeOne();
- m_mutex.unlock();
-
- wait();
+ if(m_thread.isRunning()) {
+ m_thread.quit();
+ m_thread.wait();
+ }
}
void abort(int id) {
- QMutexLocker locker(&m_mutex);
- QQueue<XmlQueryJob>::iterator it;
- for (it = m_jobs.begin(); it != m_jobs.end(); ++it) {
- if ((*it).queryId == id) {
- m_jobs.erase(it);
- return;
- }
+ QMutexLocker ml(&m_mutex);
+ if (id != -1) {
+ m_jobs.remove(id);
}
- m_abortQueryId = id;
}
- int doQuery(QString query, QString namespaces, QByteArray data, QList<QDeclarativeXmlListModelRole *> *roleObjects, QStringList keyRoleResultsCache) {
- QMutexLocker locker(&m_mutex);
+ int doQuery(QString query, QString namespaces, QByteArray data, QList<QDeclarativeXmlListModelRole *>* roleObjects, QStringList keyRoleResultsCache) {
XmlQueryJob job;
job.queryId = m_queryIds;
@@ -198,69 +190,69 @@ public:
if (roleObjects->at(i)->isKey())
job.keyRoleQueries << job.roleQueries.last();
}
- m_jobs.enqueue(job);
- m_queryIds++;
- if (!isRunning())
- start(QThread::IdlePriority);
- else
- m_condition.wakeOne();
+ {
+ QMutexLocker ml(&m_mutex);
+ m_jobs.insert(m_queryIds, job);
+ m_queryIds++;
+ if (m_queryIds <= 0)
+ m_queryIds = 1;
+ }
+
+ QMetaObject::invokeMethod(this, "processQuery", Qt::QueuedConnection, Q_ARG(int, job.queryId));
return job.queryId;
}
+private slots:
+ void processQuery(int queryId) {
+ XmlQueryJob job;
+
+ {
+ QMutexLocker ml(&m_mutex);
+ if (!m_jobs.contains(queryId))
+ return;
+ job = m_jobs.value(queryId);
+ }
+
+ QDeclarativeXmlQueryResult r;
+ doQueryJob(&job);
+ doSubQueryJob(&job);
+ r.queryId = job.queryId;
+ r.size = m_size;
+ r.data = m_modelData;
+ r.inserted = m_insertedItemRanges;
+ r.removed = m_removedItemRanges;
+ r.keyRoleResultsCache = job.keyRoleResultsCache;
+
+ {
+ QMutexLocker ml(&m_mutex);
+ if (m_jobs.contains(queryId)) {
+ emit queryCompleted(r);
+ m_jobs.remove(queryId);
+ }
+ }
+ }
+
Q_SIGNALS:
void queryCompleted(const QDeclarativeXmlQueryResult &);
void error(void*, const QString&);
protected:
- void run() {
- m_mutex.lock();
-
- while (!m_quit) {
- if (!m_jobs.isEmpty())
- m_currentJob = m_jobs.dequeue();
- m_mutex.unlock();
-
- QDeclarativeXmlQueryResult r;
- if (m_currentJob.queryId != -1) {
- doQueryJob();
- doSubQueryJob();
- r.queryId = m_currentJob.queryId;
- r.size = m_size;
- r.data = m_modelData;
- r.inserted = m_insertedItemRanges;
- r.removed = m_removedItemRanges;
- r.keyRoleResultsCache = m_currentJob.keyRoleResultsCache;
- }
- m_mutex.lock();
- if (m_currentJob.queryId != -1 && m_abortQueryId != m_currentJob.queryId)
- emit queryCompleted(r);
- if (m_jobs.isEmpty() && !m_quit)
- m_condition.wait(&m_mutex);
- m_currentJob.queryId = -1;
- m_abortQueryId = -1;
- }
-
- m_mutex.unlock();
- }
private:
- void doQueryJob();
- void doSubQueryJob();
- void getValuesOfKeyRoles(QStringList *values, QXmlQuery *query) const;
+ void doQueryJob(XmlQueryJob* job);
+ void doSubQueryJob(XmlQueryJob* job);
+ void getValuesOfKeyRoles(const XmlQueryJob& currentJob, QStringList *values, QXmlQuery *query) const;
void addIndexToRangeList(QList<QDeclarativeXmlListRange> *ranges, int index) const;
private:
QMutex m_mutex;
- QWaitCondition m_condition;
- QQueue<XmlQueryJob> m_jobs;
- XmlQueryJob m_currentJob;
- bool m_quit;
- int m_abortQueryId;
+ QThread m_thread;
+ QMap<int, XmlQueryJob> m_jobs;
+ int m_queryIds;
QString m_prefix;
int m_size;
- int m_queryIds;
QList<QList<QVariant> > m_modelData;
QList<QDeclarativeXmlListRange> m_insertedItemRanges;
QList<QDeclarativeXmlListRange> m_removedItemRanges;
@@ -268,16 +260,16 @@ private:
Q_GLOBAL_STATIC(QDeclarativeXmlQuery, globalXmlQuery)
-void QDeclarativeXmlQuery::doQueryJob()
+void QDeclarativeXmlQuery::doQueryJob(XmlQueryJob* currentJob)
{
- Q_ASSERT(m_currentJob.queryId != -1);
+ Q_ASSERT(currentJob->queryId != -1);
QString r;
QXmlQuery query;
- QBuffer buffer(&m_currentJob.data);
+ QBuffer buffer(&currentJob->data);
buffer.open(QIODevice::ReadOnly);
query.bindVariable(QLatin1String("src"), &buffer);
- query.setQuery(m_currentJob.namespaces + m_currentJob.query);
+ query.setQuery(currentJob->namespaces + currentJob->query);
query.evaluateTo(&r);
//always need a single root element
@@ -285,9 +277,9 @@ void QDeclarativeXmlQuery::doQueryJob()
QBuffer b(&xml);
b.open(QIODevice::ReadOnly);
- QString namespaces = QLatin1String("declare namespace dummy=\"http://qtsotware.com/dummy\";\n") + m_currentJob.namespaces;
+ QString namespaces = QLatin1String("declare namespace dummy=\"http://qtsotware.com/dummy\";\n") + currentJob->namespaces;
QString prefix = QLatin1String("doc($inputDocument)/dummy:items") +
- m_currentJob.query.mid(m_currentJob.query.lastIndexOf(QLatin1Char('/')));
+ currentJob->query.mid(currentJob->query.lastIndexOf(QLatin1Char('/')));
//figure out how many items we are dealing with
int count = -1;
@@ -302,18 +294,16 @@ void QDeclarativeXmlQuery::doQueryJob()
count = item.toAtomicValue().toInt();
}
- m_currentJob.data = xml;
+ currentJob->data = xml;
m_prefix = namespaces + prefix + QLatin1Char('/');
m_size = 0;
if (count > 0)
m_size = count;
}
-void QDeclarativeXmlQuery::getValuesOfKeyRoles(QStringList *values, QXmlQuery *query) const
+void QDeclarativeXmlQuery::getValuesOfKeyRoles(const XmlQueryJob& currentJob, QStringList *values, QXmlQuery *query) const
{
- Q_ASSERT(m_currentJob.queryId != -1);
-
- const QStringList &keysQueries = m_currentJob.keyRoleQueries;
+ const QStringList &keysQueries = currentJob.keyRoleQueries;
QString keysQuery;
if (keysQueries.count() == 1)
keysQuery = m_prefix + keysQueries[0];
@@ -341,34 +331,34 @@ void QDeclarativeXmlQuery::addIndexToRangeList(QList<QDeclarativeXmlListRange> *
ranges->append(qMakePair(index, 1));
}
-void QDeclarativeXmlQuery::doSubQueryJob()
+void QDeclarativeXmlQuery::doSubQueryJob(XmlQueryJob* currentJob)
{
- Q_ASSERT(m_currentJob.queryId != -1);
+ Q_ASSERT(currentJob->queryId != -1);
m_modelData.clear();
- QBuffer b(&m_currentJob.data);
+ QBuffer b(&currentJob->data);
b.open(QIODevice::ReadOnly);
QXmlQuery subquery;
subquery.bindVariable(QLatin1String("inputDocument"), &b);
QStringList keyRoleResults;
- getValuesOfKeyRoles(&keyRoleResults, &subquery);
+ getValuesOfKeyRoles(*currentJob, &keyRoleResults, &subquery);
// See if any values of key roles have been inserted or removed.
m_insertedItemRanges.clear();
m_removedItemRanges.clear();
- if (m_currentJob.keyRoleResultsCache.isEmpty()) {
+ if (currentJob->keyRoleResultsCache.isEmpty()) {
m_insertedItemRanges << qMakePair(0, m_size);
} else {
- if (keyRoleResults != m_currentJob.keyRoleResultsCache) {
+ if (keyRoleResults != currentJob->keyRoleResultsCache) {
QStringList temp;
- for (int i=0; i<m_currentJob.keyRoleResultsCache.count(); i++) {
- if (!keyRoleResults.contains(m_currentJob.keyRoleResultsCache[i]))
+ for (int i=0; i<currentJob->keyRoleResultsCache.count(); i++) {
+ if (!keyRoleResults.contains(currentJob->keyRoleResultsCache[i]))
addIndexToRangeList(&m_removedItemRanges, i);
else
- temp << m_currentJob.keyRoleResultsCache[i];
+ temp << currentJob->keyRoleResultsCache[i];
}
for (int i=0; i<keyRoleResults.count(); i++) {
@@ -379,11 +369,11 @@ void QDeclarativeXmlQuery::doSubQueryJob()
}
}
}
- m_currentJob.keyRoleResultsCache = keyRoleResults;
+ currentJob->keyRoleResultsCache = keyRoleResults;
// Get the new values for each role.
//### we might be able to condense even further (query for everything in one go)
- const QStringList &queries = m_currentJob.roleQueries;
+ const QStringList &queries = currentJob->roleQueries;
for (int i = 0; i < queries.size(); ++i) {
QList<QVariant> resultList;
if (!queries[i].isEmpty()) {
@@ -397,7 +387,7 @@ void QDeclarativeXmlQuery::doSubQueryJob()
item = resultItems.next();
}
} else {
- emit error(m_currentJob.roleQueryErrorId.at(i), queries[i]);
+ emit error(currentJob->roleQueryErrorId.at(i), queries[i]);
}
}
//### should warn here if things have gone wrong.
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index c7a3913d6b..d108ad950a 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -456,6 +456,7 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
#ifndef QT_NO_IM
setPreeditArea(m_cursor, event->preeditString());
#endif //QT_NO_IM
+ const int oldPreeditCursor = m_preeditCursor;
m_preeditCursor = event->preeditString().length();
m_hideCursor = false;
QList<QTextLayout::FormatRange> formats;
@@ -479,6 +480,8 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
updateDisplayText(/*force*/ true);
if (cursorPositionChanged)
emitCursorPositionChanged();
+ else if (m_preeditCursor != oldPreeditCursor)
+ emit updateMicroFocus();
if (isGettingInput)
finishChange(priorState);
}
diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h
index bfe50fe40c..3c505c8696 100644
--- a/src/gui/widgets/qlinecontrol_p.h
+++ b/src/gui/widgets/qlinecontrol_p.h
@@ -425,6 +425,7 @@ Q_SIGNALS:
void textEdited(const QString &);
void resetInputContext();
+ void updateMicroFocus();
void accepted();
void editingFinished();
diff --git a/src/testlib/qbenchmark_p.h b/src/testlib/qbenchmark_p.h
index 9a83a1a766..ace17dbe8b 100644
--- a/src/testlib/qbenchmark_p.h
+++ b/src/testlib/qbenchmark_p.h
@@ -130,7 +130,7 @@ public:
QBenchmarkGlobalData:current is created at the beginning of qExec()
and cleared at the end.
*/
-class QBenchmarkGlobalData
+class Q_TESTLIB_EXPORT QBenchmarkGlobalData
{
public:
static QBenchmarkGlobalData *current;
@@ -161,7 +161,7 @@ private:
created at the beginning of qInvokeTestMethod() and cleared at
the end.
*/
-class QBenchmarkTestMethodData
+class Q_TESTLIB_EXPORT QBenchmarkTestMethodData
{
public:
static QBenchmarkTestMethodData *current;
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 0ceb71dfd0..97f069e9f6 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -956,6 +956,10 @@ static bool isValidSlot(const QMetaMethod &sl)
return true;
}
+Q_TESTLIB_EXPORT bool printAvailableFunctions = false;
+Q_TESTLIB_EXPORT QStringList testFunctions;
+Q_TESTLIB_EXPORT QStringList testTags;
+
static void qPrintTestSlots()
{
for (int i = 0; i < QTest::currentTestObject->metaObject()->methodCount(); ++i) {
@@ -976,7 +980,7 @@ static int qToInt(char *str)
return l;
}
-static void qParseArgs(int argc, char *argv[])
+Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
{
lastTestFuncIdx = -1;
@@ -1025,8 +1029,12 @@ static void qParseArgs(int argc, char *argv[])
"%s", argv[0], testOptions);
exit(0);
} else if (strcmp(argv[i], "-functions") == 0) {
- qPrintTestSlots();
- exit(0);
+ if (qml) {
+ QTest::printAvailableFunctions = true;
+ } else {
+ qPrintTestSlots();
+ exit(0);
+ }
} else if(strcmp(argv[i], "-xunitxml") == 0){
QTestLog::setLogMode(QTestLog::XunitXML);
} else if (strcmp(argv[i], "-xml") == 0) {
@@ -1146,6 +1154,32 @@ static void qParseArgs(int argc, char *argv[])
} else if (argv[i][0] == '-') {
printf("Unknown option: '%s'\n\n%s", argv[i], testOptions);
exit(1);
+ } else if (qml) {
+ // We can't check the availability of test functions until
+ // we load the QML files. So just store the data for now.
+ int colon = -1;
+ int offset;
+ for(offset = 0; *(argv[i]+offset); ++offset) {
+ if (*(argv[i]+offset) == ':') {
+ if (*(argv[i]+offset+1) == ':') {
+ // "::" is used as a test name separator.
+ // e.g. "ClickTests::test_click:row1".
+ ++offset;
+ } else {
+ colon = offset;
+ break;
+ }
+ }
+ }
+ if (colon == -1) {
+ QTest::testFunctions += QString::fromLatin1(argv[i]);
+ QTest::testTags += QString();
+ } else {
+ QTest::testFunctions +=
+ QString::fromLatin1(argv[i], colon);
+ QTest::testTags +=
+ QString::fromLatin1(argv[i] + colon + 1);
+ }
} else {
int colon = -1;
char buf[512], *data=0;
@@ -1695,7 +1729,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
QTEST_ASSERT(metaObject);
QTestResult::setCurrentTestObject(metaObject->className());
- qParseArgs(argc, argv);
+ qtest_qParseArgs(argc, argv, false);
#ifdef QTESTLIB_USE_VALGRIND
if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess) {
const QStringList origAppArgs(QCoreApplication::arguments());
diff --git a/src/testlib/qtestlog_p.h b/src/testlib/qtestlog_p.h
index 08c86d18f8..6648beb2c6 100644
--- a/src/testlib/qtestlog_p.h
+++ b/src/testlib/qtestlog_p.h
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
class QBenchmarkResult;
-class QTestLog
+class Q_TESTLIB_EXPORT QTestLog
{
public:
enum LogMode { Plain = 0, XML, LightXML, XunitXML };
diff --git a/src/testlib/qtestresult_p.h b/src/testlib/qtestresult_p.h
index 15523f52b3..7ff120af77 100644
--- a/src/testlib/qtestresult_p.h
+++ b/src/testlib/qtestresult_p.h
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
class QTestResultPrivate;
class QTestData;
-class QTestResult
+class Q_TESTLIB_EXPORT QTestResult
{
public:
enum TestLocation { NoWhere = 0, DataFunc = 1, InitFunc = 2, Func = 3, CleanupFunc = 4 };
diff --git a/src/testlib/qtesttable_p.h b/src/testlib/qtesttable_p.h
index d085b57a88..f83550617f 100644
--- a/src/testlib/qtesttable_p.h
+++ b/src/testlib/qtesttable_p.h
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
class QTestData;
class QTestTablePrivate;
-class QTestTable
+class Q_TESTLIB_EXPORT QTestTable
{
public:
QTestTable();
diff --git a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp
index 917b8d82bc..d01463e3e0 100644
--- a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp
+++ b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp
@@ -166,8 +166,8 @@ void tst_QDeclarativeDebug::recursiveObjectTest(QObject *o, const QDeclarativeDe
{
const QMetaObject *meta = o->metaObject();
- QDeclarativeType *type = QDeclarativeMetaType::qmlType(o->metaObject());
- QString className = type ? type->qmlTypeName() : QString();
+ QDeclarativeType *type = QDeclarativeMetaType::qmlType(meta);
+ QString className = type ? QString(type->qmlTypeName()) : QString(meta->className());
className = className.mid(className.lastIndexOf(QLatin1Char('/'))+1);
QCOMPARE(oref.debugId(), QDeclarativeDebugService::idForObject(o));
@@ -292,12 +292,21 @@ void tst_QDeclarativeDebug::initTestCase()
QList<QByteArray> qml;
qml << "import QtQuick 1.0\n"
"Item {"
+ "id: root\n"
"width: 10; height: 20; scale: blueRect.scale;"
"Rectangle { id: blueRect; width: 500; height: 600; color: \"blue\"; }"
"Text { color: blueRect.color; }"
"MouseArea {"
"onEntered: { console.log('hello') }"
"}"
+ "property variant varObj\n"
+ "property variant varObjList: []\n"
+ "Component.onCompleted: {\n"
+ "varObj = blueRect;\n"
+ "var list = varObjList;\n"
+ "list[0] = blueRect;\n"
+ "varObjList = list;\n"
+ "}\n"
"}";
// add second component to test multiple root contexts
@@ -741,7 +750,6 @@ void tst_QDeclarativeDebug::queryObject()
QCOMPARE(findProperty(rect.properties(), "color").value(), qVariantFromValue(QColor("blue")));
QCOMPARE(findProperty(text.properties(), "color").value(), qVariantFromValue(QColor("blue")));
-
} else {
foreach(const QDeclarativeDebugObjectReference &child, obj.children())
QCOMPARE(child.properties().count(), 0);
@@ -798,6 +806,8 @@ void tst_QDeclarativeDebug::queryExpressionResult_data()
QTest::newRow("width + 50") << "width + 50" << qVariantFromValue(60);
QTest::newRow("blueRect.width") << "blueRect.width" << qVariantFromValue(500);
QTest::newRow("bad expr") << "aeaef" << qVariantFromValue(QString("<undefined>"));
+ QTest::newRow("QObject*") << "varObj" << qVariantFromValue(QString("<unnamed object>"));
+ QTest::newRow("list of QObject*") << "varObjList" << qVariantFromValue(QString("<unknown value>"));
}
void tst_QDeclarativeDebug::tst_QDeclarativeDebugFileReference()
diff --git a/tests/auto/declarative/qdeclarativemousearea/data/preventstealing.qml b/tests/auto/declarative/qdeclarativemousearea/data/preventstealing.qml
new file mode 100644
index 0000000000..11553fadaf
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativemousearea/data/preventstealing.qml
@@ -0,0 +1,24 @@
+import QtQuick 1.1
+
+Flickable {
+ property bool stealing: true
+ width: 200
+ height: 200
+ contentWidth: 400
+ contentHeight: 400
+ Rectangle {
+ color: "black"
+ width: 400
+ height: 400
+ Rectangle {
+ x: 50; y: 50
+ width: 100; height: 100
+ color: "steelblue"
+ MouseArea {
+ objectName: "mousearea"
+ anchors.fill: parent
+ preventStealing: stealing
+ }
+ }
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp
index 845d6bb5b7..60d51c6cab 100644
--- a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp
+++ b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp
@@ -43,8 +43,10 @@
#include <QtTest/QSignalSpy>
#include <private/qdeclarativemousearea_p.h>
#include <private/qdeclarativerectangle_p.h>
+#include <private/qdeclarativeflickable_p.h>
#include <QtDeclarative/qdeclarativeview.h>
#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeengine.h>
#ifdef Q_OS_SYMBIAN
// In Symbian OS test data is located in applications private dir
@@ -65,6 +67,9 @@ private slots:
void doubleClick();
void clickTwice();
void pressedOrdering();
+ void preventStealing();
+ void testQtQuick11Attributes();
+ void testQtQuick11Attributes_data();
private:
QDeclarativeView *createView();
@@ -356,6 +361,8 @@ void tst_QDeclarativeMouseArea::noOnClickedWithPressAndHold()
QVERIFY(!canvas->rootObject()->property("clicked").toBool());
QVERIFY(canvas->rootObject()->property("held").toBool());
+
+ delete canvas;
}
void tst_QDeclarativeMouseArea::onMousePressRejected()
@@ -399,6 +406,8 @@ void tst_QDeclarativeMouseArea::onMousePressRejected()
QVERIFY(canvas->rootObject()->property("mr1_released").toBool());
QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
+
+ delete canvas;
}
void tst_QDeclarativeMouseArea::doubleClick()
@@ -436,6 +445,7 @@ void tst_QDeclarativeMouseArea::doubleClick()
QCOMPARE(canvas->rootObject()->property("doubleClicked").toInt(), 1);
QCOMPARE(canvas->rootObject()->property("released").toInt(), 2);
+ delete canvas;
}
// QTBUG-14832
@@ -476,6 +486,8 @@ void tst_QDeclarativeMouseArea::clickTwice()
QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 2);
QCOMPARE(canvas->rootObject()->property("released").toInt(), 2);
QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 2);
+
+ delete canvas;
}
void tst_QDeclarativeMouseArea::pressedOrdering()
@@ -512,6 +524,129 @@ void tst_QDeclarativeMouseArea::pressedOrdering()
delete canvas;
}
+void tst_QDeclarativeMouseArea::preventStealing()
+{
+ QDeclarativeView *canvas = createView();
+
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/preventstealing.qml"));
+ canvas->show();
+ canvas->setFocus();
+ QVERIFY(canvas->rootObject() != 0);
+
+ QDeclarativeFlickable *flickable = qobject_cast<QDeclarativeFlickable*>(canvas->rootObject());
+ QVERIFY(flickable != 0);
+
+ QDeclarativeMouseArea *mouseArea = canvas->rootObject()->findChild<QDeclarativeMouseArea*>("mousearea");
+ QVERIFY(mouseArea != 0);
+
+ QSignalSpy mousePositionSpy(mouseArea, SIGNAL(positionChanged(QDeclarativeMouseEvent*)));
+
+ QGraphicsScene *scene = canvas->scene();
+ QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress);
+ pressEvent.setScenePos(QPointF(80, 80));
+ pressEvent.setButton(Qt::LeftButton);
+ pressEvent.setButtons(Qt::LeftButton);
+ QApplication::sendEvent(scene, &pressEvent);
+
+ // Without preventStealing, mouse movement over MouseArea would
+ // cause the Flickable to steal mouse and trigger content movement.
+ QGraphicsSceneMouseEvent moveEvent(QEvent::GraphicsSceneMouseMove);
+ moveEvent.setScenePos(QPointF(70, 70));
+ moveEvent.setButton(Qt::LeftButton);
+ moveEvent.setButtons(Qt::LeftButton);
+ QApplication::sendEvent(scene, &moveEvent);
+
+ moveEvent.setScenePos(QPointF(60, 60));
+ moveEvent.setButton(Qt::LeftButton);
+ moveEvent.setButtons(Qt::LeftButton);
+ QApplication::sendEvent(scene, &moveEvent);
+
+ moveEvent.setScenePos(QPointF(50, 50));
+ moveEvent.setButton(Qt::LeftButton);
+ moveEvent.setButtons(Qt::LeftButton);
+ QApplication::sendEvent(scene, &moveEvent);
+
+ // We should have received all three move events
+ QCOMPARE(mousePositionSpy.count(), 3);
+ QVERIFY(mouseArea->pressed());
+
+ // Flickable content should not have moved.
+ QCOMPARE(flickable->contentX(), 0.);
+ QCOMPARE(flickable->contentY(), 0.);
+
+ QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMouseRelease);
+ releaseEvent.setScenePos(QPointF(50, 50));
+ releaseEvent.setButton(Qt::LeftButton);
+ releaseEvent.setButtons(Qt::LeftButton);
+ QApplication::sendEvent(scene, &releaseEvent);
+
+ // Now allow stealing and confirm Flickable does its thing.
+ canvas->rootObject()->setProperty("stealing", false);
+
+ pressEvent.setScenePos(QPointF(80, 80));
+ QApplication::sendEvent(scene, &pressEvent);
+
+ // Without preventStealing, mouse movement over MouseArea would
+ // cause the Flickable to steal mouse and trigger content movement.
+ moveEvent.setScenePos(QPointF(70, 70));
+ QApplication::sendEvent(scene, &moveEvent);
+
+ moveEvent.setScenePos(QPointF(60, 60));
+ QApplication::sendEvent(scene, &moveEvent);
+
+ moveEvent.setScenePos(QPointF(50, 50));
+ QApplication::sendEvent(scene, &moveEvent);
+
+ // We should only have received the first move event
+ QCOMPARE(mousePositionSpy.count(), 4);
+ // Our press should be taken away
+ QVERIFY(!mouseArea->pressed());
+
+ // Flickable content should have moved.
+ QCOMPARE(flickable->contentX(), 10.);
+ QCOMPARE(flickable->contentY(), 10.);
+
+ releaseEvent.setScenePos(QPointF(50, 50));
+ QApplication::sendEvent(scene, &releaseEvent);
+
+ delete canvas;
+}
+
+void tst_QDeclarativeMouseArea::testQtQuick11Attributes()
+{
+ QFETCH(QString, code);
+ QFETCH(QString, warning);
+ QFETCH(QString, error);
+
+ QDeclarativeEngine engine;
+ QObject *obj;
+
+ QDeclarativeComponent valid(&engine);
+ valid.setData("import QtQuick 1.1; MouseArea { " + code.toUtf8() + " }", QUrl(""));
+ obj = valid.create();
+ QVERIFY(obj);
+ QVERIFY(valid.errorString().isEmpty());
+ delete obj;
+
+ QDeclarativeComponent invalid(&engine);
+ invalid.setData("import QtQuick 1.0; MouseArea { " + code.toUtf8() + " }", QUrl(""));
+ QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
+ obj = invalid.create();
+ QCOMPARE(invalid.errorString(), error);
+ delete obj;
+}
+
+void tst_QDeclarativeMouseArea::testQtQuick11Attributes_data()
+{
+ QTest::addColumn<QString>("code");
+ QTest::addColumn<QString>("warning");
+ QTest::addColumn<QString>("error");
+
+ QTest::newRow("preventStealing") << "preventStealing: true"
+ << "QDeclarativeComponent: Component is not ready"
+ << ":1 \"MouseArea.preventStealing\" is not available in QtQuick 1.0.\n";
+}
+
QTEST_MAIN(tst_QDeclarativeMouseArea)
#include "tst_qdeclarativemousearea.moc"
diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
index 7d5101cb33..a052752fc0 100644
--- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
+++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
@@ -137,6 +137,8 @@ private slots:
void testQtQuick11Attributes();
void testQtQuick11Attributes_data();
+ void preeditMicroFocus();
+
private:
void simulateKey(QDeclarativeView *, int key);
QDeclarativeView *createView(const QString &filename);
@@ -1177,6 +1179,8 @@ void tst_qdeclarativetextedit::dragMouseSelection()
QVERIFY(str2.length() > 3);
QVERIFY(str1 != str2); // Verify the second press and drag is a new selection and doesn't not the first moved.
+
+ delete canvas;
}
void tst_qdeclarativetextedit::mouseSelectionMode_data()
@@ -1460,7 +1464,7 @@ QDeclarativeView *tst_qdeclarativetextedit::createView(const QString &filename)
class MyInputContext : public QInputContext
{
public:
- MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false) {}
+ MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false) {}
~MyInputContext() {}
QString identifierName() { return QString(); }
@@ -1478,8 +1482,22 @@ public:
closeInputPanelReceived = true;
return QInputContext::filterEvent(event);
}
+
+ void update() { updateReceived = true; }
+
+ void sendPreeditText(const QString &text, int cursor)
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes.append(QInputMethodEvent::Attribute(
+ QInputMethodEvent::Cursor, cursor, text.length(), QVariant()));
+
+ QInputMethodEvent event(text, attributes);
+ sendEvent(event);
+ }
+
bool openInputPanelReceived;
bool closeInputPanelReceived;
+ bool updateReceived;
};
void tst_qdeclarativetextedit::textInput()
@@ -1797,6 +1815,61 @@ void tst_qdeclarativetextedit::testQtQuick11Attributes_data()
<< ":1 \"TextEdit.onLinkActivated\" is not available in QtQuick 1.0.\n";
}
+void tst_qdeclarativetextedit::preeditMicroFocus()
+{
+ QString preeditText = "super";
+
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ MyInputContext ic;
+ view.setInputContext(&ic);
+ QDeclarativeTextEdit edit;
+ edit.setPos(0, 0);
+ edit.setFocus(true);
+ scene.addItem(&edit);
+ view.show();
+ QApplication::setActiveWindow(&view);
+ QTest::qWaitForWindowShown(&view);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+
+ QRect currentRect;
+ QRect previousRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect();
+
+ // Verify that the micro focus rect is positioned the same for position 0 as
+ // it would be if there was no preedit text.
+ ic.updateReceived = false;
+ ic.sendPreeditText(preeditText, 0);
+ currentRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect();
+ QCOMPARE(currentRect, previousRect);
+#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+ QCOMPARE(ic.updateReceived, true);
+#endif
+
+ // Verify that the micro focus rect moves to the left as the cursor position
+ // is incremented.
+ for (int i = 1; i <= 5; ++i) {
+ ic.updateReceived = false;
+ ic.sendPreeditText(preeditText, i);
+ currentRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect();
+ QVERIFY(previousRect.left() < currentRect.left());
+#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+ QCOMPARE(ic.updateReceived, true);
+#endif
+ previousRect = currentRect;
+ }
+
+ // Verify that if there is no preedit cursor then the micro focus rect is the
+ // same as it would be if it were positioned at the end of the preedit text.
+ ic.sendPreeditText(preeditText, 0);
+ ic.updateReceived = false;
+ ic.sendEvent(QInputMethodEvent(preeditText, QList<QInputMethodEvent::Attribute>()));
+ currentRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect();
+ QCOMPARE(currentRect, previousRect);
+#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+ QCOMPARE(ic.updateReceived, true);
+#endif
+}
+
QTEST_MAIN(tst_qdeclarativetextedit)
#include "tst_qdeclarativetextedit.moc"
diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
index a6d30a5748..7753f1119f 100644
--- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
+++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
@@ -125,6 +125,7 @@ private slots:
void testQtQuick11Attributes_data();
void preeditAutoScroll();
+ void preeditMicroFocus();
private:
void simulateKey(QDeclarativeView *, int key);
@@ -1419,7 +1420,7 @@ QDeclarativeView *tst_qdeclarativetextinput::createView(const QString &filename)
class MyInputContext : public QInputContext
{
public:
- MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false) {}
+ MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false) {}
~MyInputContext() {}
QString identifierName() { return QString(); }
@@ -1438,6 +1439,8 @@ public:
return QInputContext::filterEvent(event);
}
+ void update() { updateReceived = true; }
+
void sendPreeditText(const QString &text, int cursor)
{
QList<QInputMethodEvent::Attribute> attributes;
@@ -1450,6 +1453,7 @@ public:
bool openInputPanelReceived;
bool closeInputPanelReceived;
+ bool updateReceived;
};
void tst_qdeclarativetextinput::openInputPanelOnClick()
@@ -1800,6 +1804,61 @@ void tst_qdeclarativetextinput::preeditAutoScroll()
QCOMPARE(input.positionAt(input.width()), 5);
}
+void tst_qdeclarativetextinput::preeditMicroFocus()
+{
+ QString preeditText = "super";
+
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ MyInputContext ic;
+ view.setInputContext(&ic);
+ QDeclarativeTextInput input;
+ input.setPos(0, 0);
+ input.setFocus(true);
+ scene.addItem(&input);
+ view.show();
+ QApplication::setActiveWindow(&view);
+ QTest::qWaitForWindowShown(&view);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+
+ QRect currentRect;
+ QRect previousRect = input.inputMethodQuery(Qt::ImMicroFocus).toRect();
+
+ // Verify that the micro focus rect is positioned the same for position 0 as
+ // it would be if there was no preedit text.
+ ic.updateReceived = false;
+ ic.sendPreeditText(preeditText, 0);
+ currentRect = input.inputMethodQuery(Qt::ImMicroFocus).toRect();
+ QCOMPARE(currentRect, previousRect);
+#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+ QCOMPARE(ic.updateReceived, true);
+#endif
+
+ // Verify that the micro focus rect moves to the left as the cursor position
+ // is incremented.
+ for (int i = 1; i <= 5; ++i) {
+ ic.updateReceived = false;
+ ic.sendPreeditText(preeditText, i);
+ currentRect = input.inputMethodQuery(Qt::ImMicroFocus).toRect();
+ QVERIFY(previousRect.left() < currentRect.left());
+#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+ QCOMPARE(ic.updateReceived, true);
+#endif
+ previousRect = currentRect;
+ }
+
+ // Verify that if there is no preedit cursor then the micro focus rect is the
+ // same as it would be if it were positioned at the end of the preedit text.
+ ic.sendPreeditText(preeditText, 0);
+ ic.updateReceived = false;
+ ic.sendEvent(QInputMethodEvent(preeditText, QList<QInputMethodEvent::Attribute>()));
+ currentRect = input.inputMethodQuery(Qt::ImMicroFocus).toRect();
+ QCOMPARE(currentRect, previousRect);
+#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+ QCOMPARE(ic.updateReceived, true);
+#endif
+}
+
QTEST_MAIN(tst_qdeclarativetextinput)
#include "tst_qdeclarativetextinput.moc"
diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp
index 19d796721f..af54008f57 100644
--- a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp
+++ b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp
@@ -569,6 +569,11 @@ void tst_qdeclarativexmllistmodel::reload()
QSignalSpy spyRemove(model, SIGNAL(itemsRemoved(int,int)));
QSignalSpy spyCount(model, SIGNAL(countChanged()));
+ //reload multiple times to test the xml query aborting
+ model->reload();
+ model->reload();
+ QCoreApplication::processEvents();
+ model->reload();
model->reload();
QTRY_COMPARE(spyCount.count(), 1);
QTRY_COMPARE(spyInsert.count(), 1);
@@ -839,9 +844,27 @@ void tst_qdeclarativexmllistmodel::threading()
data3 += "name=C" + QString::number(i) + ",age=3" + QString::number(i) + ",sport=Curling;";
}
+ //Set the xml data multiple times with randomized order and mixed with multiple event loops
+ //to test the xml query reloading/aborting, the result should be stable.
+ m1->setXml(makeItemXmlAndData(data1));
+ m2->setXml(makeItemXmlAndData(data2));
+ m3->setXml(makeItemXmlAndData(data3));
+ QCoreApplication::processEvents();
+ m2->setXml(makeItemXmlAndData(data2));
m1->setXml(makeItemXmlAndData(data1));
m2->setXml(makeItemXmlAndData(data2));
+ QCoreApplication::processEvents();
+ m3->setXml(makeItemXmlAndData(data3));
+ QCoreApplication::processEvents();
+ m2->setXml(makeItemXmlAndData(data2));
+ m1->setXml(makeItemXmlAndData(data1));
+ m2->setXml(makeItemXmlAndData(data2));
+ m3->setXml(makeItemXmlAndData(data3));
+ QCoreApplication::processEvents();
+ m2->setXml(makeItemXmlAndData(data2));
+ m3->setXml(makeItemXmlAndData(data3));
m3->setXml(makeItemXmlAndData(data3));
+ QCoreApplication::processEvents();
QTRY_VERIFY(m1->count() == dataCount && m2->count() == dataCount && m3->count() == dataCount);
diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp
index 36915d12bf..c746d8e6b4 100644
--- a/tools/qml/qmlruntime.cpp
+++ b/tools/qml/qmlruntime.cpp
@@ -50,7 +50,7 @@
# include <QWidgetAction>
# include <QStringListModel>
# include "ui_recopts_maemo5.h"
-#else
+#elif !defined(__SERIES60_31__) && !defined(__S60_32__)
# include "ui_recopts.h"
#endif