Commit 85bafac5 authored by Lasse Holmstedt's avatar Lasse Holmstedt
Browse files

QML Observer: Refresh debug id's when new objects are created

Previously, the user had to navigate to the context of a qml item in
order to edit its source code in Live Preview mode. This change tells
the client to update when new objects are created on server-side, and
makes the editing possible without having to manually trigger updates.
parent d00045bd
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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());
......
......@@ -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(); }
};
......
......@@ -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);
......
......@@ -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();
......
......@@ -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();
}
}
......
......@@ -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 &);
......
......@@ -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);
......
......@@ -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
......
......@@ -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) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment