diff --git a/src/libs/qmljsdebugger/include/qdeclarativedesigndebugserver.h b/src/libs/qmljsdebugger/include/qdeclarativedesigndebugserver.h index f93508194acdbbecae3e54934bfbe1c60eba6741..53a554949a639f7a867479e16182904d04ef96ae 100644 --- a/src/libs/qmljsdebugger/include/qdeclarativedesigndebugserver.h +++ b/src/libs/qmljsdebugger/include/qdeclarativedesigndebugserver.h @@ -72,6 +72,7 @@ public: public Q_SLOTS: void selectedColorChanged(const QColor &color); void contextPathUpdated(const QStringList &contextPath); + void sceneItemCountChanged(); Q_SIGNALS: void currentObjectsChanged(const QList<QObject*> &objects); diff --git a/src/libs/qmljsdebugger/include/qdeclarativedesignview.h b/src/libs/qmljsdebugger/include/qdeclarativedesignview.h index 2f0e7b6e3d4c3295c67826d121a0bd8e0ae2166c..7b8241e242b68ab06935f797ecbba4b3ef539316 100644 --- a/src/libs/qmljsdebugger/include/qdeclarativedesignview.h +++ b/src/libs/qmljsdebugger/include/qdeclarativedesignview.h @@ -96,6 +96,7 @@ protected: void wheelEvent(QWheelEvent *event); void setSelectedItemsForTools(QList<QGraphicsItem *> items); + private: Q_DISABLE_COPY(QDeclarativeDesignView) Q_PRIVATE_SLOT(d_func(), void _q_reloadView()) @@ -109,6 +110,8 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_changeToColorPickerTool()) Q_PRIVATE_SLOT(d_func(), void _q_changeContextPathIndex(int index)) Q_PRIVATE_SLOT(d_func(), void _q_clearComponentCache()); + Q_PRIVATE_SLOT(d_func(), void _q_sceneChanged(const QList<QRectF> &areas)); + Q_PRIVATE_SLOT(d_func(), void _q_checkSceneItemCount()); inline QDeclarativeDesignViewPrivate *d_func() { return data.data(); } QScopedPointer<QDeclarativeDesignViewPrivate> data; diff --git a/src/libs/qmljsdebugger/qdeclarativedesigndebugserver.cpp b/src/libs/qmljsdebugger/qdeclarativedesigndebugserver.cpp index dc20ae1bed1bce4e26a6500845a94a0d36a778ec..9bb3546ee8789a3e55fc92b74d6a3fee3c517879 100644 --- a/src/libs/qmljsdebugger/qdeclarativedesigndebugserver.cpp +++ b/src/libs/qmljsdebugger/qdeclarativedesigndebugserver.cpp @@ -170,6 +170,16 @@ void QDeclarativeDesignDebugServer::contextPathUpdated(const QStringList &contex sendMessage(message); } +void QDeclarativeDesignDebugServer::sceneItemCountChanged() +{ + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + + ds << QByteArray("SCENE_ITEM_COUNT_CHANGED"); + + sendMessage(message); +} + QString QDeclarativeDesignDebugServer::idStringForObject(QObject *obj) const { int id = idForObject(obj); diff --git a/src/libs/qmljsdebugger/qdeclarativedesignview.cpp b/src/libs/qmljsdebugger/qdeclarativedesignview.cpp index db6901b58d7afcd4dcbe735b4868f61dc0e551de..4d7c05cd11c74248893184cdbc61dd8d567c33a5 100644 --- a/src/libs/qmljsdebugger/qdeclarativedesignview.cpp +++ b/src/libs/qmljsdebugger/qdeclarativedesignview.cpp @@ -52,6 +52,9 @@ namespace QmlViewer { +const int SceneChangeUpdateInterval = 5000; +const int MaxSceneChangedTimerRestartCount = (SceneChangeUpdateInterval / 100); + Q_GLOBAL_STATIC(QDeclarativeDesignDebugServer, qmlDesignDebugServer) QDeclarativeDesignViewPrivate::QDeclarativeDesignViewPrivate(QDeclarativeDesignView *q) : @@ -59,9 +62,11 @@ QDeclarativeDesignViewPrivate::QDeclarativeDesignViewPrivate(QDeclarativeDesignV designModeBehavior(false), executionPaused(false), slowdownFactor(1.0f), - toolbar(0) + toolbar(0), + sceneChangedTimerRestartCount(0) { - + sceneChangedTimer.setInterval(SceneChangeUpdateInterval); + sceneChangedTimer.setSingleShot(true); } QDeclarativeDesignViewPrivate::~QDeclarativeDesignViewPrivate() @@ -79,6 +84,7 @@ QDeclarativeDesignView::QDeclarativeDesignView(QWidget *parent) : data->subcomponentEditorTool = new SubcomponentEditorTool(this); data->currentTool = data->selectionTool; + connect(scene(), SIGNAL(changed(QList<QRectF>)), SLOT(_q_sceneChanged(QList<QRectF>))); setMouseTracking(true); connect(qmlDesignDebugServer(), SIGNAL(designModeBehaviorChanged(bool)), SLOT(setDesignModeBehavior(bool))); @@ -107,6 +113,8 @@ QDeclarativeDesignView::QDeclarativeDesignView(QWidget *parent) : connect(data->subcomponentEditorTool, SIGNAL(contextPopped()), SIGNAL(inspectorContextPopped())); connect(data->subcomponentEditorTool, SIGNAL(contextPathChanged(QStringList)), qmlDesignDebugServer(), SLOT(contextPathUpdated(QStringList))); + connect(&(data->sceneChangedTimer), SIGNAL(timeout()), SLOT(_q_checkSceneItemCount())); + data->createToolbar(); data->_q_changeToSingleSelectTool(); @@ -523,6 +531,59 @@ void QDeclarativeDesignViewPrivate::_q_changeContextPathIndex(int index) subcomponentEditorTool->setContext(index); } +void QDeclarativeDesignViewPrivate::_q_sceneChanged(const QList<QRectF> & /*areas*/) +{ + if (designModeBehavior) + return; + + sceneChangedTimerRestartCount++; + if (sceneChangedTimerRestartCount == MaxSceneChangedTimerRestartCount) { + sceneChangedTimerRestartCount = 0; + _q_checkSceneItemCount(); + } + sceneChangedTimer.start(); +} + +void QDeclarativeDesignViewPrivate::_q_checkSceneItemCount() +{ + bool hasNewItems = hasNewGraphicsObjects(q->rootObject()); + + if (hasNewItems) { + qmlDesignDebugServer()->sceneItemCountChanged(); + } +} + +static bool hasNewGraphicsObjectsRecur(QGraphicsObject *object, + QSet<QGraphicsObject *> &newItems, + const QSet<QGraphicsObject *> &previousItems) +{ + bool hasNew = false; + + newItems << object; + + foreach(QGraphicsItem *item, object->childItems()) { + QGraphicsObject *gfxObject = item->toGraphicsObject(); + if (gfxObject) { + newItems << gfxObject; + + hasNew = hasNewGraphicsObjectsRecur(gfxObject, newItems, previousItems) || hasNew; + if (!previousItems.contains(gfxObject)) + hasNew = true; + } + } + + return hasNew; +} + +bool QDeclarativeDesignViewPrivate::hasNewGraphicsObjects(QGraphicsObject *object) +{ + QSet<QGraphicsObject *> newItems; + bool ret = hasNewGraphicsObjectsRecur(object, newItems, sceneGraphicsObjects); + sceneGraphicsObjects = newItems; + + return ret; +} + void QDeclarativeDesignView::changeAnimationSpeed(qreal slowdownFactor) { data->slowdownFactor = slowdownFactor; @@ -613,6 +674,8 @@ void QDeclarativeDesignViewPrivate::_q_onStatusChanged(QDeclarativeView::Status { if (status == QDeclarativeView::Ready) { if (q->rootObject()) { + sceneChangedTimerRestartCount = 0; + hasNewGraphicsObjects(q->rootObject()); if (subcomponentEditorTool->contextIndex() != -1) subcomponentEditorTool->clear(); subcomponentEditorTool->pushContext(q->rootObject()); diff --git a/src/libs/qmljsdebugger/qdeclarativedesignview_p.h b/src/libs/qmljsdebugger/qdeclarativedesignview_p.h index c06c018d0a6f690558d07da2a522a1d565cb0489..6791f236fdf726054077eb03b4c01dff2509933d 100644 --- a/src/libs/qmljsdebugger/qdeclarativedesignview_p.h +++ b/src/libs/qmljsdebugger/qdeclarativedesignview_p.h @@ -32,6 +32,7 @@ #include <QWeakPointer> #include <QPointF> +#include <QTimer> #include "qdeclarativedesignview.h" @@ -82,6 +83,9 @@ public: qreal slowdownFactor; QmlToolbar *toolbar; + int sceneChangedTimerRestartCount; + QTimer sceneChangedTimer; + QSet<QGraphicsObject *> sceneGraphicsObjects; void clearEditorItems(); void createToolbar(); @@ -93,6 +97,7 @@ public: QList<QGraphicsItem*> selectableItems(const QPointF &scenePos) const; QList<QGraphicsItem*> selectableItems(const QRectF &sceneRect, Qt::ItemSelectionMode selectionMode) const; + bool hasNewGraphicsObjects(QGraphicsObject *object); void setSelectedItemsForTools(QList<QGraphicsItem *> items); void setSelectedItems(QList<QGraphicsItem *> items); @@ -124,6 +129,9 @@ public: void _q_changeToColorPickerTool(); void _q_changeContextPathIndex(int index); void _q_clearComponentCache(); + void _q_sceneChanged(const QList<QRectF> &areas); + void _q_changeDebugObjectCount(int objectCount); + void _q_checkSceneItemCount(); static QDeclarativeDesignViewPrivate *get(QDeclarativeDesignView *v) { return v->d_func(); } }; diff --git a/src/plugins/qmljsinspector/qmljsclientproxy.cpp b/src/plugins/qmljsinspector/qmljsclientproxy.cpp index 5eb0f38f4dd89c0d6e2160e0fe68779db20b2ab7..b21f34a48698309fff464b36e1fbdd9f9b363962 100644 --- a/src/plugins/qmljsinspector/qmljsclientproxy.cpp +++ b/src/plugins/qmljsinspector/qmljsclientproxy.cpp @@ -84,6 +84,8 @@ bool ClientProxy::connectToViewer(const QString &host, quint16 port) SIGNAL(selectedColorChanged(QColor)), this, SIGNAL(selectedColorChanged(QColor))); disconnect(m_designClient, SIGNAL(contextPathUpdated(QStringList)), this, SIGNAL(contextPathUpdated(QStringList))); + disconnect(m_designClient, + SIGNAL(treeRefreshRequested()), this, SLOT(refreshObjectTree())); emit aboutToDisconnect(); @@ -229,8 +231,8 @@ void ClientProxy::connectionStateChanged() SIGNAL(designModeBehaviorChanged(bool)), SIGNAL(designModeBehaviorChanged(bool))); connect(m_designClient, SIGNAL(reloaded()), this, SIGNAL(serverReloaded())); connect(m_designClient, SIGNAL(selectedColorChanged(QColor)), SIGNAL(selectedColorChanged(QColor))); - connect(m_designClient, - SIGNAL(contextPathUpdated(QStringList)), SIGNAL(contextPathUpdated(QStringList))); + connect(m_designClient, SIGNAL(contextPathUpdated(QStringList)), SIGNAL(contextPathUpdated(QStringList))); + connect(m_designClient, SIGNAL(treeRefreshRequested()), SLOT(refreshObjectTree())); } (void) new DebuggerClient(m_conn); diff --git a/src/plugins/qmljsinspector/qmljsclientproxy.h b/src/plugins/qmljsinspector/qmljsclientproxy.h index 83803c733757817be43ffd0e023a786bdba6b50c..95264f27bfeaf60241dd65d5505c568ede16affc 100644 --- a/src/plugins/qmljsinspector/qmljsclientproxy.h +++ b/src/plugins/qmljsinspector/qmljsclientproxy.h @@ -61,7 +61,6 @@ public: QList<QDeclarativeDebugObjectReference> objectReferences(const QUrl &url = QUrl()) const; QDeclarativeDebugObjectReference objectReferenceForId(int debugId) const; QDeclarativeDebugObjectReference rootObjectReference() const; - void refreshObjectTree(); bool isConnected() const; bool isUnconnected() const; @@ -97,6 +96,7 @@ signals: void contextPathUpdated(const QStringList &contextPath); public slots: + void refreshObjectTree(); void queryEngineContext(int id); void reloadQmlViewer(); diff --git a/src/plugins/qmljsinspector/qmljsdesigndebugclient.cpp b/src/plugins/qmljsinspector/qmljsdesigndebugclient.cpp index 5bc160b52003a2c82dc48bc2fb17ec66b1d53cdd..c51bfcd31e4b86e298d423d9de6d2a3014f0751a 100644 --- a/src/plugins/qmljsinspector/qmljsdesigndebugclient.cpp +++ b/src/plugins/qmljsinspector/qmljsdesigndebugclient.cpp @@ -108,6 +108,8 @@ void QmlJSDesignDebugClient::messageReceived(const QByteArray &message) QStringList contextPath; ds >> contextPath; emit contextPathUpdated(contextPath); + } else if (type == "SCENE_ITEM_COUNT_CHANGED") { + emit treeRefreshRequested(); } } diff --git a/src/plugins/qmljsinspector/qmljsdesigndebugclient.h b/src/plugins/qmljsinspector/qmljsdesigndebugclient.h index 406495844bd57d89cee7a5c00a219c27cf91c848..9b7458f3f6abe74cfc1f4c21b073ea53663b4868 100644 --- a/src/plugins/qmljsinspector/qmljsdesigndebugclient.h +++ b/src/plugins/qmljsinspector/qmljsdesigndebugclient.h @@ -89,6 +89,7 @@ signals: void designModeBehaviorChanged(bool inDesignMode); void reloaded(); // the server has reloaded the document void contextPathUpdated(const QStringList &path); + void treeRefreshRequested(); // scene has some new items protected: virtual void messageReceived(const QByteArray &); diff --git a/src/plugins/qmljsinspector/qmljsinspector.cpp b/src/plugins/qmljsinspector/qmljsinspector.cpp index 27a3a56926f93178c5b81f6576bbe0f9130d4fc8..e579f0d89dcc2031f7ec84716b2d82fd82d29a9e 100644 --- a/src/plugins/qmljsinspector/qmljsinspector.cpp +++ b/src/plugins/qmljsinspector/qmljsinspector.cpp @@ -118,6 +118,7 @@ enum { }; bool Inspector::m_showExperimentalWarning = true; +Inspector *Inspector::m_instance = 0; Inspector::Inspector(QObject *parent) : QObject(parent), @@ -126,10 +127,11 @@ Inspector::Inspector(QObject *parent) m_cppDebuggerState(0), m_simultaneousCppAndQmlDebugMode(false), m_debugMode(StandaloneMode), - m_listeningToEditorManager(false) + m_listeningToEditorManager(false), + m_debugProject(0) { m_clientProxy = ClientProxy::instance(); - + m_instance = this; //#warning set up the context widget QWidget *contextWidget = 0; m_context = new InspectorContext(contextWidget); @@ -162,6 +164,7 @@ void Inspector::disconnectWidgets() void Inspector::disconnected() { + m_debugProject = 0; resetViews(); updateMenuActions(); applyChangesToQmlObserverHelper(false); @@ -321,6 +324,11 @@ void Inspector::startQmlProjectDebugger() m_connectionTimer->start(); } +void Inspector::currentDebugProjectRemoved() +{ + m_debugProject = 0; +} + void Inspector::resetViews() { m_crumblePath->updateContextPath(QStringList()); @@ -490,6 +498,8 @@ Debugger::DebuggerRunControl *Inspector::createDebuggerRunControl(ProjectExplore void Inspector::connected(QDeclarativeEngineDebug *client) { + m_debugProject = ProjectExplorer::ProjectExplorerPlugin::instance()->startupProject(); + connect(m_debugProject, SIGNAL(destroyed()), SLOT(currentDebugProjectRemoved())); m_client = client; resetViews(); } @@ -661,6 +671,16 @@ void Inspector::setShowExperimentalWarning(bool value) m_showExperimentalWarning = value; } +Inspector *Inspector::instance() +{ + return m_instance; +} + +ProjectExplorer::Project *Inspector::debugProject() const +{ + return m_debugProject; +} + void Inspector::setApplyChangesToQmlObserver(bool applyChanges) { emit livePreviewActivated(applyChanges); diff --git a/src/plugins/qmljsinspector/qmljsinspector.h b/src/plugins/qmljsinspector/qmljsinspector.h index 2dd8aa224ea939888257dc6e7723ebbfad2e8f0f..acd9469329d13d54278dcc5ddc31b36961262c55 100644 --- a/src/plugins/qmljsinspector/qmljsinspector.h +++ b/src/plugins/qmljsinspector/qmljsinspector.h @@ -82,7 +82,6 @@ public: Inspector(QObject *parent = 0); virtual ~Inspector(); - bool connectToViewer(); // using host, port from widgets void shutdown(); @@ -98,7 +97,10 @@ public: bool isLiteralValue); static bool showExperimentalWarning(); static void setShowExperimentalWarning(bool value); + static Inspector *instance(); + // returns the project being currently debugged, or 0 if not debugging anything + ProjectExplorer::Project *debugProject() const; void createDockWidgets(); signals: @@ -134,6 +136,9 @@ private slots: void disableLivePreview(); void crumblePathElementClicked(int); + + void currentDebugProjectRemoved(); + private: Debugger::DebuggerRunControl *createDebuggerRunControl(ProjectExplorer::RunConfiguration *runConfig, const QString &executableFile = QString(), @@ -174,6 +179,9 @@ private: // Qml/JS integration QHash<QString, QmlJSLiveTextPreview *> m_textPreviews; QmlJS::Snapshot m_loadedSnapshot; //the snapshot loaded by the viewer + ProjectExplorer::Project *m_debugProject; + + static Inspector *m_instance; }; } // Internal diff --git a/src/plugins/qmljsinspector/qmljslivetextpreview.cpp b/src/plugins/qmljsinspector/qmljslivetextpreview.cpp index 855d32195a7f11b618577243b6314b8ecebe572e..d5f8a1e654bc39401f056b76a3a14b39a563b385 100644 --- a/src/plugins/qmljsinspector/qmljslivetextpreview.cpp +++ b/src/plugins/qmljsinspector/qmljslivetextpreview.cpp @@ -40,6 +40,8 @@ #include <qmljs/qmljsdelta.h> #include <qmljs/parser/qmljsast_p.h> #include <extensionsystem/pluginmanager.h> +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/project.h> #include <coreplugin/icore.h> #include <coreplugin/editormanager/ieditor.h> @@ -532,6 +534,12 @@ void QmlJSLiveTextPreview::documentChanged(QmlJS::Document::Ptr doc) if (!core->hasContext(dbgcontext)) return; + if (ProjectExplorer::Project *debugProject = Inspector::instance()->debugProject()) { + QStringList files = debugProject->files(ProjectExplorer::Project::ExcludeGeneratedFiles); + if (!files.contains(doc->fileName())) + return; + } + bool experimentalWarningShown = false; if (m_applyChangesToQmlObserver) {