aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimjees Abraham <simjees.abraham@nokia.com>2012-05-11 14:37:33 +0200
committerQt by Nokia <qt-info@nokia.com>2012-05-14 13:58:03 +0200
commit7eb5f7b3e0630d59bfa7e4e185df6f34c237e584 (patch)
treef4a769907beec334e628266032ce8b7436016b00
parentfd5c099eea26a8101e2cc0dc3237d1250158b895 (diff)
Inspector:Modified Apply changes on Save for unsync. changes
Changes done to reload the view if the user opts to do so after making unsynchronizable changes. Inspector informs the QmlEngine about the changes which caches it. The cache is used to load the files which were changed when reloading the view. Change-Id: I22d476cace294d6ecf4e428dac104a557c3f7dde Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
-rw-r--r--src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp51
-rw-r--r--src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h5
-rw-r--r--src/plugins/qmltooling/shared/abstractviewinspector.cpp28
-rw-r--r--src/plugins/qmltooling/shared/abstractviewinspector.h4
-rw-r--r--src/qml/qml/qqmlengine_p.h17
-rw-r--r--src/qml/qml/qqmltypeloader.cpp15
-rw-r--r--tests/auto/qml/debugger/qqmlinspector/data/changes.txt8
-rw-r--r--tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp44
8 files changed, 167 insertions, 5 deletions
diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp b/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp
index 243a821cc5..dbe511957c 100644
--- a/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp
+++ b/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp
@@ -44,6 +44,7 @@
#include "highlight.h"
#include "inspecttool.h"
+#include <QtQml/private/qqmlengine_p.h>
#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/QQuickView>
@@ -120,7 +121,8 @@ QQuickViewInspector::QQuickViewInspector(QQuickView *view, QObject *parent) :
AbstractViewInspector(parent),
m_view(view),
m_overlay(new QQuickItem),
- m_inspectTool(new InspectTool(this, view))
+ m_inspectTool(new InspectTool(this, view)),
+ m_sendQmlReloadedMessage(false)
{
// Try to make sure the overlay is always on top
m_overlay->setZ(FLT_MAX);
@@ -130,6 +132,8 @@ QQuickViewInspector::QQuickViewInspector(QQuickView *view, QObject *parent) :
view->installEventFilter(this);
appendTool(m_inspectTool);
+ connect(view, SIGNAL(statusChanged(QQuickView::Status)),
+ this, SLOT(onViewStatus(QQuickView::Status)));
}
void QQuickViewInspector::changeCurrentObjects(const QList<QObject*> &objects)
@@ -310,5 +314,50 @@ QString QQuickViewInspector::titleForItem(QQuickItem *item) const
return constructedName;
}
+void QQuickViewInspector::reloadQmlFile(const QHash<QString, QByteArray> &changesHash)
+{
+ clearComponentCache();
+
+ // Reset the selection since we are reloading the main qml
+ setSelectedItems(QList<QQuickItem *>());
+
+ QHash<QUrl, QByteArray> debugCache;
+
+ foreach (const QString &str, changesHash.keys())
+ debugCache.insert(QUrl(str), changesHash.value(str, QByteArray()));
+
+ // Updating the cache in engine private such that the QML Data loader
+ // gets the changes from the cache.
+ QQmlEnginePrivate::get(declarativeEngine())->setDebugChangesCache(debugCache);
+
+ m_sendQmlReloadedMessage = true;
+ // reloading the view such that the changes done for the files are
+ // reflected in view
+ view()->setSource(view()->source());
+}
+
+void QQuickViewInspector::onViewStatus(QQuickView::Status status)
+{
+ bool success = false;
+ switch (status) {
+ case QQuickView::Loading:
+ return;
+ case QQuickView::Ready:
+ if (view()->errors().count())
+ break;
+ success = true;
+ break;
+ case QQuickView::Null:
+ case QQuickView::Error:
+ break;
+ default:
+ break;
+ }
+ if (m_sendQmlReloadedMessage) {
+ m_sendQmlReloadedMessage = false;
+ sendQmlFileReloaded(success);
+ }
+}
+
} // namespace QtQuick2
} // namespace QmlJSDebugger
diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h b/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h
index d6258c5ec1..d687d6ba0e 100644
--- a/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h
+++ b/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h
@@ -46,6 +46,7 @@
#include <QtCore/QPointer>
#include <QtCore/QHash>
+#include <QtQuick/QQuickView>
QT_BEGIN_NAMESPACE
class QQuickView;
@@ -83,6 +84,8 @@ public:
QString titleForItem(QQuickItem *item) const;
void showSelectedItemName(QQuickItem *item, const QPointF &point);
+ void reloadQmlFile(const QHash<QString, QByteArray> &changesHash);
+
protected:
bool eventFilter(QObject *obj, QEvent *event);
@@ -90,6 +93,7 @@ protected:
private slots:
void removeFromSelectedItems(QObject *);
+ void onViewStatus(QQuickView::Status status);
private:
bool syncSelectedItems(const QList<QQuickItem*> &items);
@@ -101,6 +105,7 @@ private:
QList<QPointer<QQuickItem> > m_selectedItems;
QHash<QQuickItem*, SelectionHighlight*> m_highlightItems;
+ bool m_sendQmlReloadedMessage;
};
} // namespace QtQuick2
diff --git a/src/plugins/qmltooling/shared/abstractviewinspector.cpp b/src/plugins/qmltooling/shared/abstractviewinspector.cpp
index 02a85e2e2e..174d70b20e 100644
--- a/src/plugins/qmltooling/shared/abstractviewinspector.cpp
+++ b/src/plugins/qmltooling/shared/abstractviewinspector.cpp
@@ -56,10 +56,12 @@
//INSPECTOR SERVICE PROTOCOL
// <HEADER><COMMAND><DATA>
// <HEADER> : <type{request, response, event}><requestId/eventId>[<response_success_bool>]
-// <COMMAND> : {"enable", "disable", "select", "setAnimationSpeed",
+// <COMMAND> : {"enable", "disable", "select", "reload", "setAnimationSpeed",
// "showAppOnTop", "createObject", "destroyObject", "moveObject",
// "clearCache"}
// <DATA> : select: <debugIds_int_list>
+// reload: <list of relative paths w.r.t project of changed files>
+// <list of changed file contents>
// setAnimationSpeed: <speed_real>
// showAppOnTop: <set_bool>
// createObject: <qml_string><parentId_int><imports_string_list><filename_string>
@@ -73,6 +75,7 @@ const char EVENT[] = "event";
const char ENABLE[] = "enable";
const char DISABLE[] = "disable";
const char SELECT[] = "select";
+const char RELOAD[] = "reload";
const char SET_ANIMATION_SPEED[] = "setAnimationSpeed";
const char SHOW_APP_ON_TOP[] = "showAppOnTop";
const char CREATE_OBJECT[] = "createObject";
@@ -87,7 +90,8 @@ AbstractViewInspector::AbstractViewInspector(QObject *parent) :
QObject(parent),
m_enabled(false),
m_debugService(QQmlInspectorService::instance()),
- m_eventId(0)
+ m_eventId(0),
+ m_reloadEventId(-1)
{
}
@@ -296,6 +300,13 @@ void AbstractViewInspector::handleMessage(const QByteArray &message)
if (m_enabled)
changeCurrentObjects(selectedObjects);
+ } else if (command == RELOAD) {
+ QHash<QString, QByteArray> changesHash;
+ ds >> changesHash;
+ m_reloadEventId = requestId;
+ reloadQmlFile(changesHash);
+ return;
+
} else if (command == SET_ANIMATION_SPEED) {
qreal speed;
ds >> speed;
@@ -362,6 +373,19 @@ void AbstractViewInspector::sendCurrentObjects(const QList<QObject*> &objects)
m_debugService->sendMessage(message);
}
+void AbstractViewInspector::sendQmlFileReloaded(bool success)
+{
+ if (m_reloadEventId == -1)
+ return;
+
+ QByteArray response;
+
+ QQmlDebugStream rs(&response, QIODevice::WriteOnly);
+ rs << QByteArray(RESPONSE) << m_reloadEventId << success;
+
+ m_debugService->sendMessage(response);
+}
+
QString AbstractViewInspector::idStringForObject(QObject *obj) const
{
QQmlContext *context = qmlContext(obj);
diff --git a/src/plugins/qmltooling/shared/abstractviewinspector.h b/src/plugins/qmltooling/shared/abstractviewinspector.h
index d2dd9557da..8855935e46 100644
--- a/src/plugins/qmltooling/shared/abstractviewinspector.h
+++ b/src/plugins/qmltooling/shared/abstractviewinspector.h
@@ -83,6 +83,8 @@ public:
void sendCurrentObjects(const QList<QObject*> &);
+ void sendQmlFileReloaded(bool success);
+
QString idStringForObject(QObject *obj) const;
virtual void changeCurrentObjects(const QList<QObject*> &objects) = 0;
@@ -90,6 +92,7 @@ public:
virtual Qt::WindowFlags windowFlags() const = 0;
virtual void setWindowFlags(Qt::WindowFlags flags) = 0;
virtual QQmlEngine *declarativeEngine() const = 0;
+ virtual void reloadQmlFile(const QHash<QString, QByteArray> &changesHash) = 0;
void appendTool(AbstractTool *tool);
void removeTool(AbstractTool *tool);
@@ -119,6 +122,7 @@ private:
QQmlInspectorService *m_debugService;
QList<AbstractTool *> m_tools;
int m_eventId;
+ int m_reloadEventId;
};
} // namespace QmlJSDebugger
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index c7c1a2b805..4c6b3b5f0f 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -241,6 +241,9 @@ public:
const QMetaObject *metaObjectForType(int) const;
void registerCompositeType(QQmlCompiledData *);
+ inline void setDebugChangesCache(const QHash<QUrl, QByteArray> &changes);
+ inline QHash<QUrl, QByteArray> debugChangesCache();
+
void sendQuit();
void warning(const QQmlError &);
void warning(const QList<QQmlError> &);
@@ -299,6 +302,7 @@ private:
QHash<QPair<QQmlType *, int>, QQmlPropertyCache *> typePropertyCache;
QHash<int, int> m_qmlLists;
QHash<int, QQmlCompiledData *> m_compositeTypes;
+ QHash<QUrl, QByteArray> debugChangesHash;
// These members is protected by the full QQmlEnginePrivate::mutex mutex
struct Deletable { Deletable():next(0) {} virtual ~Deletable() {} Deletable *next; };
@@ -517,6 +521,19 @@ void QQmlEnginePrivate::captureProperty(QObject *o, int c, int n)
propertyCapture->captureProperty(o, c, n);
}
+void QQmlEnginePrivate::setDebugChangesCache(const QHash<QUrl, QByteArray> &changes)
+{
+ Locker locker(this);
+ foreach (const QUrl &key, changes.keys())
+ debugChangesHash.insert(key, changes.value(key));
+}
+
+QHash<QUrl, QByteArray> QQmlEnginePrivate::debugChangesCache()
+{
+ Locker locker(this);
+ return debugChangesHash;
+}
+
QT_END_NAMESPACE
#endif // QQMLENGINE_P_H
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 74a535fce0..c01a41d686 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -1026,6 +1026,21 @@ void QQmlDataLoader::loadThread(QQmlDataBlob *blob)
return;
}
+ QQmlEnginePrivate *engine_d = QQmlEnginePrivate::get(m_engine);
+ QHash<QUrl, QByteArray> debugCache = engine_d->debugChangesCache();
+
+ if (!debugCache.isEmpty()) {
+ foreach (const QUrl &url, debugCache.keys()) {
+ if (blob->m_url == blob->m_url.resolved(url)) {
+ blob->m_data.setProgress(0xFF);
+ if (blob->m_data.isAsync())
+ m_thread->callDownloadProgressChanged(blob, 1.);
+ setData(blob, debugCache.value(url, QByteArray()));
+ return;
+ }
+ }
+ }
+
if (QQmlFile::isSynchronous(blob->m_url)) {
QQmlFile file(m_engine, blob->m_url);
diff --git a/tests/auto/qml/debugger/qqmlinspector/data/changes.txt b/tests/auto/qml/debugger/qqmlinspector/data/changes.txt
new file mode 100644
index 0000000000..38b17caeff
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmlinspector/data/changes.txt
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+Item {
+ id: test
+ Component.onCompleted: {
+ console.log("version 2.0");
+ Qt.quit()
+ }
+}
diff --git a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
index 611dc2b843..5326a053b0 100644
--- a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
+++ b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
@@ -62,10 +62,12 @@ public:
, m_showAppOnTop(false)
, m_requestId(0)
, m_requestResult(false)
+ , m_responseId(-1)
{
}
void setShowAppOnTop(bool showOnTop);
+ void reloadQml(const QHash<QString, QByteArray> &changesHash);
signals:
void responseReceived();
@@ -79,6 +81,8 @@ private:
public:
bool m_requestResult;
+ int m_responseId;
+ int m_reloadRequestId;
};
class tst_QQmlInspector : public QQmlDataTest
@@ -105,6 +109,7 @@ private slots:
void connect();
void showAppOnTop();
+ void reloadQml();
};
@@ -118,6 +123,18 @@ void QQmlInspectorClient::setShowAppOnTop(bool showOnTop)
sendMessage(message);
}
+void QQmlInspectorClient::reloadQml(const QHash<QString, QByteArray> &changesHash)
+{
+ QByteArray message;
+ QDataStream ds(&message, QIODevice::WriteOnly);
+ m_reloadRequestId = m_requestId;
+
+ ds << QByteArray("request") << m_requestId++
+ << QByteArray("reload") << changesHash;
+
+ sendMessage(message);
+}
+
void QQmlInspectorClient::messageReceived(const QByteArray &message)
{
QDataStream ds(message);
@@ -130,8 +147,7 @@ void QQmlInspectorClient::messageReceived(const QByteArray &message)
}
m_requestResult = false;
- int requestId;
- ds >> requestId >> m_requestResult;
+ ds >> m_responseId >> m_requestResult;
emit responseReceived();
}
@@ -179,6 +195,30 @@ void tst_QQmlInspector::showAppOnTop()
QCOMPARE(m_client->m_requestResult, true);
}
+void tst_QQmlInspector::reloadQml()
+{
+ QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
+
+ QByteArray fileContents;
+
+ QFile file(testFile("changes.txt"));
+ if (file.open(QFile::ReadOnly))
+ fileContents = file.readAll();
+ file.close();
+
+ QHash<QString, QByteArray> changesHash;
+ changesHash.insert("qtquick2.qml", fileContents);
+
+ m_client->reloadQml(changesHash);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(responseReceived())));
+
+ QTRY_COMPARE(m_process->output().contains(
+ QString("version 2.0")), true);
+
+ QCOMPARE(m_client->m_requestResult, true);
+ QCOMPARE(m_client->m_reloadRequestId, m_client->m_responseId);
+}
+
QTEST_MAIN(tst_QQmlInspector)
#include "tst_qqmlinspector.moc"