From 9e2179544157a28aadfbbeaaf787a4a29f9996a2 Mon Sep 17 00:00:00 2001
From: Andy Shaw <qt-info@nokia.com>
Date: Wed, 26 Jan 2011 13:01:08 +0100
Subject: Plug memory leak when using qt_mac_set_dock_menu() on Cocoa

Task-number: QTBUG-16918
Reviewed-by: Richard Moe Gustavsen
---
 src/gui/kernel/qt_cocoa_helpers_mac.mm | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index 3820bfc..20c1ddb 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -1391,6 +1391,7 @@ void qt_mac_constructQIconFromIconRef(const IconRef icon, const IconRef overlayI
 
 void qt_mac_menu_collapseSeparators(void */*NSMenu **/ theMenu, bool collapse)
 {
+    QMacCocoaAutoReleasePool pool;
     OSMenuRef menu = static_cast<OSMenuRef>(theMenu);
     if (collapse) {
         bool previousIsSeparator = true; // setting to true kills all the separators placed at the top.
-- 
cgit v0.12


From e340844bd614add505a39a3a6b915632476f6305 Mon Sep 17 00:00:00 2001
From: Gabriel de Dietrich <gabriel.dietrich-de@nokia.com>
Date: Tue, 15 Feb 2011 11:19:26 +0100
Subject: Fix crash in KPackageKit

QTreeViewPrivate::itemHeight() may refer to an invalid QModelIndex
after calling QTreeView::indexRowSizeHint().

Same thing inside QTreeView::indexRowSizeHint(), since
QHeaderView::count() will call
QAbstractItemViewPrivate::executePostedLayout() which may invalidate
all the QModelIndex.

Reviewed-by: Olivier
Task-number: QTBUG-16292
---
 src/gui/itemviews/qtreeview.cpp | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp
index f1f3236..c0573bb 100644
--- a/src/gui/itemviews/qtreeview.cpp
+++ b/src/gui/itemviews/qtreeview.cpp
@@ -2753,6 +2753,7 @@ int QTreeView::indexRowSizeHint(const QModelIndex &index) const
 
     int start = -1;
     int end = -1;
+    int indexRow = index.row();
     int count = d->header->count();
     bool emptyHeader = (count == 0);
     QModelIndex parent = index.parent();
@@ -2789,7 +2790,7 @@ int QTreeView::indexRowSizeHint(const QModelIndex &index) const
         int logicalColumn = emptyHeader ? column : d->header->logicalIndex(column);
         if (d->header->isSectionHidden(logicalColumn))
             continue;
-        QModelIndex idx = d->model->index(index.row(), logicalColumn, parent);
+        QModelIndex idx = d->model->index(indexRow, logicalColumn, parent);
         if (idx.isValid()) {
             QWidget *editor = d->editorForIndex(idx).editor;
             if (editor && d->persistent.contains(editor)) {
@@ -3224,14 +3225,14 @@ int QTreeViewPrivate::itemHeight(int item) const
     if (viewItems.isEmpty())
         return 0;
     const QModelIndex &index = viewItems.at(item).index;
+    if (!index.isValid())
+        return 0;
     int height = viewItems.at(item).height;
-    if (height <= 0 && index.isValid()) {
+    if (height <= 0) {
         height = q_func()->indexRowSizeHint(index);
         viewItems[item].height = height;
     }
-    if (!index.isValid() || height < 0)
-        return 0;
-    return height;
+    return qMax(height, 0);
 }
 
 
-- 
cgit v0.12


From 6c3868572d8f109884a1b3fb806331fda3ef84d4 Mon Sep 17 00:00:00 2001
From: Andrew den Exter <andrew.den-exter@nokia.com>
Date: Wed, 9 Feb 2011 10:23:03 +1000
Subject: Update the input context when the pre-edit cursor position changes.

The micro focus rect changes both when the regular cursor position
and the pre-edit cursor positions change.  Ensure updateMicroFocus
is called TextInput in both cases.

Change-Id: I6822a710b841e106ce2462f74fea398250596913
Task-number: QTBUG-17396
Reviewed-by: Martin Jones
---
 .../graphicsitems/qdeclarativetextinput.cpp        |  2 +
 src/gui/widgets/qlinecontrol.cpp                   |  3 +
 src/gui/widgets/qlinecontrol_p.h                   |  1 +
 .../tst_qdeclarativetextedit.cpp                   | 67 +++++++++++++++++++++-
 .../tst_qdeclarativetextinput.cpp                  | 55 +++++++++++++++++-
 5 files changed, 126 insertions(+), 2 deletions(-)

diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index 88f36b4..e7c2ac7 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/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index c7a3913..d108ad9 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 bfe50fe..3c505c8 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/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
index 7d5101c..7226dc9 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);
@@ -1460,7 +1462,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 +1480,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 +1813,55 @@ 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);
+    QCOMPARE(ic.updateReceived, true);
+
+    // 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());
+        QCOMPARE(ic.updateReceived, true);
+        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);
+    QCOMPARE(ic.updateReceived, true);
+}
+
 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 a6d30a5..77cb323 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,55 @@ 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);
+    QCOMPARE(ic.updateReceived, true);
+
+    // 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());
+        QCOMPARE(ic.updateReceived, true);
+        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);
+    QCOMPARE(ic.updateReceived, true);
+}
+
 QTEST_MAIN(tst_qdeclarativetextinput)
 
 #include "tst_qdeclarativetextinput.moc"
-- 
cgit v0.12


From 35a36e91606eaf8374a2273cbb0101e0e614321e Mon Sep 17 00:00:00 2001
From: Kai Koehne <kai.koehne@nokia.com>
Date: Tue, 15 Feb 2011 14:00:27 +0100
Subject: QDeclarativeDebug: Fix crash when serializing list of QObjects

Task-number: QTBUG-17444
Reviewed-by: Aaron Kennedy
---
 src/declarative/qml/qdeclarativeenginedebug.cpp        | 18 ++++++++++--------
 .../qdeclarativedebug/tst_qdeclarativedebug.cpp        | 16 +++++++++++++---
 2 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp
index 8c7f3ad..31fd516 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/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp
index 917b8d8..d01463e 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()
-- 
cgit v0.12


From 89b754d30eaa5c9c57fb50bc563a3c60cc314c4e Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@nokia.com>
Date: Wed, 16 Feb 2011 10:29:50 +0100
Subject: Use QElapsedTimer in QFutureInterface.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

QElapsedTimer can also keep its on vlaid/invalid state, so we don't
need to keep an additional boolean.

Task-number: https://projects.maemo.org/bugzilla/show_bug.cgi?id=227660
Reviewed-by: Morten Sørvig
---
 src/corelib/concurrent/qfutureinterface.cpp | 9 +++++----
 src/corelib/concurrent/qfutureinterface_p.h | 5 ++---
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/corelib/concurrent/qfutureinterface.cpp b/src/corelib/concurrent/qfutureinterface.cpp
index 6256944..627d0c7 100644
--- a/src/corelib/concurrent/qfutureinterface.cpp
+++ b/src/corelib/concurrent/qfutureinterface.cpp
@@ -421,9 +421,11 @@ bool QFutureInterfaceBase::referenceCountIsOne() const
 
 QFutureInterfaceBasePrivate::QFutureInterfaceBasePrivate(QFutureInterfaceBase::State initialState)
     : refCount(1), m_progressValue(0), m_progressMinimum(0), m_progressMaximum(0),
-      state(initialState), progressTimeStarted(false), pendingResults(0),
+      state(initialState), pendingResults(0),
       manualProgress(false), m_expectedResultCount(0), runnable(0)
-{ }
+{
+    progressTime.invalidate();
+}
 
 int QFutureInterfaceBasePrivate::internal_resultCount() const
 {
@@ -455,12 +457,11 @@ bool QFutureInterfaceBasePrivate::internal_updateProgress(int progress,
     m_progressValue = progress;
     m_progressText = progressText;
 
-    if (progressTimeStarted == true && m_progressValue != m_progressMaximum) // make sure the first and last steps are emitted.
+    if (progressTime.isValid() && m_progressValue != m_progressMaximum) // make sure the first and last steps are emitted.
         if (progressTime.elapsed() < (1000 / MaxProgressEmitsPerSecond))
             return false;
 
     progressTime.start();
-    progressTimeStarted = true;
     return true;
 }
 
diff --git a/src/corelib/concurrent/qfutureinterface_p.h b/src/corelib/concurrent/qfutureinterface_p.h
index 7f93c75..538947e 100644
--- a/src/corelib/concurrent/qfutureinterface_p.h
+++ b/src/corelib/concurrent/qfutureinterface_p.h
@@ -53,7 +53,7 @@
 // We mean it.
 //
 
-#include <QtCore/qdatetime.h>
+#include <QtCore/qelapsedtimer.h>
 #include <QtCore/qcoreevent.h>
 #include <QtCore/qlist.h>
 #include <QtCore/qwaitcondition.h>
@@ -137,8 +137,7 @@ public:
     int m_progressMinimum;
     int m_progressMaximum;
     QFutureInterfaceBase::State state;
-    QTime progressTime;
-    bool progressTimeStarted;
+    QElapsedTimer progressTime;
     QWaitCondition pausedWaitCondition;
     int pendingResults;
     QtConcurrent::ResultStoreBase m_results;
-- 
cgit v0.12


From df129c2449181869f0b95ae92d174b9eca52b2f7 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@nokia.com>
Date: Wed, 16 Feb 2011 11:06:08 +0100
Subject: Add a mutex to protect the access to the QSet.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

In theory, there should be no problems with doing this unlocked,
as the test should only run one thread at a time in this particular
code section.

In practice, if the test is failing, multiple threads would be
modifying the QSet. So the mutex is necessary to detect the
test failing.

Reviewed-By: Morten Sørvig
---
 .../auto/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tests/auto/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp b/tests/auto/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
index a6499ff..92e8608 100644
--- a/tests/auto/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
+++ b/tests/auto/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
@@ -201,6 +201,7 @@ void tst_QtConcurrentIterateKernel::noIterations()
         startThreadEngine(new IterateKernel<TestIterator, void>(0, 0)).startBlocking();
 }
 
+QMutex threadsMutex;
 QSet<QThread *> threads;
 class ThrottleFor : public IterateKernel<TestIterator, void>
 {
@@ -219,8 +220,10 @@ public:
 
         QThread *thread = QThread::currentThread();
 
-        if (begin > 140 && end < 160)
+        if (begin > 140 && end < 160) {
+            QMutexLocker locker(&threadsMutex);
             threads.insert(thread);
+        }
 
         if (100 >= begin && 100 < end) {
             throttling = true;
-- 
cgit v0.12


From 02f2ac6d090547f5b13534d77fe7761d6f236fb2 Mon Sep 17 00:00:00 2001
From: Martin Petersson <martin.petersson@nokia.com>
Date: Wed, 16 Feb 2011 12:46:36 +0100
Subject: SSL: fix memory leak when loading certificates on Mac OS X

Reviewed-by: Markus Goetz
---
 src/network/ssl/qsslsocket_openssl.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 7d21bd3..84e14ff 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -780,6 +780,7 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
                     systemCerts.append(QSslCertificate::fromData(rawCert, QSsl::Der));
                 }
             }
+            CFRelease(cfCerts);
         }
         else {
            // no detailed error handling here
-- 
cgit v0.12


From bfdecd0e2047fc49ed28ed095e657080897c91d1 Mon Sep 17 00:00:00 2001
From: Andrew den Exter <andrew.den-exter@nokia.com>
Date: Wed, 16 Feb 2011 17:08:10 +1000
Subject: Fix TextInput, TextEdit auto test failure on windows and mac.

Micro focus is only updated on X11, QWS and Symbian platforms.

Change-Id: Id02655cba79429e91022593ff0d1d6b8068c84ec
Reviewed-by: Martin Jones
---
 .../declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp   | 6 ++++++
 .../declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp | 6 ++++++
 2 files changed, 12 insertions(+)

diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
index 7226dc9..87c2c60 100644
--- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
+++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
@@ -1839,7 +1839,9 @@ void tst_qdeclarativetextedit::preeditMicroFocus()
     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.
@@ -1848,7 +1850,9 @@ void tst_qdeclarativetextedit::preeditMicroFocus()
         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;
     }
 
@@ -1859,7 +1863,9 @@ void tst_qdeclarativetextedit::preeditMicroFocus()
     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)
diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
index 77cb323..7753f11 100644
--- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
+++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
@@ -1830,7 +1830,9 @@ void tst_qdeclarativetextinput::preeditMicroFocus()
     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.
@@ -1839,7 +1841,9 @@ void tst_qdeclarativetextinput::preeditMicroFocus()
         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;
     }
 
@@ -1850,7 +1854,9 @@ void tst_qdeclarativetextinput::preeditMicroFocus()
     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)
-- 
cgit v0.12


From 4df66da8f9e5a9f3c981c6c60254899146dd1cc0 Mon Sep 17 00:00:00 2001
From: Charles Yin <charles.yin@nokia.com>
Date: Thu, 3 Feb 2011 13:54:13 +1000
Subject: Fix QTBUG-17008 XmlListModel blocks Windows system events

XmlListModel uses a worker thread to process XML query, however the
worker thread doesn't use it's own event loop. So after processing the
query, the worker thread just blocks on a wait condition and then blocks
all posted system events.

Change-Id: Icdd9ddd1f3f26fd632726f7200c2a81b0877d2d1
Task-number:QTBUG-17008
Reviewed-by:Martin Jones
---
 src/declarative/util/qdeclarativexmllistmodel.cpp  | 170 ++++++++++-----------
 .../tst_qdeclarativexmllistmodel.cpp               |  23 +++
 2 files changed, 103 insertions(+), 90 deletions(-)

diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp
index 976fc4a..5ed10cf 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>
 
@@ -142,39 +141,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;
@@ -193,69 +185,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;
@@ -263,16 +255,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
@@ -280,9 +272,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;
@@ -297,18 +289,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];
@@ -336,34 +326,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++) {
@@ -374,11 +364,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()) {
@@ -392,7 +382,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/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp
index 19d7967..af54008 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);
 
-- 
cgit v0.12


From 57676c237992e0aa5a93a4e8fa66b3e7b90c2c90 Mon Sep 17 00:00:00 2001
From: Martin Jones <martin.jones@nokia.com>
Date: Thu, 17 Feb 2011 14:54:09 +1000
Subject: Allow MouseArea to prevent mouse grab begin stolen by Flickable.

Placing a MouseArea in a Flickable (or PinchArea, or PathView) allows
the Flickable to steal mouse events when it detects a flick/drag event.
In some cases this is not desireable and MouseArea should be able to
retain its grab.  Added a 'preventStealing' property to prevent
an ancestor item from stealing the MouseArea's grab.

Change-Id: I6277fbb76919b2b35d4e32a247b38a90e305dbdf
Task-number: QTBUG-17285
Reviewed-by: Joona Petrell
---
 .../graphicsitems/qdeclarativeitemsmodule.cpp      |   1 +
 .../graphicsitems/qdeclarativemousearea.cpp        |  38 +++++-
 .../graphicsitems/qdeclarativemousearea_p.h        |   5 +
 .../graphicsitems/qdeclarativemousearea_p_p.h      |   3 +-
 .../qdeclarativemousearea/data/preventstealing.qml |  24 ++++
 .../tst_qdeclarativemousearea.cpp                  | 135 +++++++++++++++++++++
 6 files changed, 203 insertions(+), 3 deletions(-)
 create mode 100644 tests/auto/declarative/qdeclarativemousearea/data/preventstealing.qml

diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
index bc4a2d0..3c8f64e 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 0aa0c1b..1308e73 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 937ac78..985f27e 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 2a327af..67694fb 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/tests/auto/declarative/qdeclarativemousearea/data/preventstealing.qml b/tests/auto/declarative/qdeclarativemousearea/data/preventstealing.qml
new file mode 100644
index 0000000..11553fa
--- /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 845d6bb..60d51c6 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"
-- 
cgit v0.12


From dfde84cccb14b109bebd672108a0ce0d6131361f Mon Sep 17 00:00:00 2001
From: Ademar de Souza Reis Jr <ademar.reis@openbossa.org>
Date: Wed, 16 Feb 2011 17:05:55 -0300
Subject: Bump QtWebKit version to 2.0.2

QtWebKit 2.0.1 was part of Qt-4.7.1, QtWebKit as included
in 4.7.2 should be 2.0.2.

Merge-request: 1095
Task-number: QTBUG-17480
Reviewed-by: Jason McDonald
---
 src/3rdparty/webkit/WebKit/qt/Api/qwebkitglobal.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebkitglobal.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebkitglobal.h
index 63d9e55..2c0bf6d 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebkitglobal.h
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebkitglobal.h
@@ -22,9 +22,9 @@
 
 #include <QtCore/qglobal.h>
 
-#define QTWEBKIT_VERSION_STR "2.0.1"
+#define QTWEBKIT_VERSION_STR "2.0.2"
 // QTWEBKIT_VERSION is (major << 16) + (minor << 8) + patch. Similar to Qt.
-#define QTWEBKIT_VERSION 0x020001
+#define QTWEBKIT_VERSION 0x020002
 // Use: #if (QTWEBKIT_VERSION >= QTWEBKIT_VERSION_CHECK(2, 0, 0)). Similar to Qt.
 #define QTWEBKIT_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
 
-- 
cgit v0.12


From baed5fdbc1d14e3190b9834f00be9926f9600d62 Mon Sep 17 00:00:00 2001
From: Denis Oliver Kropp <dok@directfb.org>
Date: Thu, 17 Feb 2011 15:28:47 +0100
Subject: fix-layer-getsurface-result-check-for-screen-size-determination

GetSurface() was checked for NOT returning DFB_OK, but it should

Merge-request: 2528
Reviewed-by: Marcel Schuette <marcel.schuette@nokia.com>
---
 src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
index 09cc465..ff15078 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
@@ -1285,7 +1285,7 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
         result = d_ptr->primarySurface->GetSize(d_ptr->primarySurface, &w, &h);
 #elif (Q_DIRECTFB_VERSION >= 0x010000)
         IDirectFBSurface *layerSurface;
-        if (d_ptr->dfbLayer->GetSurface(d_ptr->dfbLayer, &layerSurface) != DFB_OK) {
+        if (d_ptr->dfbLayer->GetSurface(d_ptr->dfbLayer, &layerSurface) == DFB_OK) {
             result = layerSurface->GetSize(layerSurface, &w, &h);
             layerSurface->Release(layerSurface);
         }
-- 
cgit v0.12


From 1b5ee40f491daf0f0b1d44b648ffb7b0ca8b8a63 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@nokia.com>
Date: Thu, 10 Feb 2011 11:23:17 +0100
Subject: Make the QtDBus parser not complain about unknown things

Keep only the warnings about application errors. If the unknown things
come from the outside, it's not our job to make noise.

Task-number: QTBUG-17476
---
 src/dbus/qdbusdemarshaller.cpp                   | 14 +++----
 src/dbus/qdbusxmlparser.cpp                      | 52 +++++++++++++-----------
 tests/auto/qdbusxmlparser/tst_qdbusxmlparser.cpp | 13 +++---
 3 files changed, 43 insertions(+), 36 deletions(-)

diff --git a/src/dbus/qdbusdemarshaller.cpp b/src/dbus/qdbusdemarshaller.cpp
index ab1455f..91dbf25 100644
--- a/src/dbus/qdbusdemarshaller.cpp
+++ b/src/dbus/qdbusdemarshaller.cpp
@@ -176,10 +176,10 @@ QDBusArgument::ElementType QDBusDemarshaller::currentType()
     case DBUS_TYPE_INVALID:
         return QDBusArgument::UnknownType;
 
-    default:
-        qWarning("QDBusDemarshaller: Found unknown D-Bus type %d '%c'",
-                 q_dbus_message_iter_get_arg_type(&iterator),
-                 q_dbus_message_iter_get_arg_type(&iterator));
+//    default:
+//        qWarning("QDBusDemarshaller: Found unknown D-Bus type %d '%c'",
+//                 q_dbus_message_iter_get_arg_type(&iterator),
+//                 q_dbus_message_iter_get_arg_type(&iterator));
     }
     return QDBusArgument::UnknownType;
 }
@@ -232,9 +232,9 @@ QVariant QDBusDemarshaller::toVariantInternal()
         return qVariantFromValue(duplicate());
 
     default:
-        qWarning("QDBusDemarshaller: Found unknown D-Bus type %d '%c'",
-                 q_dbus_message_iter_get_arg_type(&iterator),
-                 q_dbus_message_iter_get_arg_type(&iterator));
+//        qWarning("QDBusDemarshaller: Found unknown D-Bus type %d '%c'",
+//                 q_dbus_message_iter_get_arg_type(&iterator),
+//                 q_dbus_message_iter_get_arg_type(&iterator));
         return QVariant();
         break;
     };
diff --git a/src/dbus/qdbusxmlparser.cpp b/src/dbus/qdbusxmlparser.cpp
index 1b99ced..413ebbe 100644
--- a/src/dbus/qdbusxmlparser.cpp
+++ b/src/dbus/qdbusxmlparser.cpp
@@ -52,6 +52,13 @@
 
 #ifndef QT_NO_DBUS
 
+//#define QDBUS_PARSER_DEBUG
+#ifdef QDBUS_PARSER_DEBUG
+# define qDBusParserError qWarning
+#else
+# define qDBusParserError if (true) {} else qDebug
+#endif
+
 QT_BEGIN_NAMESPACE
 
 static QDBusIntrospection::Annotations
@@ -69,8 +76,8 @@ parseAnnotations(const QDomElement& elem)
                value = ann.attribute(QLatin1String("value"));
 
         if (!QDBusUtil::isValidInterfaceName(name)) {
-            qWarning("Invalid D-BUS annotation '%s' found while parsing introspection",
-                     qPrintable(name));
+            qDBusParserError("Invalid D-BUS annotation '%s' found while parsing introspection",
+                             qPrintable(name));
             continue;
         }
 
@@ -99,9 +106,8 @@ parseArgs(const QDomElement& elem, const QLatin1String& direction, bool acceptEm
                 argData.name = arg.attribute(QLatin1String("name")); // can be empty
             argData.type = arg.attribute(QLatin1String("type"));
             if (!QDBusUtil::isValidSingleSignature(argData.type)) {
-                qWarning("Invalid D-BUS type signature '%s' found while parsing introspection",
-                         qPrintable(argData.type));
-                continue;
+                qDBusParserError("Invalid D-BUS type signature '%s' found while parsing introspection",
+                                 qPrintable(argData.type));
             }
 
             retval << argData;
@@ -141,8 +147,8 @@ QDBusXmlParser::interfaces() const
         if (iface.isNull())
             continue;           // for whatever reason
         if (!QDBusUtil::isValidInterfaceName(ifaceName)) {
-            qWarning("Invalid D-BUS interface name '%s' found while parsing introspection",
-                     qPrintable(ifaceName));
+            qDBusParserError("Invalid D-BUS interface name '%s' found while parsing introspection",
+                             qPrintable(ifaceName));
             continue;
         }
 
@@ -166,8 +172,8 @@ QDBusXmlParser::interfaces() const
             if (method.isNull())
                 continue;
             if (!QDBusUtil::isValidMemberName(methodName)) {
-                qWarning("Invalid D-BUS member name '%s' found in interface '%s' while parsing introspection",
-                         qPrintable(methodName), qPrintable(ifaceName));
+                qDBusParserError("Invalid D-BUS member name '%s' found in interface '%s' while parsing introspection",
+                                 qPrintable(methodName), qPrintable(ifaceName));
                 continue;
             }
 
@@ -192,8 +198,8 @@ QDBusXmlParser::interfaces() const
             if (signal.isNull())
                 continue;
             if (!QDBusUtil::isValidMemberName(signalName)) {
-                qWarning("Invalid D-BUS member name '%s' found in interface '%s' while parsing introspection",
-                         qPrintable(signalName), qPrintable(ifaceName));
+                qDBusParserError("Invalid D-BUS member name '%s' found in interface '%s' while parsing introspection",
+                                 qPrintable(signalName), qPrintable(ifaceName));
                 continue;
             }
 
@@ -217,8 +223,8 @@ QDBusXmlParser::interfaces() const
             if (property.isNull())
                 continue;
             if (!QDBusUtil::isValidMemberName(propertyName)) {
-                qWarning("Invalid D-BUS member name '%s' found in interface '%s' while parsing introspection",
-                         qPrintable(propertyName), qPrintable(ifaceName));
+                qDBusParserError("Invalid D-BUS member name '%s' found in interface '%s' while parsing introspection",
+                                 qPrintable(propertyName), qPrintable(ifaceName));
                 continue;
             }
 
@@ -231,9 +237,9 @@ QDBusXmlParser::interfaces() const
 
             if (!QDBusUtil::isValidSingleSignature(propertyData.type)) {
                 // cannot be!
-                qWarning("Invalid D-BUS type signature '%s' found in property '%s.%s' while parsing introspection",
-                         qPrintable(propertyData.type), qPrintable(ifaceName),
-                         qPrintable(propertyName));
+                qDBusParserError("Invalid D-BUS type signature '%s' found in property '%s.%s' while parsing introspection",
+                                 qPrintable(propertyData.type), qPrintable(ifaceName),
+                                 qPrintable(propertyName));
                 continue;
             }
 
@@ -245,9 +251,9 @@ QDBusXmlParser::interfaces() const
             else if (access == QLatin1String("readwrite"))
                 propertyData.access = QDBusIntrospection::Property::ReadWrite;
             else {
-                qWarning("Invalid D-BUS property access '%s' found in property '%s.%s' while parsing introspection",
-                         qPrintable(access), qPrintable(ifaceName),
-                         qPrintable(propertyName));
+                qDBusParserError("Invalid D-BUS property access '%s' found in property '%s.%s' while parsing introspection",
+                                 qPrintable(access), qPrintable(ifaceName),
+                                 qPrintable(propertyName));
                 continue;       // invalid one!
             }
 
@@ -286,8 +292,8 @@ QDBusXmlParser::object() const
             if (obj.isNull())
                 continue;           // for whatever reason
             if (!QDBusUtil::isValidObjectPath(m_path + QLatin1Char('/') + objName)) {
-                qWarning("Invalid D-BUS object path '%s/%s' found while parsing introspection",
-                         qPrintable(m_path), qPrintable(objName));
+                qDBusParserError("Invalid D-BUS object path '%s/%s' found while parsing introspection",
+                                 qPrintable(m_path), qPrintable(objName));
                 continue;
             }
 
@@ -301,8 +307,8 @@ QDBusXmlParser::object() const
             if (iface.isNull())
                 continue;
             if (!QDBusUtil::isValidInterfaceName(ifaceName)) {
-                qWarning("Invalid D-BUS interface name '%s' found while parsing introspection",
-                         qPrintable(ifaceName));
+                qDBusParserError("Invalid D-BUS interface name '%s' found while parsing introspection",
+                                 qPrintable(ifaceName));
                 continue;
             }
 
diff --git a/tests/auto/qdbusxmlparser/tst_qdbusxmlparser.cpp b/tests/auto/qdbusxmlparser/tst_qdbusxmlparser.cpp
index 25595c5..f83795c 100644
--- a/tests/auto/qdbusxmlparser/tst_qdbusxmlparser.cpp
+++ b/tests/auto/qdbusxmlparser/tst_qdbusxmlparser.cpp
@@ -287,11 +287,14 @@ void tst_QDBusXmlParser::methods_data()
         "</method>" << map;
 
     // one invalid arg
+    method.inputArgs << arg("~", "invalid");
+    map.clear();
+    map << method;
     QTest::newRow("two-in-one-invalid") <<
         "<method name=\"Method\">"
         "<arg type=\"s\" direction=\"in\"/>"
-        "<arg type=\"~\" name=\"invalid\" direction=\"in\"/>" // this line should be ignored
         "<arg type=\"v\" direction=\"in\"/>"
+        "<arg type=\"~\" name=\"invalid\" direction=\"in\"/>"
         "</method>" << map;
 
     // one out argument
@@ -380,8 +383,6 @@ void tst_QDBusXmlParser::methods()
 
     QFETCH(QString, xmlDataFragment);
 
-    if (strcmp(QTest::currentDataTag(), "two-in-one-invalid") == 0)
-        QTest::ignoreMessage(QtWarningMsg, "Invalid D-BUS type signature '~' found while parsing introspection");
     QDBusIntrospection::Interface iface =
         QDBusIntrospection::parseInterface(xmlHeader + xmlDataFragment + xmlFooter);
 
@@ -390,9 +391,9 @@ void tst_QDBusXmlParser::methods()
     QFETCH(MethodMap, methodMap);
     MethodMap parsedMap = iface.methods;
 
-    QCOMPARE(methodMap.count(), parsedMap.count());
-    QCOMPARE(methodMap, parsedMap);
-}             
+    QCOMPARE(parsedMap.count(), methodMap.count());
+    QCOMPARE(parsedMap, methodMap);
+}
 
 void tst_QDBusXmlParser::signals__data()
 {
-- 
cgit v0.12


From 5b53b44a2be8478adeee4a9e4796345828ad0248 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@nokia.com>
Date: Thu, 10 Feb 2011 13:05:53 +0100
Subject: Autotest: add a new test for parsing an introspection with unknown
 types

Task-number: QTBUG-17476
---
 tests/auto/qdbusinterface/tst_qdbusinterface.cpp | 35 ++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp
index c1938b1..37e1c64 100644
--- a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp
+++ b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp
@@ -169,6 +169,25 @@ public slots:
 int MyObject::callCount = 0;
 QVariantList MyObject::callArgs;
 
+class MyObjectUnknownType: public QObject
+{
+    Q_OBJECT
+    Q_CLASSINFO("D-Bus Interface", "com.trolltech.QtDBus.MyObject")
+    Q_CLASSINFO("D-Bus Introspection", ""
+"  <interface name=\"com.trolltech.QtDBus.MyObjectUnknownTypes\" >\n"
+"    <property access=\"readwrite\" type=\"~\" name=\"prop1\" />\n"
+"    <signal name=\"somethingHappened\" >\n"
+"      <arg direction=\"out\" type=\"~\" />\n"
+"    </signal>\n"
+"    <method name=\"ping\" >\n"
+"      <arg direction=\"in\" type=\"~\" name=\"ping\" />\n"
+"      <arg direction=\"out\" type=\"~\" name=\"ping\" />\n"
+"    </method>\n"
+"    <method name=\"regularMethod\" />\n"
+"  </interface>\n"
+                "")
+};
+
 class Spy: public QObject
 {
     Q_OBJECT
@@ -228,6 +247,7 @@ private slots:
     void notValidDerived();
     void invalidAfterServiceOwnerChanged();
     void introspect();
+    void introspectUnknownTypes();
     void callMethod();
     void invokeMethod();
     void invokeMethodWithReturn();
@@ -250,8 +270,7 @@ void tst_QDBusInterface::initTestCase()
 
     con.registerObject("/", &obj, QDBusConnection::ExportAllProperties
                        | QDBusConnection::ExportAllSlots
-                       | QDBusConnection::ExportAllInvokables
-                       | QDBusConnection::ExportChildObjects);
+                       | QDBusConnection::ExportAllInvokables);
 }
 
 void tst_QDBusInterface::notConnected()
@@ -322,6 +341,18 @@ void tst_QDBusInterface::introspect()
     QVERIFY(mo->indexOfProperty("complexProp") != -1);
 }
 
+void tst_QDBusInterface::introspectUnknownTypes()
+{
+    QDBusConnection con = QDBusConnection::sessionBus();
+    MyObjectUnknownType obj;
+    con.registerObject("/unknownTypes", &obj, QDBusConnection::ExportAllContents);
+    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/unknownTypes"),
+                         "com.trolltech.QtDBus.MyObjectUnknownTypes");
+
+    const QMetaObject *mo = iface.metaObject();
+    QVERIFY(mo->indexOfMethod("regularMethod()") != -1);
+}
+
 void tst_QDBusInterface::callMethod()
 {
     QDBusConnection con = QDBusConnection::sessionBus();
-- 
cgit v0.12


From cc2db7a49c9208a00a913f7c4a410009814a5580 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@nokia.com>
Date: Thu, 10 Feb 2011 13:26:56 +0100
Subject: QtDBus meta object: keep methods, signals and props with unknown
 types

Use VoidStar as the metatype, with an unknown type called
"QDBusRawType". The actual D-Bus type is saved as an hex value as a
template parameter.

  D-Bus type	Qt type			comment
    h		QDBusRawType<0x68>*	Unix file descriptors
    ~		QDBusRawType<0x7e>*	invalid type
    ai		QDBusRawType<0x6169>*	array of int32
    a{i(ssy)}	QDBusRawType<0x617b6928737379297d>*

Note that the number in the template doesn't have to be valid. The
QDBusRawType class doesn't exist anyway.

I thought of just leaving the raw D-Bus type there, but who knows what
kind of things can appear there, like other '>' (which may cause
problems for anything trying to parse the meta object later).

Task-number: QTBUG-17476
---
 src/dbus/qdbusmetaobject.cpp                     | 21 +++++++++++++--------
 src/dbus/qdbusxmlparser.cpp                      |  1 -
 tests/auto/qdbusinterface/tst_qdbusinterface.cpp | 11 ++++++++++-
 3 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp
index 6683505..df8bc1d 100644
--- a/src/dbus/qdbusmetaobject.cpp
+++ b/src/dbus/qdbusmetaobject.cpp
@@ -193,14 +193,19 @@ QDBusMetaObjectGenerator::findType(const QByteArray &signature,
         QByteArray typeName = annotations.value(annotationName).toLatin1();
 
         // verify that it's a valid one
-        if (typeName.isEmpty())
-            return result;      // invalid
-
-        type = QVariant::nameToType(typeName);
-        if (type == QVariant::UserType)
-            type = QMetaType::type(typeName);
-        if (type == QVariant::Invalid || signature != QDBusMetaType::typeToSignature(type))
-            return result;      // unknown type is invalid too
+        if (!typeName.isEmpty()) {
+            // type name found
+            type = QVariant::nameToType(typeName);
+            if (type == QVariant::UserType)
+                type = QMetaType::type(typeName);
+        }
+
+        if (type == QVariant::Invalid || signature != QDBusMetaType::typeToSignature(type)) {
+            // type is still unknown or doesn't match back to the signature that it
+            // was expected to, so synthesize a fake type
+            type = QMetaType::VoidStar;
+            typeName = "QDBusRawType<0x" + signature.toHex() + ">*";
+        }
 
         result.name = typeName;
     } else if (type == QVariant::Invalid) {
diff --git a/src/dbus/qdbusxmlparser.cpp b/src/dbus/qdbusxmlparser.cpp
index 413ebbe..3feedde 100644
--- a/src/dbus/qdbusxmlparser.cpp
+++ b/src/dbus/qdbusxmlparser.cpp
@@ -240,7 +240,6 @@ QDBusXmlParser::interfaces() const
                 qDBusParserError("Invalid D-BUS type signature '%s' found in property '%s.%s' while parsing introspection",
                                  qPrintable(propertyData.type), qPrintable(ifaceName),
                                  qPrintable(propertyName));
-                continue;
             }
 
             QString access = property.attribute(QLatin1String("access"));
diff --git a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp
index 37e1c64..39f0677 100644
--- a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp
+++ b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp
@@ -350,7 +350,16 @@ void tst_QDBusInterface::introspectUnknownTypes()
                          "com.trolltech.QtDBus.MyObjectUnknownTypes");
 
     const QMetaObject *mo = iface.metaObject();
-    QVERIFY(mo->indexOfMethod("regularMethod()") != -1);
+    QVERIFY(mo->indexOfMethod("regularMethod()") != -1); // this is the control
+    QVERIFY(mo->indexOfMethod("somethingHappened(QDBusRawType<0x7e>*)") != -1);
+
+    QVERIFY(mo->indexOfMethod("ping(QDBusRawType<0x7e>*)") != -1);
+    int midx = mo->indexOfMethod("ping(QDBusRawType<0x7e>*)");
+    QCOMPARE(mo->method(midx).typeName(), "QDBusRawType<0x7e>*");
+
+    QVERIFY(mo->indexOfProperty("prop1") != -1);
+    int pidx = mo->indexOfProperty("prop1");
+    QCOMPARE(mo->property(pidx).typeName(), "QDBusRawType<0x7e>*");
 }
 
 void tst_QDBusInterface::callMethod()
-- 
cgit v0.12


From 1d8ebff955d357d3723487308e2906a12c6c043b Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@nokia.com>
Date: Thu, 10 Feb 2011 14:38:35 +0100
Subject: QtDBus: Make sure we can receive unknown types

We must make sure we advance the receiving iterator, or we end up in
an infinite loop.

Task-number: QTBUG-17476
---
 src/dbus/qdbusdemarshaller.cpp                 |   7 +-
 tests/auto/qdbusmarshall/test/test.pro         |   3 +-
 tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 107 ++++++++++++++++++++++++-
 3 files changed, 114 insertions(+), 3 deletions(-)

diff --git a/src/dbus/qdbusdemarshaller.cpp b/src/dbus/qdbusdemarshaller.cpp
index 91dbf25..ac3b5fa 100644
--- a/src/dbus/qdbusdemarshaller.cpp
+++ b/src/dbus/qdbusdemarshaller.cpp
@@ -235,7 +235,12 @@ QVariant QDBusDemarshaller::toVariantInternal()
 //        qWarning("QDBusDemarshaller: Found unknown D-Bus type %d '%c'",
 //                 q_dbus_message_iter_get_arg_type(&iterator),
 //                 q_dbus_message_iter_get_arg_type(&iterator));
-        return QVariant();
+        char *ptr = 0;
+        ptr += q_dbus_message_iter_get_arg_type(&iterator);
+        q_dbus_message_iter_next(&iterator);
+
+        // I hope you never dereference this pointer!
+        return QVariant::fromValue<void *>(ptr);
         break;
     };
 }
diff --git a/tests/auto/qdbusmarshall/test/test.pro b/tests/auto/qdbusmarshall/test/test.pro
index 8901999..71fc656 100644
--- a/tests/auto/qdbusmarshall/test/test.pro
+++ b/tests/auto/qdbusmarshall/test/test.pro
@@ -5,4 +5,5 @@ TARGET = ../tst_qdbusmarshall
 QT = core
 QT += dbus
 
-
+LIBS += $$QT_LIBS_DBUS
+QMAKE_CXXFLAGS += $$QT_CFLAGS_DBUS
diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
index c05e49c..0d28dbd 100644
--- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
+++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
@@ -38,7 +38,6 @@
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/
-#define DBUS_API_SUBJECT_TO_CHANGE
 #include <QtCore/QtCore>
 #include <QtTest/QtTest>
 #include <QtDBus/QtDBus>
@@ -47,6 +46,8 @@
 #include "common.h"
 #include <limits>
 
+#include <dbus/dbus.h>
+
 static const char serviceName[] = "com.trolltech.autotests.qpong";
 static const char objectPath[] = "/com/trolltech/qpong";
 static const char *interfaceName = serviceName;
@@ -88,6 +89,9 @@ private slots:
     void sendCallErrors_data();
     void sendCallErrors();
 
+    void receiveUnknownType_data();
+    void receiveUnknownType();
+
 private:
     QProcess proc;
 };
@@ -938,5 +942,106 @@ void tst_QDBusMarshall::sendCallErrors()
     QCOMPARE(reply.errorMessage(), errorMsg);
 }
 
+void tst_QDBusMarshall::receiveUnknownType_data()
+{
+    QTest::newRow("in-call");
+    QTest::newRow("type-variant");
+    QTest::newRow("type-array");
+    QTest::newRow("type-struct");
+    QTest::newRow("type-naked");
+}
+
+void tst_QDBusMarshall::receiveUnknownType()
+{
+#ifndef DBUS_TYPE_UNIX_FD
+    QSKIP("Your system's D-Bus library is too old for this test", SkipAll);
+#else
+    QDBusConnection con = QDBusConnection::sessionBus();
+    QVERIFY(con.isConnected());
+
+    // this needs to be implemented in raw
+    // open a new connection to the bus daemon
+    DBusError error;
+    dbus_error_init(&error);
+    DBusConnection *rawcon = dbus_bus_get_private(DBUS_BUS_SESSION, &error);
+    QVERIFY2(rawcon, error.name);
+
+    // check if this bus supports passing file descriptors
+    if (!dbus_connection_can_send_type(rawcon, DBUS_TYPE_UNIX_FD))
+        QSKIP("Your session bus does not allow sending Unix file descriptors", SkipAll);
+
+    if (qstrcmp(QTest::currentDataTag(), "in-call") == 0) {
+        // create a call back to us containing a file descriptor
+        DBusMessage *msg = dbus_message_new_method_call(con.baseService().toLatin1(), "/irrelevant/path", NULL, "irrelevantMethod");
+
+        int fd = fileno(stdout);
+        dbus_message_append_args(msg, DBUS_TYPE_UNIX_FD, &fd, DBUS_TYPE_INVALID);
+
+        // try to send to us
+        DBusPendingCall *pending;
+        dbus_connection_send_with_reply(rawcon, msg, &pending, 1000);
+        dbus_message_unref(msg);
+
+        // check that it got sent
+        while (dbus_connection_dispatch(rawcon) == DBUS_DISPATCH_DATA_REMAINS)
+            ;
+
+        // now spin our event loop. We don't catch this call, so let's get the reply
+        QEventLoop loop;
+        QTimer::singleShot(200, &loop, SLOT(quit()));
+        loop.exec();
+
+        // now try to receive the reply
+        dbus_pending_call_block(pending);
+        msg = dbus_pending_call_steal_reply(pending);
+        dbus_pending_call_unref(pending);
+        QVERIFY(msg);
+        QCOMPARE(dbus_message_get_type(msg), DBUS_MESSAGE_TYPE_ERROR);
+        QCOMPARE(dbus_message_get_error_name(msg), "org.freedesktop.DBus.Error.UnknownObject");
+        qDebug() << dbus_message_get_signature(msg);
+    } else {
+        // create a signal that we'll emit
+        static const char signalName[] = "signalName";
+        static const char interfaceName[] = "local.interface.name";
+        DBusMessage *msg = dbus_message_new_signal("/", interfaceName, signalName);
+        con.connect(dbus_bus_get_unique_name(rawcon), QString(), interfaceName, signalName, &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+        DBusMessageIter iter;
+        dbus_message_iter_init_append(msg, &iter);
+        int fd = fileno(stdout);
+
+        if (qstrcmp(QTest::currentDataTag(), "type-naked") == 0) {
+            // send naked
+            dbus_message_iter_append_basic(&iter, DBUS_TYPE_UNIX_FD, &fd);
+        } else {
+            DBusMessageIter subiter;
+            if (qstrcmp(QTest::currentDataTag(), "type-variant") == 0)
+                dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, DBUS_TYPE_UNIX_FD_AS_STRING, &subiter);
+            else if (qstrcmp(QTest::currentDataTag(), "type-array") == 0)
+                dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_UNIX_FD_AS_STRING, &subiter);
+            else if (qstrcmp(QTest::currentDataTag(), "type-struct") == 0)
+                dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, 0, &subiter);
+            dbus_message_iter_append_basic(&subiter, DBUS_TYPE_UNIX_FD, &fd);
+            dbus_message_iter_close_container(&iter, &subiter);
+        }
+
+        // send it
+        dbus_connection_send(rawcon, msg, 0);
+        dbus_message_unref(msg);
+
+        // check that it got sent
+        while (dbus_connection_dispatch(rawcon) == DBUS_DISPATCH_DATA_REMAINS)
+            ;
+
+        // now let's see what happens
+        QTestEventLoop::instance().enterLoop(1);
+        QVERIFY(!QTestEventLoop::instance().timeout());
+    }
+
+    dbus_connection_close(rawcon);
+    dbus_connection_unref(rawcon);
+#endif
+}
+
 QTEST_MAIN(tst_QDBusMarshall)
 #include "tst_qdbusmarshall.moc"
-- 
cgit v0.12


From ebdbd453a7612b3764b2e423ecb97aa9fb6cd28e Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@nokia.com>
Date: Thu, 10 Feb 2011 15:01:40 +0100
Subject: Autotest: avoid memory leaks if test fails

---
 tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 65 ++++++++++++++++----------
 1 file changed, 41 insertions(+), 24 deletions(-)

diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
index 0d28dbd..6ad991b 100644
--- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
+++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
@@ -951,6 +951,29 @@ void tst_QDBusMarshall::receiveUnknownType_data()
     QTest::newRow("type-naked");
 }
 
+struct DisconnectRawDBus {
+    static void cleanup(DBusConnection *connection)
+    {
+        if (!connection)
+            return;
+        dbus_connection_close(connection);
+        dbus_connection_unref(connection);
+    }
+};
+template <typename T, void (*unref)(T *)> struct GenericUnref
+{
+    static void cleanup(T *type)
+    {
+        if (!type) return;
+        unref(type);
+    }
+};
+
+// use these scoped types to avoid memory leaks if QVERIFY or QCOMPARE fails
+typedef QScopedPointer<DBusConnection, DisconnectRawDBus> ScopedDBusConnection;
+typedef QScopedPointer<DBusMessage, GenericUnref<DBusMessage, dbus_message_unref> > ScopedDBusMessage;
+typedef QScopedPointer<DBusPendingCall, GenericUnref<DBusPendingCall, dbus_pending_call_unref> > ScopedDBusPendingCall;
+
 void tst_QDBusMarshall::receiveUnknownType()
 {
 #ifndef DBUS_TYPE_UNIX_FD
@@ -963,27 +986,27 @@ void tst_QDBusMarshall::receiveUnknownType()
     // open a new connection to the bus daemon
     DBusError error;
     dbus_error_init(&error);
-    DBusConnection *rawcon = dbus_bus_get_private(DBUS_BUS_SESSION, &error);
-    QVERIFY2(rawcon, error.name);
+    ScopedDBusConnection rawcon(dbus_bus_get_private(DBUS_BUS_SESSION, &error));
+    QVERIFY2(rawcon.data(), error.name);
 
     // check if this bus supports passing file descriptors
-    if (!dbus_connection_can_send_type(rawcon, DBUS_TYPE_UNIX_FD))
+    if (!dbus_connection_can_send_type(rawcon.data(), DBUS_TYPE_UNIX_FD))
         QSKIP("Your session bus does not allow sending Unix file descriptors", SkipAll);
 
     if (qstrcmp(QTest::currentDataTag(), "in-call") == 0) {
         // create a call back to us containing a file descriptor
-        DBusMessage *msg = dbus_message_new_method_call(con.baseService().toLatin1(), "/irrelevant/path", NULL, "irrelevantMethod");
+        ScopedDBusMessage msg(dbus_message_new_method_call(con.baseService().toLatin1(), "/irrelevant/path", NULL, "irrelevantMethod"));
 
         int fd = fileno(stdout);
-        dbus_message_append_args(msg, DBUS_TYPE_UNIX_FD, &fd, DBUS_TYPE_INVALID);
+        dbus_message_append_args(msg.data(), DBUS_TYPE_UNIX_FD, &fd, DBUS_TYPE_INVALID);
 
         // try to send to us
-        DBusPendingCall *pending;
-        dbus_connection_send_with_reply(rawcon, msg, &pending, 1000);
-        dbus_message_unref(msg);
+        DBusPendingCall *pending_ptr;
+        dbus_connection_send_with_reply(rawcon.data(), msg.data(), &pending_ptr, 1000);
+        ScopedDBusPendingCall pending(pending_ptr);
 
         // check that it got sent
-        while (dbus_connection_dispatch(rawcon) == DBUS_DISPATCH_DATA_REMAINS)
+        while (dbus_connection_dispatch(rawcon.data()) == DBUS_DISPATCH_DATA_REMAINS)
             ;
 
         // now spin our event loop. We don't catch this call, so let's get the reply
@@ -992,22 +1015,20 @@ void tst_QDBusMarshall::receiveUnknownType()
         loop.exec();
 
         // now try to receive the reply
-        dbus_pending_call_block(pending);
-        msg = dbus_pending_call_steal_reply(pending);
-        dbus_pending_call_unref(pending);
+        dbus_pending_call_block(pending.data());
+        msg.reset(dbus_pending_call_steal_reply(pending.data()));
         QVERIFY(msg);
-        QCOMPARE(dbus_message_get_type(msg), DBUS_MESSAGE_TYPE_ERROR);
-        QCOMPARE(dbus_message_get_error_name(msg), "org.freedesktop.DBus.Error.UnknownObject");
-        qDebug() << dbus_message_get_signature(msg);
+        QCOMPARE(dbus_message_get_type(msg.data()), DBUS_MESSAGE_TYPE_ERROR);
+        QCOMPARE(dbus_message_get_error_name(msg.data()), "org.freedesktop.DBus.Error.UnknownObject");
     } else {
         // create a signal that we'll emit
         static const char signalName[] = "signalName";
         static const char interfaceName[] = "local.interface.name";
-        DBusMessage *msg = dbus_message_new_signal("/", interfaceName, signalName);
-        con.connect(dbus_bus_get_unique_name(rawcon), QString(), interfaceName, signalName, &QTestEventLoop::instance(), SLOT(exitLoop()));
+        ScopedDBusMessage msg(dbus_message_new_signal("/", interfaceName, signalName));
+        con.connect(dbus_bus_get_unique_name(rawcon.data()), QString(), interfaceName, signalName, &QTestEventLoop::instance(), SLOT(exitLoop()));
 
         DBusMessageIter iter;
-        dbus_message_iter_init_append(msg, &iter);
+        dbus_message_iter_init_append(msg.data(), &iter);
         int fd = fileno(stdout);
 
         if (qstrcmp(QTest::currentDataTag(), "type-naked") == 0) {
@@ -1026,20 +1047,16 @@ void tst_QDBusMarshall::receiveUnknownType()
         }
 
         // send it
-        dbus_connection_send(rawcon, msg, 0);
-        dbus_message_unref(msg);
+        dbus_connection_send(rawcon.data(), msg.data(), 0);
 
         // check that it got sent
-        while (dbus_connection_dispatch(rawcon) == DBUS_DISPATCH_DATA_REMAINS)
+        while (dbus_connection_dispatch(rawcon.data()) == DBUS_DISPATCH_DATA_REMAINS)
             ;
 
         // now let's see what happens
         QTestEventLoop::instance().enterLoop(1);
         QVERIFY(!QTestEventLoop::instance().timeout());
     }
-
-    dbus_connection_close(rawcon);
-    dbus_connection_unref(rawcon);
 #endif
 }
 
-- 
cgit v0.12


From 00f689370ce97d557f8af4596c780f381aa66cb7 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@nokia.com>
Date: Thu, 17 Feb 2011 14:25:07 +0100
Subject: Fix warnings in QtDeclarative

---
 src/declarative/qml/qdeclarativeobjectscriptclass.cpp    | 2 +-
 src/declarative/qml/qdeclarativeproperty.cpp             | 2 +-
 src/declarative/qml/qdeclarativevaluetypescriptclass.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
index 2aa2059..dc3ecca 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
@@ -368,7 +368,7 @@ void QDeclarativeObjectScriptClass::setProperty(QObject *obj,
         newBinding = new QDeclarativeBinding(value, obj, evalContext);
         newBinding->setSourceLocation(ctxtInfo.fileName(), ctxtInfo.functionStartLineNumber());
         newBinding->setTarget(QDeclarativePropertyPrivate::restore(*lastData, valueTypeData, obj, evalContext));
-        if (newBinding->expression().contains("this"))
+        if (newBinding->expression().contains(QLatin1String("this")))
             newBinding->setEvaluateFlags(newBinding->evaluateFlags() | QDeclarativeBinding::RequiresThisObject);
     }
 
diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp
index 61e3002..0dd0edb 100644
--- a/src/declarative/qml/qdeclarativeproperty.cpp
+++ b/src/declarative/qml/qdeclarativeproperty.cpp
@@ -427,7 +427,7 @@ bool QDeclarativeProperty::operator==(const QDeclarativeProperty &other) const
 */
 int QDeclarativeProperty::propertyType() const
 {
-    return d ? d->propertyType() : QVariant::Invalid;
+    return d ? d->propertyType() : int(QVariant::Invalid);
 }
 
 bool QDeclarativePropertyPrivate::isValueType() const
diff --git a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
index 200cc1c..4c312b5 100644
--- a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
+++ b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
@@ -184,7 +184,7 @@ void QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier
             newBinding->setSourceLocation(ctxtInfo.fileName(), ctxtInfo.functionStartLineNumber());
             QDeclarativeProperty prop = QDeclarativePropertyPrivate::restore(cacheData, valueTypeData, ref->object, ctxt);
             newBinding->setTarget(prop);
-            if (newBinding->expression().contains("this"))
+            if (newBinding->expression().contains(QLatin1String("this")))
                 newBinding->setEvaluateFlags(newBinding->evaluateFlags() | QDeclarativeBinding::RequiresThisObject);
         }
 
-- 
cgit v0.12


From 426833486c3d801ec4dbce96407ec6e1e6c525f8 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@nokia.com>
Date: Thu, 17 Feb 2011 17:03:13 +0100
Subject: Autotest: be nicer to the subprocess and SIGTERM it

---
 tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
index 6ad991b..d0c9675 100644
--- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
+++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
@@ -151,7 +151,8 @@ void tst_QDBusMarshall::initTestCase()
 void tst_QDBusMarshall::cleanupTestCase()
 {
     proc.close();
-    proc.kill();
+    proc.terminate();
+    proc.waitForFinished(200);
 }
 
 void tst_QDBusMarshall::sendBasic_data()
-- 
cgit v0.12


From 63bfd78b6a80f608f9b09254d815b6da04f8e2fc Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@nokia.com>
Date: Wed, 16 Feb 2011 14:56:24 +0100
Subject: Autotest: don't use the deprecated signal from
 QDBusConnectionInterface

---
 tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 56 ++++++++------------------
 1 file changed, 17 insertions(+), 39 deletions(-)

diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
index d0c9675..0c53087 100644
--- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
+++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
@@ -99,53 +99,29 @@ private:
 struct UnregisteredType { };
 Q_DECLARE_METATYPE(UnregisteredType)
 
-class WaitForQPong: public QObject
-{
-    Q_OBJECT
-public:
-    WaitForQPong();
-    bool ok();
-public Q_SLOTS:
-    void ownerChange(const QString &name)
-    {
-        if (name == serviceName)
-            loop.quit();
-    }
-
-private:
-    QEventLoop loop;
-};
-
-WaitForQPong::WaitForQPong()
-{
-    QDBusConnection con = QDBusConnection::sessionBus();
-    if (!ok()) {
-        connect(con.interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)),
-                SLOT(ownerChange(QString)));
-        QTimer::singleShot(2000, &loop, SLOT(quit()));
-        loop.exec();
-    }
-}
-
-bool WaitForQPong::ok()
-{
-    return QDBusConnection::sessionBus().isConnected() &&
-        QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName);
-}
-
 void tst_QDBusMarshall::initTestCase()
 {
     commonInit();
+    QDBusConnection con = QDBusConnection::sessionBus();
 #ifdef Q_OS_WIN
     proc.start("qpong");
 #else
     proc.start("./qpong/qpong");
 #endif
-    QVERIFY(proc.waitForStarted());
-
-    WaitForQPong w;
-    QVERIFY(w.ok());
-    //QTest::qWait(2000);
+    if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName)) {
+        QVERIFY(proc.waitForStarted());
+
+        QVERIFY(con.isConnected());
+        con.connect("org.freedesktop.DBus", QString(), "org.freedesktop.DBus", "NameOwnerChanged",
+                    QStringList() << serviceName << QString(""), QString(),
+                    &QTestEventLoop::instance(), SLOT(exitLoop()));
+        QTestEventLoop::instance().enterLoop(2);
+        QVERIFY(!QTestEventLoop::instance().timeout());
+        QVERIFY(QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName));
+        con.disconnect("org.freedesktop.DBus", QString(), "org.freedesktop.DBus", "NameOwnerChanged",
+                       QStringList() << serviceName << QString(""), QString(),
+                       &QTestEventLoop::instance(), SLOT(exitLoop()));
+    }
 }
 
 void tst_QDBusMarshall::cleanupTestCase()
@@ -705,6 +681,8 @@ void tst_QDBusMarshall::sendBasic()
     msg << value;
 
     QDBusMessage reply = con.call(msg);
+    QVERIFY2(reply.type() == QDBusMessage::ReplyMessage,
+             qPrintable(reply.errorName() + ": " + reply.errorMessage()));
     //qDebug() << reply;
 
     QCOMPARE(reply.arguments().count(), msg.arguments().count());
-- 
cgit v0.12


From a6e1a7caeb7f03d1c102c250df8e602d5e40ab62 Mon Sep 17 00:00:00 2001
From: Anders Bakken <agbakken@gmail.com>
Date: Thu, 17 Feb 2011 18:37:15 +0100
Subject: Make Qt/DirectFB less verbose about failing to load pixmaps.

Qt/DirectFB is way too verbose about not being able to use DirectFB for
loading images. A lot of times DirectFB doesn't have support for e.g.
pngs or gifs and currently one gets a message for every failed pixmap
load, even if they will succeed when falling back to Qt.

Merge-request: 2552
Reviewed-by: Marcel Schuette <marcel.schuette@nokia.com>
---
 src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
index 50e0f5f..eaff74a 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
@@ -245,10 +245,9 @@ bool QDirectFBPixmapData::fromDataBufferDescription(const DFBDataBufferDescripti
     QDirectFBPointer<IDirectFBDataBuffer> dataBuffer(dataBufferPtr);
 
     IDirectFBImageProvider *providerPtr;
-    if ((result = dataBuffer->CreateImageProvider(dataBuffer.data(), &providerPtr)) != DFB_OK) {
-        DirectFBError("QDirectFBPixmapData::fromDataBufferDescription(): Can't create image provider", result);
+    if ((result = dataBuffer->CreateImageProvider(dataBuffer.data(), &providerPtr)) != DFB_OK)
         return false;
-    }
+
     QDirectFBPointer<IDirectFBImageProvider> provider(providerPtr);
 
     DFBImageDescription imageDescription;
-- 
cgit v0.12


From 1a9ea90144c7131029fdf19950d1f313a64eb4a1 Mon Sep 17 00:00:00 2001
From: Denis Oliver Kropp <dok@directfb.org>
Date: Thu, 17 Feb 2011 19:01:29 +0100
Subject: directfb: fix crash in client/server mode of qws

The server was crashing due to client pointer being sent as "sibling".

Instead surface flags are sent and sibling code is removed.

Also the window ID is transfered and used on receiver side to get a
local handle to the window.

Click to focus window works, but it is not raised.

Merge-request: 989
Reviewed-by: Marcel Schuette <marcel.schuette@nokia.com>
---
 .../gfxdrivers/directfb/qdirectfbwindowsurface.cpp | 46 +++++++++++++++-------
 .../gfxdrivers/directfb/qdirectfbwindowsurface.h   |  1 -
 2 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
index d0056a7..3d8cf50 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
@@ -55,7 +55,6 @@ QT_BEGIN_NAMESPACE
 
 QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr)
     : QDirectFBPaintDevice(scr)
-    , sibling(0)
 #ifndef QT_NO_DIRECTFB_WM
     , dfbWindow(0)
 #endif
@@ -75,7 +74,6 @@ QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirect
 
 QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr, QWidget *widget)
     : QWSWindowSurface(widget), QDirectFBPaintDevice(scr)
-    , sibling(0)
 #ifndef QT_NO_DIRECTFB_WM
     , dfbWindow(0)
 #endif
@@ -123,7 +121,7 @@ void QDirectFBWindowSurface::raise()
 
 IDirectFBWindow *QDirectFBWindowSurface::directFBWindow() const
 {
-    return (dfbWindow ? dfbWindow : (sibling ? sibling->dfbWindow : 0));
+    return dfbWindow;
 }
 
 void QDirectFBWindowSurface::createWindow(const QRect &rect)
@@ -287,17 +285,40 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect)
 
 QByteArray QDirectFBWindowSurface::permanentState() const
 {
-    QByteArray state(sizeof(this), 0);
-    *reinterpret_cast<const QDirectFBWindowSurface**>(state.data()) = this;
+    QByteArray state(sizeof(SurfaceFlags) + sizeof(DFBWindowID), 0);
+    char *ptr = state.data();
+    SurfaceFlags flags = surfaceFlags();
+    memcpy(ptr, &flags, sizeof(SurfaceFlags));
+    ptr += sizeof(SurfaceFlags);
+    DFBWindowID did = (DFBWindowID)(-1);
+    if (dfbWindow)
+        dfbWindow->GetID(dfbWindow, &did);
+    memcpy(ptr, &did, sizeof(DFBWindowID));
     return state;
 }
 
 void QDirectFBWindowSurface::setPermanentState(const QByteArray &state)
 {
-    if (state.size() == sizeof(this)) {
-        sibling = *reinterpret_cast<QDirectFBWindowSurface *const*>(state.constData());
-        Q_ASSERT(sibling);
-        setSurfaceFlags(sibling->surfaceFlags());
+    const char *ptr = state.constData();
+    IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer();
+    SurfaceFlags flags;
+    memcpy(&flags, ptr, sizeof(SurfaceFlags));
+
+    setSurfaceFlags(flags);
+    ptr += sizeof(SurfaceFlags);
+    DFBWindowID id;
+    memcpy(&id, ptr, sizeof(DFBWindowID));
+    if (dfbSurface)
+        dfbSurface->Release(dfbSurface);
+    if (id != (DFBWindowID)-1) {
+        IDirectFBWindow *dw;
+        layer->GetWindow(layer, id, &dw);
+        if (dw->GetSurface(dw, &dfbSurface) != DFB_OK)
+                dfbSurface = 0;
+        dw->Release(dw);
+    }
+    else {
+        dfbSurface = 0;
     }
 }
 
@@ -406,8 +427,6 @@ void QDirectFBWindowSurface::endPaint(const QRegion &)
 
 IDirectFBSurface *QDirectFBWindowSurface::directFBSurface() const
 {
-    if (!dfbSurface && sibling && sibling->dfbSurface)
-        return sibling->dfbSurface;
     return dfbSurface;
 }
 
@@ -415,11 +434,8 @@ IDirectFBSurface *QDirectFBWindowSurface::directFBSurface() const
 IDirectFBSurface *QDirectFBWindowSurface::surfaceForWidget(const QWidget *widget, QRect *rect) const
 {
     Q_ASSERT(widget);
-    if (!dfbSurface) {
-        if (sibling && (!sibling->sibling || sibling->dfbSurface))
-            return sibling->surfaceForWidget(widget, rect);
+    if (!dfbSurface)
         return 0;
-    }
     QWidget *win = window();
     Q_ASSERT(win);
     if (rect) {
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
index f683fc8..75d462b 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
@@ -100,7 +100,6 @@ private:
     void updateIsOpaque();
     void setOpaque(bool opaque);
     void releaseSurface();
-    QDirectFBWindowSurface *sibling;
 
 #ifdef QT_DIRECTFB_WM
     void createWindow(const QRect &rect);
-- 
cgit v0.12


From 935b7ab960cf417336571754659d04958b707fc8 Mon Sep 17 00:00:00 2001
From: Rhys Weatherley <rhys.weatherley@nokia.com>
Date: Thu, 17 Feb 2011 13:54:52 +1000
Subject: Export symbols from qtestlib required for QtQuickTest

Task-number: QTBUG-16084
Reviewed-by: Jason McDonald
---
 src/testlib/qbenchmark_p.h  |  4 ++--
 src/testlib/qtestcase.cpp   | 42 ++++++++++++++++++++++++++++++++++++++----
 src/testlib/qtestlog_p.h    |  2 +-
 src/testlib/qtestresult_p.h |  2 +-
 src/testlib/qtesttable_p.h  |  2 +-
 5 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/src/testlib/qbenchmark_p.h b/src/testlib/qbenchmark_p.h
index 9a83a1a..ace17db 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 0ceb71d..97f069e 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 08c86d1..6648beb 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 15523f5..7ff120a 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 d085b57..f835506 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();
-- 
cgit v0.12


From fcd12e1826f2974ec9cf10af4e6893774d666362 Mon Sep 17 00:00:00 2001
From: Joona Petrell <joona.t.petrell@nokia.com>
Date: Fri, 18 Feb 2011 10:53:16 +1000
Subject: Fix compilation on old Symbian platforms

Task-number: QTBUG-17472
Reviewed-by: Martin Jones
---
 tools/qml/qmlruntime.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp
index 36915d1..c746d8e 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
 
-- 
cgit v0.12


From b1d036fd9fc45060bf2886114051eef8db735311 Mon Sep 17 00:00:00 2001
From: Michael Brasser <michael.brasser@nokia.com>
Date: Fri, 18 Feb 2011 11:33:17 +1000
Subject: Fix FocusScope example.

Task-number: QTBUG-17501
Reviewed-by: Martin Jones
---
 examples/declarative/keyinteraction/focus/focus.qml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/examples/declarative/keyinteraction/focus/focus.qml b/examples/declarative/keyinteraction/focus/focus.qml
index 9cb1fef..935db25 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
         }
     }
 
-- 
cgit v0.12


From 9e063f7e4790cc15b279a44807ff59c620d53ce6 Mon Sep 17 00:00:00 2001
From: Andrew den Exter <andrew.den-exter@nokia.com>
Date: Fri, 18 Feb 2011 17:19:05 +1000
Subject: Fix TextEdit auto test failure on windows.

A leaked window from a previous test held focus meaning events weren't
being delivered to the expected widget.  Delete the offending widget.
---
 .../auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp  | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
index 87c2c60..a052752 100644
--- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
+++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
@@ -1179,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()
-- 
cgit v0.12


From d6c1e5d78bdfbeb373970b65d8260f7e9f9ce1bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mauri=20Vehni=C3=A4inen?= <ext-mauri.vehniainen@nokia.com>
Date: Fri, 18 Feb 2011 10:10:08 +0100
Subject: Prevents crashing when ICO file has bad color table value

When color table value is read from ICO header memory allocation is
made based on this value. This case is relevant only when reading
8bit images. Therefore values over 256 will abort reading the image.

Task-number: QT-4535

Merge-request: 1090
Reviewed-by: Harald Fernengel <harald.fernengel@nokia.com>
---
 src/plugins/imageformats/ico/qicohandler.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp
index 5aa26d3..701207d 100644
--- a/src/plugins/imageformats/ico/qicohandler.cpp
+++ b/src/plugins/imageformats/ico/qicohandler.cpp
@@ -559,6 +559,8 @@ QImage ICOReader::iconAt(int index)
                     icoAttrib.ncolors = 0;
                 else                    // # colors used
                     icoAttrib.ncolors = header.biClrUsed ? header.biClrUsed : 1 << icoAttrib.nbits;
+                if (icoAttrib.ncolors > 256) //color table can't be more than 256
+                    return img;
                 icoAttrib.w = iconEntry.bWidth;
                 if (icoAttrib.w == 0)
                     icoAttrib.w = header.biWidth;
-- 
cgit v0.12


From 5949c215bd53582d0c6481f606a9ec015f067b37 Mon Sep 17 00:00:00 2001
From: Richard Moe Gustavsen <richard.gustavsen@nokia.com>
Date: Fri, 18 Feb 2011 10:19:58 +0100
Subject: Cocoa: fix crash when using a drawer with a focus widget

The crash happends when you close down an application that has a
drawer that contains a widget with keyboard focus. The NSView
backing this widget is then the first responder in Cocoa.

This bug was a bit more hard-boiled than usual, and I can't say I truly
understand whats going on. My findings are that both the drawer and the
parent window both points to the same view inside the drawer as its
first responder. And when deleting the drawer (togheter with the focus
widget), the parent window is left pointing to a first responder that
is actually deleted. Is seems that us refusing to release a view as first
responder if we have no attached widget is wrong. So we choose to return
YES instead, which after all makes much more sense.

Task-number: QTBUG-15897
Reviewed-by: msorvig
---
 src/gui/kernel/qcocoaview_mac.mm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 749472a..d9f428c 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -1115,7 +1115,7 @@ static int qCocoaViewCount = 0;
 - (BOOL)resignFirstResponder
 {
     if (!qwidget)
-        return NO;
+        return YES;
     // Seems like the following test only triggers if this
     // view is inside a QMacNativeWidget:
     if (qwidget == QApplication::focusWidget())
-- 
cgit v0.12


From c658394f1b34c98b141eff22a69a3f4c7bbd4c51 Mon Sep 17 00:00:00 2001
From: Jason McDonald <jason.mcdonald@nokia.com>
Date: Fri, 18 Feb 2011 22:03:55 +1000
Subject: Attempt to fix symbian 3.1 and 3.2 compile break.

e46c44f9538dbe5b44ce61d3a42403cfa471ae8b restructured qml.pri.  In the
original version the else part at the bottom of the file was processed
for Symbian 3.1 and 3.2, but the commit stopped that from happening.

This commit makes the minimal change to make the statements in the else
part apply to 3.1 and 3.2 again.

Really the file should be restructured to have separate logic for
setting each vairable, but I'll leave that task for the developers.

Reviewed-by: Eckhart Koppen
---
 tools/qml/qml.pri | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/tools/qml/qml.pri b/tools/qml/qml.pri
index 08cd506..650de94 100644
--- a/tools/qml/qml.pri
+++ b/tools/qml/qml.pri
@@ -19,17 +19,21 @@ SOURCES += $$PWD/qmlruntime.cpp \
 RESOURCES = $$PWD/browser/browser.qrc \
             $$PWD/startup/startup.qrc
 
-symbian: {
-    contains(QT_CONFIG, s60): {
+symbian {
+    contains(QT_CONFIG, s60) {
         LIBS += -lavkon -lcone
     }
     !contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2) {
         LIBS += -lsensrvclient -lsensrvutil
     }
-    !contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2): {
+    !contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2) {
         SOURCES += $$PWD/deviceorientation_symbian.cpp
         FORMS = $$PWD/recopts.ui \
                      $$PWD/proxysettings.ui
+    } else {
+        SOURCES += $$PWD/deviceorientation.cpp
+        FORMS = $$PWD/recopts.ui \
+                $$PWD/proxysettings.ui
     }
 } else:maemo5 {
     QT += dbus
-- 
cgit v0.12


From 7b6b9201bdc6435aaa50370c8cf511e47f6e630d Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@nokia.com>
Date: Wed, 16 Feb 2011 14:05:54 +0100
Subject: Autotest: check that the type received is the expected one

Task-number: QTBUG-17476
---
 tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 51 ++++++++++++++++++++++----
 1 file changed, 43 insertions(+), 8 deletions(-)

diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
index 0c53087..9bae6af 100644
--- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
+++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
@@ -96,6 +96,19 @@ private:
     QProcess proc;
 };
 
+class QDBusMessageSpy: public QObject
+{
+    Q_OBJECT
+public slots:
+    Q_SCRIPTABLE int theSlot(const QDBusMessage &msg)
+    {
+        list << msg;
+        return 42;
+    }
+public:
+    QList<QDBusMessage> list;
+};
+
 struct UnregisteredType { };
 Q_DECLARE_METATYPE(UnregisteredType)
 
@@ -923,11 +936,12 @@ void tst_QDBusMarshall::sendCallErrors()
 
 void tst_QDBusMarshall::receiveUnknownType_data()
 {
-    QTest::newRow("in-call");
-    QTest::newRow("type-variant");
-    QTest::newRow("type-array");
-    QTest::newRow("type-struct");
-    QTest::newRow("type-naked");
+    QTest::addColumn<int>("receivedTypeId");
+    QTest::newRow("in-call") << qMetaTypeId<void*>();
+    QTest::newRow("type-variant") << qMetaTypeId<QDBusVariant>();
+    QTest::newRow("type-array") << qMetaTypeId<QDBusArgument>();
+    QTest::newRow("type-struct") << qMetaTypeId<QDBusArgument>();
+    QTest::newRow("type-naked") << qMetaTypeId<void *>();
 }
 
 struct DisconnectRawDBus {
@@ -974,7 +988,9 @@ void tst_QDBusMarshall::receiveUnknownType()
 
     if (qstrcmp(QTest::currentDataTag(), "in-call") == 0) {
         // create a call back to us containing a file descriptor
-        ScopedDBusMessage msg(dbus_message_new_method_call(con.baseService().toLatin1(), "/irrelevant/path", NULL, "irrelevantMethod"));
+        QDBusMessageSpy spy;
+        con.registerObject("/spyObject", &spy, QDBusConnection::ExportAllSlots);
+        ScopedDBusMessage msg(dbus_message_new_method_call(con.baseService().toLatin1(), "/spyObject", NULL, "theSlot"));
 
         int fd = fileno(stdout);
         dbus_message_append_args(msg.data(), DBUS_TYPE_UNIX_FD, &fd, DBUS_TYPE_INVALID);
@@ -995,10 +1011,21 @@ void tst_QDBusMarshall::receiveUnknownType()
 
         // now try to receive the reply
         dbus_pending_call_block(pending.data());
+
+        // check that the spy received what it was supposed to receive
+        QCOMPARE(spy.list.size(), 1);
+        QCOMPARE(spy.list.at(0).arguments().size(), 1);
+        QFETCH(int, receivedTypeId);
+        QCOMPARE(spy.list.at(0).arguments().at(0).userType(), receivedTypeId);
+
         msg.reset(dbus_pending_call_steal_reply(pending.data()));
         QVERIFY(msg);
-        QCOMPARE(dbus_message_get_type(msg.data()), DBUS_MESSAGE_TYPE_ERROR);
-        QCOMPARE(dbus_message_get_error_name(msg.data()), "org.freedesktop.DBus.Error.UnknownObject");
+        QCOMPARE(dbus_message_get_type(msg.data()), DBUS_MESSAGE_TYPE_METHOD_RETURN);
+        QCOMPARE(dbus_message_get_signature(msg.data()), DBUS_TYPE_INT32_AS_STRING);
+
+        int retval;
+        QVERIFY(dbus_message_get_args(msg.data(), &error, DBUS_TYPE_INT32, &retval, DBUS_TYPE_INVALID));
+        QCOMPARE(retval, 42);
     } else {
         // create a signal that we'll emit
         static const char signalName[] = "signalName";
@@ -1006,6 +1033,9 @@ void tst_QDBusMarshall::receiveUnknownType()
         ScopedDBusMessage msg(dbus_message_new_signal("/", interfaceName, signalName));
         con.connect(dbus_bus_get_unique_name(rawcon.data()), QString(), interfaceName, signalName, &QTestEventLoop::instance(), SLOT(exitLoop()));
 
+        QDBusMessageSpy spy;
+        con.connect(dbus_bus_get_unique_name(rawcon.data()), QString(), interfaceName, signalName, &spy, SLOT(theSlot(QDBusMessage)));
+
         DBusMessageIter iter;
         dbus_message_iter_init_append(msg.data(), &iter);
         int fd = fileno(stdout);
@@ -1035,6 +1065,11 @@ void tst_QDBusMarshall::receiveUnknownType()
         // now let's see what happens
         QTestEventLoop::instance().enterLoop(1);
         QVERIFY(!QTestEventLoop::instance().timeout());
+        QCOMPARE(spy.list.size(), 1);
+        QCOMPARE(spy.list.at(0).arguments().count(), 1);
+        QFETCH(int, receivedTypeId);
+        //qDebug() << spy.list.at(0).arguments().at(0).typeName();
+        QCOMPARE(spy.list.at(0).arguments().at(0).userType(), receivedTypeId);
     }
 #endif
 }
-- 
cgit v0.12


From d6e509936358141b1fef93852edd10b3b324ec5b Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@nokia.com>
Date: Sat, 19 Feb 2011 13:53:41 +0100
Subject: Doc: setSslConfiguration also sets the CA certificates

---
 src/network/access/qnetworkrequest.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index 89f7d44..7eec24e 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -529,8 +529,9 @@ QSslConfiguration QNetworkRequest::sslConfiguration() const
 /*!
     Sets this network request's SSL configuration to be \a config. The
     settings that apply are the private key, the local certificate,
-    the SSL protocol (SSLv2, SSLv3, TLSv1 where applicable) and the
-    ciphers that the SSL backend is allowed to use.
+    the SSL protocol (SSLv2, SSLv3, TLSv1 where applicable), the CA
+    certificates and the ciphers that the SSL backend is allowed to
+    use.
 
     By default, no SSL configuration is set, which allows the backends
     to choose freely what configuration is best for them.
-- 
cgit v0.12


From ef06cbef2e3240d49848f398b2d19adbbea1e781 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@nokia.com>
Date: Sat, 19 Feb 2011 11:46:22 +0100
Subject: Fix warning about id maybe used when uninitialised

The code would indicate it's never used uninitialised, but gcc doesn't
know it.
---
 src/declarative/util/qdeclarativepropertychanges.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp
index ccd122e..9bcb263 100644
--- a/src/declarative/util/qdeclarativepropertychanges.cpp
+++ b/src/declarative/util/qdeclarativepropertychanges.cpp
@@ -281,7 +281,7 @@ QDeclarativePropertyChangesParser::compile(const QList<QDeclarativeCustomParserP
         QDeclarativeParser::Variant v = qvariant_cast<QDeclarativeParser::Variant>(data.at(ii).second);
         QVariant var;
         bool isScript = v.isScript();
-        QDeclarativeBinding::Identifier id;
+        QDeclarativeBinding::Identifier id = 0;
         switch(v.type()) {
         case QDeclarativeParser::Variant::Boolean:
             var = QVariant(v.asBoolean());
-- 
cgit v0.12


From 13e9642616ab480d09bda2603cc89dcaea7a1ad6 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@nokia.com>
Date: Sun, 20 Feb 2011 15:37:06 +0100
Subject: Autotest: make at least one update before checking if more are needed

The timer gets started only by making updates. If you try to check if
an update is needed without making the first update, the timer won't
be started and the function will return false.
---
 tests/auto/qfuturewatcher/tst_qfuturewatcher.cpp | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/tests/auto/qfuturewatcher/tst_qfuturewatcher.cpp b/tests/auto/qfuturewatcher/tst_qfuturewatcher.cpp
index 2ca1a47..9875fb5 100644
--- a/tests/auto/qfuturewatcher/tst_qfuturewatcher.cpp
+++ b/tests/auto/qfuturewatcher/tst_qfuturewatcher.cpp
@@ -484,8 +484,6 @@ class ProgressTextTask : public RunFunctionTask<T>
 public:
     void runFunctor()
     {
-        while (this->isProgressUpdateNeeded() == false)
-            QTest::qSleep(1);
         this->setProgressValueAndText(1, QLatin1String("Foo 1"));
 
         while (this->isProgressUpdateNeeded() == false)
@@ -495,6 +493,10 @@ public:
         while (this->isProgressUpdateNeeded() == false)
             QTest::qSleep(1);
         this->setProgressValueAndText(3, QLatin1String("Foo 3"));
+
+        while (this->isProgressUpdateNeeded() == false)
+            QTest::qSleep(1);
+        this->setProgressValueAndText(4, QLatin1String("Foo 4"));
     }
 };
 
@@ -522,14 +524,16 @@ void tst_QFutureWatcher::progressText()
         QTestEventLoop::instance().enterLoop(5);
         QVERIFY(!QTestEventLoop::instance().timeout());
 
-        QCOMPARE(f.progressText(), QLatin1String("Foo 3"));
-        QCOMPARE(f.progressValue(), 3);
+        QCOMPARE(f.progressText(), QLatin1String("Foo 4"));
+        QCOMPARE(f.progressValue(), 4);
         QVERIFY(progressValues.contains(1));
         QVERIFY(progressValues.contains(2));
         QVERIFY(progressValues.contains(3));
+        QVERIFY(progressValues.contains(4));
         QVERIFY(progressTexts.contains(QLatin1String("Foo 1")));
         QVERIFY(progressTexts.contains(QLatin1String("Foo 2")));
         QVERIFY(progressTexts.contains(QLatin1String("Foo 3")));
+        QVERIFY(progressTexts.contains(QLatin1String("Foo 4")));
     }
 }
 
-- 
cgit v0.12


From 32e8cef8f0792727134ee64f196529ed19f35d6a Mon Sep 17 00:00:00 2001
From: Martin Jones <martin.jones@nokia.com>
Date: Mon, 21 Feb 2011 09:42:09 +1000
Subject: Ensure QDeclarativeListProperty docs are associated with
 QtDeclarative.

There is a copy of QDeclarativeListProperty in qgraphicsitem_p.h, which
confused qdoc.

Change-Id: I159b5e51af11a8b5874b0ffeb923cbd67df86d0d
Task-number: QTBUG-17555
---
 src/declarative/qml/qdeclarativelist.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/declarative/qml/qdeclarativelist.cpp b/src/declarative/qml/qdeclarativelist.cpp
index 9598d98..346fee5 100644
--- a/src/declarative/qml/qdeclarativelist.cpp
+++ b/src/declarative/qml/qdeclarativelist.cpp
@@ -88,6 +88,7 @@ void QDeclarativeListReferencePrivate::release()
 /*!
 \class QDeclarativeListReference
 \since 4.7
+\module QtDeclarative
 \brief The QDeclarativeListReference class allows the manipulation of QDeclarativeListProperty properties.
 
 QDeclarativeListReference allows C++ programs to read from, and assign values to a QML list property in a
-- 
cgit v0.12


From f141b42b87e0835552c85dbfd1ccce950da5aee3 Mon Sep 17 00:00:00 2001
From: Bea Lam <bea.lam@nokia.com>
Date: Mon, 21 Feb 2011 09:50:19 +1000
Subject: Docs: fix inherits tag for SpringAnimation

---
 src/declarative/util/qdeclarativespringanimation.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/declarative/util/qdeclarativespringanimation.cpp b/src/declarative/util/qdeclarativespringanimation.cpp
index ec2b083..1212a1c 100644
--- a/src/declarative/util/qdeclarativespringanimation.cpp
+++ b/src/declarative/util/qdeclarativespringanimation.cpp
@@ -236,7 +236,7 @@ void QDeclarativeSpringAnimationPrivate::updateMode()
 /*!
     \qmlclass SpringAnimation QDeclarativeSpringAnimation
     \ingroup qml-animation-transition
-    \inherits Animation
+    \inherits NumberAnimation
     \since 4.7
 
     \brief The SpringAnimation element allows a property to track a value in a spring-like motion.
-- 
cgit v0.12


From 521a9bba59fe198ec7b1afe9bb25a9d3334675cf Mon Sep 17 00:00:00 2001
From: Andrew den Exter <andrew.den-exter@nokia.com>
Date: Mon, 14 Feb 2011 18:00:15 +1000
Subject: Forward mouse events from TextInput and TextEdit to QInputContext.

This brings TextInput in line with QLineEdit.  The fix for TextEdit
applies equally to QTextEdit.

Change-Id: I5c47e5c8e951ee53cb1fe45d9c302050cd19deef
Task-number: QTBUG-15705
Reviewed-by: axis
---
 .../graphicsitems/qdeclarativetextedit.cpp         |  36 +++---
 .../graphicsitems/qdeclarativetextinput.cpp        |  47 +++++++
 .../graphicsitems/qdeclarativetextinput_p_p.h      |   1 +
 src/gui/text/qtextcontrol.cpp                      | 120 +++++++++++------
 src/gui/text/qtextcontrol_p_p.h                    |  20 ++-
 .../tst_qdeclarativetextedit.cpp                   | 142 ++++++++++++++++++++-
 .../tst_qdeclarativetextinput.cpp                  | 140 +++++++++++++++++++-
 7 files changed, 442 insertions(+), 64 deletions(-)

diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
index 87a49bd..2946f6e 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
@@ -975,6 +975,10 @@ void QDeclarativeTextEdit::setSelectByMouse(bool on)
     if (d->selectByMouse != on) {
         d->selectByMouse = on;
         setKeepMouseGrab(on);
+        if (on)
+            setTextInteractionFlags(d->control->textInteractionFlags() | Qt::TextSelectableByMouse);
+        else
+            setTextInteractionFlags(d->control->textInteractionFlags() & ~Qt::TextSelectableByMouse);
         emit selectByMouseChanged(on);
     }
 }
@@ -1027,11 +1031,10 @@ void QDeclarativeTextEdit::setReadOnly(bool r)
     setFlag(QGraphicsItem::ItemAcceptsInputMethod, !r);
 
     Qt::TextInteractionFlags flags = Qt::LinksAccessibleByMouse;
-    if (r) {
+    if (d->selectByMouse)
         flags = flags | Qt::TextSelectableByMouse;
-    } else {
-        flags = flags | Qt::TextEditorInteraction;
-    }
+    if (!r)
+        flags = flags | Qt::TextSelectableByKeyboard | Qt::TextEditable;
     d->control->setTextInteractionFlags(flags);
     if (!r)
         d->control->moveCursor(QTextCursor::End);
@@ -1249,8 +1252,8 @@ void QDeclarativeTextEdit::mousePressEvent(QGraphicsSceneMouseEvent *event)
             }
         }
     }
-    if (event->type() != QEvent::GraphicsSceneMouseDoubleClick || d->selectByMouse)
-        d->control->processEvent(event, QPointF(0, -d->yoff));
+
+    d->control->processEvent(event, QPointF(0, -d->yoff));
     if (!event->isAccepted())
         QDeclarativePaintedItem::mousePressEvent(event);
 }
@@ -1285,13 +1288,11 @@ Handles the given mouse \a event.
 void QDeclarativeTextEdit::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
 {
     Q_D(QDeclarativeTextEdit);
-    if (d->selectByMouse) {
-        d->control->processEvent(event, QPointF(0, -d->yoff));
-        if (!event->isAccepted())
-            QDeclarativePaintedItem::mouseDoubleClickEvent(event);
-    } else {
+
+    d->control->processEvent(event, QPointF(0, -d->yoff));
+    if (!event->isAccepted())
         QDeclarativePaintedItem::mouseDoubleClickEvent(event);
-    }
+
 }
 
 /*!
@@ -1301,14 +1302,9 @@ Handles the given mouse \a event.
 void QDeclarativeTextEdit::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
 {
     Q_D(QDeclarativeTextEdit);
-    if (d->selectByMouse) {
-        d->control->processEvent(event, QPointF(0, -d->yoff));
-        if (!event->isAccepted())
-            QDeclarativePaintedItem::mouseMoveEvent(event);
-        event->setAccepted(true);
-    } else {
+    d->control->processEvent(event, QPointF(0, -d->yoff));
+    if (!event->isAccepted())
         QDeclarativePaintedItem::mouseMoveEvent(event);
-    }
 }
 
 /*!
@@ -1407,7 +1403,7 @@ void QDeclarativeTextEditPrivate::init()
 
     control = new QTextControl(q);
     control->setIgnoreUnusedNavigationEvents(true);
-    control->setTextInteractionFlags(control->textInteractionFlags() | Qt::LinksAccessibleByMouse);
+    control->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard | Qt::TextEditable);
     control->setDragEnabled(false);
 
     // QTextControl follows the default text color
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index e7c2ac7..bfcd715 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
@@ -51,6 +51,7 @@
 #include <QFontMetrics>
 #include <QPainter>
 #include <QTextBoundaryFinder>
+#include <QInputContext>
 #include <qstyle.h>
 
 #ifndef QT_NO_LINEEDIT
@@ -1002,6 +1003,8 @@ Handles the given mouse \a event.
 void QDeclarativeTextInput::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
 {
     Q_D(QDeclarativeTextInput);
+    if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonDblClick))
+        return;
     if (d->selectByMouse) {
         int cursor = d->xToPos(event->pos().x());
         d->control->selectWordAtPos(cursor);
@@ -1014,6 +1017,8 @@ void QDeclarativeTextInput::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *even
 void QDeclarativeTextInput::mousePressEvent(QGraphicsSceneMouseEvent *event)
 {
     Q_D(QDeclarativeTextInput);
+    if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonPress))
+        return;
     if(d->focusOnPress){
         bool hadActiveFocus = hasActiveFocus();
         forceActiveFocus();
@@ -1041,6 +1046,8 @@ void QDeclarativeTextInput::mousePressEvent(QGraphicsSceneMouseEvent *event)
 void QDeclarativeTextInput::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
 {
     Q_D(QDeclarativeTextInput);
+    if (d->sendMouseEventToInputContext(event, QEvent::MouseMove))
+        event->setAccepted(true);
     if (d->selectByMouse) {
         if (qAbs(int(event->pos().x() - d->pressPos.x())) > QApplication::startDragDistance())
             setKeepMouseGrab(true);
@@ -1058,6 +1065,8 @@ Handles the given mouse \a event.
 void QDeclarativeTextInput::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
 {
     Q_D(QDeclarativeTextInput);
+    if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonRelease))
+        return;
     if (d->selectByMouse)
         setKeepMouseGrab(false);
     if (!d->showInputPanelOnFocus) { // input panel on click
@@ -1075,6 +1084,44 @@ void QDeclarativeTextInput::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
         QDeclarativePaintedItem::mouseReleaseEvent(event);
 }
 
+bool QDeclarativeTextInputPrivate::sendMouseEventToInputContext(
+        QGraphicsSceneMouseEvent *event, QEvent::Type eventType)
+{
+#if !defined QT_NO_IM
+    if (event->widget() && control->composeMode()) {
+        int tmp_cursor = xToPos(event->pos().x());
+        int mousePos = tmp_cursor - control->cursor();
+        if (mousePos < 0 || mousePos > control->preeditAreaText().length()) {
+            mousePos = -1;
+            // don't send move events outside the preedit area
+            if (eventType == QEvent::MouseMove)
+                return true;
+        }
+
+        QInputContext *qic = event->widget()->inputContext();
+        if (qic) {
+            QMouseEvent mouseEvent(
+                    eventType,
+                    event->widget()->mapFromGlobal(event->screenPos()),
+                    event->screenPos(),
+                    event->button(),
+                    event->buttons(),
+                    event->modifiers());
+            // may be causing reset() in some input methods
+            qic->mouseHandler(mousePos, &mouseEvent);
+            event->setAccepted(mouseEvent.isAccepted());
+        }
+        if (!control->preeditAreaText().isEmpty())
+            return true;
+    }
+#else
+    Q_UNUSED(event);
+    Q_UNUSED(eventType)
+#endif
+
+    return false;
+}
+
 bool QDeclarativeTextInput::sceneEvent(QEvent *event)
 {
     bool rv = QDeclarativeItem::sceneEvent(event);
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
index f7446b4..ab2838b 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
@@ -104,6 +104,7 @@ public:
     void focusChanged(bool hasFocus);
     void updateHorizontalScroll();
     int calculateTextWidth();
+    bool sendMouseEventToInputContext(QGraphicsSceneMouseEvent *event, QEvent::Type eventType);
 
     QLineControl* control;
 
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index e380b37..b25588d 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -932,15 +932,18 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte
             break; }
         case QEvent::MouseMove: {
             QMouseEvent *ev = static_cast<QMouseEvent *>(e);
-            d->mouseMoveEvent(ev->buttons(), matrix.map(ev->pos()));
+            d->mouseMoveEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(),
+                              ev->buttons(), ev->globalPos());
             break; }
         case QEvent::MouseButtonRelease: {
             QMouseEvent *ev = static_cast<QMouseEvent *>(e);
-            d->mouseReleaseEvent(ev->button(), matrix.map(ev->pos()));
+            d->mouseReleaseEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(),
+                                 ev->buttons(), ev->globalPos());
             break; }
         case QEvent::MouseButtonDblClick: {
             QMouseEvent *ev = static_cast<QMouseEvent *>(e);
-            d->mouseDoubleClickEvent(e, ev->button(), matrix.map(ev->pos()));
+            d->mouseDoubleClickEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(),
+                                     ev->buttons(), ev->globalPos());
             break; }
         case QEvent::InputMethod:
             d->inputMethodEvent(static_cast<QInputMethodEvent *>(e));
@@ -1000,15 +1003,18 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte
             break; }
         case QEvent::GraphicsSceneMouseMove: {
             QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
-            d->mouseMoveEvent(ev->buttons(), matrix.map(ev->pos()));
+            d->mouseMoveEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
+                              ev->screenPos());
             break; }
         case QEvent::GraphicsSceneMouseRelease: {
             QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
-            d->mouseReleaseEvent(ev->button(), matrix.map(ev->pos()));
+            d->mouseReleaseEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
+                                 ev->screenPos());
             break; }
         case QEvent::GraphicsSceneMouseDoubleClick: {
             QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
-            d->mouseDoubleClickEvent(e, ev->button(), matrix.map(ev->pos()));
+            d->mouseDoubleClickEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
+                                     ev->screenPos());
             break; }
         case QEvent::GraphicsSceneContextMenu: {
             QGraphicsSceneContextMenuEvent *ev = static_cast<QGraphicsSceneContextMenuEvent *>(e);
@@ -1017,7 +1023,8 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte
 
         case QEvent::GraphicsSceneHoverMove: {
             QGraphicsSceneHoverEvent *ev = static_cast<QGraphicsSceneHoverEvent *>(e);
-            d->mouseMoveEvent(Qt::NoButton, matrix.map(ev->pos()));
+            d->mouseMoveEvent(ev, Qt::NoButton, matrix.map(ev->pos()), ev->modifiers(),Qt::NoButton,
+                              ev->screenPos());
             break; }
 
         case QEvent::GraphicsSceneDragEnter: {
@@ -1487,6 +1494,11 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con
 {
     Q_Q(QTextControl);
 
+    if (sendMouseEventToInputContext(
+            e, QEvent::MouseButtonPress, button, pos, modifiers, buttons, globalPos)) {
+        return;
+    }
+
     if (interactionFlags & Qt::LinksAccessibleByMouse) {
         anchorOnMousePress = q->anchorAt(pos);
 
@@ -1529,22 +1541,7 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con
             return;
         }
 
-#if !defined(QT_NO_IM)
-        QTextLayout *layout = cursor.block().layout();
-        if (contextWidget && layout && !layout->preeditAreaText().isEmpty()) {
-            QInputContext *ctx = inputContext();
-            if (ctx) {
-                QMouseEvent ev(QEvent::MouseButtonPress, contextWidget->mapFromGlobal(globalPos), globalPos,
-                               button, buttons, modifiers);
-                ctx->mouseHandler(cursorPos - cursor.position(), &ev);
-            }
-            if (!layout->preeditAreaText().isEmpty()) {
-                e->ignore();
-                return;
-            }
-        }
-#endif
-        if (modifiers == Qt::ShiftModifier) {
+        if (modifiers == Qt::ShiftModifier && (interactionFlags & Qt::TextSelectableByMouse)) {
             if (wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) {
                 selectedWordOnDoubleClick = cursor;
                 selectedWordOnDoubleClick.select(QTextCursor::WordUnderCursor);
@@ -1589,10 +1586,16 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con
     hadSelectionOnMousePress = cursor.hasSelection();
 }
 
-void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF &mousePos)
+void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, const QPointF &mousePos, Qt::KeyboardModifiers modifiers,
+                                         Qt::MouseButtons buttons, const QPoint &globalPos)
 {
     Q_Q(QTextControl);
 
+    if (sendMouseEventToInputContext(
+            e, QEvent::MouseMove, button, mousePos, modifiers, buttons, globalPos)) {
+        return;
+    }
+
     if (interactionFlags & Qt::LinksAccessibleByMouse) {
         QString anchor = q->anchorAt(mousePos);
         if (anchor != highlightedAnchor) {
@@ -1622,12 +1625,6 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF
     }
     const qreal mouseX = qreal(mousePos.x());
 
-#if !defined(QT_NO_IM)
-    QTextLayout *layout = cursor.block().layout();
-    if (layout && !layout->preeditAreaText().isEmpty())
-        return;
-#endif
-
     int newCursorPos = q->hitTest(mousePos, Qt::FuzzyHit);
     if (newCursorPos == -1)
         return;
@@ -1641,7 +1638,7 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF
         extendBlockwiseSelection(newCursorPos);
     else if (selectedWordOnDoubleClick.hasSelection())
         extendWordwiseSelection(newCursorPos, mouseX);
-    else
+    else if (interactionFlags & Qt::TextSelectableByMouse)
         setCursorPosition(newCursorPos, QTextCursor::KeepAnchor);
 
     if (interactionFlags & Qt::TextEditable) {
@@ -1665,10 +1662,16 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF
     repaintOldAndNewSelection(oldSelection);
 }
 
-void QTextControlPrivate::mouseReleaseEvent(Qt::MouseButton button, const QPointF &pos)
+void QTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers,
+                                            Qt::MouseButtons buttons, const QPoint &globalPos)
 {
     Q_Q(QTextControl);
 
+    if (sendMouseEventToInputContext(
+            e, QEvent::MouseButtonRelease, button, pos, modifiers, buttons, globalPos)) {
+        return;
+    }
+
     const QTextCursor oldSelection = cursor;
     const int oldCursorPos = cursor.position();
 
@@ -1726,19 +1729,21 @@ void QTextControlPrivate::mouseReleaseEvent(Qt::MouseButton button, const QPoint
     }
 }
 
-void QTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos)
+void QTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers,
+                                                Qt::MouseButtons buttons, const QPoint &globalPos)
 {
     Q_Q(QTextControl);
+
+    if (sendMouseEventToInputContext(
+            e, QEvent::MouseButtonDblClick, button, pos, modifiers, buttons, globalPos)) {
+        return;
+    }
+
     if (button != Qt::LeftButton
         || !(interactionFlags & Qt::TextSelectableByMouse)) {
         e->ignore();
         return;
     }
-#if !defined(QT_NO_IM)
-    QTextLayout *layout = cursor.block().layout();
-    if (layout && !layout->preeditAreaText().isEmpty())
-        return;
-#endif
 
 #ifndef QT_NO_DRAGANDDROP
     mightStartDrag = false;
@@ -1767,6 +1772,45 @@ void QTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton butto
     }
 }
 
+bool QTextControlPrivate::sendMouseEventToInputContext(
+        QEvent *e, QEvent::Type eventType, Qt::MouseButton button, const QPointF &pos,
+        Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, const QPoint &globalPos)
+{
+#if !defined(QT_NO_IM)
+    Q_Q(QTextControl);
+
+    QTextLayout *layout = cursor.block().layout();
+    if (contextWidget && layout && !layout->preeditAreaText().isEmpty()) {
+        QInputContext *ctx = inputContext();
+        int cursorPos = q->hitTest(pos, Qt::FuzzyHit) - cursor.position();
+
+        if (cursorPos < 0 || cursorPos > layout->preeditAreaText().length()) {
+            cursorPos = -1;
+            // don't send move events outside the preedit area
+            if (eventType == QEvent::MouseMove)
+                return true;
+        }
+        if (ctx) {
+            QMouseEvent ev(eventType, contextWidget->mapFromGlobal(globalPos), globalPos,
+                           button, buttons, modifiers);
+            ctx->mouseHandler(cursorPos, &ev);
+            e->setAccepted(ev.isAccepted());
+        }
+        if (!layout->preeditAreaText().isEmpty())
+            return true;
+    }
+#else
+    Q_UNUSED(e);
+    Q_UNUSED(eventType);
+    Q_UNUSED(button);
+    Q_UNUSED(pos);
+    Q_UNUSED(modifiers);
+    Q_UNUSED(buttons);
+    Q_UNUSED(globalPos);
+#endif
+    return false;
+}
+
 void QTextControlPrivate::contextMenuEvent(const QPoint &screenPos, const QPointF &docPos, QWidget *contextWidget)
 {
 #ifdef QT_NO_CONTEXTMENU
diff --git a/src/gui/text/qtextcontrol_p_p.h b/src/gui/text/qtextcontrol_p_p.h
index ecd13ea..94670e2 100644
--- a/src/gui/text/qtextcontrol_p_p.h
+++ b/src/gui/text/qtextcontrol_p_p.h
@@ -135,9 +135,23 @@ public:
                          Qt::KeyboardModifiers modifiers,
                          Qt::MouseButtons buttons,
                          const QPoint &globalPos);
-    void mouseMoveEvent(Qt::MouseButtons buttons, const QPointF &pos);
-    void mouseReleaseEvent(Qt::MouseButton button, const QPointF &pos);
-    void mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos);
+    void mouseMoveEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos,
+                        Qt::KeyboardModifiers modifiers,
+                        Qt::MouseButtons buttons,
+                        const QPoint &globalPos);
+    void mouseReleaseEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos,
+                           Qt::KeyboardModifiers modifiers,
+                           Qt::MouseButtons buttons,
+                           const QPoint &globalPos);
+    void mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos,
+                               Qt::KeyboardModifiers modifiers,
+                               Qt::MouseButtons buttons,
+                               const QPoint &globalPos);
+    bool sendMouseEventToInputContext(QEvent *e,  QEvent::Type eventType, Qt::MouseButton button,
+                                      const QPointF &pos,
+                                      Qt::KeyboardModifiers modifiers,
+                                      Qt::MouseButtons buttons,
+                                      const QPoint &globalPos);
     void contextMenuEvent(const QPoint &screenPos, const QPointF &docPos, QWidget *contextWidget);
     void focusEvent(QFocusEvent *e);
 #ifdef QT_KEYPAD_NAVIGATION
diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
index a052752..f74a27d 100644
--- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
+++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
@@ -138,6 +138,7 @@ private slots:
     void testQtQuick11Attributes_data();
 
     void preeditMicroFocus();
+    void inputContextMouseHandler();
 
 private:
     void simulateKey(QDeclarativeView *, int key);
@@ -1464,7 +1465,7 @@ QDeclarativeView *tst_qdeclarativetextedit::createView(const QString &filename)
 class MyInputContext : public QInputContext
 {
 public:
-    MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false) {}
+    MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false), eventType(QEvent::None) {}
     ~MyInputContext() {}
 
     QString identifierName() { return QString(); }
@@ -1495,9 +1496,27 @@ public:
         sendEvent(event);
     }
 
+    void mouseHandler(int x, QMouseEvent *event)
+    {
+        cursor = x;
+        eventType = event->type();
+        eventPosition = event->pos();
+        eventGlobalPosition = event->globalPos();
+        eventButton = event->button();
+        eventButtons = event->buttons();
+        eventModifiers = event->modifiers();
+    }
+
     bool openInputPanelReceived;
     bool closeInputPanelReceived;
     bool updateReceived;
+    int cursor;
+    QEvent::Type eventType;
+    QPoint eventPosition;
+    QPoint eventGlobalPosition;
+    Qt::MouseButton eventButton;
+    Qt::MouseButtons eventButtons;
+    Qt::KeyboardModifiers eventModifiers;
 };
 
 void tst_qdeclarativetextedit::textInput()
@@ -1824,7 +1843,6 @@ void tst_qdeclarativetextedit::preeditMicroFocus()
     MyInputContext ic;
     view.setInputContext(&ic);
     QDeclarativeTextEdit edit;
-    edit.setPos(0, 0);
     edit.setFocus(true);
     scene.addItem(&edit);
     view.show();
@@ -1870,6 +1888,126 @@ void tst_qdeclarativetextedit::preeditMicroFocus()
 #endif
 }
 
+void tst_qdeclarativetextedit::inputContextMouseHandler()
+{
+    QString text = "supercalifragisiticexpialidocious!";
+
+    QGraphicsScene scene;
+    QGraphicsView view(&scene);
+    MyInputContext ic;
+    view.setInputContext(&ic);
+    QDeclarativeTextEdit edit;
+    edit.setPos(0, 0);
+    edit.setWidth(200);
+    edit.setText(text.mid(0, 5));
+    edit.setPos(0, 0);
+    edit.setCursorPosition(5);
+    edit.setFocus(true);
+    scene.addItem(&edit);
+    view.show();
+    QApplication::setActiveWindow(&view);
+    QTest::qWaitForWindowShown(&view);
+    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+    view.setFocus();
+
+    QFontMetricsF fm(edit.font());
+    const qreal y = fm.height() / 2;
+
+    QPoint position2 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 2)), y)));
+    QPoint position4 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 4)), y)));
+    QPoint position7 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 7)), y)));
+    QPoint position12 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 12)), y)));
+    QPoint globalPosition2 = view.viewport()->mapToGlobal(position2);
+    QPoint globalPosition4 = view.viewport()->mapToGlobal(position4);
+    QPoint globalPosition7 = view.viewport()->mapToGlobal(position7);
+    QPoint globalPosition12 = view.viewport()->mapToGlobal(position12);
+
+    ic.sendEvent(QInputMethodEvent(text.mid(5), QList<QInputMethodEvent::Attribute>()));
+
+    QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
+    QCOMPARE(ic.eventPosition, position2);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
+    QVERIFY(ic.cursor < 0);
+    ic.eventType = QEvent::None;
+
+    QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
+    QCOMPARE(ic.eventPosition, position2);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
+    QVERIFY(ic.cursor < 0);
+    ic.eventType = QEvent::None;
+
+    {   QMouseEvent mv(QEvent::MouseMove, position4, globalPosition4, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+        QApplication::sendEvent(view.viewport(), &mv); }
+    QCOMPARE(ic.eventType, QEvent::None);
+
+    {   QMouseEvent mv(QEvent::MouseMove, position12, globalPosition12, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+        QApplication::sendEvent(view.viewport(), &mv); }
+    QCOMPARE(ic.eventType, QEvent::MouseMove);
+    QCOMPARE(ic.eventPosition, position12);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition12);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
+    QCOMPARE(ic.cursor, 7);
+    ic.eventType = QEvent::None;
+
+    QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, position12);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
+    QCOMPARE(ic.eventPosition, position12);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition12);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
+    QCOMPARE(ic.cursor, 7);
+    ic.eventType = QEvent::None;
+
+    // And in the other direction.
+    QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, position12);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
+    QCOMPARE(ic.eventPosition, position12);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition12);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
+    QCOMPARE(ic.cursor, 7);
+    ic.eventType = QEvent::None;
+
+    QTest::mousePress(view.viewport(), Qt::RightButton, Qt::ControlModifier, position12);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
+    QCOMPARE(ic.eventPosition, position12);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition12);
+    QCOMPARE(ic.eventButton, Qt::RightButton);
+    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
+    QCOMPARE(ic.cursor, 7);
+    ic.eventType = QEvent::None;
+
+    {   QMouseEvent mv(QEvent::MouseMove, position7, globalPosition7, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
+        QApplication::sendEvent(view.viewport(), &mv); }
+    QCOMPARE(ic.eventType, QEvent::MouseMove);
+    QCOMPARE(ic.eventPosition, position7);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition7);
+    QCOMPARE(ic.eventButton, Qt::RightButton);
+    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
+    QCOMPARE(ic.cursor, 2);
+    ic.eventType = QEvent::None;
+
+    {   QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
+        QApplication::sendEvent(view.viewport(), &mv); }
+    QCOMPARE(ic.eventType, QEvent::None);
+
+    QTest::mouseRelease(view.viewport(), Qt::RightButton, Qt::ControlModifier, position2);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
+    QCOMPARE(ic.eventPosition, position2);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
+    QCOMPARE(ic.eventButton, Qt::RightButton);
+    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
+    QVERIFY(ic.cursor < 0);
+    ic.eventType = QEvent::None;
+}
+
 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 7753f11..b601af8 100644
--- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
+++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
@@ -126,6 +126,7 @@ private slots:
 
     void preeditAutoScroll();
     void preeditMicroFocus();
+    void inputContextMouseHandler();
 
 private:
     void simulateKey(QDeclarativeView *, int key);
@@ -1420,7 +1421,7 @@ QDeclarativeView *tst_qdeclarativetextinput::createView(const QString &filename)
 class MyInputContext : public QInputContext
 {
 public:
-    MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false) {}
+    MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false), eventType(QEvent::None) {}
     ~MyInputContext() {}
 
     QString identifierName() { return QString(); }
@@ -1441,6 +1442,17 @@ public:
 
     void update() { updateReceived = true; }
 
+    void mouseHandler(int x, QMouseEvent *event)
+    {
+        cursor = x;
+        eventType = event->type();
+        eventPosition = event->pos();
+        eventGlobalPosition = event->globalPos();
+        eventButton = event->button();
+        eventButtons = event->buttons();
+        eventModifiers = event->modifiers();
+    }
+
     void sendPreeditText(const QString &text, int cursor)
     {
         QList<QInputMethodEvent::Attribute> attributes;
@@ -1454,6 +1466,13 @@ public:
     bool openInputPanelReceived;
     bool closeInputPanelReceived;
     bool updateReceived;
+    int cursor;
+    QEvent::Type eventType;
+    QPoint eventPosition;
+    QPoint eventGlobalPosition;
+    Qt::MouseButton eventButton;
+    Qt::MouseButtons eventButtons;
+    Qt::KeyboardModifiers eventModifiers;
 };
 
 void tst_qdeclarativetextinput::openInputPanelOnClick()
@@ -1859,6 +1878,125 @@ void tst_qdeclarativetextinput::preeditMicroFocus()
 #endif
 }
 
+void tst_qdeclarativetextinput::inputContextMouseHandler()
+{
+    QString text = "supercalifragisiticexpialidocious!";
+
+    QGraphicsScene scene;
+    QGraphicsView view(&scene);
+    MyInputContext ic;
+    view.setInputContext(&ic);
+    QDeclarativeTextInput input;
+    input.setWidth(200);
+    input.setText(text.mid(0, 5));
+    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));
+
+    ic.sendEvent(QInputMethodEvent(text.mid(5), QList<QInputMethodEvent::Attribute>()));
+
+    QFontMetricsF fm(input.font());
+    const qreal y = fm.height() / 2;
+
+    QPoint position2 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 2)), y)));
+    QPoint position4 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 4)), y)));
+    QPoint position7 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 7)), y)));
+    QPoint position12 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 12)), y)));
+    QPoint globalPosition2 = view.viewport()->mapToGlobal(position2);
+    QPoint globalPosition4 = view.viewport()->mapToGlobal(position4);
+    QPoint globalPosition7 = view.viewport()->mapToGlobal(position7);
+    QPoint globalPosition12 = view.viewport()->mapToGlobal(position12);
+
+    ic.sendEvent(QInputMethodEvent(text.mid(5), QList<QInputMethodEvent::Attribute>()));
+
+    QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
+    QCOMPARE(ic.eventPosition, position2);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
+    QVERIFY(ic.cursor < 0);
+    ic.eventType = QEvent::None;
+
+    QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
+    QCOMPARE(ic.eventPosition, position2);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
+    QVERIFY(ic.cursor < 0);
+    ic.eventType = QEvent::None;
+
+    {   QMouseEvent mv(QEvent::MouseMove, position4, globalPosition4, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+        QApplication::sendEvent(view.viewport(), &mv); }
+    QCOMPARE(ic.eventType, QEvent::None);
+
+    {   QMouseEvent mv(QEvent::MouseMove, position12, globalPosition12, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+        QApplication::sendEvent(view.viewport(), &mv); }
+    QCOMPARE(ic.eventType, QEvent::MouseMove);
+    QCOMPARE(ic.eventPosition, position12);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition12);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
+    QCOMPARE(ic.cursor, 7);
+    ic.eventType = QEvent::None;
+
+    QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, position12);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
+    QCOMPARE(ic.eventPosition, position12);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition12);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
+    QCOMPARE(ic.cursor, 7);
+    ic.eventType = QEvent::None;
+
+    // And in the other direction.
+    QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, position12);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
+    QCOMPARE(ic.eventPosition, position12);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition12);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
+    QCOMPARE(ic.cursor, 7);
+    ic.eventType = QEvent::None;
+
+    QTest::mousePress(view.viewport(), Qt::RightButton, Qt::ControlModifier, position12);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
+    QCOMPARE(ic.eventPosition, position12);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition12);
+    QCOMPARE(ic.eventButton, Qt::RightButton);
+    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
+    QCOMPARE(ic.cursor, 7);
+    ic.eventType = QEvent::None;
+
+    {   QMouseEvent mv(QEvent::MouseMove, position7, globalPosition7, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
+        QApplication::sendEvent(view.viewport(), &mv); }
+    QCOMPARE(ic.eventType, QEvent::MouseMove);
+    QCOMPARE(ic.eventPosition, position7);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition7);
+    QCOMPARE(ic.eventButton, Qt::RightButton);
+    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
+    QCOMPARE(ic.cursor, 2);
+    ic.eventType = QEvent::None;
+
+    {   QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
+        QApplication::sendEvent(view.viewport(), &mv); }
+    QCOMPARE(ic.eventType, QEvent::None);
+
+    QTest::mouseRelease(view.viewport(), Qt::RightButton, Qt::ControlModifier, position2);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
+    QCOMPARE(ic.eventPosition, position2);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
+    QCOMPARE(ic.eventButton, Qt::RightButton);
+    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
+    QVERIFY(ic.cursor < 0);
+    ic.eventType = QEvent::None;
+}
+
 QTEST_MAIN(tst_qdeclarativetextinput)
 
 #include "tst_qdeclarativetextinput.moc"
-- 
cgit v0.12


From fd198736e1da02f535bc81d9934cb4e8412a87bc Mon Sep 17 00:00:00 2001
From: Andrew den Exter <andrew.den-exter@nokia.com>
Date: Wed, 16 Feb 2011 13:33:52 +1000
Subject: Hide the TextInput/Edit cursor when the view doesn't have focus.

Only display a cursor if both the item and its scene have focus.

Change-Id: I0c91ab4d533cd7d773ffc2489633e12c0d399ad9
Task-number: QTBUG-17365
Reviewed-by: Martin Jones
---
 .../graphicsitems/qdeclarativetextedit.cpp         |  2 +-
 .../graphicsitems/qdeclarativetextinput.cpp        |  2 +-
 .../tst_qdeclarativetextedit.cpp                   | 71 ++++++++++++++++++++++
 .../tst_qdeclarativetextinput.cpp                  | 70 +++++++++++++++++++++
 4 files changed, 143 insertions(+), 2 deletions(-)

diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
index 2946f6e..83c7420 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
@@ -1126,7 +1126,7 @@ void QDeclarativeTextEdit::keyReleaseEvent(QKeyEvent *event)
 void QDeclarativeTextEditPrivate::focusChanged(bool hasFocus)
 {
     Q_Q(QDeclarativeTextEdit);
-    q->setCursorVisible(hasFocus);
+    q->setCursorVisible(hasFocus && scene && scene->hasFocus());
     QDeclarativeItemPrivate::focusChanged(hasFocus);
 }
 
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index bfcd715..ba1ae63 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
@@ -948,7 +948,7 @@ void QDeclarativeTextInputPrivate::focusChanged(bool hasFocus)
 {
     Q_Q(QDeclarativeTextInput);
     focused = hasFocus;
-    q->setCursorVisible(hasFocus);
+    q->setCursorVisible(hasFocus && scene && scene->hasFocus());
     if(q->echoMode() == QDeclarativeTextInput::PasswordEchoOnEdit && !hasFocus)
         control->updatePasswordEchoEditing(false);//QLineControl sets it on key events, but doesn't deal with focus events
     if (!hasFocus)
diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
index f74a27d..ba410ce 100644
--- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
+++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
@@ -122,6 +122,7 @@ private slots:
     void inputMethodHints();
 
     void cursorDelegate();
+    void cursorVisible();
     void delegateLoading_data();
     void delegateLoading();
     void navigation();
@@ -1277,6 +1278,76 @@ void tst_qdeclarativetextedit::cursorDelegate()
     delete view;
 }
 
+void tst_qdeclarativetextedit::cursorVisible()
+{
+    QGraphicsScene scene;
+    QGraphicsView view(&scene);
+    view.show();
+    QApplication::setActiveWindow(&view);
+    QTest::qWaitForWindowShown(&view);
+    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+    view.setFocus();
+
+    QDeclarativeTextEdit edit;
+    QSignalSpy spy(&edit, SIGNAL(cursorVisibleChanged(bool)));
+
+    QCOMPARE(edit.isCursorVisible(), false);
+
+    edit.setCursorVisible(true);
+    QCOMPARE(edit.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 1);
+
+    edit.setCursorVisible(false);
+    QCOMPARE(edit.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 2);
+
+    edit.setFocus(true);
+    QCOMPARE(edit.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 2);
+
+    scene.addItem(&edit);
+    QCOMPARE(edit.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 3);
+
+    edit.setFocus(false);
+    QCOMPARE(edit.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 4);
+
+    edit.setFocus(true);
+    QCOMPARE(edit.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 5);
+
+    scene.clearFocus();
+    QCOMPARE(edit.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 6);
+
+    scene.setFocus();
+    QCOMPARE(edit.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 7);
+
+    view.clearFocus();
+    QCOMPARE(edit.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 8);
+
+    view.setFocus();
+    QCOMPARE(edit.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 9);
+
+    // on mac, setActiveWindow(0) on mac does not deactivate the current application
+    // (you have to switch to a different app or hide the current app to trigger this)
+#if !defined(Q_WS_MAC)
+    QApplication::setActiveWindow(0);
+    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(0));
+    QCOMPARE(edit.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 10);
+
+    QApplication::setActiveWindow(&view);
+    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+    QCOMPARE(edit.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 11);
+#endif
+}
+
 void tst_qdeclarativetextedit::delegateLoading_data()
 {
     QTest::addColumn<QString>("qmlfile");
diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
index b601af8..b8f73bd 100644
--- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
+++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
@@ -110,6 +110,7 @@ private slots:
 
     void passwordCharacter();
     void cursorDelegate();
+    void cursorVisible();
     void navigation();
     void copyAndPaste();
     void readOnly();
@@ -1316,6 +1317,75 @@ void tst_qdeclarativetextinput::cursorDelegate()
     delete view;
 }
 
+void tst_qdeclarativetextinput::cursorVisible()
+{
+    QGraphicsScene scene;
+    QGraphicsView view(&scene);
+    view.show();
+    QApplication::setActiveWindow(&view);
+    QTest::qWaitForWindowShown(&view);
+    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+
+    QDeclarativeTextInput input;
+    QSignalSpy spy(&input, SIGNAL(cursorVisibleChanged(bool)));
+
+    QCOMPARE(input.isCursorVisible(), false);
+
+    input.setCursorVisible(true);
+    QCOMPARE(input.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 1);
+
+    input.setCursorVisible(false);
+    QCOMPARE(input.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 2);
+
+    input.setFocus(true);
+    QCOMPARE(input.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 2);
+
+    scene.addItem(&input);
+    QCOMPARE(input.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 3);
+
+    input.setFocus(false);
+    QCOMPARE(input.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 4);
+
+    input.setFocus(true);
+    QCOMPARE(input.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 5);
+
+    scene.clearFocus();
+    QCOMPARE(input.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 6);
+
+    scene.setFocus();
+    QCOMPARE(input.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 7);
+
+    view.clearFocus();
+    QCOMPARE(input.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 8);
+
+    view.setFocus();
+    QCOMPARE(input.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 9);
+
+    // on mac, setActiveWindow(0) on mac does not deactivate the current application
+    // (you have to switch to a different app or hide the current app to trigger this)
+#if !defined(Q_WS_MAC)
+    QApplication::setActiveWindow(0);
+    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(0));
+    QCOMPARE(input.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 10);
+
+    QApplication::setActiveWindow(&view);
+    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+    QCOMPARE(input.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 11);
+#endif
+}
+
 void tst_qdeclarativetextinput::readOnly()
 {
     QDeclarativeView *canvas = createView(SRCDIR "/data/readOnly.qml");
-- 
cgit v0.12


From 8e9c28eaa4d7a3372b9a9a21a984701b62f96456 Mon Sep 17 00:00:00 2001
From: Michael Brasser <michael.brasser@nokia.com>
Date: Fri, 18 Feb 2011 13:52:10 +1000
Subject: Ensure animations start correctly when running is bound to a value.

Animations register to be started when the component is finalized,
but in the case of a binding, the registration doesn't happen until
we are already working with a copy of the finalization list. With this
patch, we no longer work with a copy, but with the actual list.

Change-Id: If460c250d2403590907e9ac854d277db68ba8b2a
Task-number: QTBUG-14042
Reviewed-by: Aaron Kennedy
---
 src/declarative/qml/qdeclarativecomponent.cpp      | 23 ++++++++++------------
 src/declarative/qml/qdeclarativecomponent_p.h      |  1 -
 src/declarative/qml/qdeclarativevme.cpp            |  1 -
 .../data/registrationBug.qml                       | 18 +++++++++++++++++
 .../tst_qdeclarativeanimations.cpp                 | 12 +++++++++++
 5 files changed, 40 insertions(+), 15 deletions(-)
 create mode 100644 tests/auto/declarative/qdeclarativeanimations/data/registrationBug.qml

diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index 5840f70..cf40182 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -870,7 +870,6 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *parentCon
 
         state->bindValues = enginePriv->bindValues;
         state->parserStatus = enginePriv->parserStatus;
-        state->finalizedParserStatus = enginePriv->finalizedParserStatus;
         state->componentAttached = enginePriv->componentAttached;
         if (state->componentAttached)
             state->componentAttached->prev = &state->componentAttached;
@@ -878,7 +877,6 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *parentCon
         enginePriv->componentAttached = 0;
         enginePriv->bindValues.clear();
         enginePriv->parserStatus.clear();
-        enginePriv->finalizedParserStatus.clear();
         state->completePending = true;
         enginePriv->inProgressCreations++;
     }
@@ -909,7 +907,6 @@ void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeEnginePrivate *engi
 
         state->bindValues = enginePriv->bindValues;
         state->parserStatus = enginePriv->parserStatus;
-        state->finalizedParserStatus = enginePriv->finalizedParserStatus;
         state->componentAttached = enginePriv->componentAttached;
         if (state->componentAttached)
             state->componentAttached->prev = &state->componentAttached;
@@ -917,7 +914,6 @@ void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeEnginePrivate *engi
         enginePriv->componentAttached = 0;
         enginePriv->bindValues.clear();
         enginePriv->parserStatus.clear();
-        enginePriv->finalizedParserStatus.clear();
         state->completePending = true;
         enginePriv->inProgressCreations++;
     }
@@ -955,14 +951,17 @@ void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePri
             QDeclarativeEnginePrivate::clear(ps);
         }
 
-        for (int ii = 0; ii < state->finalizedParserStatus.count(); ++ii) {
-            QPair<QDeclarativeGuard<QObject>, int> status = state->finalizedParserStatus.at(ii);
-            QObject *obj = status.first;
-            if (obj) {
-                void *args[] = { 0 };
-                QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod,
-                                      status.second, args);
+        if (1 == enginePriv->inProgressCreations) {
+            for (int ii = 0; ii < enginePriv->finalizedParserStatus.count(); ++ii) {
+                QPair<QDeclarativeGuard<QObject>, int> status = enginePriv->finalizedParserStatus.at(ii);
+                QObject *obj = status.first;
+                if (obj) {
+                    void *args[] = { 0 };
+                    QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod,
+                                          status.second, args);
+                }
             }
+            enginePriv->finalizedParserStatus.clear();
         }
 
         while (state->componentAttached) {
@@ -977,7 +976,6 @@ void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePri
 
         state->bindValues.clear();
         state->parserStatus.clear();
-        state->finalizedParserStatus.clear();
         state->completePending = false;
 
         enginePriv->inProgressCreations--;
@@ -987,7 +985,6 @@ void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePri
                 enginePriv->erroredBindings->removeError();
             }
         }
-
     }
 }
 
diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h
index f8bec2b..020c5e0 100644
--- a/src/declarative/qml/qdeclarativecomponent_p.h
+++ b/src/declarative/qml/qdeclarativecomponent_p.h
@@ -101,7 +101,6 @@ public:
         ConstructionState() : componentAttached(0), completePending(false) {}
         QList<QDeclarativeEnginePrivate::SimpleList<QDeclarativeAbstractBinding> > bindValues;
         QList<QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus> > parserStatus;
-        QList<QPair<QDeclarativeGuard<QObject>, int> > finalizedParserStatus;
         QDeclarativeComponentAttached *componentAttached;
         QList<QDeclarativeError> errors;
         bool completePending;
diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp
index 366c64b..2d551f2 100644
--- a/src/declarative/qml/qdeclarativevme.cpp
+++ b/src/declarative/qml/qdeclarativevme.cpp
@@ -938,7 +938,6 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
 
         QDeclarativeEnginePrivate::clear(bindValues);
         QDeclarativeEnginePrivate::clear(parserStatus);
-        ep->finalizedParserStatus.clear();
         return 0;
     }
 
diff --git a/tests/auto/declarative/qdeclarativeanimations/data/registrationBug.qml b/tests/auto/declarative/qdeclarativeanimations/data/registrationBug.qml
new file mode 100644
index 0000000..7dc29f9
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeanimations/data/registrationBug.qml
@@ -0,0 +1,18 @@
+import QtQuick 1.0
+
+Rectangle {
+    id: rect
+    width: 200
+    height: 200
+
+    property bool animating: true
+    property int value: 0
+
+    NumberAnimation {
+        target: rect
+        property: "value"
+        running: rect.animating
+        to: 100
+        duration: 50
+    }
+}
diff --git a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
index 6f71dec..d1b7c1b 100644
--- a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
+++ b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
@@ -85,6 +85,7 @@ private slots:
     void rotation();
     void runningTrueBug();
     void nonTransitionBug();
+    void registrationBug();
 };
 
 #define QTIMED_COMPARE(lhs, rhs) do { \
@@ -793,6 +794,17 @@ void tst_qdeclarativeanimations::nonTransitionBug()
     QCOMPARE(mover->x(), qreal(100));
 }
 
+//QTBUG-14042
+void tst_qdeclarativeanimations::registrationBug()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent c(&engine, SRCDIR "/data/registrationBug.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(c.create());
+    QVERIFY(rect != 0);
+    QTRY_COMPARE(rect->property("value"), QVariant(int(100)));
+}
+
 QTEST_MAIN(tst_qdeclarativeanimations)
 
 #include "tst_qdeclarativeanimations.moc"
-- 
cgit v0.12


From 1bcddaaf318fc37c71c5191913f3487c49444ec6 Mon Sep 17 00:00:00 2001
From: Martin Jones <martin.jones@nokia.com>
Date: Mon, 21 Feb 2011 14:57:08 +1000
Subject: Prevent recursion due to nested Flickables with pressDelay

The outermost Flickable handles pressDelay for all descendents, rather
than having it cascade up and replayed multiple times.

Change-Id: Id294862469f3ce56b0940fbbb0e041d4c9f64f28
Task-number: QTBUG-17361
Reviewed-by: Michael Brasser
---
 .../graphicsitems/qdeclarativeflickable.cpp        | 48 ++++++++++++++++++++--
 .../graphicsitems/qdeclarativeflickable_p.h        |  1 +
 .../graphicsitems/qdeclarativeflickable_p_p.h      |  1 +
 .../tst_qdeclarativeflickable.cpp                  | 29 +++++++++++++
 .../tst_qdeclarativemousearea.cpp                  | 20 +++------
 5 files changed, 80 insertions(+), 19 deletions(-)

diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index 5d5fd0b..a3d9f41 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -845,7 +845,8 @@ void QDeclarativeFlickable::mousePressEvent(QGraphicsSceneMouseEvent *event)
 {
     Q_D(QDeclarativeFlickable);
     if (d->interactive) {
-        d->handleMousePressEvent(event);
+        if (!d->pressed)
+            d->handleMousePressEvent(event);
         event->accept();
     } else {
         QDeclarativeItem::mousePressEvent(event);
@@ -910,11 +911,27 @@ void QDeclarativeFlickable::wheelEvent(QGraphicsSceneWheelEvent *event)
     }
 }
 
+bool QDeclarativeFlickablePrivate::isOutermostPressDelay() const
+{
+    Q_Q(const QDeclarativeFlickable);
+    QDeclarativeItem *item = q->parentItem();
+    while (item) {
+        QDeclarativeFlickable *flick = qobject_cast<QDeclarativeFlickable*>(item);
+        if (flick && flick->pressDelay() > 0 && flick->isInteractive())
+            return false;
+        item = item->parentItem();
+    }
+
+    return true;
+}
+
 void QDeclarativeFlickablePrivate::captureDelayedPress(QGraphicsSceneMouseEvent *event)
 {
     Q_Q(QDeclarativeFlickable);
     if (!q->scene() || pressDelay <= 0)
         return;
+    if (!isOutermostPressDelay())
+        return;
     delayedPressTarget = q->scene()->mouseGrabberItem();
     delayedPressEvent = new QGraphicsSceneMouseEvent(event->type());
     delayedPressEvent->setAccepted(false);
@@ -970,9 +987,10 @@ void QDeclarativeFlickable::timerEvent(QTimerEvent *event)
                 if (scene()->mouseGrabberItem() == d->delayedPressTarget)
                     d->delayedPressTarget->ungrabMouse();
                 //Use the event handler that will take care of finding the proper item to propagate the event
-                QApplication::sendEvent(scene(), d->delayedPressEvent);
+                QApplication::postEvent(scene(), d->delayedPressEvent);
+            } else {
+                delete d->delayedPressEvent;
             }
-            delete d->delayedPressEvent;
             d->delayedPressEvent = 0;
         }
     }
@@ -1364,6 +1382,22 @@ bool QDeclarativeFlickable::yflick() const
     return d->flickableDirection & QDeclarativeFlickable::VerticalFlick;
 }
 
+bool QDeclarativeFlickable::sceneEvent(QEvent *event)
+{
+    bool rv = QDeclarativeItem::sceneEvent(event);
+    if (event->type() == QEvent::UngrabMouse) {
+        Q_D(QDeclarativeFlickable);
+        if (d->pressed) {
+            // if our mouse grab has been removed (probably by another Flickable),
+            // fix our state
+            d->pressed = false;
+            d->stealMouse = false;
+            setKeepMouseGrab(false);
+        }
+    }
+    return rv;
+}
+
 bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event)
 {
     Q_D(QDeclarativeFlickable);
@@ -1391,7 +1425,7 @@ bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event)
             d->handleMouseMoveEvent(&mouseEvent);
             break;
         case QEvent::GraphicsSceneMousePress:
-            if (d->delayedPressEvent)
+            if (d->pressed) // we are already pressed - this is a delayed replay
                 return false;
 
             d->handleMousePressEvent(&mouseEvent);
@@ -1410,6 +1444,8 @@ bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event)
                 // We send the release
                 scene()->sendEvent(s->mouseGrabberItem(), event);
                 // And the event has been consumed
+                d->stealMouse = false;
+                d->pressed = false;
                 return true;
             }
             d->handleMouseReleaseEvent(&mouseEvent);
@@ -1432,6 +1468,7 @@ bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event)
         d->stealMouse = false;
         d->pressed = false;
     }
+
     return false;
 }
 
@@ -1530,6 +1567,9 @@ bool QDeclarativeFlickable::isFlickingVertically() const
     If the flickable is dragged/flicked before the delay times out
     the press event will not be delivered.  If the button is released
     within the timeout, both the press and release will be delivered.
+
+    Note that for nested Flickables with pressDelay set, the pressDelay of
+    inner Flickables is overridden by the outermost Flickable.
 */
 int QDeclarativeFlickable::pressDelay() const
 {
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p.h
index 4fde1d5..a14cc1c 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeflickable_p.h
@@ -204,6 +204,7 @@ protected:
     virtual void viewportMoved();
     virtual void geometryChanged(const QRectF &newGeometry,
                                  const QRectF &oldGeometry);
+    bool sceneEvent(QEvent *event);
     bool sendMouseEvent(QGraphicsSceneMouseEvent *event);
 
     bool xflick() const;
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h
index 5ad6ff6..1b6081c 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h
@@ -118,6 +118,7 @@ public:
 
     void updateBeginningEnd();
 
+    bool isOutermostPressDelay() const;
     void captureDelayedPress(QGraphicsSceneMouseEvent *event);
     void clearDelayedPress();
 
diff --git a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp
index f4bec8f..736f8f4 100644
--- a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp
+++ b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp
@@ -69,6 +69,7 @@ private slots:
     void maximumFlickVelocity();
     void flickDeceleration();
     void pressDelay();
+    void nestedPressDelay();
     void flickableDirection();
     void qgraphicswidget();
     void resizeContent();
@@ -246,6 +247,34 @@ void tst_qdeclarativeflickable::pressDelay()
     QCOMPARE(spy.count(),1);
 }
 
+// QTBUG-17361
+void tst_qdeclarativeflickable::nestedPressDelay()
+{
+    QDeclarativeView *canvas = new QDeclarativeView;
+    canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/nestedPressDelay.qml"));
+    canvas->show();
+    canvas->setFocus();
+    QVERIFY(canvas->rootObject() != 0);
+
+    QDeclarativeFlickable *outer = qobject_cast<QDeclarativeFlickable*>(canvas->rootObject());
+    QVERIFY(outer != 0);
+
+    QDeclarativeFlickable *inner = canvas->rootObject()->findChild<QDeclarativeFlickable*>("innerFlickable");
+    QVERIFY(inner != 0);
+
+    QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(150, 150)));
+    // the MouseArea is not pressed immediately
+    QVERIFY(outer->property("pressed").toBool() == false);
+
+    // The outer pressDelay will prevail (50ms, vs. 10sec)
+    QTest::qWait(300);
+    QVERIFY(outer->property("pressed").toBool() == true);
+
+    QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(150, 150)));
+
+    delete canvas;
+}
+
 void tst_qdeclarativeflickable::flickableDirection()
 {
     QDeclarativeComponent component(&engine);
diff --git a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp
index 60d51c6..e1c34fc 100644
--- a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp
+++ b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp
@@ -541,15 +541,11 @@ void tst_QDeclarativeMouseArea::preventStealing()
 
     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);
+    QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(80, 80)));
 
     // Without preventStealing, mouse movement over MouseArea would
     // cause the Flickable to steal mouse and trigger content movement.
+    QGraphicsScene *scene = canvas->scene();
     QGraphicsSceneMouseEvent moveEvent(QEvent::GraphicsSceneMouseMove);
     moveEvent.setScenePos(QPointF(70, 70));
     moveEvent.setButton(Qt::LeftButton);
@@ -574,17 +570,12 @@ void tst_QDeclarativeMouseArea::preventStealing()
     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);
+    QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(50, 50)));
 
     // Now allow stealing and confirm Flickable does its thing.
     canvas->rootObject()->setProperty("stealing", false);
 
-    pressEvent.setScenePos(QPointF(80, 80));
-    QApplication::sendEvent(scene, &pressEvent);
+    QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(80, 80)));
 
     // Without preventStealing, mouse movement over MouseArea would
     // cause the Flickable to steal mouse and trigger content movement.
@@ -606,8 +597,7 @@ void tst_QDeclarativeMouseArea::preventStealing()
     QCOMPARE(flickable->contentX(), 10.);
     QCOMPARE(flickable->contentY(), 10.);
 
-    releaseEvent.setScenePos(QPointF(50, 50));
-    QApplication::sendEvent(scene, &releaseEvent);
+    QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(50, 50)));
 
     delete canvas;
 }
-- 
cgit v0.12


From 95a9ab2d0e94c735ac813c809a4fe98dd466cc64 Mon Sep 17 00:00:00 2001
From: Dean Dettman <dean.dettman@nokia.com>
Date: Mon, 21 Feb 2011 12:18:09 +0100
Subject: Wheel delta is always zero in QEventTransition's event

When a QGraphicsSceneWheelEvent was cloned, the original
event's delta property was not copied.

Task-number: QTBUG-17536
Reviewed-by: Kent Hansen
---
 src/gui/statemachine/qguistatemachine.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/gui/statemachine/qguistatemachine.cpp b/src/gui/statemachine/qguistatemachine.cpp
index eadb8ff..2a0de3c 100644
--- a/src/gui/statemachine/qguistatemachine.cpp
+++ b/src/gui/statemachine/qguistatemachine.cpp
@@ -404,6 +404,7 @@ static QEvent *cloneEvent(QEvent *e)
         we2->setButtons(we->buttons());
         we2->setModifiers(we->modifiers());
         we2->setOrientation(we->orientation());
+        we2->setDelta(we->delta());
         return we2;
     }
 #endif
-- 
cgit v0.12


From 2d4298854ba57667a8aa0a0dd3a4bd7ce41aceae Mon Sep 17 00:00:00 2001
From: Miikka Heikkinen <miikka.heikkinen@digia.com>
Date: Mon, 21 Feb 2011 15:38:24 +0200
Subject: Only add NetworkServices capability automatically if no caps are set.

This allows overriding the NetworkServices capability for the
applications that do not need the capability even though they link
network, webkit, or declarative. It is also more intuitive as there
are no magic additions to user defined capabilities.

Task-number: QTBUG-17540
Reviewed-by: Janne Koskinen
---
 doc/src/platforms/platform-notes.qdoc | 6 +++---
 mkspecs/features/qt_functions.prf     | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/doc/src/platforms/platform-notes.qdoc b/doc/src/platforms/platform-notes.qdoc
index aac6bb0..de6eb7f 100644
--- a/doc/src/platforms/platform-notes.qdoc
+++ b/doc/src/platforms/platform-notes.qdoc
@@ -735,9 +735,9 @@
     \row    \o QtCore
             \o \c AllFiles when \l{http://developer.symbian.org/wiki/index.php/Capabilities_%28Symbian_Signed%29/AllFiles_Capability}{accessing specific areas.}
     \row    \o QtDeclarative
-            \o \c NetworkServices is automatically added for this module.
+            \o \c NetworkServices is automatically added for this module if no capabilities are explicitly specified.
     \row    \o QtNetwork
-            \o \c NetworkServices is automatically added for this module.
+            \o \c NetworkServices is automatically added for this module if no capabilities are explicitly specified.
     \row    \o QtNetwork
             \o \c ReadUserData is required to include all the phone's SSL certificates in the system's default CA certificate list
                   (for example those added by the user or stored in the SIM card),
@@ -745,7 +745,7 @@
     \row    \o QtMultiMedia
             \o \c UserEnvironment if QAudioInput is used.
     \row    \o QtWebkit
-            \o \c NetworkServices is automatically added for this module.
+            \o \c NetworkServices is automatically added for this module if no capabilities are explicitly specified.
     \endtable
 
     \note Some modules rely on other modules. E.g. QtWebkit and QtDeclarative
diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf
index 964e13b..24c84a5 100644
--- a/mkspecs/features/qt_functions.prf
+++ b/mkspecs/features/qt_functions.prf
@@ -53,15 +53,15 @@ defineTest(qtAddLibrary) {
             # Needed for because relative inclusion problem in toolchain
             INCLUDEPATH *= $$QMAKE_INCDIR_QT/QtXmlPatterns
             INCLUDEPATH *= $$QMAKE_INCDIR_QT/QtNetwork
-            TARGET.CAPABILITY *= NetworkServices
+            isEmpty(TARGET.CAPABILITY): TARGET.CAPABILITY = NetworkServices
             isEmpty(TARGET.EPOCHEAPSIZE):TARGET.EPOCHEAPSIZE = 0x20000 0x2000000
         } else:isEqual(LIB_NAME, QtXmlPatterns) {
             # Needed for #include <QtXmlPatterns/QtXmlPatterns> because relative inclusion problem in toolchain
             INCLUDEPATH *= $$QMAKE_INCDIR_QT/QtNetwork
         } else:isEqual(LIB_NAME, QtNetwork) {
-            TARGET.CAPABILITY *= NetworkServices
+            isEmpty(TARGET.CAPABILITY): TARGET.CAPABILITY = NetworkServices
         } else:isEqual(LIB_NAME, QtDeclarative) {
-            TARGET.CAPABILITY *= NetworkServices
+            isEmpty(TARGET.CAPABILITY): TARGET.CAPABILITY = NetworkServices
             isEmpty(TARGET.EPOCHEAPSIZE):TARGET.EPOCHEAPSIZE = 0x20000 0x2000000
         }
         export(TARGET.EPOCHEAPSIZE)
-- 
cgit v0.12


From de1417c6648a2589f56a7df0603b26387037aa31 Mon Sep 17 00:00:00 2001
From: Miikka Heikkinen <miikka.heikkinen@digia.com>
Date: Mon, 21 Feb 2011 16:00:07 +0200
Subject: Added support for QMAKE_CLEAN in symbian-sbsv2

Files specified in QMAKE_CLEAN variable will now be properly
cleaned in symbian-sbsv2 builds.

Task-number: QTBUG-17004
Reviewed-by: Janne Koskinen
---
 mkspecs/symbian-sbsv2/flm/qt/qmake_clean.flm | 18 ++++++++++++++++++
 mkspecs/symbian-sbsv2/flm/qt/qt.xml          |  5 +++++
 qmake/generators/symbian/symmake_sbsv2.cpp   | 12 ++++++++++++
 3 files changed, 35 insertions(+)
 create mode 100644 mkspecs/symbian-sbsv2/flm/qt/qmake_clean.flm

diff --git a/mkspecs/symbian-sbsv2/flm/qt/qmake_clean.flm b/mkspecs/symbian-sbsv2/flm/qt/qmake_clean.flm
new file mode 100644
index 0000000..fe35e6e
--- /dev/null
+++ b/mkspecs/symbian-sbsv2/flm/qt/qmake_clean.flm
@@ -0,0 +1,18 @@
+# /****************************************************************************
+# **
+# ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+# ** Contact: Nokia Corporation (qt-info@nokia.com)
+# **
+# ** This file is part of symbian-sbsv2 mkspec.
+# **
+# ****************************************************************************/
+
+
+SINGLETON:=$(call sanitise,QMAKE_CLEAN_SINGLETON_$(EXTENSION_ROOT))
+
+ifeq ($($(SINGLETON)),)
+# Prevent duplicate targets from being created
+$(SINGLETON):=1
+$(eval $(call GenerateStandardCleanTarget,$(CLEAN_FILES),''))
+endif
+
diff --git a/mkspecs/symbian-sbsv2/flm/qt/qt.xml b/mkspecs/symbian-sbsv2/flm/qt/qt.xml
index ddd8d55..f2f32ee 100644
--- a/mkspecs/symbian-sbsv2/flm/qt/qt.xml
+++ b/mkspecs/symbian-sbsv2/flm/qt/qt.xml
@@ -38,4 +38,9 @@
     <interface name="qt.qmake_store_build" extends="Symbian.UserFLM"
                 flm="qmake_store_build.flm">
     </interface>    
+
+    <interface name="qt.qmake_clean" extends="Symbian.UserFLM"
+                flm="qmake_clean.flm">
+        <param name='CLEAN_FILES' />
+    </interface>
 </build>
diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp
index 9eccd46..f94a63f 100644
--- a/qmake/generators/symbian/symmake_sbsv2.cpp
+++ b/qmake/generators/symbian/symmake_sbsv2.cpp
@@ -721,6 +721,18 @@ void SymbianSbsv2MakefileGenerator::writeBldInfExtensionRulesPart(QTextStream& t
     t << "END" << endl;
     t << endl;
 
+    // Handle QMAKE_CLEAN
+    QStringList cleanFiles = project->values("QMAKE_CLEAN");
+    if (!cleanFiles.isEmpty()) {
+        QStringList absoluteCleanFiles;
+        foreach (QString cleanFile, cleanFiles) {
+            QFileInfo fi(cleanFile);
+            absoluteCleanFiles << fi.absoluteFilePath();
+        }
+        t << "START EXTENSION qt/qmake_clean" << endl;
+        t << "OPTION CLEAN_FILES " << absoluteCleanFiles.join(" ") << endl;
+        t << "END" << endl;
+    }
     t << endl;
 }
 
-- 
cgit v0.12


From 11f11f8ad562472759df24a410d52edd63eb2cf4 Mon Sep 17 00:00:00 2001
From: Jason McDonald <jason.mcdonald@nokia.com>
Date: Tue, 22 Feb 2011 00:58:12 +1000
Subject: Add selected P1 tasks to changes file.

Reviewed-by: Trust Me
---
 dist/changes-4.7.2 | 271 +++++++++++++++++++++++++++--------------------------
 1 file changed, 138 insertions(+), 133 deletions(-)

diff --git a/dist/changes-4.7.2 b/dist/changes-4.7.2
index 17a066f..c7e0089 100644
--- a/dist/changes-4.7.2
+++ b/dist/changes-4.7.2
@@ -16,35 +16,48 @@ Qt Bug Tracker: http://bugreports.qt.nokia.com
 Merge Request:  http://qt.gitorious.org
 
 ****************************************************************************
-*                           General                                        *
-****************************************************************************
-
-New features
-------------
-
- - SomeClass, SomeOtherClass
-    * New classes for foo, bar and baz
-
-Optimizations
--------------
-
- - Optimized foo in QSomeClass
-    * See list of Important Behavior Changes below
-
-
-****************************************************************************
 *                          Library                                         *
 ****************************************************************************
 
 QtCore
 ------
 
+ - QMutex
+    * [QTBUG-16115] Fixed deadlock when calling tryLock repeatedly.
  - QStateMachine
-    * [QTBUG-14491] Fix compilation on AIX 5.3 with gcc.
+    * [QTBUG-14491] Fixed compilation on AIX 5.3 with gcc.
+ - QThread
+    * [QTBUG-15378] QThread::exec returaed immediately if QThread::exit had
+      been called when event loop was not running.
 
 QtGui
 -----
 
+ - Painting
+    * [QTBUG-14907] Fix OpenVG painting artifacts after restoreState().
+    * [QTBUG-15320] QPainter::drawRect crashed when drawing a null QRectF 
+      with OpenGL.
+    * [QTBUG-15693] Prevent crash in drawhelper code when the cpu has MMXEXT
+      but no SSE.
+ - QDoubleValidator
+    * [QTBUG-14935] With some locales, QDoubleValidator would not accept "C"
+      locale valid numbers.
+ - QFileDialog
+    * [QTBUG-17298] QFileDialog::getOpenFileNames didn't show any file.
+ - QGraphicsView
+    * [QTBUG-16063] Fix precision loss when querying micro focus rectangle
+      in QGraphicsView.
+ - QPainterPath
+    * [QTBUG-16377] Prevent QPainterPath::connectPath() returning incorrect
+      path, which caused OpenGL paint engine to crash.
+ - QTableWidget
+    * [QTBUG-15973] Resizinag a QTableWidget column where a cell contains a
+      QProgressBar made it crash.
+ - QTextDocument
+    * [QTBUG-15777] Fxied crash in QTextDocument::markContentsDirty.
+ - QTextLayout
+    * [QTBUG-15823] Fixed crash in QTextLayout when drawing full width
+      selection spanning multiple QTextLine's.
  - QWidget
     * [QTMOBILITY-645] Send WinIdChange event when winId is set to zero.
       The window handle of a native widget may be set to zero in two
@@ -52,27 +65,32 @@ QtGui
       widget destruction.  Previously, no WinIdChange event was sent in
       either of these cases; now, it is sent in both cases.
 
-QtDBus
-------
-
- - foo
-    * bar
-
 QtNetwork
 ---------
 
- - foo
-    * bar
+ - Bearer Management
+    * [QTBUG-15276] Fixed possible crash when parsing new connection.
+ - QUrl
+    * [QTBUG-16425] QUrl::setUrl() did not call detach().
 
-QtOpenGL
---------
+QtQuick
+-------
 
- - foo
-    * bar
+ - [QTBUG-14374] Fixed broken alignment of rich text.
+ - [QTBUG-14727] QML Text element did not play nice with transformations.
+ - [QTBUG-14761] Fixed memory leak in QDeclarativeComponent.
+ - [QTBUG-14830] Fixed crash when adjusting width inside onWidthChanged.
+ - [QTBUG-15710] Ensure header is considered when positioning content with
+   snapping.
+ - [QTBUG-16365] When using a PathView with a VisualDataModel which in turn
+   used a Tree model (DirModel, for example), nothing was shown.
+ - [QTBUG-16769] QML BorderImage failed if .sci file contained a URL.
 
 QtScript
 --------
 
+ - General
+    * [QTBUG-17166] Fix ScopeChainNode memory leak in JavaScriptCore.
  - QScriptContext
     * [QTBUG-17137] Fix crash when generating backtrace involving a
       built-in (ECMA) function.
@@ -94,56 +112,55 @@ QtScript
 QtSql
 -----
 
- - foo
-    * bar
-
-QtXml
------
-
- - foo
-    * bar
-
-Qt Plugins
-----------
-
- - foo
-    * bar
-
-Third party components
-----------------------
-
- - Updated foo to version 2.3.9.
-
- - Updated bar to the latest version from baz.org.
+ - [QTBUG-14132] Fix errors in Oracle (xe) stored procedures with bind
+   variables.
+ - [QTBUG-14831] Fix regression in dynamic sorting of a QSortFilterProxyModel
+   on a QSqlTableModel with OnManualSubmit.
+ - [QTBUG-17076] Fix plugins/sqldrivers/oci compile error when using
+   QT_NAMESPACE.
 
 
 ****************************************************************************
 *                      Platform Specific Changes                           *
 ****************************************************************************
 
-Qt for Unix (X11 and Mac OS X)
-------------------------------
-
- - 
-
 Qt for Linux/X11
 ----------------
 
- -
+ - [QTBUG-15008] Fix broken prefix setting in configure when EPOCROOT shell
+   variable is set.
 
 Qt for Windows
 --------------
 
- -
+ - QtQuick
+    * [QTBUG-16885] QDeclarativeEngine::addImportPath() did not work if the
+      drive letter is in lowercase.
+    * [QTBUG-17360] Make sure $QTDIR/plugins/qmldebugging/tcpserver.dll is
+      found in windows release builds.
 
 Qt for Mac OS X
 ---------------
 
- -
+ - [QTBUG-13772] Returning form fullscreen mode causes assertion failure.
+ - [QTBUG-14023] Added missing plugins to debug-libs package.
+ - [QTBUG-14420] Switching from an application with undocked widgets hid the
+   application.
+ - [QTBUG-15638] Fixed incorrect QComboBox drop-down menu Z-ordering.
+ - [QTBUG-15666] Fixed crash when closing QFontDialog::getFont() dialog before
+   its event loop finished.
+ - [QTBUG-16279] Fixed deadlock in QSyntaxHighlighter::highlightBlock.
 
 Qt for Symbian
 --------------
 
+ - Multimedia
+    * [QTBUG-17040] Prevent menu and native title pane area popping up when
+      setting fullscreen mode off during video playback.
+ - Packaging changes
+    * [QTBUG-17399] Remove sqlite3 from Qt SIS for S60 3.2 and 5.0 to allow
+      Nokia Content Signing, which doesn't permit sis files to have other
+      sis files embedded inside.
  - Paging changes
     * [QT-3503] Remove PAGED keyword from all Qt-based binaries for
       MMP-based build systems (abld, SBSv2 (a.k.a. Raptor)).
@@ -159,65 +176,92 @@ Qt for Symbian
       appropriate types of paging rather than being forced by the binary
       (which may be deployed to several different devices with different
       characteristics).
-
  - Phonon MMF backend
    * [QTBUG-11436] Added a MediaObject property which allows the client to
      specify which Internet Access Point should be used for streaming.
-
- - QNetworkProxyFactory
-   * [QTBUG-13857] Added systemProxyForQuery() for Symbian, allowing
-     network proxies configured on the device to be used by applications.
-
  - QApplication
-   * [QTBUG-15915] Fix crash when creating more than one QApplication in single test case.
-
+   * [QTBUG-15915] Fix crash when creating more than one QApplication in single
+     test case.
+   * [QTBUG-16065] QApplication object with QApplication::GuiServer type caused
+     crash on Symbian devices.
  - QDesktopWidget
    * [QTBUG-16095] Resize event for QDesktopWidget was sent too early.
-
- - QFileDialog
-   * [QTBUG-16204] Fix using QFileDialog statics in Symbian.
-
  - QDialog
    * [QTBUG-16277] Fix fullscreen/Maximized dialog misplacement in Symbian.
-
- - QSystemSemaphore
-   * [QTBUG-16615] Fix QSystemSemaphore handle management issues in Symbian.
-
+   * [QTBUG-16110] QMessageBox softkeys were dimmed when application returned
+     to foreground.
+ - QEventDispatcherSymbian
+   * [QTBUG-16380] Fix leaking of RTimer handles.
+ - QFileDialog
+   * [QTBUG-16204] Fix using QFileDialog statics in Symbian.
+ - QFontDatabase
+   * [QTBUG-16514] Avoid collision of application fonts.
+ - QGraphicsView
+   * [QTBUG-16932] Fix rendering errors on QGraphicsView with OpenVG engine.
  - QLineEdit
    * [QTBUG-16238] Fix one character displacement for cursor in line edits.
-
- - QtScript
-    * [QTBUG-16685] Fix crash in JavaScript stack allocator.
-    * [QTBUG-15847] Add compiler optimizations.
-    * [QTBUG-14293] Enhanced JavaScript heap allocator.
-
  - qmake & mkspecs
    * [QT-4193] Only add ICON for application projects in symbianpkgrules.pri
-   * [QTBUG-13159] Allow pkg_prerules and pkg_postrules to be targeted to separate files.
-   * [QTBUG-13367] Make default application deployment removable & added .flags modifier
-      support for DEPLOYMENT items in Symbian.
+   * [QTBUG-13159] Allow pkg_prerules and pkg_postrules to be targeted to separate
+     files.
+   * [QTBUG-13367] Make default application deployment removable & added .flags
+     modifier support for DEPLOYMENT items in Symbian.
    * [QTBUG-14280] Implement support for DEPLOYMENT.display_name in Symbian.
    * [QTBUG-13917] Localize .loc and .pkg content based on TRANSLATIONS.
-   * [QTBUG-15159] Use include(original mkspec) instead of copying of mkspec to default.
+   * [QTBUG-15159] Use include(original mkspec) instead of copying of mkspec to
+     default.
    * [QTBUG-15393] Resolve EPOCROOT in qt.conf using same logic as in .pro.
    * [QTBUG-15501] Fix symbian-mmp.conf include path.
-   * [QTBUG-15539] Use parent class function to generate Makefile headers in Symbian.
-   * [QTBUG-14472] Add NetworkServices capability automatically for network apps
+   * [QTBUG-15539] Use parent class function to generate Makefile headers.
+   * [QTBUG-14472] Add NetworkServices capability automatically for network apps.
    * [QTBUG-14736] Add libinfix support for QML plugins in Symbian.
-   * [QT-4375] Fix incorrect file name case for OpenGL libraries in symbian.conf.
-   * [QTBUG-16172] Use relative include instead of absolute in default qmake.conf.
+   * [QT-4375] Fix incorrect file name case for OpenGL libraries in
+     symbian.conf.
+   * [QTBUG-16172] Use relative include instead of absolute in default
+     qmake.conf.
    * [QTBUG-16221] Fix libinfixed usage in Symbian when def files are used.
    * [QTBUG-16261] Fix infinite loop in qmake when reading malformed .ts files.
    * [QTBUG-16298] Ignore static_and_shared in Symbian builds.
+   * [QTBUG-16477] Fix compile error when QT_NO_BEARERMANAGEMENT is defined.
    * [QTBUG-13769] Generate freeze targets in Symbian.
-   * [QTBUG-16691] Remove toolcheck from generic clean targets for symbian-sbsv2.
-   * [QT-4476] Fixed UTF-8 application names in device application menu in Symbian.
+   * [QTBUG-16691] Remove toolcheck from generic clean targets for
+     symbian-sbsv2.
+   * [QT-4476] Fixed UTF-8 application names in device application menu.
    * [QTBUG-16753] Improved QMAKE_POST_LINK support in symbian-sbsv2.
-   * [QTBUG-16881] Fix QMAKE_POST_LINK in Symbian for targets with special characters.
-   * [QTBUG-16888] No longer replace dash and dot in TARGET with underscore in Symbian.
+   * [QTBUG-16881] Fix QMAKE_POST_LINK for targets with special characters.
+   * [QTBUG-16888] No longer replace dash and dot in TARGET with underscore.
+   * [QTBUG-17187] Ensure that package generated against Symbian^3 SDK has no
+     Symbian^1 platforms as dependencies.
    * Fix partial upgrade package UID for libinfixed Qt.
    * Cleaned up sis_targets.prf.
-
+ - QNetworkProxyFactory
+   * [QTBUG-13857] Added systemProxyForQuery() for Symbian, allowing
+     network proxies configured on the device to be used by applications.
+ - QPaintEngine
+   * [QTBUG-16008] Fixed broken constant alpha blending on ARMV6.
+   * [QTBUG-16240] Fix blurry text in word-wrapped, center-aligned text items
+     with OpenVG.
+ - QSystemSemaphore
+   * [QTBUG-16615] Fix QSystemSemaphore handle management issues in Symbian.
+ - qtmain.lib
+   * [QTBUG-14735] Use qtmain.lib to provide entry point for all applications.
+ - QtQuick
+   * [QTBUG-15405] QML Plugins were not loaded when installed on different
+     drives.
+ - QtScript
+   * [QTBUG-14293] Enhanced JavaScript heap allocator.
+   * [QTBUG-15800] Creating QScriptEngine on the heap caused app crash.
+   * [QTBUG-15847] Add compiler optimizations.
+   * [QTBUG-16685] Fix crash in JavaScript stack allocator.
+ - QWidget
+   * [QTBUG-16578] In cases where the widget was created from the event loop
+     instead of main(), the middle three softkeys would not get the right
+     visibility and would leave a "hole" in the application where one could
+     see what was beneath it.
+   * [QT-4416, QTBUG-17288] On devices which lack support for transparency
+     in EGL surfaces, setting Qt::WA_TranslucentBackground on a widget
+     whose windowType() is Qt::Window causes that widget to be rendered
+     using the raster graphics system.
  - Tool scripts
    * [QTBUG-13886] Disallow patching capabilities of executables.
    * [QTBUG-13891] Add Location as self signable capability in patch_capabilities.pl.
@@ -225,49 +269,10 @@ Qt for Symbian
    * Fix epocroot handling in createpackage.pl script.
    * Unify epocroot usage in createpackage and patch_capabilities scripts.
 
- - qtmain.lib
-   * [QTBUG-14735] Use qtmain.lib to provide entry point for all Symbian applications.
-
- - QWidget
-    * [QT-4416, QTBUG-17288] On devices which lack support for transparency
-      in EGL surfaces, setting Qt::WA_TranslucentBackground on a widget
-      whose windowType() is Qt::Window causes that widget to be rendered
-      using the raster graphics system.
-
-Qt for Embedded Linux
----------------------
-
- -
-
-DirectFB
---------
-
- -
-
-Qt for Windows CE
------------------
-
- -
-
 ****************************************************************************
 *                          Tools                                           *
 ****************************************************************************
 
- - Designer
-   * foo
-
- - qdoc3
-   * bar
-
- - Linguist
-   * baz
-
  - qmake
    * [QTBUG-14357] Make qmake to pass all UTF-8 characters unchanged through parser.
 
-****************************************************************************
-* Important Behavior Changes *
-****************************************************************************
-
- -
-
-- 
cgit v0.12


From 0c24787a2f35a7b0585c9dfb3bf0a8cb34ce867f Mon Sep 17 00:00:00 2001
From: Martin Jones <martin.jones@nokia.com>
Date: Tue, 22 Feb 2011 10:03:14 +1000
Subject: Add missing test file.

Missed in 1bcddaaf318fc37c71c5191913f3487c49444ec6

Change-Id: I4f71e5fb2b0e67a6e64ee64ae03b9d9cfc7a244f
Task-number: QTBUG-17361
---
 .../data/nestedPressDelay.qml                      | 33 ++++++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 tests/auto/declarative/qdeclarativeflickable/data/nestedPressDelay.qml

diff --git a/tests/auto/declarative/qdeclarativeflickable/data/nestedPressDelay.qml b/tests/auto/declarative/qdeclarativeflickable/data/nestedPressDelay.qml
new file mode 100644
index 0000000..d0ee545
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeflickable/data/nestedPressDelay.qml
@@ -0,0 +1,33 @@
+import QtQuick 1.0
+
+Flickable {
+    property bool pressed: ma.pressed
+    width: 240
+    height: 320
+    contentWidth: 480
+    contentHeight: 320
+    flickableDirection: Flickable.HorizontalFlick
+    pressDelay: 50
+    Flickable {
+        objectName: "innerFlickable"
+        flickableDirection: Flickable.VerticalFlick
+        width: 480
+        height: 320
+        contentWidth: 480
+        contentHeight: 400
+        pressDelay: 10000
+        Rectangle {
+            y: 100
+            anchors.horizontalCenter: parent.horizontalCenter
+            width: 240
+            height: 100
+            color: ma.pressed ? 'blue' : 'green'
+            MouseArea {
+                id: ma
+                objectName: "mouseArea"
+                anchors.fill: parent
+            }
+        }
+    }
+}
+
-- 
cgit v0.12


From 5fa90e4bc83541dc23db150166157e2a3f04a668 Mon Sep 17 00:00:00 2001
From: Michael Brasser <michael.brasser@nokia.com>
Date: Mon, 21 Feb 2011 16:11:50 +1000
Subject: Prevent an animation from being registered to run twice.

This could cause animations to start running that could not later be
stopped.

Change-Id: I320f50121f3566619f08181664d049b02e2848e5
Reviewed-by: Martin Jones
---
 src/declarative/util/qdeclarativeanimation.cpp             |  5 ++---
 src/declarative/util/qdeclarativeanimation_p_p.h           |  3 ++-
 .../declarative/qdeclarativeanimations/data/Double.qml     | 14 ++++++++++++++
 .../qdeclarativeanimations/data/doubleRegistrationBug.qml  |  8 ++++++++
 .../qdeclarativeanimations/tst_qdeclarativeanimations.cpp  | 14 ++++++++++++++
 5 files changed, 40 insertions(+), 4 deletions(-)
 create mode 100644 tests/auto/declarative/qdeclarativeanimations/data/Double.qml
 create mode 100644 tests/auto/declarative/qdeclarativeanimations/data/doubleRegistrationBug.qml

diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp
index f22b9dd..014d368 100644
--- a/src/declarative/util/qdeclarativeanimation.cpp
+++ b/src/declarative/util/qdeclarativeanimation.cpp
@@ -182,12 +182,11 @@ void QDeclarativeAbstractAnimation::setRunning(bool r)
 {
     Q_D(QDeclarativeAbstractAnimation);
     if (!d->componentComplete) {
-        if (d->running && r == d->running)    //don't re-register
-            return;
         d->running = r;
         if (r == false)
             d->avoidPropertyValueSourceStart = true;
-        else {
+        else if (!d->registered) {
+            d->registered = true;
             QDeclarativeEnginePrivate *engPriv = QDeclarativeEnginePrivate::get(qmlEngine(this));
             engPriv->registerFinalizedParserStatusObject(this, this->metaObject()->indexOfSlot("componentFinalized()"));
         }
diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h
index 84bc0ef..3c41565 100644
--- a/src/declarative/util/qdeclarativeanimation_p_p.h
+++ b/src/declarative/util/qdeclarativeanimation_p_p.h
@@ -210,7 +210,7 @@ public:
     : running(false), paused(false), alwaysRunToEnd(false),
       connectedTimeLine(false), componentComplete(true),
       avoidPropertyValueSourceStart(false), disableUserControl(false),
-      loopCount(1), group(0) {}
+      registered(false), loopCount(1), group(0) {}
 
     bool running:1;
     bool paused:1;
@@ -219,6 +219,7 @@ public:
     bool componentComplete:1;
     bool avoidPropertyValueSourceStart:1;
     bool disableUserControl:1;
+    bool registered:1;
 
     int loopCount;
 
diff --git a/tests/auto/declarative/qdeclarativeanimations/data/Double.qml b/tests/auto/declarative/qdeclarativeanimations/data/Double.qml
new file mode 100644
index 0000000..b247fce
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeanimations/data/Double.qml
@@ -0,0 +1,14 @@
+import QtQuick 1.0
+
+Rectangle {
+    id: container
+    property bool on: false
+    border.color: "#ffffff"
+    color: "green"
+    width: 50
+    height: 50
+    NumberAnimation on x {
+        objectName: "animation"
+        running: container.on; from: 0; to: 600; loops: Animation.Infinite; duration: 2000
+    }
+}
diff --git a/tests/auto/declarative/qdeclarativeanimations/data/doubleRegistrationBug.qml b/tests/auto/declarative/qdeclarativeanimations/data/doubleRegistrationBug.qml
new file mode 100644
index 0000000..f0fdf9c
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeanimations/data/doubleRegistrationBug.qml
@@ -0,0 +1,8 @@
+import QtQuick 1.0
+
+Rectangle {
+    width: 400; height: 400
+
+    Double { id: dub; on: parent.width < 800 }
+    Component.onCompleted: dub.on = false
+}
diff --git a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
index d1b7c1b..f7fee3b 100644
--- a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
+++ b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
@@ -86,6 +86,7 @@ private slots:
     void runningTrueBug();
     void nonTransitionBug();
     void registrationBug();
+    void doubleRegistrationBug();
 };
 
 #define QTIMED_COMPARE(lhs, rhs) do { \
@@ -805,6 +806,19 @@ void tst_qdeclarativeanimations::registrationBug()
     QTRY_COMPARE(rect->property("value"), QVariant(int(100)));
 }
 
+void tst_qdeclarativeanimations::doubleRegistrationBug()
+{
+    QDeclarativeEngine engine;
+
+    QDeclarativeComponent c(&engine, SRCDIR "/data/doubleRegistrationBug.qml");
+    QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(c.create());
+    QVERIFY(rect != 0);
+
+    QDeclarativeAbstractAnimation *anim = rect->findChild<QDeclarativeAbstractAnimation*>("animation");
+    QVERIFY(anim != 0);
+    QTRY_COMPARE(anim->qtAnimation()->state(), QAbstractAnimation::Stopped);
+}
+
 QTEST_MAIN(tst_qdeclarativeanimations)
 
 #include "tst_qdeclarativeanimations.moc"
-- 
cgit v0.12


From 15ebe8a375542826278aac2b920f0e3dac3ffaea Mon Sep 17 00:00:00 2001
From: Joona Petrell <joona.t.petrell@nokia.com>
Date: Mon, 21 Feb 2011 14:41:38 +1000
Subject: Another stab at fixing compilation on old Symbian platforms

Task-number: QTBUG-17472
Reviewed-by: Martin Jones
---
 tools/qml/qml.pri        | 6 ++----
 tools/qml/qmlruntime.cpp | 2 +-
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/tools/qml/qml.pri b/tools/qml/qml.pri
index 08cd506..5397384 100644
--- a/tools/qml/qml.pri
+++ b/tools/qml/qml.pri
@@ -25,12 +25,10 @@ symbian: {
     }
     !contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2) {
         LIBS += -lsensrvclient -lsensrvutil
-    }
-    !contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2): {
         SOURCES += $$PWD/deviceorientation_symbian.cpp
-        FORMS = $$PWD/recopts.ui \
-                     $$PWD/proxysettings.ui
     }
+    FORMS += $$PWD/recopts.ui \
+             $$PWD/proxysettings.ui
 } else:maemo5 {
     QT += dbus
     HEADERS += $$PWD/texteditautoresizer_maemo5.h
diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp
index c746d8e..36915d1 100644
--- a/tools/qml/qmlruntime.cpp
+++ b/tools/qml/qmlruntime.cpp
@@ -50,7 +50,7 @@
 #  include <QWidgetAction>
 #  include <QStringListModel>
 #  include "ui_recopts_maemo5.h"
-#elif !defined(__SERIES60_31__) && !defined(__S60_32__)
+#else
 #  include "ui_recopts.h"
 #endif
 
-- 
cgit v0.12


From ceecec1083bac96bdb600020b01c299c389eaa8c Mon Sep 17 00:00:00 2001
From: Joona Petrell <joona.t.petrell@nokia.com>
Date: Tue, 22 Feb 2011 11:39:56 +1000
Subject: Update QtGui def files

Task-number:
Reviewed-by: Martin Jones
---
 src/s60installs/bwins/QtGuiu.def | 2 ++
 src/s60installs/eabi/QtGuiu.def  | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def
index adf2b3c..a41f784 100644
--- a/src/s60installs/bwins/QtGuiu.def
+++ b/src/s60installs/bwins/QtGuiu.def
@@ -12950,4 +12950,6 @@ EXPORTS
 	?dynamicPageCount@QTextDocumentLayout@@QBEHXZ @ 12949 NONAME ; int QTextDocumentLayout::dynamicPageCount(void) const
 	?setWordSelectionEnabled@QTextControl@@QAEX_N@Z @ 12950 NONAME ; void QTextControl::setWordSelectionEnabled(bool)
 	?isWordSelectionEnabled@QTextControl@@QBE_NXZ @ 12951 NONAME ; bool QTextControl::isWordSelectionEnabled(void) const
+	?assignedInputContext@QWidgetPrivate@@QBEPAVQInputContext@@XZ @ 12952 NONAME ; class QInputContext * QWidgetPrivate::assignedInputContext(void) const
+	?updateMicroFocus@QLineControl@@IAEXXZ @ 12953 NONAME ; void QLineControl::updateMicroFocus(void)
 
diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def
index 564f530..2de88f2 100644
--- a/src/s60installs/eabi/QtGuiu.def
+++ b/src/s60installs/eabi/QtGuiu.def
@@ -12145,4 +12145,6 @@ EXPORTS
 	_ZTV19QTextDocumentLayout @ 12144 NONAME
 	_ZN12QTextControl23setWordSelectionEnabledEb @ 12145 NONAME
 	_ZNK12QTextControl22isWordSelectionEnabledEv @ 12146 NONAME
+	_ZN12QLineControl16updateMicroFocusEv @ 12147 NONAME
+	_ZNK14QWidgetPrivate20assignedInputContextEv @ 12148 NONAME
 
-- 
cgit v0.12


From 2dad737a8cef6191a46eead8ea9940034d083884 Mon Sep 17 00:00:00 2001
From: Andrew den Exter <andrew.den-exter@nokia.com>
Date: Tue, 22 Feb 2011 10:51:18 +1000
Subject: Fix auto test failure on mac.

Allow for some error in the cursor position due to plaform specific
offsets and the like.

Change-Id: I2bef793596ab2a5e38cf77aee624bd9fdd5ca38c
---
 .../tst_qdeclarativetextedit.cpp                   | 60 ++++++++++-----------
 .../tst_qdeclarativetextinput.cpp                  | 61 +++++++++++-----------
 2 files changed, 60 insertions(+), 61 deletions(-)

diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
index ba410ce..2c3ec7c 100644
--- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
+++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
@@ -1970,9 +1970,9 @@ void tst_qdeclarativetextedit::inputContextMouseHandler()
     QDeclarativeTextEdit edit;
     edit.setPos(0, 0);
     edit.setWidth(200);
-    edit.setText(text.mid(0, 5));
+    edit.setText(text.mid(0, 12));
     edit.setPos(0, 0);
-    edit.setCursorPosition(5);
+    edit.setCursorPosition(12);
     edit.setFocus(true);
     scene.addItem(&edit);
     view.show();
@@ -1985,15 +1985,15 @@ void tst_qdeclarativetextedit::inputContextMouseHandler()
     const qreal y = fm.height() / 2;
 
     QPoint position2 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 2)), y)));
-    QPoint position4 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 4)), y)));
-    QPoint position7 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 7)), y)));
-    QPoint position12 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 12)), y)));
+    QPoint position8 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 8)), y)));
+    QPoint position20 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 20)), y)));
+    QPoint position27 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 27)), y)));
     QPoint globalPosition2 = view.viewport()->mapToGlobal(position2);
-    QPoint globalPosition4 = view.viewport()->mapToGlobal(position4);
-    QPoint globalPosition7 = view.viewport()->mapToGlobal(position7);
-    QPoint globalPosition12 = view.viewport()->mapToGlobal(position12);
+    QPoint globalposition8 = view.viewport()->mapToGlobal(position8);
+    QPoint globalposition20 = view.viewport()->mapToGlobal(position20);
+    QPoint globalposition27 = view.viewport()->mapToGlobal(position27);
 
-    ic.sendEvent(QInputMethodEvent(text.mid(5), QList<QInputMethodEvent::Attribute>()));
+    ic.sendEvent(QInputMethodEvent(text.mid(12), QList<QInputMethodEvent::Attribute>()));
 
     QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2);
     QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
@@ -2013,56 +2013,56 @@ void tst_qdeclarativetextedit::inputContextMouseHandler()
     QVERIFY(ic.cursor < 0);
     ic.eventType = QEvent::None;
 
-    {   QMouseEvent mv(QEvent::MouseMove, position4, globalPosition4, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+    {   QMouseEvent mv(QEvent::MouseMove, position8, globalposition8, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
         QApplication::sendEvent(view.viewport(), &mv); }
     QCOMPARE(ic.eventType, QEvent::None);
 
-    {   QMouseEvent mv(QEvent::MouseMove, position12, globalPosition12, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+    {   QMouseEvent mv(QEvent::MouseMove, position27, globalposition27, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
         QApplication::sendEvent(view.viewport(), &mv); }
     QCOMPARE(ic.eventType, QEvent::MouseMove);
-    QCOMPARE(ic.eventPosition, position12);
-    QCOMPARE(ic.eventGlobalPosition, globalPosition12);
+    QCOMPARE(ic.eventPosition, position27);
+        QCOMPARE(ic.eventGlobalPosition, globalposition27);
     QCOMPARE(ic.eventButton, Qt::LeftButton);
     QCOMPARE(ic.eventModifiers, Qt::NoModifier);
-    QCOMPARE(ic.cursor, 7);
+    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);    // 15 is expected but some platforms may be off by one.
     ic.eventType = QEvent::None;
 
-    QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, position12);
+    QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, position27);
     QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
-    QCOMPARE(ic.eventPosition, position12);
-    QCOMPARE(ic.eventGlobalPosition, globalPosition12);
+    QCOMPARE(ic.eventPosition, position27);
+    QCOMPARE(ic.eventGlobalPosition, globalposition27);
     QCOMPARE(ic.eventButton, Qt::LeftButton);
     QCOMPARE(ic.eventModifiers, Qt::NoModifier);
-    QCOMPARE(ic.cursor, 7);
+    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
     ic.eventType = QEvent::None;
 
     // And in the other direction.
-    QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, position12);
+    QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, position27);
     QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
-    QCOMPARE(ic.eventPosition, position12);
-    QCOMPARE(ic.eventGlobalPosition, globalPosition12);
+    QCOMPARE(ic.eventPosition, position27);
+    QCOMPARE(ic.eventGlobalPosition, globalposition27);
     QCOMPARE(ic.eventButton, Qt::LeftButton);
     QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
-    QCOMPARE(ic.cursor, 7);
+    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
     ic.eventType = QEvent::None;
 
-    QTest::mousePress(view.viewport(), Qt::RightButton, Qt::ControlModifier, position12);
+    QTest::mousePress(view.viewport(), Qt::RightButton, Qt::ControlModifier, position27);
     QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
-    QCOMPARE(ic.eventPosition, position12);
-    QCOMPARE(ic.eventGlobalPosition, globalPosition12);
+    QCOMPARE(ic.eventPosition, position27);
+    QCOMPARE(ic.eventGlobalPosition, globalposition27);
     QCOMPARE(ic.eventButton, Qt::RightButton);
     QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
-    QCOMPARE(ic.cursor, 7);
+    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
     ic.eventType = QEvent::None;
 
-    {   QMouseEvent mv(QEvent::MouseMove, position7, globalPosition7, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
+    {   QMouseEvent mv(QEvent::MouseMove, position20, globalposition20, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
         QApplication::sendEvent(view.viewport(), &mv); }
     QCOMPARE(ic.eventType, QEvent::MouseMove);
-    QCOMPARE(ic.eventPosition, position7);
-    QCOMPARE(ic.eventGlobalPosition, globalPosition7);
+    QCOMPARE(ic.eventPosition, position20);
+    QCOMPARE(ic.eventGlobalPosition, globalposition20);
     QCOMPARE(ic.eventButton, Qt::RightButton);
     QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
-    QCOMPARE(ic.cursor, 2);
+    QVERIFY(ic.cursor >= 7 && ic.cursor <= 9);
     ic.eventType = QEvent::None;
 
     {   QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
index b8f73bd..49a05a3 100644
--- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
+++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
@@ -1958,7 +1958,8 @@ void tst_qdeclarativetextinput::inputContextMouseHandler()
     view.setInputContext(&ic);
     QDeclarativeTextInput input;
     input.setWidth(200);
-    input.setText(text.mid(0, 5));
+    input.setText(text.mid(0, 12));
+    input.setCursorPosition(12);
     input.setPos(0, 0);
     input.setFocus(true);
     scene.addItem(&input);
@@ -1967,21 +1968,19 @@ void tst_qdeclarativetextinput::inputContextMouseHandler()
     QTest::qWaitForWindowShown(&view);
     QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
 
-    ic.sendEvent(QInputMethodEvent(text.mid(5), QList<QInputMethodEvent::Attribute>()));
-
     QFontMetricsF fm(input.font());
     const qreal y = fm.height() / 2;
 
     QPoint position2 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 2)), y)));
-    QPoint position4 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 4)), y)));
-    QPoint position7 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 7)), y)));
-    QPoint position12 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 12)), y)));
+    QPoint position8 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 8)), y)));
+    QPoint position20 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 20)), y)));
+    QPoint position27 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 27)), y)));
     QPoint globalPosition2 = view.viewport()->mapToGlobal(position2);
-    QPoint globalPosition4 = view.viewport()->mapToGlobal(position4);
-    QPoint globalPosition7 = view.viewport()->mapToGlobal(position7);
-    QPoint globalPosition12 = view.viewport()->mapToGlobal(position12);
+    QPoint globalposition8 = view.viewport()->mapToGlobal(position8);
+    QPoint globalposition20 = view.viewport()->mapToGlobal(position20);
+    QPoint globalposition27 = view.viewport()->mapToGlobal(position27);
 
-    ic.sendEvent(QInputMethodEvent(text.mid(5), QList<QInputMethodEvent::Attribute>()));
+    ic.sendEvent(QInputMethodEvent(text.mid(12), QList<QInputMethodEvent::Attribute>()));
 
     QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2);
     QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
@@ -2001,56 +2000,56 @@ void tst_qdeclarativetextinput::inputContextMouseHandler()
     QVERIFY(ic.cursor < 0);
     ic.eventType = QEvent::None;
 
-    {   QMouseEvent mv(QEvent::MouseMove, position4, globalPosition4, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+    {   QMouseEvent mv(QEvent::MouseMove, position8, globalposition8, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
         QApplication::sendEvent(view.viewport(), &mv); }
     QCOMPARE(ic.eventType, QEvent::None);
 
-    {   QMouseEvent mv(QEvent::MouseMove, position12, globalPosition12, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+    {   QMouseEvent mv(QEvent::MouseMove, position27, globalposition27, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
         QApplication::sendEvent(view.viewport(), &mv); }
     QCOMPARE(ic.eventType, QEvent::MouseMove);
-    QCOMPARE(ic.eventPosition, position12);
-    QCOMPARE(ic.eventGlobalPosition, globalPosition12);
+    QCOMPARE(ic.eventPosition, position27);
+    QCOMPARE(ic.eventGlobalPosition, globalposition27);
     QCOMPARE(ic.eventButton, Qt::LeftButton);
     QCOMPARE(ic.eventModifiers, Qt::NoModifier);
-    QCOMPARE(ic.cursor, 7);
+    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);    // 15 is expected but some platforms may be off by one.
     ic.eventType = QEvent::None;
 
-    QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, position12);
+    QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, position27);
     QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
-    QCOMPARE(ic.eventPosition, position12);
-    QCOMPARE(ic.eventGlobalPosition, globalPosition12);
+    QCOMPARE(ic.eventPosition, position27);
+    QCOMPARE(ic.eventGlobalPosition, globalposition27);
     QCOMPARE(ic.eventButton, Qt::LeftButton);
     QCOMPARE(ic.eventModifiers, Qt::NoModifier);
-    QCOMPARE(ic.cursor, 7);
+    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
     ic.eventType = QEvent::None;
 
     // And in the other direction.
-    QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, position12);
+    QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, position27);
     QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
-    QCOMPARE(ic.eventPosition, position12);
-    QCOMPARE(ic.eventGlobalPosition, globalPosition12);
+    QCOMPARE(ic.eventPosition, position27);
+    QCOMPARE(ic.eventGlobalPosition, globalposition27);
     QCOMPARE(ic.eventButton, Qt::LeftButton);
     QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
-    QCOMPARE(ic.cursor, 7);
+    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
     ic.eventType = QEvent::None;
 
-    QTest::mousePress(view.viewport(), Qt::RightButton, Qt::ControlModifier, position12);
+    QTest::mousePress(view.viewport(), Qt::RightButton, Qt::ControlModifier, position27);
     QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
-    QCOMPARE(ic.eventPosition, position12);
-    QCOMPARE(ic.eventGlobalPosition, globalPosition12);
+    QCOMPARE(ic.eventPosition, position27);
+    QCOMPARE(ic.eventGlobalPosition, globalposition27);
     QCOMPARE(ic.eventButton, Qt::RightButton);
     QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
-    QCOMPARE(ic.cursor, 7);
+    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
     ic.eventType = QEvent::None;
 
-    {   QMouseEvent mv(QEvent::MouseMove, position7, globalPosition7, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
+    {   QMouseEvent mv(QEvent::MouseMove, position20, globalposition20, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
         QApplication::sendEvent(view.viewport(), &mv); }
     QCOMPARE(ic.eventType, QEvent::MouseMove);
-    QCOMPARE(ic.eventPosition, position7);
-    QCOMPARE(ic.eventGlobalPosition, globalPosition7);
+    QCOMPARE(ic.eventPosition, position20);
+    QCOMPARE(ic.eventGlobalPosition, globalposition20);
     QCOMPARE(ic.eventButton, Qt::RightButton);
     QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
-    QCOMPARE(ic.cursor, 2);
+    QVERIFY(ic.cursor >= 7 && ic.cursor <= 9);
     ic.eventType = QEvent::None;
 
     {   QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
-- 
cgit v0.12


From b254be20c03d4dbfc1803cd40dc95d52115b955c Mon Sep 17 00:00:00 2001
From: Michael Brasser <michael.brasser@nokia.com>
Date: Tue, 22 Feb 2011 13:33:12 +1000
Subject: Fix animations with alwaysRunToEnd that are frequently
 stopped/started.

A previous refactoring of the animation logic introduced a regression
-- 'restart' rather than 'continue' behavior.

Change-Id: I8ade2286298fad48f5e268793a0b2571884bc5d0
Task-number: QTBUG-16736
Reviewed-by: Martin Jones
---
 src/declarative/util/qdeclarativeanimation.cpp     |  5 ++++-
 .../tst_qdeclarativeanimations.cpp                 | 25 ++++++++++++++++++++++
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp
index 014d368..58c346c 100644
--- a/src/declarative/util/qdeclarativeanimation.cpp
+++ b/src/declarative/util/qdeclarativeanimation.cpp
@@ -203,6 +203,7 @@ void QDeclarativeAbstractAnimation::setRunning(bool r)
 
     d->running = r;
     if (d->running) {
+        bool supressStart = false;
         if (d->alwaysRunToEnd && d->loopCount != 1
             && qtAnimation()->state() == QAbstractAnimation::Running) {
             //we've restarted before the final loop finished; restore proper loop count
@@ -210,6 +211,7 @@ void QDeclarativeAbstractAnimation::setRunning(bool r)
                 qtAnimation()->setLoopCount(d->loopCount);
             else
                 qtAnimation()->setLoopCount(qtAnimation()->currentLoop() + d->loopCount);
+            supressStart = true;    //we want the animation to continue, rather than restart
         }
 
         if (!d->connectedTimeLine) {
@@ -217,7 +219,8 @@ void QDeclarativeAbstractAnimation::setRunning(bool r)
                              this, SLOT(timelineComplete()));
             d->connectedTimeLine = true;
         }
-        d->commence();
+        if (!supressStart)
+            d->commence();
         emit started();
     } else {
         if (d->alwaysRunToEnd) {
diff --git a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
index f7fee3b..e2a54c0 100644
--- a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
+++ b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
@@ -87,6 +87,7 @@ private slots:
     void nonTransitionBug();
     void registrationBug();
     void doubleRegistrationBug();
+    void alwaysRunToEndRestartBug();
 };
 
 #define QTIMED_COMPARE(lhs, rhs) do { \
@@ -819,6 +820,30 @@ void tst_qdeclarativeanimations::doubleRegistrationBug()
     QTRY_COMPARE(anim->qtAnimation()->state(), QAbstractAnimation::Stopped);
 }
 
+//QTBUG-16736
+void tst_qdeclarativeanimations::alwaysRunToEndRestartBug()
+{
+    QDeclarativeRectangle rect;
+    QDeclarativePropertyAnimation animation;
+    animation.setTarget(&rect);
+    animation.setProperty("x");
+    animation.setTo(200);
+    animation.setDuration(1000);
+    animation.setLoops(-1);
+    animation.setAlwaysRunToEnd(true);
+    QVERIFY(animation.loops() == -1);
+    QVERIFY(animation.alwaysRunToEnd() == true);
+    animation.start();
+    animation.stop();
+    animation.start();
+    animation.stop();
+    QTest::qWait(500);
+    QVERIFY(rect.x() != qreal(200));
+    QTest::qWait(800);
+    QTIMED_COMPARE(rect.x(), qreal(200));
+    QCOMPARE(static_cast<QDeclarativeAbstractAnimation*>(&animation)->qtAnimation()->state(), QAbstractAnimation::Stopped);
+}
+
 QTEST_MAIN(tst_qdeclarativeanimations)
 
 #include "tst_qdeclarativeanimations.moc"
-- 
cgit v0.12


From 4d3b9aa83cf7f6d9f9b88d9936e5980629daac2a Mon Sep 17 00:00:00 2001
From: Cristiano di Flora <cristiano.di-flora@nokia.com>
Date: Tue, 22 Feb 2011 05:27:51 +0200
Subject: Fix QNetworkConfigurationManager crash due to null private pointer.

Reviewed-by: Aaron McCarthy
Task-Number: QTBUG-17305
(cherry picked from commit 7388fcb83592a90aace054314e0c3e7e7a94fdae)
---
 src/network/bearer/qnetworkconfigmanager.cpp | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp
index 0e3c519..7eadb82 100644
--- a/src/network/bearer/qnetworkconfigmanager.cpp
+++ b/src/network/bearer/qnetworkconfigmanager.cpp
@@ -57,16 +57,17 @@ QT_BEGIN_NAMESPACE
     {                                                                   \
         delete this_##NAME.pointer;                                     \
         this_##NAME.pointer = 0;                                        \
-        this_##NAME.destroyed = true;                                   \
     }                                                                   \
     static TYPE *NAME()                                                 \
     {                                                                   \
-        if (!this_##NAME.pointer && !this_##NAME.destroyed) {           \
+        if (!this_##NAME.pointer) {                                     \
             TYPE *x = new TYPE;                                         \
             if (!this_##NAME.pointer.testAndSetOrdered(0, x))           \
                 delete x;                                               \
-            else                                                        \
+            else {                                                      \
                 qAddPostRoutine(NAME##_cleanup);                        \
+                this_##NAME.pointer->updateConfigurations();            \
+            }								\
         }                                                               \
         return this_##NAME.pointer;                                     \
     }
@@ -75,15 +76,7 @@ Q_GLOBAL_STATIC_QAPP_DESTRUCTION(QNetworkConfigurationManagerPrivate, connManage
 
 QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate()
 {
-    static bool initialized = false;
-
-    QNetworkConfigurationManagerPrivate *m = connManager();
-    if (!initialized) {
-        initialized = true;
-        m->updateConfigurations();
-    }
-
-    return m;
+    return connManager();
 }
 
 /*!
-- 
cgit v0.12


From e02d7079ca2851831c8a08e7c4994fe4428363ed Mon Sep 17 00:00:00 2001
From: Cristiano di Flora <cristiano.di-flora@nokia.com>
Date: Tue, 22 Feb 2011 05:32:10 +0200
Subject: Removing tabs from 7388fcb83592a90aace054314e0c3e7e7a94fdae changeset

(cherry picked from commit 44373d71dde16c4899377703e724d46d803ade9e)
---
 src/network/bearer/qnetworkconfigmanager.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp
index 7eadb82..dc4e4f7 100644
--- a/src/network/bearer/qnetworkconfigmanager.cpp
+++ b/src/network/bearer/qnetworkconfigmanager.cpp
@@ -67,7 +67,7 @@ QT_BEGIN_NAMESPACE
             else {                                                      \
                 qAddPostRoutine(NAME##_cleanup);                        \
                 this_##NAME.pointer->updateConfigurations();            \
-            }								\
+            }                                                           \
         }                                                               \
         return this_##NAME.pointer;                                     \
     }
-- 
cgit v0.12


From e32f432127bd049c6c11431055360c536e259114 Mon Sep 17 00:00:00 2001
From: Richard Moe Gustavsen <richard.gustavsen@nokia.com>
Date: Tue, 22 Feb 2011 09:25:53 +0100
Subject: Cocoa: Sheets looses focus when moving parent window

The reason seems to be that we need to be more careful
what we answer when cocoa ask us if a sheet should get
main window status, and if the parent window should get
key status. So we add in two extra checks so we can
return the correct answer.

Task-number: QTBUG-15474
Reviewed-by: msorvig
---
 src/gui/kernel/qcocoasharedwindowmethods_mac_p.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
index 9c110fd..6254061 100644
--- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
+++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
@@ -89,6 +89,8 @@ QT_END_NAMESPACE
     QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)];
     if (!widget)
         return NO; // This should happen only for qt_root_win
+    if (QApplicationPrivate::isBlockedByModal(widget))
+        return NO;
 
     bool isToolTip = (widget->windowType() == Qt::ToolTip);
     bool isPopup = (widget->windowType() == Qt::Popup);
@@ -100,6 +102,8 @@ QT_END_NAMESPACE
     QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)];
     if (!widget)
         return NO; // This should happen only for qt_root_win
+    if ([self isSheet])
+        return NO;
 
     bool isToolTip = (widget->windowType() == Qt::ToolTip);
     bool isPopup = (widget->windowType() == Qt::Popup);
-- 
cgit v0.12


From 9d019830169289a3aa00e8baca9c320963904993 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <samuel.rodal@nokia.com>
Date: Tue, 22 Feb 2011 14:44:58 +0100
Subject: Prevent infinite loop in raster engine on zero dash pattern length.

Task-number: QTBUG-17053
Reviewed-by: Kim
---
 src/gui/painting/qpaintengine_raster.cpp |  7 +++++++
 tests/auto/qpainter/tst_qpainter.cpp     | 22 ++++++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 682731a..ba618ea 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3706,6 +3706,13 @@ void QRasterPaintEnginePrivate::rasterizeLine_dashed(QLineF line,
     const bool squareCap = (pen.capStyle() == Qt::SquareCap);
     const QVector<qreal> pattern = pen.dashPattern();
 
+    qreal patternLength = 0;
+    for (int i = 0; i < pattern.size(); ++i)
+        patternLength += pattern.at(i);
+
+    if (patternLength <= 0)
+        return;
+
     qreal length = line.length();
     Q_ASSERT(length > 0);
     while (length > 0) {
diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp
index 4cf64f1..c9eca89 100644
--- a/tests/auto/qpainter/tst_qpainter.cpp
+++ b/tests/auto/qpainter/tst_qpainter.cpp
@@ -258,6 +258,8 @@ private slots:
     void QTBUG14614_gradientCacheRaceCondition();
     void drawTextOpacity();
 
+    void QTBUG17053_zeroDashPattern();
+
 private:
     void fillData();
     void setPenColor(QPainter& p);
@@ -4601,6 +4603,26 @@ void tst_QPainter::drawTextOpacity()
     QCOMPARE(image, copy);
 }
 
+void tst_QPainter::QTBUG17053_zeroDashPattern()
+{
+    QImage image(32, 32, QImage::Format_RGB32);
+    image.fill(0xffffffff);
+
+    QImage original = image;
+
+    QVector<qreal> pattern;
+    pattern << qreal(0) << qreal(0);
+
+    QPainter p(&image);
+    QPen pen(Qt::black, 2.0);
+    pen.setDashPattern(pattern);
+
+    p.setPen(pen);
+    p.drawLine(0, 0, image.width(), image.height());
+
+    QCOMPARE(image, original);
+}
+
 QTEST_MAIN(tst_QPainter)
 
 #include "tst_qpainter.moc"
-- 
cgit v0.12


From f93d1245e5c36cf25cd6fd3c3418ee7e63e04ac2 Mon Sep 17 00:00:00 2001
From: Martin Jones <martin.jones@nokia.com>
Date: Wed, 23 Feb 2011 09:55:24 +1000
Subject: ListView and GridView indexAt should use qreal coordinates.

Change-Id: Ibe6969b5c3209062213c6582eaf4c285bcb793de
Task-number: QTBUG-17594
Reviewed-by: Bea Lam
---
 src/declarative/graphicsitems/qdeclarativegridview.cpp | 4 ++--
 src/declarative/graphicsitems/qdeclarativegridview_p.h | 2 +-
 src/declarative/graphicsitems/qdeclarativelistview.cpp | 4 ++--
 src/declarative/graphicsitems/qdeclarativelistview_p.h | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index 694130b..6d2285d 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -82,7 +82,7 @@ public:
             item->setPos(QPointF(row, col));
         }
     }
-    bool contains(int x, int y) const {
+    bool contains(qreal x, qreal y) const {
         return (x >= item->x() && x < item->x() + view->cellWidth() &&
                 y >= item->y() && y < item->y() + view->cellHeight());
     }
@@ -2294,7 +2294,7 @@ void QDeclarativeGridView::positionViewAtEnd()
 
     \bold Note: methods should only be called after the Component has completed.
 */
-int QDeclarativeGridView::indexAt(int x, int y) const
+int QDeclarativeGridView::indexAt(qreal x, qreal y) const
 {
     Q_D(const QDeclarativeGridView);
     for (int i = 0; i < d->visibleItems.count(); ++i) {
diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h
index 248b9ef..e68a9ba 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h
@@ -158,7 +158,7 @@ public:
     enum PositionMode { Beginning, Center, End, Visible, Contain };
 
     Q_INVOKABLE void positionViewAtIndex(int index, int mode);
-    Q_INVOKABLE int indexAt(int x, int y) const;
+    Q_INVOKABLE int indexAt(qreal x, qreal y) const;
     Q_INVOKABLE Q_REVISION(1) void positionViewAtBeginning();
     Q_INVOKABLE Q_REVISION(1) void positionViewAtEnd();
 
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index a60a4aa..91de5a6 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -148,7 +148,7 @@ public:
         else
             item->setWidth(size);
     }
-    bool contains(int x, int y) const {
+    bool contains(qreal x, qreal y) const {
         return (x >= item->x() && x < item->x() + item->width() &&
                 y >= item->y() && y < item->y() + item->height());
     }
@@ -2732,7 +2732,7 @@ void QDeclarativeListView::positionViewAtEnd()
 
     \bold Note: methods should only be called after the Component has completed.
 */
-int QDeclarativeListView::indexAt(int x, int y) const
+int QDeclarativeListView::indexAt(qreal x, qreal y) const
 {
     Q_D(const QDeclarativeListView);
     for (int i = 0; i < d->visibleItems.count(); ++i) {
diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h
index 10fbf10..265f4bd 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h
@@ -208,7 +208,7 @@ public:
     enum PositionMode { Beginning, Center, End, Visible, Contain };
 
     Q_INVOKABLE void positionViewAtIndex(int index, int mode);
-    Q_INVOKABLE int indexAt(int x, int y) const;
+    Q_INVOKABLE int indexAt(qreal x, qreal y) const;
     Q_INVOKABLE Q_REVISION(1) void positionViewAtBeginning();
     Q_INVOKABLE Q_REVISION(1) void positionViewAtEnd();
 
-- 
cgit v0.12


From 660f752c4db544d6fc5f827589d2f2704684eb8c Mon Sep 17 00:00:00 2001
From: Lorn Potter <lorn.potter@nokia.com>
Date: Wed, 23 Feb 2011 09:43:53 +1000
Subject: add gsm to connectable bearer for networkmanager.

Reviewed-by: trustme
---
 src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
index 30d6b50..6b37b38 100644
--- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
@@ -213,6 +213,11 @@ void QNetworkManagerEngine::connectToId(const QString &id)
             dbusDevicePath = devicePath.path();
             break;
         }
+        else if (device.deviceType() == DEVICE_TYPE_GSM &&
+                connectionType == QLatin1String("gsm")) {
+            dbusDevicePath = devicePath.path();
+            break;
+        }
     }
 
     const QString service = connection->connectionInterface()->service();
-- 
cgit v0.12