From 524d4453e5aa071c559c959ca4cc6c3390f401c9 Mon Sep 17 00:00:00 2001
From: Lasse Holmstedt <lasse.holmstedt@nokia.com>
Date: Mon, 2 Aug 2010 17:25:29 +0200
Subject: [PATCH] Qml JS Inspector: Added context crumble path as a dock widget

The crumble path shows the current context of the debugger/inspector.
---
 src/libs/qmljsdebugger/editor/editor.qrc      |  6 ---
 .../editor/subcomponenteditortool.cpp         | 14 +++++--
 .../editor/subcomponenteditortool.h           |  3 ++
 .../include/qdeclarativedesigndebugserver.h   |  2 +-
 .../qdeclarativedesigndebugserver.cpp         | 11 +++++
 .../qmljsdebugger/qdeclarativedesignview.cpp  |  1 +
 .../qmljsinspector/qmljsclientproxy.cpp       |  4 ++
 src/plugins/qmljsinspector/qmljsclientproxy.h |  1 +
 .../qmljscontextcrumblepath.cpp               | 29 +++++++++++++
 .../qmljsinspector/qmljscontextcrumblepath.h  | 25 +++++++++++
 .../qmljsinspector/qmljsdesigndebugclient.cpp |  4 ++
 .../qmljsinspector/qmljsdesigndebugclient.h   |  1 +
 src/plugins/qmljsinspector/qmljsinspector.cpp | 42 ++++++++-----------
 src/plugins/qmljsinspector/qmljsinspector.h   |  7 ++++
 src/plugins/qmljsinspector/qmljsinspector.pro |  6 ++-
 .../qmljsinspector/qmljsinspectorplugin.cpp   | 16 ++-----
 16 files changed, 124 insertions(+), 48 deletions(-)
 create mode 100644 src/plugins/qmljsinspector/qmljscontextcrumblepath.cpp
 create mode 100644 src/plugins/qmljsinspector/qmljscontextcrumblepath.h

diff --git a/src/libs/qmljsdebugger/editor/editor.qrc b/src/libs/qmljsdebugger/editor/editor.qrc
index 485420e5690..09fc2f6fb01 100644
--- a/src/libs/qmljsdebugger/editor/editor.qrc
+++ b/src/libs/qmljsdebugger/editor/editor.qrc
@@ -9,12 +9,6 @@
         <file>images/from-qml.png</file>
         <file>images/to-qml.png</file>
         <file>images/designmode.png</file>
-        <file>images/segment-end.png</file>
-        <file>images/segment-selected.png</file>
-        <file>images/segment.png</file>
-        <file>images/segment-hover-end.png</file>
-        <file>images/segment-hover.png</file>
-        <file>images/segment-selected-end.png</file>
         <file>images/color-picker-hicontrast.png</file>
         <file>images/zoom.png</file>
         <file>images/color-picker-24.png</file>
diff --git a/src/libs/qmljsdebugger/editor/subcomponenteditortool.cpp b/src/libs/qmljsdebugger/editor/subcomponenteditortool.cpp
index 2a3069b4595..9bb13ab4334 100644
--- a/src/libs/qmljsdebugger/editor/subcomponenteditortool.cpp
+++ b/src/libs/qmljsdebugger/editor/subcomponenteditortool.cpp
@@ -122,7 +122,9 @@ void SubcomponentEditorTool::clear()
     m_mask->setCurrentItem(0);
     m_animTimer->stop();
     m_mask->hide();
+    m_path.clear();
 
+    emit contextPathChanged(m_path);
     emit cleared();
 }
 
@@ -222,7 +224,11 @@ void SubcomponentEditorTool::pushContext(QGraphicsObject *contextItem)
 {
     connect(contextItem, SIGNAL(destroyed(QObject*)), SLOT(contextDestroyed(QObject*)));
     m_currentContext.push(contextItem);
-    emit contextPushed(titleForItem(contextItem));
+    QString title = titleForItem(contextItem);
+    emit contextPushed(title);
+
+    m_path << title;
+    emit contextPathChanged(m_path);
 }
 
 void SubcomponentEditorTool::aboutToPopContext()
@@ -238,6 +244,7 @@ void SubcomponentEditorTool::aboutToPopContext()
 QGraphicsObject *SubcomponentEditorTool::popContext()
 {
     QGraphicsObject *popped = m_currentContext.pop();
+    m_path.removeLast();
 
     emit contextPopped();
 
@@ -275,11 +282,12 @@ void SubcomponentEditorTool::contextDestroyed(QObject *contextToDestroy)
     // pop out the whole context - it might not be safe anymore.
     while (m_currentContext.size() > 1) {
         m_currentContext.pop();
+        m_path.removeLast();
         emit contextPopped();
     }
-
-
     m_mask->setVisible(false);
+
+    emit contextPathChanged(m_path);
 }
 
 QGraphicsObject *SubcomponentEditorTool::setContext(int contextIndex)
diff --git a/src/libs/qmljsdebugger/editor/subcomponenteditortool.h b/src/libs/qmljsdebugger/editor/subcomponenteditortool.h
index fdd4aedfae2..e8e771fa1e9 100644
--- a/src/libs/qmljsdebugger/editor/subcomponenteditortool.h
+++ b/src/libs/qmljsdebugger/editor/subcomponenteditortool.h
@@ -3,6 +3,7 @@
 
 #include "abstractformeditortool.h"
 #include <QStack>
+#include <QStringList>
 
 QT_FORWARD_DECLARE_CLASS(QGraphicsObject)
 QT_FORWARD_DECLARE_CLASS(QPoint)
@@ -54,6 +55,7 @@ signals:
     void cleared();
     void contextPushed(const QString &contextTitle);
     void contextPopped();
+    void contextPathChanged(const QStringList &path);
 
 protected:
     void selectedItemsChanged(const QList<QGraphicsItem*> &itemList);
@@ -68,6 +70,7 @@ private:
 
 private:
     QStack<QGraphicsObject *> m_currentContext;
+    QStringList m_path;
 
     qreal m_animIncrement;
     SubcomponentMaskLayerItem *m_mask;
diff --git a/src/libs/qmljsdebugger/include/qdeclarativedesigndebugserver.h b/src/libs/qmljsdebugger/include/qdeclarativedesigndebugserver.h
index a43684234fe..5fb486fcfd4 100644
--- a/src/libs/qmljsdebugger/include/qdeclarativedesigndebugserver.h
+++ b/src/libs/qmljsdebugger/include/qdeclarativedesigndebugserver.h
@@ -67,11 +67,11 @@ public:
     void setAnimationSpeed(qreal slowdownFactor);
     void setCurrentTool(QmlViewer::Constants::DesignTool toolId);
     void reloaded();
-
     QString idStringForObject(QObject *obj) const;
 
 public Q_SLOTS:
     void selectedColorChanged(const QColor &color);
+    void contextPathUpdated(const QStringList &contextPath);
 
 Q_SIGNALS:
     void currentObjectsChanged(const QList<QObject*> &objects);
diff --git a/src/libs/qmljsdebugger/qdeclarativedesigndebugserver.cpp b/src/libs/qmljsdebugger/qdeclarativedesigndebugserver.cpp
index 5a90fa39c2f..61b2ceb330b 100644
--- a/src/libs/qmljsdebugger/qdeclarativedesigndebugserver.cpp
+++ b/src/libs/qmljsdebugger/qdeclarativedesigndebugserver.cpp
@@ -153,6 +153,17 @@ void QDeclarativeDesignDebugServer::selectedColorChanged(const QColor &color)
     sendMessage(message);
 }
 
+void QDeclarativeDesignDebugServer::contextPathUpdated(const QStringList &contextPath)
+{
+    QByteArray message;
+    QDataStream ds(&message, QIODevice::WriteOnly);
+
+    ds << QByteArray("CONTEXT_PATH_UPDATED")
+       << contextPath;
+
+    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 51f48abbbab..07ea92ac469 100644
--- a/src/libs/qmljsdebugger/qdeclarativedesignview.cpp
+++ b/src/libs/qmljsdebugger/qdeclarativedesignview.cpp
@@ -104,6 +104,7 @@ QDeclarativeDesignView::QDeclarativeDesignView(QWidget *parent) :
     connect(data->subcomponentEditorTool, SIGNAL(cleared()), SIGNAL(inspectorContextCleared()));
     connect(data->subcomponentEditorTool, SIGNAL(contextPushed(QString)), SIGNAL(inspectorContextPushed(QString)));
     connect(data->subcomponentEditorTool, SIGNAL(contextPopped()), SIGNAL(inspectorContextPopped()));
+    connect(data->subcomponentEditorTool, SIGNAL(contextPathChanged(QStringList)), qmlDesignDebugServer(), SLOT(contextPathUpdated(QStringList)));
 
     data->createToolbar();
 }
diff --git a/src/plugins/qmljsinspector/qmljsclientproxy.cpp b/src/plugins/qmljsinspector/qmljsclientproxy.cpp
index 3af1272b601..d81f0dfd423 100644
--- a/src/plugins/qmljsinspector/qmljsclientproxy.cpp
+++ b/src/plugins/qmljsinspector/qmljsclientproxy.cpp
@@ -82,6 +82,8 @@ bool ClientProxy::connectToViewer(const QString &host, quint16 port)
                    SIGNAL(designModeBehaviorChanged(bool)), this, SIGNAL(designModeBehaviorChanged(bool)));
         disconnect(m_designClient,
                    SIGNAL(selectedColorChanged(QColor)), this, SIGNAL(selectedColorChanged(QColor)));
+        disconnect(m_designClient,
+                   SIGNAL(contextPathUpdated(QStringList)), this, SIGNAL(contextPathUpdated(QStringList)));
 
         emit aboutToDisconnect();
 
@@ -227,6 +229,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)));
             }
 
             (void) new DebuggerClient(m_conn);
diff --git a/src/plugins/qmljsinspector/qmljsclientproxy.h b/src/plugins/qmljsinspector/qmljsclientproxy.h
index 810ff65b0ff..8ca9e8dd748 100644
--- a/src/plugins/qmljsinspector/qmljsclientproxy.h
+++ b/src/plugins/qmljsinspector/qmljsclientproxy.h
@@ -93,6 +93,7 @@ signals:
     void designModeBehaviorChanged(bool inDesignMode);
     void serverReloaded();
     void selectedColorChanged(const QColor &color);
+    void contextPathUpdated(const QStringList &contextPath);
 
 public slots:
     void queryEngineContext(int id);
diff --git a/src/plugins/qmljsinspector/qmljscontextcrumblepath.cpp b/src/plugins/qmljsinspector/qmljscontextcrumblepath.cpp
new file mode 100644
index 00000000000..295c15321ae
--- /dev/null
+++ b/src/plugins/qmljsinspector/qmljscontextcrumblepath.cpp
@@ -0,0 +1,29 @@
+#include "qmljscontextcrumblepath.h"
+
+#include <QMouseEvent>
+#include <QDebug>
+
+namespace QmlJSInspector {
+namespace Internal {
+
+ContextCrumblePath::ContextCrumblePath(QWidget *parent)
+    : CrumblePath(parent)
+{
+    setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+}
+
+ContextCrumblePath::~ContextCrumblePath()
+{
+
+}
+
+void ContextCrumblePath::updateContextPath(const QStringList &path)
+{
+    clear();
+    foreach(const QString &pathPart, path) {
+        pushElement(pathPart);
+    }
+}
+
+} // namespace Internal
+} // namespace QmlJSInspector
diff --git a/src/plugins/qmljsinspector/qmljscontextcrumblepath.h b/src/plugins/qmljsinspector/qmljscontextcrumblepath.h
new file mode 100644
index 00000000000..c19de84596d
--- /dev/null
+++ b/src/plugins/qmljsinspector/qmljscontextcrumblepath.h
@@ -0,0 +1,25 @@
+#ifndef QMLJSCONTEXTCRUMBLEPATH_H
+#define QMLJSCONTEXTCRUMBLEPATH_H
+
+#include <utils/crumblepath.h>
+#include <QStringList>
+
+namespace QmlJSInspector {
+namespace Internal {
+
+class ContextCrumblePath : public Utils::CrumblePath
+{
+    Q_OBJECT
+public:
+    ContextCrumblePath(QWidget *parent = 0);
+    virtual ~ContextCrumblePath();
+
+public slots:
+    void updateContextPath(const QStringList &path);
+
+};
+
+} // namespace Internal
+} // namespace QmlJSInspector
+
+#endif // QMLJSCONTEXTCRUMBLEPATH_H
diff --git a/src/plugins/qmljsinspector/qmljsdesigndebugclient.cpp b/src/plugins/qmljsinspector/qmljsdesigndebugclient.cpp
index cbc1be4b235..319518ccd39 100644
--- a/src/plugins/qmljsinspector/qmljsdesigndebugclient.cpp
+++ b/src/plugins/qmljsinspector/qmljsdesigndebugclient.cpp
@@ -104,6 +104,10 @@ void QmlJSDesignDebugClient::messageReceived(const QByteArray &message)
         QColor col;
         ds >> col;
         emit selectedColorChanged(col);
+    } else if (type == "CONTEXT_PATH_UPDATED") {
+        QStringList contextPath;
+        ds >> contextPath;
+        emit contextPathUpdated(contextPath);
     }
 }
 
diff --git a/src/plugins/qmljsinspector/qmljsdesigndebugclient.h b/src/plugins/qmljsinspector/qmljsdesigndebugclient.h
index d74030c8546..727321a50a2 100644
--- a/src/plugins/qmljsinspector/qmljsdesigndebugclient.h
+++ b/src/plugins/qmljsinspector/qmljsdesigndebugclient.h
@@ -85,6 +85,7 @@ signals:
     void animationSpeedChanged(qreal slowdownFactor);
     void designModeBehaviorChanged(bool inDesignMode);
     void reloaded(); // the server has reloaded the document
+    void contextPathUpdated(const QStringList &path);
 
 protected:
     virtual void messageReceived(const QByteArray &);
diff --git a/src/plugins/qmljsinspector/qmljsinspector.cpp b/src/plugins/qmljsinspector/qmljsinspector.cpp
index 5e0ca38bd2e..ef024f5133e 100644
--- a/src/plugins/qmljsinspector/qmljsinspector.cpp
+++ b/src/plugins/qmljsinspector/qmljsinspector.cpp
@@ -32,6 +32,7 @@
 #include "qmljsinspectorcontext.h"
 #include "qmljslivetextpreview.h"
 #include "qmljsprivateapi.h"
+#include "qmljscontextcrumblepath.h"
 
 #include <qmljseditor/qmljseditorconstants.h>
 
@@ -323,7 +324,7 @@ void Inspector::startQmlProjectDebugger()
 
 void Inspector::resetViews()
 {
-//#warning reset the views here
+    m_crumblePath->clear();
 }
 
 void Inspector::simultaneouslyDebugQmlCppApplication()
@@ -565,34 +566,15 @@ void Inspector::reloadQmlViewer()
 
 void Inspector::setSimpleDockWidgetArrangement()
 {
-#if 0
     Utils::FancyMainWindow *mainWindow = Debugger::DebuggerUISwitcher::instance()->mainWindow();
 
     mainWindow->setTrackingEnabled(false);
-    QList<QDockWidget *> dockWidgets = mainWindow->dockWidgets();
-    foreach (QDockWidget *dockWidget, dockWidgets) {
-        if (m_dockWidgets.contains(dockWidget)) {
-            dockWidget->setFloating(false);
-            mainWindow->removeDockWidget(dockWidget);
-        }
-    }
-
-    foreach (QDockWidget *dockWidget, dockWidgets) {
-        if (m_dockWidgets.contains(dockWidget)) {
-            mainWindow->addDockWidget(Qt::BottomDockWidgetArea, dockWidget);
-            dockWidget->show();
-        }
-    }
-    mainWindow->splitDockWidget(mainWindow->toolBarDockWidget(), m_propertyWatcherDock, Qt::Vertical);
-    //mainWindow->tabifyDockWidget(m_frameRateDock, m_propertyWatcherDock);
-    mainWindow->tabifyDockWidget(m_propertyWatcherDock, m_expressionQueryDock);
-    mainWindow->tabifyDockWidget(m_propertyWatcherDock, m_inspectorOutputDock);
-    m_propertyWatcherDock->raise();
-
-    m_inspectorOutputDock->setVisible(false);
+    mainWindow->removeDockWidget(m_crumblePathDock);
+    mainWindow->addDockWidget(Qt::BottomDockWidgetArea, m_crumblePathDock);
+    mainWindow->splitDockWidget(mainWindow->toolBarDockWidget(), m_crumblePathDock, Qt::Vertical);
+    //m_crumblePathDock->setVisible(true);
 
     mainWindow->setTrackingEnabled(true);
-#endif
 }
 
 void Inspector::setSelectedItemsByObjectReference(QList<QDeclarativeDebugObjectReference> objectReferences)
@@ -651,6 +633,18 @@ bool Inspector::addQuotesForData(const QVariant &value) const
     return false;
 }
 
+void Inspector::createDockWidgets()
+{
+    m_crumblePath = new ContextCrumblePath;
+    m_crumblePath->setWindowTitle("Context Path");
+    Debugger::DebuggerUISwitcher *uiSwitcher = Debugger::DebuggerUISwitcher::instance();
+    m_crumblePathDock = uiSwitcher->createDockWidget(QmlJSInspector::Constants::LANG_QML,
+                                                                m_crumblePath, Qt::BottomDockWidgetArea);
+    m_crumblePathDock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
+    m_crumblePathDock->setTitleBarWidget(new QWidget(m_crumblePathDock));
+    connect(m_clientProxy, SIGNAL(contextPathUpdated(QStringList)), m_crumblePath, SLOT(updateContextPath(QStringList)));
+}
+
 bool Inspector::showExperimentalWarning()
 {
     return m_showExperimentalWarning;
diff --git a/src/plugins/qmljsinspector/qmljsinspector.h b/src/plugins/qmljsinspector/qmljsinspector.h
index 971aa6fb1a0..41e25030561 100644
--- a/src/plugins/qmljsinspector/qmljsinspector.h
+++ b/src/plugins/qmljsinspector/qmljsinspector.h
@@ -58,11 +58,14 @@ namespace QmlJS {
     class ModelManagerInterface;
 }
 
+QT_FORWARD_DECLARE_CLASS(QDockWidget)
+
 namespace QmlJSInspector {
 namespace Internal {
 
 class ClientProxy;
 class InspectorContext;
+class ContextCrumblePath;
 class QmlJSLiveTextPreview;
 
 class Inspector : public QObject
@@ -96,6 +99,7 @@ public:
     static bool showExperimentalWarning();
     static void setShowExperimentalWarning(bool value);
 
+    void createDockWidgets();
 
 signals:
     void statusMessage(const QString &text);
@@ -164,6 +168,9 @@ private:
     static bool m_showExperimentalWarning;
     bool m_listeningToEditorManager;
 
+    ContextCrumblePath *m_crumblePath;
+    QDockWidget *m_crumblePathDock;
+
     // Qml/JS integration
     QHash<QString, QmlJSLiveTextPreview *> m_textPreviews;
     QmlJS::Snapshot m_loadedSnapshot; //the snapshot loaded by the viewer
diff --git a/src/plugins/qmljsinspector/qmljsinspector.pro b/src/plugins/qmljsinspector/qmljsinspector.pro
index 48a5c0b4e20..98502907311 100644
--- a/src/plugins/qmljsinspector/qmljsinspector.pro
+++ b/src/plugins/qmljsinspector/qmljsinspector.pro
@@ -18,7 +18,8 @@ qmljsinspector.h \
 qmlinspectortoolbar.h \
 qmljslivetextpreview.h \
 qmljstoolbarcolorbox.h \
-qmljsdesigndebugclient.h
+qmljsdesigndebugclient.h \
+    qmljscontextcrumblepath.h
 
 SOURCES += \
 qmljsdebuggerclient.cpp \
@@ -30,6 +31,7 @@ qmlinspectortoolbar.cpp \
 qmljslivetextpreview.cpp \
 qmljstoolbarcolorbox.cpp \
 qmljsdesigndebugclient.cpp \
+    qmljscontextcrumblepath.cpp
 
 include(../../libs/qmljsdebugclient/qmljsdebugclient-lib.pri)
 
@@ -42,4 +44,4 @@ include(../../plugins/qmlprojectmanager/qmlprojectmanager.pri)
 include(../../plugins/coreplugin/coreplugin.pri)
 include(../../plugins/texteditor/texteditor.pri)
 include(../../plugins/debugger/debugger.pri)
-
+include(../../libs/utils/utils.pri)
diff --git a/src/plugins/qmljsinspector/qmljsinspectorplugin.cpp b/src/plugins/qmljsinspector/qmljsinspectorplugin.cpp
index 8a5a0dc9629..b58b6bde290 100644
--- a/src/plugins/qmljsinspector/qmljsinspectorplugin.cpp
+++ b/src/plugins/qmljsinspector/qmljsinspectorplugin.cpp
@@ -132,13 +132,7 @@ bool InspectorPlugin::initialize(const QStringList &arguments, QString *errorStr
 
     uiSwitcher->addLanguage(LANG_QML, Core::Context(C_INSPECTOR));
 
-#ifdef __GNUC__
-#  warning set up the QML/JS Inspector UI
-#endif
-
-#if 0
     _inspector->createDockWidgets();
-#endif
 
     return true;
 }
@@ -177,6 +171,8 @@ void InspectorPlugin::extensionsInitialized()
     connect(_clientProxy, SIGNAL(selectedColorChanged(QColor)), m_toolbar, SLOT(setSelectedColor(QColor)));
 
     connect(_clientProxy, SIGNAL(animationSpeedChanged(qreal)), m_toolbar, SLOT(changeAnimationSpeed(qreal)));
+
+
 }
 
 void InspectorPlugin::activateDebuggerForProject(ProjectExplorer::Project *project, const QString &runMode)
@@ -214,12 +210,8 @@ void InspectorPlugin::prepareDebugger(Core::IMode *mode)
 
 void InspectorPlugin::setDockWidgetArrangement(const QString &activeLanguage)
 {
-    Q_UNUSED(activeLanguage);
-
-#if 0
-    if (activeLanguage == Qml::Constants::LANG_QML || activeLanguage.isEmpty())
-        m_inspector->setSimpleDockWidgetArrangement();
-#endif
+    if (activeLanguage == QmlJSInspector::Constants::LANG_QML || activeLanguage.isEmpty())
+        _inspector->setSimpleDockWidgetArrangement();
 }
 
 
-- 
GitLab