From ae8a8a5c8453deab9cd019e15c64eed658d7b7ba Mon Sep 17 00:00:00 2001
From: Lasse Holmstedt <lasse.holmstedt@nokia.com>
Date: Fri, 16 Apr 2010 10:20:01 +0200
Subject: [PATCH] UI fixes to QML inspector

---
 .../components/expressionquerywidget.cpp      |  4 +-
 .../components/objectpropertiesview.cpp       | 62 +++++++++++++++++--
 .../components/objectpropertiesview.h         | 16 ++++-
 .../qmlinspector/components/watchtable.cpp    | 24 ++++++-
 .../qmlinspector/components/watchtable.h      |  5 +-
 src/plugins/qmlinspector/qmlinspector.cpp     | 42 ++++++-------
 src/plugins/qmlinspector/qmlinspector.h       |  1 +
 7 files changed, 119 insertions(+), 35 deletions(-)

diff --git a/src/plugins/qmlinspector/components/expressionquerywidget.cpp b/src/plugins/qmlinspector/components/expressionquerywidget.cpp
index 50a1c5d5169..9888980ef56 100644
--- a/src/plugins/qmlinspector/components/expressionquerywidget.cpp
+++ b/src/plugins/qmlinspector/components/expressionquerywidget.cpp
@@ -84,7 +84,7 @@ ExpressionQueryWidget::ExpressionQueryWidget(Mode mode, QDeclarativeEngineDebug
         Utils::StyledBar *bar = new Utils::StyledBar;
         m_lineEdit = new Utils::FilterLineEdit;
 
-        m_lineEdit->setPlaceholderText(tr("<Expression>"));
+        m_lineEdit->setPlaceholderText(tr("<Type expression to evaluate>"));
         m_lineEdit->setToolTip(tr("Write and evaluate QtScript expressions."));
 
         m_clearButton = new QToolButton();
@@ -119,7 +119,7 @@ void ExpressionQueryWidget::changeContextHelpId(const QString &)
 void ExpressionQueryWidget::clearTextEditor()
 {
     m_textEdit->clear();
-    m_textEdit->appendPlainText(tr("Debug Console\n"));
+    m_textEdit->appendPlainText(tr("Script Console\n"));
 }
 
 void ExpressionQueryWidget::setFontSettings()
diff --git a/src/plugins/qmlinspector/components/objectpropertiesview.cpp b/src/plugins/qmlinspector/components/objectpropertiesview.cpp
index 8c618227216..b1788258112 100644
--- a/src/plugins/qmlinspector/components/objectpropertiesview.cpp
+++ b/src/plugins/qmlinspector/components/objectpropertiesview.cpp
@@ -34,6 +34,9 @@
 #include <QtGui/QTreeWidget>
 #include <QtGui/QLayout>
 #include <QtGui/QHeaderView>
+#include <QtGui/QMenu>
+#include <QtGui/QContextMenuEvent>
+
 namespace Qml {
 namespace Internal {
 
@@ -68,7 +71,7 @@ ObjectPropertiesView::ObjectPropertiesView(QDeclarativeEngineDebug *client, QWid
     : QWidget(parent),
       m_client(client),
       m_query(0),
-      m_watch(0)
+      m_watch(0), m_clickedItem(0)
 {
     QVBoxLayout *layout = new QVBoxLayout;
     layout->setContentsMargins(0, 0, 0, 0);
@@ -83,9 +86,14 @@ ObjectPropertiesView::ObjectPropertiesView(QDeclarativeEngineDebug *client, QWid
     m_tree->setHeaderLabels(QStringList()
             << tr("Name") << tr("Value") << tr("Type"));
     QObject::connect(m_tree, SIGNAL(itemActivated(QTreeWidgetItem *, int)),
-                     this, SLOT(itemActivated(QTreeWidgetItem *)));
+                     this, SLOT(itemDoubleClicked(QTreeWidgetItem *, int)));
     connect(m_tree, SIGNAL(itemSelectionChanged()), SLOT(changeItemSelection()));
 
+    m_addWatchAction = new QAction(tr("Watch expression"), this);
+    m_removeWatchAction = new QAction(tr("Remove watch"), this);
+    connect(m_addWatchAction, SIGNAL(triggered()), SLOT(addWatch()));
+    connect(m_removeWatchAction, SIGNAL(triggered()), SLOT(removeWatch()));
+
     m_tree->setColumnCount(3);
     m_tree->header()->setDefaultSectionSize(150);
 
@@ -250,6 +258,11 @@ void ObjectPropertiesView::setWatched(const QString &property, bool watched)
     }
 }
 
+bool ObjectPropertiesView::isWatched(QTreeWidgetItem *item)
+{
+    return item->font(0).bold();
+}
+
 void ObjectPropertiesView::valueChanged(const QByteArray &name, const QVariant &value)
 {
     for (int i=0; i<m_tree->topLevelItemCount(); ++i) {
@@ -261,14 +274,51 @@ void ObjectPropertiesView::valueChanged(const QByteArray &name, const QVariant &
     }
 }
 
-void ObjectPropertiesView::itemActivated(QTreeWidgetItem *i)
+void ObjectPropertiesView::itemDoubleClicked(QTreeWidgetItem *item, int /*column*/)
 {
-    PropertiesViewItem *item = static_cast<PropertiesViewItem *>(i);
-    if (!item->property.name().isEmpty())
-        emit activated(m_object, item->property);
+    toggleWatch(item);
 }
 
+void ObjectPropertiesView::addWatch()
+{
+    toggleWatch(m_clickedItem);
+}
+void ObjectPropertiesView::removeWatch()
+{
+    toggleWatch(m_clickedItem);
+}
+
+void ObjectPropertiesView::toggleWatch(QTreeWidgetItem *item)
+{
+    if (!item)
+        return;
+
+    PropertiesViewItem *propItem = static_cast<PropertiesViewItem *>(item);
+    if (!propItem->property.name().isEmpty())
+        emit watchToggleRequested(m_object, propItem->property);
 }
+
+void ObjectPropertiesView::contextMenuEvent(QContextMenuEvent *event)
+{
+    m_clickedItem = m_tree->itemAt(QPoint(event->pos().x(),
+                                          event->pos().y() - m_tree->header()->height()));
+    if (!m_clickedItem)
+        return;
+
+    PropertiesViewItem *propItem = static_cast<PropertiesViewItem *>(m_clickedItem);
+
+    QMenu menu;
+    if (!isWatched(m_clickedItem)) {
+        m_addWatchAction->setText(tr("Watch expression '%1'").arg(propItem->property.name()));
+        menu.addAction(m_addWatchAction);
+    } else {
+        menu.addAction(m_removeWatchAction);
+    }
+
+    menu.exec(event->globalPos());
 }
 
+} // Internal
+} // Qml
+
 #include "objectpropertiesview.moc"
diff --git a/src/plugins/qmlinspector/components/objectpropertiesview.h b/src/plugins/qmlinspector/components/objectpropertiesview.h
index 8cd3a7decd6..68d9585116c 100644
--- a/src/plugins/qmlinspector/components/objectpropertiesview.h
+++ b/src/plugins/qmlinspector/components/objectpropertiesview.h
@@ -56,22 +56,30 @@ public:
     void clear();
 
 signals:
-    void activated(const QDeclarativeDebugObjectReference &, const QDeclarativeDebugPropertyReference &);
+    void watchToggleRequested(const QDeclarativeDebugObjectReference &, const QDeclarativeDebugPropertyReference &);
     void contextHelpIdChanged(const QString &contextHelpId);
 
 public slots:
     void reload(const QDeclarativeDebugObjectReference &);
     void watchCreated(QDeclarativeDebugWatch *);
 
+protected:
+    void contextMenuEvent(QContextMenuEvent *);
+
 private slots:
     void changeItemSelection();
     void queryFinished();
     void watchStateChanged();
     void valueChanged(const QByteArray &name, const QVariant &value);
-    void itemActivated(QTreeWidgetItem *i);
+    void itemDoubleClicked(QTreeWidgetItem *i, int column);
+
+    void addWatch();
+    void removeWatch();
 
 private:
+    void toggleWatch(QTreeWidgetItem *item);
     void setObject(const QDeclarativeDebugObjectReference &object);
+    bool isWatched(QTreeWidgetItem *item);
     void setWatched(const QString &property, bool watched);
     void setPropertyValue(PropertiesViewItem *item, const QVariant &value, bool makeGray);
 
@@ -79,6 +87,10 @@ private:
     QDeclarativeDebugObjectQuery *m_query;
     QDeclarativeDebugWatch *m_watch;
 
+    QAction *m_addWatchAction;
+    QAction *m_removeWatchAction;
+    QTreeWidgetItem *m_clickedItem;
+
     QTreeWidget *m_tree;
     QDeclarativeDebugObjectReference m_object;
 };
diff --git a/src/plugins/qmlinspector/components/watchtable.cpp b/src/plugins/qmlinspector/components/watchtable.cpp
index a765f86b709..74b61da3d8c 100644
--- a/src/plugins/qmlinspector/components/watchtable.cpp
+++ b/src/plugins/qmlinspector/components/watchtable.cpp
@@ -94,6 +94,7 @@ void WatchTableModel::removeWatch(QDeclarativeDebugWatch *watch)
     m_entities.takeAt(column);
 
     reset();
+    emit watchRemoved();
 }
 
 void WatchTableModel::updateWatch(QDeclarativeDebugWatch *watch, const QVariant &value)
@@ -274,6 +275,7 @@ void WatchTableModel::removeAllWatches()
     }
     m_entities.clear();
     reset();
+    emit watchRemoved();
 }
 
 //----------------------------------------------
@@ -303,7 +305,7 @@ WatchTableView::WatchTableView(WatchTableModel *model, QWidget *parent)
     setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);
     setFrameStyle(QFrame::NoFrame);
 
-
+    connect(model, SIGNAL(watchRemoved()), SLOT(watchRemoved()));
     connect(model, SIGNAL(watchCreated(QDeclarativeDebugWatch*)), SLOT(watchCreated(QDeclarativeDebugWatch*)));
     connect(this, SIGNAL(activated(QModelIndex)), SLOT(indexActivated(QModelIndex)));
 }
@@ -320,6 +322,9 @@ void WatchTableView::watchCreated(QDeclarativeDebugWatch *watch)
     int row = m_model->rowForWatch(watch);
     resizeRowToContents(row);
     resizeColumnToContents(C_NAME);
+
+    if (!isVisible())
+        show();
 }
 
 void WatchTableView::mousePressEvent(QMouseEvent *me)
@@ -332,12 +337,27 @@ void WatchTableView::mousePressEvent(QMouseEvent *me)
             QAction action(tr("Stop watching"), 0);
             QList<QAction *> actions;
             actions << &action;
-            if (QMenu::exec(actions, me->globalPos()))
+            if (QMenu::exec(actions, me->globalPos())) {
                 m_model->removeWatchAt(row);
+                hideIfEmpty();
+            }
         }
     }
 }
 
+void WatchTableView::hideIfEmpty()
+{
+    if (m_model->rowCount() == 0) {
+        hide();
+    } else if (!isVisible())
+        show();
+}
+
+void WatchTableView::watchRemoved()
+{
+    hideIfEmpty();
+}
+
 
 } // Internal
 } // Qml
diff --git a/src/plugins/qmlinspector/components/watchtable.h b/src/plugins/qmlinspector/components/watchtable.h
index e38f89c3e92..3ec7583e951 100644
--- a/src/plugins/qmlinspector/components/watchtable.h
+++ b/src/plugins/qmlinspector/components/watchtable.h
@@ -74,6 +74,7 @@ public:
 
 signals:
     void watchCreated(QDeclarativeDebugWatch *watch);
+    void watchRemoved();
 
 public slots:
     void togglePropertyWatch(const QDeclarativeDebugObjectReference &obj, const QDeclarativeDebugPropertyReference &prop);
@@ -130,7 +131,9 @@ protected:
 private slots:
     void indexActivated(const QModelIndex &index);
     void watchCreated(QDeclarativeDebugWatch *watch);
-
+    void watchRemoved();
+private:
+    void hideIfEmpty();
 private:
     WatchTableModel *m_model;
 };
diff --git a/src/plugins/qmlinspector/qmlinspector.cpp b/src/plugins/qmlinspector/qmlinspector.cpp
index 7929cdce92f..be333299cdb 100644
--- a/src/plugins/qmlinspector/qmlinspector.cpp
+++ b/src/plugins/qmlinspector/qmlinspector.cpp
@@ -185,9 +185,9 @@ QmlInspector::QmlInspector(QObject *parent)
     m_objectTreeWidget = new Internal::ObjectTree;
     m_propertiesWidget = new Internal::ObjectPropertiesView;
     m_watchTableView = new Internal::WatchTableView(m_watchTableModel);
+    m_expressionWidget = new Internal::ExpressionQueryWidget(Internal::ExpressionQueryWidget::SeparateEntryMode);
 //    m_frameRateWidget = new Internal::CanvasFrameRate;
 //    m_frameRateWidget->setObjectName(QLatin1String("QmlDebugFrameRate"));
-    m_expressionWidget = new Internal::ExpressionQueryWidget(Internal::ExpressionQueryWidget::SeparateEntryMode);
 
     connect(m_connectionTimer, SIGNAL(timeout()), SLOT(pollInspector()));
 }
@@ -383,7 +383,7 @@ void QmlInspector::createDockWidgets()
     connect(m_objectTreeWidget, SIGNAL(expressionWatchRequested(QDeclarativeDebugObjectReference,QString)),
             m_watchTableModel, SLOT(expressionWatchRequested(QDeclarativeDebugObjectReference,QString)));
 
-    connect(m_propertiesWidget, SIGNAL(activated(QDeclarativeDebugObjectReference,QDeclarativeDebugPropertyReference)),
+    connect(m_propertiesWidget, SIGNAL(watchToggleRequested(QDeclarativeDebugObjectReference,QDeclarativeDebugPropertyReference)),
             m_watchTableModel, SLOT(togglePropertyWatch(QDeclarativeDebugObjectReference,QDeclarativeDebugPropertyReference)));
 
     connect(m_watchTableModel, SIGNAL(watchCreated(QDeclarativeDebugWatch*)),
@@ -399,42 +399,39 @@ void QmlInspector::createDockWidgets()
             m_expressionWidget, SLOT(setCurrentObject(QDeclarativeDebugObjectReference)));
 
 
-    Core::MiniSplitter *leftSplitter = new Core::MiniSplitter(Qt::Vertical);
-    leftSplitter->addWidget(m_propertiesWidget);
-    leftSplitter->addWidget(m_watchTableView);
-    leftSplitter->setStretchFactor(0, 2);
-    leftSplitter->setStretchFactor(1, 1);
-
-    Core::MiniSplitter *propSplitter = new Core::MiniSplitter(Qt::Horizontal);
-    propSplitter->setObjectName(QLatin1String("QmlDebugProperties"));
-    propSplitter->addWidget(leftSplitter);
-    propSplitter->addWidget(m_expressionWidget);
+    Core::MiniSplitter *propSplitter = new Core::MiniSplitter(Qt::Vertical);
+    propSplitter->addWidget(m_propertiesWidget);
+    propSplitter->addWidget(m_watchTableView);
     propSplitter->setStretchFactor(0, 2);
     propSplitter->setStretchFactor(1, 1);
     propSplitter->setWindowTitle(tr("Properties and Watchers"));
-
-
+    propSplitter->setObjectName(QLatin1String("QmlDebugProperties"));
 
     InspectorOutputWidget *inspectorOutput = new InspectorOutputWidget();
     inspectorOutput->setObjectName(QLatin1String("QmlDebugInspectorOutput"));
     connect(this, SIGNAL(statusMessage(QString)),
             inspectorOutput, SLOT(addInspectorStatus(QString)));
 
-    m_objectTreeDock = Debugger::DebuggerUISwitcher::instance()->createDockWidget(Qml::Constants::LANG_QML,
+    Debugger::DebuggerUISwitcher *uiSwitcher = Debugger::DebuggerUISwitcher::instance();
+
+    m_watchTableView->hide();
+    m_objectTreeDock = uiSwitcher->createDockWidget(Qml::Constants::LANG_QML,
                                                             treeWindow, Qt::BottomDockWidgetArea);
-//    m_frameRateDock = Debugger::DebuggerUISwitcher::instance()->createDockWidget(Qml::Constants::LANG_QML,
+//    m_frameRateDock = uiSwitcher->createDockWidget(Qml::Constants::LANG_QML,
 //                                                            m_frameRateWidget, Qt::BottomDockWidgetArea);
-    m_propertyWatcherDock = Debugger::DebuggerUISwitcher::instance()->createDockWidget(Qml::Constants::LANG_QML,
+    m_propertyWatcherDock = uiSwitcher->createDockWidget(Qml::Constants::LANG_QML,
                                                             propSplitter, Qt::BottomDockWidgetArea);
-    m_inspectorOutputDock = Debugger::DebuggerUISwitcher::instance()->createDockWidget(Qml::Constants::LANG_QML,
+    m_inspectorOutputDock = uiSwitcher->createDockWidget(Qml::Constants::LANG_QML,
                                                             inspectorOutput, Qt::BottomDockWidgetArea);
 
-    m_objectTreeDock->setToolTip(tr("Contents of the scene."));
-//    m_frameRateDock->setToolTip(tr("Frame rate graph for analyzing performance."));
-    m_propertyWatcherDock->setToolTip(tr("Properties of the selected item."));
+    m_expressionWidget->setWindowTitle(tr("Script console"));
+    m_expressionQueryDock = uiSwitcher->createDockWidget(Qml::Constants::LANG_QML,
+                                                         m_expressionWidget, Qt::BottomDockWidgetArea);
+
     m_inspectorOutputDock->setToolTip(tr("Output of the QML inspector, such as information on connecting to the server."));
 
-    m_dockWidgets << m_objectTreeDock << /*m_frameRateDock << */ m_propertyWatcherDock << m_inspectorOutputDock;
+    m_dockWidgets << m_objectTreeDock << /*m_frameRateDock << */ m_propertyWatcherDock
+                  << m_inspectorOutputDock << m_expressionQueryDock;
 
     m_context = new Internal::InspectorContext(m_objectTreeDock);
     m_propWatcherContext = new Internal::InspectorContext(m_propertyWatcherDock);
@@ -578,6 +575,7 @@ void QmlInspector::setSimpleDockWidgetArrangement()
     }
 
     //mainWindow->tabifyDockWidget(m_frameRateDock, m_propertyWatcherDock);
+    mainWindow->tabifyDockWidget(m_propertyWatcherDock, m_expressionQueryDock);
     mainWindow->tabifyDockWidget(m_propertyWatcherDock, m_inspectorOutputDock);
 
     m_inspectorOutputDock->setVisible(false);
diff --git a/src/plugins/qmlinspector/qmlinspector.h b/src/plugins/qmlinspector/qmlinspector.h
index b9a4ef410d5..13be41d8afa 100644
--- a/src/plugins/qmlinspector/qmlinspector.h
+++ b/src/plugins/qmlinspector/qmlinspector.h
@@ -136,6 +136,7 @@ private:
 
     QDockWidget *m_objectTreeDock;
     QDockWidget *m_frameRateDock;
+    QDockWidget *m_expressionQueryDock;
     QDockWidget *m_propertyWatcherDock;
     QDockWidget *m_inspectorOutputDock;
     QList<QDockWidget*> m_dockWidgets;
-- 
GitLab