From f5039a4a022a31cc4c1330d35350ae39cf11b5dd Mon Sep 17 00:00:00 2001
From: Christiaan Janssen <christiaan.janssen@nokia.com>
Date: Tue, 18 Jan 2011 17:17:17 +0100
Subject: [PATCH] QmlJsInspector: implemented Property Inspector

Reviewed-by: Kai Koehne
---
 src/libs/utils/crumblepath.cpp                |  80 ++++--
 src/libs/utils/crumblepath.h                  |   5 +-
 src/plugins/qmljseditor/qmljseditor.cpp       |  18 +-
 .../qmljsinspector/qmlinspectortoolbar.cpp    |   9 +-
 .../qmljsinspector/qmlinspectortoolbar.h      |   4 +
 .../qmljsinspector/qmljsclientproxy.cpp       |  70 ++++-
 src/plugins/qmljsinspector/qmljsclientproxy.h |   8 +
 .../qmljscontextcrumblepath.cpp               |  21 +-
 .../qmljsinspector/qmljscontextcrumblepath.h  |   4 +-
 src/plugins/qmljsinspector/qmljsinspector.cpp | 268 ++++++++++++++----
 src/plugins/qmljsinspector/qmljsinspector.h   |  15 +-
 src/plugins/qmljsinspector/qmljsinspector.pro |   4 +-
 .../qmljsinspector/qmljsobjecttree.cpp        | 242 ----------------
 src/plugins/qmljsinspector/qmljsobjecttree.h  |  86 ------
 14 files changed, 401 insertions(+), 433 deletions(-)
 delete mode 100644 src/plugins/qmljsinspector/qmljsobjecttree.cpp
 delete mode 100644 src/plugins/qmljsinspector/qmljsobjecttree.h

diff --git a/src/libs/utils/crumblepath.cpp b/src/libs/utils/crumblepath.cpp
index ea1b20b5850..fc938c0c78a 100644
--- a/src/libs/utils/crumblepath.cpp
+++ b/src/libs/utils/crumblepath.cpp
@@ -57,6 +57,9 @@ public:
 
     explicit CrumblePathButton(const QString &title, QWidget *parent = 0);
     void setSegmentType(int type);
+    void select(bool s);
+    void setData(QVariant data);
+    QVariant data() const;
 protected:
     void paintEvent(QPaintEvent *);
     void mouseMoveEvent(QMouseEvent *e);
@@ -70,6 +73,7 @@ private:
 private:
     bool m_isHovering;
     bool m_isPressed;
+    bool m_isSelected;
     bool m_isEnd;
     QColor m_baseColor;
     QImage m_segment;
@@ -79,10 +83,12 @@ private:
     QImage m_segmentHover;
     QImage m_segmentHoverEnd;
     QPoint m_textPos;
+
+    QVariant m_data;
 };
 
 CrumblePathButton::CrumblePathButton(const QString &title, QWidget *parent)
-    : QPushButton(title, parent), m_isHovering(false), m_isPressed(false), m_isEnd(true)
+    : QPushButton(title, parent), m_isHovering(false), m_isPressed(false), m_isSelected(false), m_isEnd(true)
 {
     setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
     setToolTip(title);
@@ -114,7 +120,7 @@ void CrumblePathButton::paintEvent(QPaintEvent *)
     }
 
     if (m_isEnd) {
-        if (m_isPressed) {
+        if (m_isPressed || m_isSelected) {
             Utils::StyleHelper::drawCornerImage(m_segmentSelectedEnd, &p, geom, 2, 0, 2, 0);
         } else if (m_isHovering) {
             Utils::StyleHelper::drawCornerImage(m_segmentHoverEnd, &p, geom, 2, 0, 2, 0);
@@ -122,7 +128,7 @@ void CrumblePathButton::paintEvent(QPaintEvent *)
             Utils::StyleHelper::drawCornerImage(m_segmentEnd, &p, geom, 2, 0, 2, 0);
         }
     } else {
-        if (m_isPressed) {
+        if (m_isPressed || m_isSelected) {
             Utils::StyleHelper::drawCornerImage(m_segmentSelected, &p, geom, 2, 0, 12, 0);
         } else if (m_isHovering) {
             Utils::StyleHelper::drawCornerImage(m_segmentHover, &p, geom, 2, 0, 12, 0);
@@ -175,6 +181,12 @@ void CrumblePathButton::mouseReleaseEvent(QMouseEvent *e)
     update();
 }
 
+void CrumblePathButton::select(bool s)
+{
+    m_isSelected = s;
+    update();
+}
+
 void CrumblePathButton::setSegmentType(int type)
 {
     bool useLeftPadding = !(type & FirstSegment);
@@ -182,6 +194,16 @@ void CrumblePathButton::setSegmentType(int type)
     m_textPos.setX(useLeftPadding ? 18 : 4);
 }
 
+void CrumblePathButton::setData(QVariant data)
+{
+    m_data = data;
+}
+
+QVariant CrumblePathButton::data() const
+{
+    return m_data;
+}
+
 struct CrumblePathPrivate {
     explicit CrumblePathPrivate(CrumblePath *q);
 
@@ -216,12 +238,25 @@ CrumblePath::~CrumblePath()
     d->m_buttons.clear();
 }
 
+void CrumblePath::selectIndex(int index)
+{
+    if ((index > -1) && (index < d->m_buttons.length()))
+        d->m_buttons[index]->select(true);
+}
+
+QVariant CrumblePath::dataForIndex(int index) const
+{
+    if ((index > -1) && (index < d->m_buttons.length()))
+        return d->m_buttons[index]->data();
+    return QVariant();
+}
+
 void CrumblePath::setBackgroundStyle()
 {
     d->m_background->setStyleSheet("QWidget { background-color:" + d->m_baseColor.name() + ";}");
 }
 
-void CrumblePath::pushElement(const QString &title)
+void CrumblePath::pushElement(const QString &title, const QVariant data)
 {
     CrumblePathButton *newButton = new CrumblePathButton(title, this);
     newButton->hide();
@@ -237,6 +272,7 @@ void CrumblePath::pushElement(const QString &title)
         segType = CrumblePathButton::FirstSegment | CrumblePathButton::LastSegment;
         newButton->setSegmentType(segType);
     }
+    newButton->setData(data);
     d->m_buttons.append(newButton);
 
     resizeButtons();
@@ -272,8 +308,6 @@ void CrumblePath::resizeEvent(QResizeEvent *)
 
 void CrumblePath::resizeButtons()
 {
-    int buttonMinWidth = 0;
-    int buttonMaxWidth = 0;
     int totalWidthLeft = width();
 
     if (d->m_buttons.length() >= 1) {
@@ -281,26 +315,34 @@ void CrumblePath::resizeButtons()
 
         d->m_buttons[0]->raise();
         // rearrange all items so that the first item is on top (added last).
+
+        // compute relative sizes
+        QList <int> sizes;
+        int totalSize = 0;
         for(int i = 0; i < d->m_buttons.length() ; ++i) {
             CrumblePathButton *button = d->m_buttons[i];
 
             QFontMetrics fm(button->font());
-            buttonMinWidth = ArrowBorderSize + fm.width(button->text()) + ArrowBorderSize * 2 ;
-            buttonMaxWidth = (totalWidthLeft + ArrowBorderSize * (d->m_buttons.length() - i)) / (d->m_buttons.length() - i);
-
-            if (buttonMinWidth > buttonMaxWidth && i < d->m_buttons.length() - 1) {
-                buttonMinWidth = buttonMaxWidth;
-            } else if (i > 3 && (i == d->m_buttons.length() - 1)) {
-                buttonMinWidth = width() - nextElementPosition.x();
-                buttonMaxWidth = buttonMinWidth;
-            }
-
-            button->setMinimumWidth(buttonMinWidth);
-            button->setMaximumWidth(buttonMaxWidth);
+            int originalSize = ArrowBorderSize + fm.width(button->text()) + ArrowBorderSize + 12;
+            sizes << originalSize;
+            totalSize += originalSize - ArrowBorderSize;
+        }
+
+        for (int i = 0; i < d->m_buttons.length() ; ++i) {
+            CrumblePathButton *button = d->m_buttons[i];
+
+            int candidateSize = (sizes[i]*totalWidthLeft)/totalSize;
+            if (candidateSize < ArrowBorderSize)
+                candidateSize = ArrowBorderSize;
+            if (candidateSize > sizes[i]*1.3)
+                candidateSize = sizes[i]*1.3;
+
+
+            button->setMinimumWidth(candidateSize);
+            button->setMaximumWidth(candidateSize);
             button->move(nextElementPosition);
 
             nextElementPosition.rx() += button->width() - ArrowBorderSize;
-            totalWidthLeft -= button->width();
 
             button->show();
             if (i > 0)
diff --git a/src/libs/utils/crumblepath.h b/src/libs/utils/crumblepath.h
index 402a4109ae1..62efb158d02 100644
--- a/src/libs/utils/crumblepath.h
+++ b/src/libs/utils/crumblepath.h
@@ -37,6 +37,7 @@
 #include "utils_global.h"
 
 #include <QtGui/QWidget>
+#include <QVariant>
 
 QT_FORWARD_DECLARE_CLASS(QResizeEvent)
 
@@ -50,9 +51,11 @@ class QTCREATOR_UTILS_EXPORT CrumblePath : public QWidget
 public:
     explicit CrumblePath(QWidget *parent = 0);
     ~CrumblePath();
+    void selectIndex(int index);
+    QVariant dataForIndex(int index) const;
 
 public slots:
-    void pushElement(const QString &title);
+    void pushElement(const QString &title, const QVariant data = QVariant());
     void popElement();
     void clear();
 
diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp
index 4037994470a..0eac867b7e5 100644
--- a/src/plugins/qmljseditor/qmljseditor.cpp
+++ b/src/plugins/qmljseditor/qmljseditor.cpp
@@ -1054,22 +1054,6 @@ protected:
         return 0;
     }
 
-    inline bool hasVisualPresentation(Node *ast)
-    {
-        Bind *bind = m_lookupContext->document()->bind();
-        const Interpreter::ObjectValue *objValue = bind->findQmlObject(ast);
-        if (!objValue)
-            return false;
-
-        QStringList prototypes;
-        foreach (const Interpreter::ObjectValue *value,
-                 Interpreter::PrototypeIterator(objValue, m_lookupContext->context()).all()) {
-            prototypes.append(value->className());
-        }
-
-        return prototypes.contains(QString("QGraphicsObject"));
-    }
-
     inline bool isIdBinding(UiObjectMember *member) const
     {
         if (UiScriptBinding *script = cast<UiScriptBinding *>(member)) {
@@ -1116,7 +1100,7 @@ protected:
             if ((isRangeSelected() && intersectsCursor(begin, end))
             || (!isRangeSelected() && containsCursor(begin, end)))
             {
-                if (initializer(member) && isSelectable(member) && hasVisualPresentation(member)) {
+                if (initializer(member) && isSelectable(member)) {
                     m_selectedMembers << member;
                     // move start towards end; this facilitates multiselection so that root is usually ignored.
                     m_cursorPositionStart = qMin(end, m_cursorPositionEnd);
diff --git a/src/plugins/qmljsinspector/qmlinspectortoolbar.cpp b/src/plugins/qmljsinspector/qmlinspectortoolbar.cpp
index c0d3b42e6ab..9006f0f09e1 100644
--- a/src/plugins/qmljsinspector/qmlinspectortoolbar.cpp
+++ b/src/plugins/qmljsinspector/qmlinspectortoolbar.cpp
@@ -43,13 +43,13 @@
 #include <projectexplorer/projectexplorerconstants.h>
 
 #include <utils/styledbar.h>
-#include <utils/filterlineedit.h>
 
 #include <QAction>
 #include <QActionGroup>
 #include <QHBoxLayout>
 #include <QMenu>
 #include <QToolButton>
+#include <QLineEdit>
 
 namespace QmlJSInspector {
 namespace Internal {
@@ -78,6 +78,7 @@ QmlInspectorToolbar::QmlInspectorToolbar(QObject *parent) :
     m_menuPauseAction(0),
     m_playIcon(QIcon(QLatin1String(":/qml/images/play-small.png"))),
     m_pauseIcon(QIcon(QLatin1String(":/qml/images/pause-small.png"))),
+    m_filterExp(0),
     m_colorBox(0),
     m_emitSignals(true),
     m_isRunning(false),
@@ -98,6 +99,7 @@ void QmlInspectorToolbar::setEnabled(bool value)
     m_zoomAction->setEnabled(value);
     m_colorPickerAction->setEnabled(value);
     m_colorBox->setEnabled(value);
+    m_filterExp->setEnabled(value);
 }
 
 void QmlInspectorToolbar::enable()
@@ -295,6 +297,10 @@ void QmlInspectorToolbar::createActions(const Core::Context &context)
     m_colorBox->setInnerBorderColor(QColor(192,192,192));
     m_colorBox->setOuterBorderColor(QColor(58,58,58));
     configBarLayout->addWidget(m_colorBox);
+
+    m_filterExp = new QLineEdit(m_barWidget);
+    m_filterExp->setPlaceholderText("<filter property list>");
+    configBarLayout->addWidget(m_filterExp);
     configBarLayout->addStretch();
 
     setEnabled(false);
@@ -307,6 +313,7 @@ void QmlInspectorToolbar::createActions(const Core::Context &context)
     connect(m_selectAction, SIGNAL(triggered()), SLOT(activateSelectToolOnClick()));
     connect(m_zoomAction, SIGNAL(triggered()), SLOT(activateZoomOnClick()));
     connect(m_colorPickerAction, SIGNAL(triggered()), SLOT(activateColorPickerOnClick()));
+    connect(m_filterExp, SIGNAL(textChanged(QString)), SIGNAL(filterTextChanged(QString)));
 }
 
 QWidget *QmlInspectorToolbar::widget() const
diff --git a/src/plugins/qmljsinspector/qmlinspectortoolbar.h b/src/plugins/qmljsinspector/qmlinspectortoolbar.h
index 990b60f6820..6cc78e9b272 100644
--- a/src/plugins/qmljsinspector/qmlinspectortoolbar.h
+++ b/src/plugins/qmljsinspector/qmlinspectortoolbar.h
@@ -40,6 +40,7 @@
 QT_FORWARD_DECLARE_CLASS(QAction)
 QT_FORWARD_DECLARE_CLASS(QColor)
 QT_FORWARD_DECLARE_CLASS(QToolButton)
+QT_FORWARD_DECLARE_CLASS(QLineEdit)
 
 namespace Core {
     class Context;
@@ -98,6 +99,7 @@ signals:
 
     void showAppOnTopSelected(bool isChecked);
     void animationSpeedChanged(qreal slowdownFactor = 1.0f);
+    void filterTextChanged(const QString &);
 
 private slots:
     void activateDesignModeOnClick();
@@ -140,6 +142,8 @@ private:
     QIcon m_playIcon;
     QIcon m_pauseIcon;
 
+    QLineEdit *m_filterExp;
+
     ToolBarColorBox *m_colorBox;
 
     bool m_emitSignals;
diff --git a/src/plugins/qmljsinspector/qmljsclientproxy.cpp b/src/plugins/qmljsinspector/qmljsclientproxy.cpp
index 58fb50852fa..29c5b07817f 100644
--- a/src/plugins/qmljsinspector/qmljsclientproxy.cpp
+++ b/src/plugins/qmljsinspector/qmljsclientproxy.cpp
@@ -157,6 +157,8 @@ void ClientProxy::disconnectFromServer()
     qDeleteAll(m_objectTreeQuery);
     m_objectTreeQuery.clear();
 
+    removeAllObjectWatches();
+
     updateConnected();
 }
 
@@ -226,7 +228,7 @@ QDeclarativeDebugObjectReference ClientProxy::objectReferenceForId(int debugId,
     if (objectRef.debugId() == debugId)
         return objectRef;
 
-    foreach(const QDeclarativeDebugObjectReference &child, objectRef.children()) {
+    foreach (const QDeclarativeDebugObjectReference &child, objectRef.children()) {
         QDeclarativeDebugObjectReference result = objectReferenceForId(debugId, child);
         if (result.debugId() == debugId)
             return result;
@@ -261,7 +263,7 @@ QDeclarativeDebugObjectReference ClientProxy::objectReferenceForLocation(const i
 QList<QDeclarativeDebugObjectReference> ClientProxy::objectReferences() const
 {
     QList<QDeclarativeDebugObjectReference> result;
-    foreach(const QDeclarativeDebugObjectReference &it, m_rootObjects) {
+    foreach (const QDeclarativeDebugObjectReference &it, m_rootObjects) {
         result.append(objectReferences(it));
     }
     return result;
@@ -272,7 +274,7 @@ QList<QDeclarativeDebugObjectReference> ClientProxy::objectReferences(const QDec
     QList<QDeclarativeDebugObjectReference> result;
     result.append(objectRef);
 
-    foreach(const QDeclarativeDebugObjectReference &child, objectRef.children()) {
+    foreach (const QDeclarativeDebugObjectReference &child, objectRef.children()) {
         result.append(objectReferences(child));
     }
 
@@ -331,6 +333,64 @@ void ClientProxy::clearComponentCache()
         m_observerClient->clearComponentCache();
 }
 
+bool ClientProxy::addObjectWatch(int objectDebugId)
+{
+    if (debug)
+        qDebug() << "addObjectWatch():" << objectDebugId;
+    if (objectDebugId == -1)
+        return false;
+
+    // already set
+    if (m_objectWatches.keys().contains(objectDebugId))
+        return true;
+
+    QDeclarativeDebugObjectReference ref = objectReferenceForId(objectDebugId);
+    if (ref.debugId() != objectDebugId)
+        return false;
+
+    QDeclarativeDebugWatch *watch = m_engineClient->addWatch(ref, this);
+    m_objectWatches.insert(objectDebugId, watch);
+
+    connect(watch,SIGNAL(valueChanged(QByteArray,QVariant)),this,SLOT(objectWatchTriggered(QByteArray,QVariant)));
+
+    return false;
+}
+
+void ClientProxy::objectWatchTriggered(const QByteArray &propertyName, const QVariant &propertyValue)
+{
+    QDeclarativeDebugWatch *watch = dynamic_cast<QDeclarativeDebugWatch *>(QObject::sender());
+    if (watch)
+        emit propertyChanged(watch->objectDebugId(),propertyName, propertyValue);
+
+}
+
+bool ClientProxy::removeObjectWatch(int objectDebugId)
+{
+    if (debug)
+        qDebug() << "removeObjectWatch():" << objectDebugId;
+    if (objectDebugId == -1)
+        return false;
+
+    if (!m_objectWatches.keys().contains(objectDebugId))
+        return false;
+
+    QDeclarativeDebugWatch *watch = m_objectWatches.value(objectDebugId);
+    disconnect(watch,SIGNAL(valueChanged(QByteArray,QVariant)), this, SLOT(objectWatchTriggered(QByteArray,QVariant)));
+    m_engineClient->removeWatch(watch);
+    delete watch;
+    m_objectWatches.remove(objectDebugId);
+
+
+    return true;
+}
+
+void ClientProxy::removeAllObjectWatches()
+{
+    foreach (int watchedObject, m_objectWatches.keys())
+        removeObjectWatch(watchedObject);
+    Q_ASSERT(m_objectWatches.count() == 0);
+}
+
 void ClientProxy::queryEngineContext(int id)
 {
     if (id < 0)
@@ -403,7 +463,7 @@ void ClientProxy::objectTreeFetched(QDeclarativeDebugQuery::State state)
         int old_count = m_debugIdHash.count();
         m_debugIdHash.clear();
         m_debugIdHash.reserve(old_count + 1);
-        foreach(const QDeclarativeDebugObjectReference &it, m_rootObjects)
+        foreach (const QDeclarativeDebugObjectReference &it, m_rootObjects)
             buildDebugIdHashRecursive(it);
         emit objectTreeUpdated();
 
@@ -445,7 +505,7 @@ void ClientProxy::buildDebugIdHashRecursive(const QDeclarativeDebugObjectReferen
     // append the debug ids in the hash
     m_debugIdHash[qMakePair<QString, int>(filename, rev)][qMakePair<int, int>(lineNum, colNum)].append(ref.debugId());
 
-    foreach(const QDeclarativeDebugObjectReference &it, ref.children())
+    foreach (const QDeclarativeDebugObjectReference &it, ref.children())
         buildDebugIdHashRecursive(it);
 }
 
diff --git a/src/plugins/qmljsinspector/qmljsclientproxy.h b/src/plugins/qmljsinspector/qmljsclientproxy.h
index c88cc839f3e..ac975398630 100644
--- a/src/plugins/qmljsinspector/qmljsclientproxy.h
+++ b/src/plugins/qmljsinspector/qmljsclientproxy.h
@@ -70,6 +70,10 @@ public:
     QDeclarativeDebugExpressionQuery *queryExpressionResult(int objectDebugId, const QString &expr, QObject *parent=0);
     void clearComponentCache();
 
+    bool addObjectWatch(int objectDebugId);
+    bool removeObjectWatch(int objectDebugId);
+    void removeAllObjectWatches();
+
     // returns the object references
     QList<QDeclarativeDebugObjectReference> objectReferences() const;
     QDeclarativeDebugObjectReference objectReferenceForId(int debugId) const;
@@ -108,6 +112,7 @@ signals:
     void serverReloaded();
     void selectedColorChanged(const QColor &color);
     void contextPathUpdated(const QStringList &contextPath);
+    void propertyChanged(int debugId, const QByteArray &propertyName, const QVariant &propertyValue);
 
 public slots:
     void refreshObjectTree();
@@ -139,6 +144,7 @@ private slots:
     void objectTreeFetched(QDeclarativeDebugQuery::State state = QDeclarativeDebugQuery::Completed);
     void fetchContextObjectRecursive(const QmlJsDebugClient::QDeclarativeDebugContextReference& context);
     void newObjects();
+    void objectWatchTriggered(const QByteArray &propertyName, const QVariant &propertyValue);
 
 private:
     void updateConnected();
@@ -164,6 +170,8 @@ private:
     QTimer m_requestObjectsTimer;
     DebugIdHash m_debugIdHash;
 
+    QHash<int, QDeclarativeDebugWatch *> m_objectWatches;
+
     bool m_isConnected;
 };
 
diff --git a/src/plugins/qmljsinspector/qmljscontextcrumblepath.cpp b/src/plugins/qmljsinspector/qmljscontextcrumblepath.cpp
index bd4c4fec4c8..8ea623cb3a1 100644
--- a/src/plugins/qmljsinspector/qmljscontextcrumblepath.cpp
+++ b/src/plugins/qmljsinspector/qmljscontextcrumblepath.cpp
@@ -42,7 +42,7 @@ ContextCrumblePath::ContextCrumblePath(QWidget *parent)
     : CrumblePath(parent), m_isEmpty(true)
 {
     setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
-    updateContextPath(QStringList());
+    updateContextPath(QStringList(),QList<int>());
 }
 
 ContextCrumblePath::~ContextCrumblePath()
@@ -50,11 +50,14 @@ ContextCrumblePath::~ContextCrumblePath()
 
 }
 
-void ContextCrumblePath::updateContextPath(const QStringList &path)
+void ContextCrumblePath::updateContextPath(const QStringList &path, const QList<int> &debugIds)
 {
+    Q_ASSERT(path.count() == debugIds.count());
+
     clear();
-    foreach(const QString &pathPart, path) {
-        pushElement(pathPart);
+
+    for (int i=0; i<path.count(); i++) {
+        pushElement(path[i],QVariant(debugIds[i]));
     }
 
     m_isEmpty = path.isEmpty();
@@ -63,10 +66,20 @@ void ContextCrumblePath::updateContextPath(const QStringList &path)
     }
 }
 
+void ContextCrumblePath::selectIndex(int index)
+{
+    CrumblePath::selectIndex(index);
+}
+
 bool ContextCrumblePath::isEmpty() const
 {
     return m_isEmpty;
 }
 
+int ContextCrumblePath::debugIdForIndex(int index) const
+{
+    return CrumblePath::dataForIndex(index).toInt();
+}
+
 } // namespace Internal
 } // namespace QmlJSInspector
diff --git a/src/plugins/qmljsinspector/qmljscontextcrumblepath.h b/src/plugins/qmljsinspector/qmljscontextcrumblepath.h
index b1c38ba3f4a..2349cb4f97b 100644
--- a/src/plugins/qmljsinspector/qmljscontextcrumblepath.h
+++ b/src/plugins/qmljsinspector/qmljscontextcrumblepath.h
@@ -46,9 +46,11 @@ public:
     ContextCrumblePath(QWidget *parent = 0);
     virtual ~ContextCrumblePath();
     bool isEmpty() const;
+    int debugIdForIndex(int index) const;
 
 public slots:
-    void updateContextPath(const QStringList &path);
+    void updateContextPath(const QStringList &path, const QList<int> &debugIds);
+    void selectIndex(int index);
 private:
     bool m_isEmpty;
 };
diff --git a/src/plugins/qmljsinspector/qmljsinspector.cpp b/src/plugins/qmljsinspector/qmljsinspector.cpp
index f651a596cb4..03367a4c34d 100644
--- a/src/plugins/qmljsinspector/qmljsinspector.cpp
+++ b/src/plugins/qmljsinspector/qmljsinspector.cpp
@@ -39,7 +39,7 @@
 #include "qmljsprivateapi.h"
 #include "qmljscontextcrumblepath.h"
 #include "qmljsinspectorsettings.h"
-#include "qmljsobjecttree.h"
+#include "qmljspropertyinspector.h"
 
 #include <qmljs/qmljsmodelmanagerinterface.h>
 #include <qmljs/qmljsdocument.h>
@@ -126,13 +126,13 @@ InspectorUi::InspectorUi(QObject *parent)
     , m_listeningToEditorManager(false)
     , m_toolbar(0)
     , m_crumblePath(0)
-    , m_objectTreeWidget(0)
+    , m_propertyInspector(0)
     , m_settings(new InspectorSettings(this))
     , m_clientProxy(0)
     , m_qmlEngine(0)
     , m_debugQuery(0)
-    , m_lastSelectedDebugId(-1)
     , m_debugProject(0)
+    , m_selectionCallbackExpected(false)
 {
     m_instance = this;
     m_toolbar = new QmlInspectorToolbar(this);
@@ -225,7 +225,7 @@ void InspectorUi::showDebuggerTooltip(const QPoint &mousePos, TextEditor::ITextE
                 if ((qmlNode->kind == QmlJS::AST::Node::Kind_IdentifierExpression) &&
                         (m_clientProxy->objectReferenceForId(refToLook).debugId() == -1)) {
                     query = doubleQuote + QString("local: ") + refToLook + doubleQuote;
-                    foreach(QDeclarativeDebugPropertyReference property, ref.properties()) {
+                    foreach (QDeclarativeDebugPropertyReference property, ref.properties()) {
                         if (property.name() == wordAtCursor
                                 && !property.valueTypeName().isEmpty()) {
                             query = doubleQuote + property.name() + QLatin1Char(':')
@@ -239,7 +239,7 @@ void InspectorUi::showDebuggerTooltip(const QPoint &mousePos, TextEditor::ITextE
                             + QLatin1Char('+') + refToLook;
             } else {
                 // show properties
-                foreach(QDeclarativeDebugPropertyReference property, ref.properties()) {
+                foreach (QDeclarativeDebugPropertyReference property, ref.properties()) {
                     if (property.name() == wordAtCursor && !property.valueTypeName().isEmpty()) {
                         query = doubleQuote + property.name() + QLatin1Char(':')
                                 + doubleQuote + QLatin1Char('+') + property.name();
@@ -250,7 +250,7 @@ void InspectorUi::showDebuggerTooltip(const QPoint &mousePos, TextEditor::ITextE
         }
 
         if (!query.isEmpty()) {
-            m_debugQuery = m_clientProxy->queryExpressionResult(ref.debugId(),query);
+            m_debugQuery = m_clientProxy->queryExpressionResult(ref.debugId(),query, this);
             connect(m_debugQuery, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)),
                     this, SLOT(debugQueryUpdated(QDeclarativeDebugQuery::State)));
         }
@@ -281,13 +281,23 @@ void InspectorUi::connected(ClientProxy *clientProxy)
 {
     m_clientProxy = clientProxy;
 
+    QmlJS::Snapshot snapshot = modelManager()->snapshot();
+    for (QHash<QString, QmlJSLiveTextPreview *>::const_iterator it = m_textPreviews.constBegin();
+         it != m_textPreviews.constEnd(); ++it) {
+        Document::Ptr doc = snapshot.document(it.key());
+        it.value()->resetInitialDoc(doc);
+    }
+
     connect(m_clientProxy, SIGNAL(selectedItemsChanged(QList<QDeclarativeDebugObjectReference>)),
-            SLOT(gotoObjectReferenceDefinition(QList<QDeclarativeDebugObjectReference>)));
+            SLOT(selectItems(QList<QDeclarativeDebugObjectReference>)));
 
     connect(m_clientProxy, SIGNAL(enginesChanged()), SLOT(updateEngineList()));
     connect(m_clientProxy, SIGNAL(serverReloaded()), this, SLOT(serverReloaded()));
-    connect(m_clientProxy, SIGNAL(contextPathUpdated(QStringList)),
-            m_crumblePath, SLOT(updateContextPath(QStringList)));
+    connect(m_clientProxy, SIGNAL(propertyChanged(int, QByteArray,QVariant)),
+            m_propertyInspector, SLOT(propertyValueChanged(int, QByteArray,QVariant)));
+    connect(m_propertyInspector, SIGNAL(changePropertyValue(int,QString,QString)),
+            this, SLOT(changePropertyValue(int,QString,QString)));
+    connect(m_clientProxy,SIGNAL(objectTreeUpdated()),this,SLOT(objectTreeReady()));
 
     m_debugProject = ProjectExplorer::ProjectExplorerPlugin::instance()->startupProject();
     if (m_debugProject->activeTarget()
@@ -307,22 +317,34 @@ void InspectorUi::connected(ClientProxy *clientProxy)
     initializeDocuments();
 
     QHashIterator<QString, QmlJSLiveTextPreview *> iter(m_textPreviews);
-    while(iter.hasNext()) {
+    while (iter.hasNext()) {
         iter.next();
         iter.value()->setClientProxy(m_clientProxy);
         iter.value()->updateDebugIds();
     }
+
+
+}
+
+void InspectorUi::objectTreeReady()
+{
+    // Should only run once, after debugger startup
+    if (!m_clientProxy->rootObjectReference().isEmpty()) {
+        selectItems(m_clientProxy->rootObjectReference());
+        disconnect(m_clientProxy,SIGNAL(objectTreeUpdated()),this,SLOT(objectTreeReady()));
+    }
 }
 
 void InspectorUi::disconnected()
 {
     disconnect(m_clientProxy, SIGNAL(selectedItemsChanged(QList<QDeclarativeDebugObjectReference>)),
-               this, SLOT(gotoObjectReferenceDefinition(QList<QDeclarativeDebugObjectReference>)));
-
+               this, SLOT(selectItems(QList<QDeclarativeDebugObjectReference>)));
     disconnect(m_clientProxy, SIGNAL(enginesChanged()), this, SLOT(updateEngineList()));
     disconnect(m_clientProxy, SIGNAL(serverReloaded()), this, SLOT(serverReloaded()));
-    disconnect(m_clientProxy, SIGNAL(contextPathUpdated(QStringList)),
-               m_crumblePath, SLOT(updateContextPath(QStringList)));
+    disconnect(m_clientProxy, SIGNAL(propertyChanged(int, QByteArray,QVariant)),
+               m_propertyInspector, SLOT(propertyValueChanged(int, QByteArray,QVariant)));
+    disconnect(m_propertyInspector, SIGNAL(changePropertyValue(int,QString,QString)),
+               this, SLOT(changePropertyValue(int,QString,QString)));
 
     m_debugProject = 0;
     m_qmlEngine = 0;
@@ -332,12 +354,12 @@ void InspectorUi::disconnected()
     applyChangesToQmlObserverHelper(false);
 
     QHashIterator<QString, QmlJSLiveTextPreview *> iter(m_textPreviews);
-    while(iter.hasNext()) {
+    while (iter.hasNext()) {
         iter.next();
         iter.value()->setClientProxy(0);
     }
     m_clientProxy = 0;
-    m_objectTreeWidget->clear();
+    m_propertyInspector->clear();
     m_pendingPreviewDocumentNames.clear();
 }
 
@@ -357,19 +379,20 @@ void InspectorUi::updateEngineList()
 
 void InspectorUi::changeSelectedItems(const QList<QDeclarativeDebugObjectReference> &objects)
 {
-    if (m_lastSelectedDebugId >= 0) {
-        foreach (const QDeclarativeDebugObjectReference &ref, objects) {
-            if (ref.debugId() == m_lastSelectedDebugId) {
-                // this is only the 'call back' after we have programatically set a new cursor
-                // position in
-                m_lastSelectedDebugId = -1;
-                return;
-            }
-        }
-        m_lastSelectedDebugId = -1;
+    if (m_selectionCallbackExpected) {
+        m_selectionCallbackExpected = false;
+        return;
+    }
+
+    // QmlJSLiveTextPreview doesn't provide valid references, only correct debugIds. We need to remap them
+    QList <QDeclarativeDebugObjectReference> realList;
+    foreach (const QDeclarativeDebugObjectReference &obj, objects) {
+        QDeclarativeDebugObjectReference clientRef = m_clientProxy->objectReferenceForId(obj.debugId());
+        realList <<  clientRef;
     }
 
-    m_clientProxy->setSelectedItemsByObjectId(objects);
+    m_clientProxy->setSelectedItemsByObjectId(realList);
+    selectItems(realList);
 }
 
 void InspectorUi::initializeDocuments()
@@ -474,7 +497,8 @@ void InspectorUi::currentDebugProjectRemoved()
 
 void InspectorUi::resetViews()
 {
-    m_crumblePath->updateContextPath(QStringList());
+    m_propertyInspector->clear();
+    m_crumblePath->clear();
 }
 
 void InspectorUi::reloadQmlViewer()
@@ -483,31 +507,170 @@ void InspectorUi::reloadQmlViewer()
         m_clientProxy->reloadQmlViewer();
 }
 
-void InspectorUi::gotoObjectReferenceDefinition(QList<QDeclarativeDebugObjectReference>
-                                                objectReferences)
+inline QDeclarativeDebugObjectReference findParentRecursive( int goalDebugId,
+                                                            const QList< QDeclarativeDebugObjectReference > &objectsToSearch)
+{
+    if (goalDebugId == -1)
+        return QDeclarativeDebugObjectReference();
+
+    foreach (const QDeclarativeDebugObjectReference &possibleParent, objectsToSearch) {
+        // Am I a root object? No parent
+        if ( possibleParent.debugId() == goalDebugId )
+            return QDeclarativeDebugObjectReference();
+
+        // Is the goal one of my children?
+        foreach (const QDeclarativeDebugObjectReference &child, possibleParent.children())
+            if ( child.debugId() == goalDebugId )
+                return possibleParent;
+
+        // no luck? pass this on
+        QDeclarativeDebugObjectReference candidate = findParentRecursive(goalDebugId, possibleParent.children());
+        if (candidate.debugId() != -1)
+            return candidate;
+    }
+
+    return QDeclarativeDebugObjectReference();
+}
+
+void InspectorUi::selectItems(const QList<QDeclarativeDebugObjectReference> &objectReferences)
 {
-    if (objectReferences.length())
-        gotoObjectReferenceDefinition(objectReferences.first());
+    foreach (const QDeclarativeDebugObjectReference &objref, objectReferences)
+        if (objref.debugId() != -1) {
+            // select only the first valid element of the list
+
+            m_clientProxy->removeAllObjectWatches();
+            m_clientProxy->addObjectWatch(objref.debugId());
+            QList <QDeclarativeDebugObjectReference> selectionList;
+            selectionList << objref;
+            m_propertyInspector->setCurrentObjects(selectionList);
+            populateCrumblePath(objref);
+            gotoObjectReferenceDefinition(objref);
+            return;
+        }
+
+    // empty list
+    m_propertyInspector->clear();
+    m_crumblePath->clear();
+}
+
+inline QString displayName(const QDeclarativeDebugObjectReference &obj)
+{
+    // special! state names
+    if (obj.className() == "State") {
+        foreach (const QDeclarativeDebugPropertyReference &prop, obj.properties()) {
+            if (prop.name() == "name")
+                return prop.value().toString();
+        }
+    }
+
+    // has id?
+    if (!obj.idString().isEmpty())
+        return obj.idString();
+
+    // return the simplified class name then
+    QString objTypeName = obj.className();
+    QString declarativeString("QDeclarative");
+    if (objTypeName.startsWith(declarativeString)) {
+        objTypeName = objTypeName.mid(declarativeString.length()).section('_',0,0);
+    }
+    return QString("<%1>").arg(objTypeName);
+}
+
+bool InspectorUi::isRoot(const QDeclarativeDebugObjectReference &obj) const
+{
+    foreach (const QDeclarativeDebugObjectReference &rootObj, m_clientProxy->rootObjectReference())
+        if (obj.debugId() == rootObj.debugId())
+            return true;
+    return false;
+}
+
+void InspectorUi::populateCrumblePath(const QDeclarativeDebugObjectReference &objRef)
+{
+    QStringList crumbleStrings;
+    QList <int> crumbleData;
+
+    // first find path by climbing the hierarchy
+    QDeclarativeDebugObjectReference ref = objRef;
+    crumbleData << objRef.debugId();
+    crumbleStrings << displayName(objRef);
+
+    while ((!isRoot(ref)) && (ref.debugId()!=-1)) {
+        ref = findParentRecursive(ref.debugId(), m_clientProxy->rootObjectReference());
+        crumbleData.push_front( ref.debugId() );
+        crumbleStrings.push_front( displayName(ref) );
+    }
+
+    int itemIndex = crumbleData.length()-1;
+
+    // now append the children
+    foreach (const QDeclarativeDebugObjectReference &child, objRef.children()) {
+        crumbleData.push_back(child.debugId());
+        crumbleStrings.push_back( displayName(child) );
+    }
+
+    m_crumblePath->updateContextPath(crumbleStrings, crumbleData);
+    m_crumblePath->selectIndex(itemIndex);
+}
+
+void InspectorUi::selectItems(const QList<int> &objectIds)
+{
+    QList<QDeclarativeDebugObjectReference> objectReferences;
+    foreach (int objectId, objectIds)
+    {
+        QDeclarativeDebugObjectReference ref = m_clientProxy->objectReferenceForId(objectId);
+        if (ref.debugId() == objectId)
+            objectReferences.append(ref);
+    }
+    if (objectReferences.length() > 0)
+        selectItems(objectReferences);
+}
+
+void InspectorUi::changePropertyValue(int debugId,const QString &propertyName, const QString &valueExpression)
+{
+    QString query = propertyName + '=' + valueExpression;
+    m_clientProxy->queryExpressionResult(debugId,query, this);
 }
 
 void InspectorUi::enable()
 {
     m_toolbar->enable();
     m_crumblePath->setEnabled(true);
-    m_objectTreeWidget->setEnabled(true);
+    m_propertyInspector->setEnabled(true);
 }
 
 void InspectorUi::disable()
 {
     m_toolbar->disable();
     m_crumblePath->setEnabled(false);
-    m_objectTreeWidget->setEnabled(false);
+    m_propertyInspector->setEnabled(false);
 }
 
-void InspectorUi::gotoObjectReferenceDefinition(const QDeclarativeDebugObjectReference &obj)
+QDeclarativeDebugObjectReference InspectorUi::objectReferenceForLocation(const QString &fileName, int cursorPosition) const
 {
-    Q_UNUSED(obj);
+    Core::EditorManager *editorManager = Core::EditorManager::instance();
+    Core::IEditor *editor = editorManager->openEditor(fileName);
+    TextEditor::ITextEditor *textEditor = qobject_cast<TextEditor::ITextEditor*>(editor);
+
+    if (textEditor && m_clientProxy && textEditor->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID) {
+        if (cursorPosition == -1)
+            cursorPosition = textEditor->position();
+        QmlJSEditor::QmlJSTextEditor *qmlEditor =
+                static_cast<QmlJSEditor::QmlJSTextEditor*>(textEditor->widget());
+
+        if (QmlJS::AST::Node *node
+                = qmlEditor->semanticInfo().declaringMemberNoProperties(cursorPosition)) {
+            if (QmlJS::AST::UiObjectMember *objMember = node->uiObjectMemberCast()) {
+                return m_clientProxy->objectReferenceForLocation(
+                            objMember->firstSourceLocation().startLine,
+                            objMember->firstSourceLocation().startColumn);
+            }
+        }
+    }
+    return QDeclarativeDebugObjectReference();
+}
 
+void InspectorUi::gotoObjectReferenceDefinition(const QDeclarativeDebugObjectReference &obj)
+{
     QDeclarativeDebugFileReference source = obj.source();
     QString fileName = source.url().toLocalFile();
 
@@ -521,11 +684,14 @@ void InspectorUi::gotoObjectReferenceDefinition(const QDeclarativeDebugObjectRef
     TextEditor::ITextEditor *textEditor = qobject_cast<TextEditor::ITextEditor*>(editor);
 
     if (textEditor) {
-        m_lastSelectedDebugId = obj.debugId();
-
-        editorManager->addCurrentPositionToNavigationHistory();
-        textEditor->gotoLine(source.lineNumber());
-        textEditor->widget()->setFocus();
+        QDeclarativeDebugObjectReference ref = objectReferenceForLocation(fileName);
+        if (ref.debugId() != obj.debugId())
+        {
+            m_selectionCallbackExpected = true;
+            editorManager->addCurrentPositionToNavigationHistory();
+            textEditor->gotoLine(source.lineNumber());
+            textEditor->widget()->setFocus();
+        }
     }
 }
 
@@ -553,7 +719,7 @@ void InspectorUi::setupDockWidgets()
     m_crumblePath->setWindowTitle(tr("Context Path"));
     connect(m_crumblePath, SIGNAL(elementClicked(int)), SLOT(crumblePathElementClicked(int)));
 
-    m_objectTreeWidget = new QmlJSObjectTree;
+    m_propertyInspector = new QmlJSPropertyInspector;
 
     QWidget *observerWidget = new QWidget;
     observerWidget->setWindowTitle(tr("QML Observer"));
@@ -564,7 +730,7 @@ void InspectorUi::setupDockWidgets()
     wlay->setSpacing(0);
     observerWidget->setLayout(wlay);
     wlay->addWidget(m_toolbar->widget());
-    wlay->addWidget(m_objectTreeWidget);
+    wlay->addWidget(m_propertyInspector);
     wlay->addWidget(m_crumblePath);
 
     Debugger::DebuggerMainWindow *mw = Debugger::DebuggerPlugin::mainWindow();
@@ -575,9 +741,9 @@ void InspectorUi::setupDockWidgets()
 
 void InspectorUi::crumblePathElementClicked(int pathIndex)
 {
-    if (m_clientProxy && m_clientProxy->isConnected() && !m_crumblePath->isEmpty()) {
-        m_clientProxy->setContextPathIndex(pathIndex);
-    }
+    QList <int> l;
+    l << m_crumblePath->debugIdForIndex(pathIndex);
+    selectItems(l);
 }
 
 bool InspectorUi::showExperimentalWarning()
@@ -623,7 +789,7 @@ void InspectorUi::setApplyChangesToQmlObserver(bool applyChanges)
 void InspectorUi::applyChangesToQmlObserverHelper(bool applyChanges)
 {
     QHashIterator<QString, QmlJSLiveTextPreview *> iter(m_textPreviews);
-    while(iter.hasNext()) {
+    while (iter.hasNext()) {
         iter.next();
         iter.value()->setApplyChangesToQmlObserver(applyChanges);
     }
@@ -648,7 +814,7 @@ void InspectorUi::updatePendingPreviewDocuments(QmlJS::Document::Ptr doc)
     QmlJSLiveTextPreview *preview = createPreviewForEditor(editors.first());
     editors.removeFirst();
 
-    foreach(Core::IEditor *editor, editors) {
+    foreach (Core::IEditor *editor, editors) {
         preview->associateEditor(editor);
     }
 }
@@ -682,7 +848,8 @@ void InspectorUi::setupToolbar(bool doConnect)
                 this, SLOT(setApplyChangesToQmlObserver(bool)));
         connect(m_toolbar, SIGNAL(showAppOnTopSelected(bool)),
                 m_clientProxy, SLOT(showAppOnTop(bool)));
-
+        connect(m_toolbar, SIGNAL(filterTextChanged(QString)),
+                m_propertyInspector,SLOT(filterBy(QString)));
         connect(m_clientProxy, SIGNAL(colorPickerActivated()),
                 m_toolbar, SLOT(activateColorPicker()));
         connect(m_clientProxy, SIGNAL(selectToolActivated()),
@@ -720,7 +887,8 @@ void InspectorUi::setupToolbar(bool doConnect)
                    this, SLOT(setApplyChangesToQmlObserver(bool)));
         disconnect(m_toolbar, SIGNAL(showAppOnTopSelected(bool)),
                    m_clientProxy, SLOT(showAppOnTop(bool)));
-
+        disconnect(m_toolbar, SIGNAL(filterTextChanged(QString)),
+                   m_propertyInspector,SLOT(filterBy(QString)));
         disconnect(m_clientProxy, SIGNAL(colorPickerActivated()),
                    m_toolbar, SLOT(activateColorPicker()));
         disconnect(m_clientProxy, SIGNAL(selectToolActivated()),
diff --git a/src/plugins/qmljsinspector/qmljsinspector.h b/src/plugins/qmljsinspector/qmljsinspector.h
index 7d3940e233d..c890ce53715 100644
--- a/src/plugins/qmljsinspector/qmljsinspector.h
+++ b/src/plugins/qmljsinspector/qmljsinspector.h
@@ -67,7 +67,7 @@ namespace QmlJSInspector {
 namespace Internal {
 
 class QmlInspectorToolbar;
-class QmlJSObjectTree;
+class QmlJSPropertyInspector;
 class ClientProxy;
 class InspectorSettings;
 class ContextCrumblePath;
@@ -120,8 +120,11 @@ private slots:
     void enable();
     void disable();
     void gotoObjectReferenceDefinition(const QDeclarativeDebugObjectReference &obj);
-    void gotoObjectReferenceDefinition(QList<QDeclarativeDebugObjectReference> objectReferences);
+    void selectItems(const QList<QDeclarativeDebugObjectReference> &objectReferences);
+    void selectItems(const QList<int> &objectIds);
     void changeSelectedItems(const QList<QDeclarativeDebugObjectReference> &objects);
+    void changePropertyValue(int debugId,const QString &propertyName, const QString &valueExpression);
+    void objectTreeReady();
 
     void updateEngineList();
 
@@ -146,19 +149,20 @@ private:
     void setupToolbar(bool doConnect);
     void setupDockWidgets();
     QString filenameForShadowBuildFile(const QString &filename) const;
+    void populateCrumblePath(const QDeclarativeDebugObjectReference &objRef);
+    bool isRoot(const QDeclarativeDebugObjectReference &obj) const;
+    QDeclarativeDebugObjectReference objectReferenceForLocation(const QString &fileName, int cursorPosition=-1) const;
 
 private:
     bool m_listeningToEditorManager;
-
     QmlInspectorToolbar *m_toolbar;
     ContextCrumblePath *m_crumblePath;
-    QmlJSObjectTree *m_objectTreeWidget;
+    QmlJSPropertyInspector *m_propertyInspector;
 
     InspectorSettings *m_settings;
     ClientProxy *m_clientProxy;
     QObject *m_qmlEngine;
     QDeclarativeDebugExpressionQuery *m_debugQuery;
-    int m_lastSelectedDebugId;
 
     // Qml/JS integration
     QHash<QString, QmlJSLiveTextPreview *> m_textPreviews;
@@ -172,6 +176,7 @@ private:
     Utils::FileInProjectFinder m_projectFinder;
 
     static InspectorUi *m_instance;
+    bool m_selectionCallbackExpected;
 };
 
 } // Internal
diff --git a/src/plugins/qmljsinspector/qmljsinspector.pro b/src/plugins/qmljsinspector/qmljsinspector.pro
index 61e71483f3c..6459785bdb8 100644
--- a/src/plugins/qmljsinspector/qmljsinspector.pro
+++ b/src/plugins/qmljsinspector/qmljsinspector.pro
@@ -19,7 +19,7 @@ qmljstoolbarcolorbox.h \
 qmljsobserverclient.h \
 qmljscontextcrumblepath.h \
 qmljsinspectorsettings.h \
-qmljsobjecttree.h
+qmljspropertyinspector.h
 
 SOURCES += \
 qmljsinspectorplugin.cpp \
@@ -31,7 +31,7 @@ qmljstoolbarcolorbox.cpp \
 qmljsobserverclient.cpp \
 qmljscontextcrumblepath.cpp \
 qmljsinspectorsettings.cpp \
-qmljsobjecttree.cpp
+qmljspropertyinspector.cpp
 
 include(../../libs/qmljsdebugclient/qmljsdebugclient-lib.pri)
 
diff --git a/src/plugins/qmljsinspector/qmljsobjecttree.cpp b/src/plugins/qmljsinspector/qmljsobjecttree.cpp
deleted file mode 100644
index 937c6c2ffcc..00000000000
--- a/src/plugins/qmljsinspector/qmljsobjecttree.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** No Commercial Usage
-**
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**************************************************************************/
-#include "qmljsobjecttree.h"
-
-#include <QContextMenuEvent>
-#include <QEvent>
-#include <QtGui/QMenu>
-#include <QtGui/QAction>
-#include <QApplication>
-#include <QInputDialog>
-
-#include <QDebug>
-
-namespace QmlJSInspector {
-namespace Internal {
-
-// *************************************************************************
-//  ObjectTreeItem
-// *************************************************************************
-
-class ObjectTreeItem : public QTreeWidgetItem
-{
-public:
-    explicit ObjectTreeItem(QTreeWidget *widget, int type = 0);
-    ObjectTreeItem(QTreeWidgetItem *parentItem, int type = 0);
-    QVariant data (int column, int role) const;
-    void setData (int column, int role, const QVariant & value);
-
-    void setHasValidDebugId(bool value);
-
-
-private:
-    bool m_hasValidDebugId;
-};
-
-ObjectTreeItem::ObjectTreeItem(QTreeWidget *widget, int type) :
-    QTreeWidgetItem(widget, type), m_hasValidDebugId(true)
-{
-
-}
-
-ObjectTreeItem::ObjectTreeItem(QTreeWidgetItem *parentItem, int type) :
-    QTreeWidgetItem(parentItem, type), m_hasValidDebugId(true)
-{
-
-}
-
-QVariant ObjectTreeItem::data (int column, int role) const
-{
-    if (role == Qt::ForegroundRole)
-        return m_hasValidDebugId ? qApp->palette().color(QPalette::Foreground) : qApp->palette().color(QPalette::Disabled, QPalette::Foreground);
-
-    return QTreeWidgetItem::data(column, role);
-}
-
-void ObjectTreeItem::setData (int column, int role, const QVariant & value)
-{
-    QTreeWidgetItem::setData(column, role, value);
-}
-
-void ObjectTreeItem::setHasValidDebugId(bool value)
-{
-    m_hasValidDebugId = value;
-}
-
-// *************************************************************************
-//  QmlJSObjectTree
-// *************************************************************************
-
-QmlJSObjectTree::QmlJSObjectTree(QWidget *parent)
-    : QTreeWidget(parent)
-    , m_clickedItem(0)
-    , m_currentObjectDebugId(0)
-{
-    setAttribute(Qt::WA_MacShowFocusRect, false);
-    setFrameStyle(QFrame::NoFrame);
-    setHeaderHidden(true);
-    setExpandsOnDoubleClick(false);
-
-    m_goToFileAction = new QAction(tr("Go to file"), this);
-    connect(m_goToFileAction, SIGNAL(triggered()), SLOT(goToFile()));
-
-    connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
-            SLOT(currentItemChanged(QTreeWidgetItem *)));
-    connect(this, SIGNAL(itemActivated(QTreeWidgetItem *, int)),
-            SLOT(activated(QTreeWidgetItem *)));
-    connect(this, SIGNAL(itemSelectionChanged()), SLOT(selectionChanged()));
-}
-
-void QmlJSObjectTree::selectionChanged()
-{
-    if (selectedItems().isEmpty())
-        return;
-
-    // TODO
-}
-
-void QmlJSObjectTree::setCurrentObject(int debugId)
-{
-    QTreeWidgetItem *item = findItemByObjectId(debugId);
-    if (item) {
-        setCurrentItem(item);
-        scrollToItem(item);
-        item->setExpanded(true);
-    }
-}
-
-void QmlJSObjectTree::currentItemChanged(QTreeWidgetItem *item)
-{
-    if (!item)
-        return;
-
-    QDeclarativeDebugObjectReference obj = item->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>();
-    if (obj.debugId() >= 0)
-        emit currentObjectChanged(obj);
-}
-
-void QmlJSObjectTree::activated(QTreeWidgetItem *item)
-{
-    if (!item)
-        return;
-
-    QDeclarativeDebugObjectReference obj = item->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>();
-    if (obj.debugId() >= 0)
-        emit activated(obj);
-}
-
-void QmlJSObjectTree::buildTree(const QDeclarativeDebugObjectReference &obj, QTreeWidgetItem *parent)
-{
-    if (!parent)
-        clear();
-
-    if (obj.contextDebugId() < 0)
-        return;
-
-    ObjectTreeItem *item = parent ? new ObjectTreeItem(parent) : new ObjectTreeItem(this);
-    if (obj.idString().isEmpty())
-        item->setText(0, QString("<%1>").arg(obj.className()));
-    else
-        item->setText(0, obj.idString());
-    item->setData(0, Qt::UserRole, qVariantFromValue(obj));
-
-    if (parent && obj.contextDebugId() >= 0
-            && obj.contextDebugId() != parent->data(0, Qt::UserRole
-                    ).value<QDeclarativeDebugObjectReference>().contextDebugId())
-    {
-
-        QDeclarativeDebugFileReference source = obj.source();
-        if (!source.url().isEmpty()) {
-            QString toolTipString = tr("Url: ") + source.url().toString();
-            item->setToolTip(0, toolTipString);
-        }
-    } else {
-        item->setExpanded(true);
-    }
-
-    if (obj.contextDebugId() < 0)
-        item->setHasValidDebugId(false);
-
-    for (int ii = 0; ii < obj.children().count(); ++ii)
-        buildTree(obj.children().at(ii), item);
-}
-
-QTreeWidgetItem *QmlJSObjectTree::findItemByObjectId(int debugId) const
-{
-    for (int i=0; i<topLevelItemCount(); ++i) {
-        QTreeWidgetItem *item = findItem(topLevelItem(i), debugId);
-        if (item)
-            return item;
-    }
-
-    return 0;
-}
-
-QTreeWidgetItem *QmlJSObjectTree::findItem(QTreeWidgetItem *item, int debugId) const
-{
-    if (item->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>().debugId() == debugId)
-        return item;
-
-    QTreeWidgetItem *child;
-    for (int i=0; i<item->childCount(); ++i) {
-        child = findItem(item->child(i), debugId);
-        if (child)
-            return child;
-    }
-
-    return 0;
-}
-
-void QmlJSObjectTree::goToFile()
-{
-    QDeclarativeDebugObjectReference obj =
-            currentItem()->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>();
-
-    if (obj.debugId() >= 0)
-        emit activated(obj);
-}
-
-void QmlJSObjectTree::contextMenuEvent(QContextMenuEvent *event)
-{
-    m_clickedItem = itemAt(QPoint(event->pos().x(),
-                                  event->pos().y() ));
-    if (!m_clickedItem)
-        return;
-
-    QMenu menu;
-    menu.addAction(m_goToFileAction);
-    menu.exec(event->globalPos());
-}
-
-} // Internal
-} // QmlJSInspector
diff --git a/src/plugins/qmljsinspector/qmljsobjecttree.h b/src/plugins/qmljsinspector/qmljsobjecttree.h
deleted file mode 100644
index 3864903b14c..00000000000
--- a/src/plugins/qmljsinspector/qmljsobjecttree.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** No Commercial Usage
-**
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**************************************************************************/
-#ifndef OBJECTTREE_H
-#define OBJECTTREE_H
-
-#include <qmljsprivateapi.h>
-#include <QtGui/QTreeWidget>
-
-QT_BEGIN_NAMESPACE
-
-class QTreeWidgetItem;
-
-QT_END_NAMESPACE
-
-namespace QmlJSInspector {
-namespace Internal {
-
-class QmlJSObjectTree : public QTreeWidget
-{
-    Q_OBJECT
-public:
-    QmlJSObjectTree(QWidget *parent = 0);
-
-signals:
-    void currentObjectChanged(const QDeclarativeDebugObjectReference &);
-    void activated(const QDeclarativeDebugObjectReference &);
-    void expressionWatchRequested(const QDeclarativeDebugObjectReference &, const QString &);
-    void contextHelpIdChanged(const QString &contextHelpId);
-
-public slots:
-    void setCurrentObject(int debugId); // select an object in the tree
-
-protected:
-    virtual void contextMenuEvent(QContextMenuEvent *);
-
-private slots:
-    void currentItemChanged(QTreeWidgetItem *);
-    void activated(QTreeWidgetItem *);
-    void selectionChanged();
-    void goToFile();
-
-private:
-    QTreeWidgetItem *findItemByObjectId(int debugId) const;
-    QTreeWidgetItem *findItem(QTreeWidgetItem *item, int debugId) const;
-    void buildTree(const QDeclarativeDebugObjectReference &, QTreeWidgetItem *parent);
-
-    QTreeWidgetItem *m_clickedItem;
-    QAction *m_addWatchAction;
-    QAction *m_goToFileAction;
-    int m_currentObjectDebugId;
-};
-
-} // Internal
-} // QmlJSInspector
-
-#endif
-- 
GitLab