summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/debugger/qmldebug.cpp1
-rw-r--r--tools/qmldebugger/engine.cpp286
-rw-r--r--tools/qmldebugger/engine.h7
-rw-r--r--tools/qmldebugger/propertyview.cpp117
-rw-r--r--tools/qmldebugger/propertyview.h40
-rw-r--r--tools/qmldebugger/qmldebugger.pro11
-rw-r--r--tools/qmldebugger/watchtablemodel.cpp168
-rw-r--r--tools/qmldebugger/watchtablemodel.h57
8 files changed, 420 insertions, 267 deletions
diff --git a/src/declarative/debugger/qmldebug.cpp b/src/declarative/debugger/qmldebug.cpp
index de97cda..406d955 100644
--- a/src/declarative/debugger/qmldebug.cpp
+++ b/src/declarative/debugger/qmldebug.cpp
@@ -343,6 +343,7 @@ void QmlEngineDebug::removeWatch(QmlDebugWatch *watch)
{
Q_D(QmlEngineDebug);
+ watch->setState(QmlDebugWatch::Inactive);
d->watched.remove(watch->queryId());
if (d->client->isConnected()) {
diff --git a/tools/qmldebugger/engine.cpp b/tools/qmldebugger/engine.cpp
index f17b779..3fee46d 100644
--- a/tools/qmldebugger/engine.cpp
+++ b/tools/qmldebugger/engine.cpp
@@ -1,4 +1,6 @@
#include "engine.h"
+#include "propertyview.h"
+#include "watchtablemodel.h"
#include <QtDeclarative/qmldebugclient.h>
#include <QPushButton>
#include <QVBoxLayout>
@@ -95,205 +97,6 @@ void QmlObjectTree::mousePressEvent(QMouseEvent *me)
}
-class WatchTableModel : public QAbstractTableModel
-{
- Q_OBJECT
-public:
- WatchTableModel(QObject *parent = 0);
-
- void addWatch(QmlDebugWatch *watch, const QString &title);
- void removeWatch(QmlDebugWatch *watch);
-
- void updateWatch(QmlDebugWatch *watch, const QVariant &value);
-
- QmlDebugWatch *findWatch(int column) const;
- QmlDebugWatch *findWatch(int objectDebugId, const QString &property) const;
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
- int columnCount(const QModelIndex &parent = QModelIndex()) const;
- QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
-
-private:
- int columnForWatch(QmlDebugWatch *watch) const;
- void addValue(int column, const QVariant &value);
-
- struct WatchedEntity
- {
- QString title;
- bool hasFirstValue;
- QString property;
- QPointer<QmlDebugWatch> watch;
- };
-
- struct Value {
- int column;
- QVariant variant;
- bool first;
- };
-
- QList<WatchedEntity> m_columns;
- QList<Value> m_values;
-};
-
-WatchTableModel::WatchTableModel(QObject *parent)
- : QAbstractTableModel(parent)
-{
-}
-
-void WatchTableModel::addWatch(QmlDebugWatch *watch, const QString &title)
-{
- QString property;
- if (qobject_cast<QmlDebugPropertyWatch *>(watch))
- property = qobject_cast<QmlDebugPropertyWatch *>(watch)->name();
-
- int col = columnCount(QModelIndex());
- beginInsertColumns(QModelIndex(), col, col);
-
- WatchedEntity e;
- e.title = title;
- e.hasFirstValue = false;
- e.property = property;
- e.watch = watch;
- m_columns.append(e);
-
- endInsertColumns();
-}
-
-void WatchTableModel::removeWatch(QmlDebugWatch *watch)
-{
- int column = columnForWatch(watch);
- if (column == -1)
- return;
-
- WatchedEntity entity = m_columns.takeAt(column);
-
- for (QList<Value>::Iterator iter = m_values.begin(); iter != m_values.end();) {
- if (iter->column == column) {
- iter = m_values.erase(iter);
- } else {
- if(iter->column > column)
- --iter->column;
- ++iter;
- }
- }
-
- reset();
-}
-
-void WatchTableModel::updateWatch(QmlDebugWatch *watch, const QVariant &value)
-{
- int column = columnForWatch(watch);
- if (column == -1)
- return;
-
- addValue(column, value);
-
- if (!m_columns[column].hasFirstValue) {
- m_columns[column].hasFirstValue = true;
- m_values[m_values.count() - 1].first = true;
- }
-}
-
-QmlDebugWatch *WatchTableModel::findWatch(int column) const
-{
- if (column < m_columns.count())
- return m_columns.at(column).watch;
- return 0;
-}
-
-QmlDebugWatch *WatchTableModel::findWatch(int objectDebugId, const QString &property) const
-{
- for (int i=0; i<m_columns.count(); i++) {
- if (m_columns[i].watch->objectDebugId() == objectDebugId
- && m_columns[i].property == property) {
- return m_columns[i].watch;
- }
- }
- return 0;
-}
-
-int WatchTableModel::rowCount(const QModelIndex &) const
-{
- return m_values.count();
-}
-
-int WatchTableModel::columnCount(const QModelIndex &) const
-{
- return m_columns.count();
-}
-
-QVariant WatchTableModel::headerData(int section, Qt::Orientation orientation, int role) const
-{
- if (orientation == Qt::Horizontal) {
- if (section < m_columns.count() && role == Qt::DisplayRole)
- return m_columns.at(section).title;
- } else {
- if (role == Qt::DisplayRole)
- return section + 1;
- }
- return QVariant();
-}
-
-QVariant WatchTableModel::data(const QModelIndex &idx, int role) const
-{
- if (m_values.at(idx.row()).column == idx.column()) {
- if (role == Qt::DisplayRole) {
- const QVariant &value = m_values.at(idx.row()).variant;
- QString str = value.toString();
-
- if (str.isEmpty() && QmlMetaType::isObject(value.userType())) {
- QObject *o = QmlMetaType::toQObject(value);
- if(o) {
- QString objectName = o->objectName();
- if(objectName.isEmpty())
- objectName = QLatin1String("<unnamed>");
- str = QLatin1String(o->metaObject()->className()) +
- QLatin1String(": ") + objectName;
- }
- }
-
- if(str.isEmpty()) {
- QDebug d(&str);
- d << value;
- }
- return QVariant(str);
- } else if(role == Qt::BackgroundRole) {
- if(m_values.at(idx.row()).first)
- return QColor(Qt::green);
- else
- return QVariant();
- } else {
- return QVariant();
- }
- } else {
- return QVariant();
- }
-}
-
-int WatchTableModel::columnForWatch(QmlDebugWatch *watch) const
-{
- for (int i=0; i<m_columns.count(); i++) {
- if (m_columns.at(i).watch == watch)
- return i;
- }
- return -1;
-}
-
-void WatchTableModel::addValue(int column, const QVariant &value)
-{
- int row = columnCount(QModelIndex());
- beginInsertRows(QModelIndex(), row, row);
-
- Value v;
- v.column = column;
- v.variant = value;
- v.first = false;
- m_values.append(v);
-
- endInsertRows();
-}
-
class WatchTableView : public QTableView
{
@@ -389,12 +192,9 @@ EnginePane::EnginePane(QmlDebugConnection *client, QWidget *parent)
connect(m_objTree, SIGNAL(addExpressionWatch(int,QString)), this, SLOT(addExpressionWatch(int,QString)));
hbox->addWidget(m_objTree);
- m_propTable = new QTableWidget(this);
- connect(m_propTable, SIGNAL(itemDoubleClicked(QTableWidgetItem *)), this, SLOT(propertyDoubleClicked(QTableWidgetItem *)));
- m_propTable->setColumnCount(2);
- m_propTable->setColumnWidth(0, 150);
- m_propTable->setColumnWidth(1, 400);
- m_propTable->setHorizontalHeaderLabels(QStringList() << "name" << "value");
+ m_propView = new PropertyView(this);
+ connect(m_propView, SIGNAL(propertyDoubleClicked(QmlDebugPropertyReference)),
+ this, SLOT(propertyDoubleClicked(QmlDebugPropertyReference)));
m_watchTableModel = new WatchTableModel(this);
m_watchTable = new WatchTableView(this);
@@ -405,7 +205,7 @@ EnginePane::EnginePane(QmlDebugConnection *client, QWidget *parent)
this, SLOT(stopWatching(int)));
m_tabs = new QTabWidget(this);
- m_tabs->addTab(m_propTable, tr("Properties"));
+ m_tabs->addTab(m_propView, tr("Properties"));
m_tabs->addTab(m_watchTable, tr("Watching"));
hbox->addWidget(m_tabs);
@@ -422,7 +222,7 @@ void EnginePane::engineSelected(int id)
void EnginePane::itemClicked(QTreeWidgetItem *item)
{
- m_propTable->clearContents();
+ m_propView->clear();
if (m_object) {
delete m_object;
@@ -440,19 +240,7 @@ void EnginePane::itemClicked(QTreeWidgetItem *item)
void EnginePane::showProperties()
{
QmlDebugObjectReference obj = m_object->object();
- m_propTable->setRowCount(obj.properties().count());
- for (int ii = 0; ii < obj.properties().count(); ++ii) {
- QTableWidgetItem *name = new QTableWidgetItem(obj.properties().at(ii).name());
- name->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
- m_propTable->setItem(ii, 0, name);
- QTableWidgetItem *value;
- if (!obj.properties().at(ii).binding().isEmpty())
- value = new QTableWidgetItem(obj.properties().at(ii).binding());
- else
- value = new QTableWidgetItem(obj.properties().at(ii).value().toString());
- value->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
- m_propTable->setItem(ii, 1, value);
- }
+ m_propView->setObject(obj);
if (m_watchedObject) {
m_client.removeWatch(m_watchedObject);
@@ -465,8 +253,7 @@ void EnginePane::showProperties()
QObject::connect(watch, SIGNAL(valueChanged(QByteArray,QVariant)),
this, SLOT(valueChanged(QByteArray,QVariant)));
- // don't delete, keep it for when property table cells are clicked
- //delete m_object; m_object = 0;
+ delete m_object; m_object = 0;
}
void EnginePane::addExpressionWatch(int debugId, const QString &expr)
@@ -481,50 +268,32 @@ void EnginePane::addExpressionWatch(int debugId, const QString &expr)
void EnginePane::valueChanged(const QByteArray &propertyName, const QVariant &value)
{
- if (!m_object)
- return;
-
QmlDebugWatch *watch = qobject_cast<QmlDebugWatch*>(sender());
m_watchTableModel->updateWatch(watch, value);
if (!propertyName.isEmpty()) {
- QmlDebugObjectReference obj = m_object->object();
- if (obj.debugId() == watch->objectDebugId()) {
- for (int ii=0; ii<m_propTable->rowCount(); ii++) {
- if (m_propTable->item(ii, 0)->text() == propertyName) {
- m_propTable->item(ii, 1)->setText(value.toString());
- break;
- }
- }
- }
+ if (watch->objectDebugId() == m_propView->object().debugId())
+ m_propView->updateProperty(propertyName, value);
}
}
-void EnginePane::propertyDoubleClicked(QTableWidgetItem *item)
+void EnginePane::propertyDoubleClicked(const QmlDebugPropertyReference &property)
{
- if (!m_object || item->column() > 0)
+ PropertyView *view = qobject_cast<PropertyView*>(sender());
+ if (!view)
return;
- QList<QmlDebugPropertyReference> props = m_object->object().properties();
- if (item->row() < props.count()) {
- bool watching = togglePropertyWatch(m_object->object(), props.at(item->row()));
- if (watching)
- item->setForeground(Qt::red);
- else
- item->setForeground(QBrush());
- }
-}
-bool EnginePane::togglePropertyWatch(const QmlDebugObjectReference &object, const QmlDebugPropertyReference &property)
-{
+ QmlDebugObjectReference object = view->object();
QmlDebugWatch *watch = m_watchTableModel->findWatch(object.debugId(), property.name());
if (watch) {
m_watchTableModel->removeWatch(watch);
m_client.removeWatch(watch);
delete watch;
- return false;
} else {
QmlDebugWatch *watch = m_client.addWatch(property, this);
+ QObject::connect(watch, SIGNAL(stateChanged(State)),
+ this, SLOT(propertyWatchStateChanged()));
QObject::connect(watch, SIGNAL(valueChanged(QByteArray,QVariant)),
this, SLOT(valueChanged(QByteArray,QVariant)));
QString desc = property.name()
@@ -534,27 +303,20 @@ bool EnginePane::togglePropertyWatch(const QmlDebugObjectReference &object, cons
+ (object.name().isEmpty() ? QLatin1String("<unnamed>") : object.name());
m_watchTableModel->addWatch(watch, desc);
m_watchTable->resizeColumnsToContents();
- return true;
}
}
+void EnginePane::propertyWatchStateChanged()
+{
+ QmlDebugPropertyWatch *watch = qobject_cast<QmlDebugPropertyWatch*>(sender());
+ if (watch && watch->objectDebugId() == m_propView->object().debugId())
+ m_propView->setPropertyIsWatched(watch->name(), watch->state() == QmlDebugWatch::Active);
+}
+
void EnginePane::stopWatching(int column)
{
QmlDebugWatch *watch = m_watchTableModel->findWatch(column);
if (watch) {
- if (m_object && m_object->object().debugId() == watch->objectDebugId()
- && qobject_cast<QmlDebugPropertyWatch *>(watch)) {
- QString property = qobject_cast<QmlDebugPropertyWatch *>(watch)->name();
- QTableWidgetItem *item;
- for (int row=0; row<m_propTable->rowCount(); row++) {
- item = m_propTable->item(row, 0);
- if (item->text() == property) {
- item->setForeground(QBrush());
- break;
- }
- }
- }
-
m_watchTableModel->removeWatch(watch);
m_client.removeWatch(watch);
delete watch;
diff --git a/tools/qmldebugger/engine.h b/tools/qmldebugger/engine.h
index 899a21d..b3e0129 100644
--- a/tools/qmldebugger/engine.h
+++ b/tools/qmldebugger/engine.h
@@ -15,6 +15,7 @@ class QmlDebugPropertyReference;
class QmlDebugWatch;
class QmlObjectTree;
class EngineClientPlugin;
+class PropertyView;
class WatchTableModel;
class WatchTableView;
class QLineEdit;
@@ -51,7 +52,8 @@ private slots:
void valueChanged(const QByteArray &property, const QVariant &value);
- void propertyDoubleClicked(QTableWidgetItem *);
+ void propertyDoubleClicked(const QmlDebugPropertyReference &property);
+ void propertyWatchStateChanged();
void watchedItemActivated(const QModelIndex &index);
void stopWatching(int column);
@@ -59,7 +61,6 @@ private:
void dump(const QmlDebugContextReference &, int);
void dump(const QmlDebugObjectReference &, int);
void buildTree(const QmlDebugObjectReference &, QTreeWidgetItem *parent);
- bool togglePropertyWatch(const QmlDebugObjectReference &object, const QmlDebugPropertyReference &property);
QmlEngineDebug m_client;
QmlDebugEnginesQuery *m_engines;
@@ -69,7 +70,7 @@ private:
QLineEdit *m_text;
QmlObjectTree *m_objTree;
QTabWidget *m_tabs;
- QTableWidget *m_propTable;
+ PropertyView *m_propView;
WatchTableView *m_watchTable;
QmlView *m_engineView;
diff --git a/tools/qmldebugger/propertyview.cpp b/tools/qmldebugger/propertyview.cpp
new file mode 100644
index 0000000..d5bb3df
--- /dev/null
+++ b/tools/qmldebugger/propertyview.cpp
@@ -0,0 +1,117 @@
+#include "propertyview.h"
+#include <QtCore/qdebug.h>
+#include <QtGui/qboxlayout.h>
+#include <QtGui/qtreewidget.h>
+
+QT_BEGIN_NAMESPACE
+
+PropertyView::PropertyView(QWidget *parent)
+: QWidget(parent), m_tree(0)
+{
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+ setLayout(layout);
+
+ m_tree = new QTreeWidget(this);
+ m_tree->setExpandsOnDoubleClick(false);
+ m_tree->setHeaderLabels(QStringList() << tr("Property") << tr("Value"));
+ QObject::connect(m_tree, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
+ this, SLOT(itemDoubleClicked(QTreeWidgetItem *)));
+
+ m_tree->setColumnCount(2);
+
+ layout->addWidget(m_tree);
+}
+
+class PropertyViewItem : public QObject, public QTreeWidgetItem
+{
+ Q_OBJECT
+public:
+ PropertyViewItem(QTreeWidget *widget);
+ PropertyViewItem(QTreeWidgetItem *parent);
+
+ QmlDebugPropertyReference property;
+};
+
+PropertyViewItem::PropertyViewItem(QTreeWidget *widget)
+: QTreeWidgetItem(widget)
+{
+}
+
+PropertyViewItem::PropertyViewItem(QTreeWidgetItem *parent)
+: QTreeWidgetItem(parent)
+{
+}
+
+
+void PropertyView::setObject(const QmlDebugObjectReference &object)
+{
+ m_object = object;
+ m_tree->clear();
+
+ QList<QmlDebugPropertyReference> properties = object.properties();
+ for (int i=0; i<properties.count(); i++) {
+ const QmlDebugPropertyReference &p = properties[i];
+
+ PropertyViewItem *item = new PropertyViewItem(m_tree);
+ item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
+ item->setCheckState(0, Qt::Unchecked);
+ item->property = p;
+
+ item->setText(0, p.name());
+
+ if (!p.binding().isEmpty()) {
+ PropertyViewItem *binding = new PropertyViewItem(item);
+ binding->setText(1, p.binding());
+ binding->setForeground(1, Qt::darkGreen);
+ }
+
+ item->setExpanded(true);
+ }
+
+ m_tree->resizeColumnToContents(0);
+}
+
+const QmlDebugObjectReference &PropertyView::object() const
+{
+ return m_object;
+}
+
+void PropertyView::clear()
+{
+ setObject(QmlDebugObjectReference());
+}
+
+void PropertyView::updateProperty(const QString &name, const QVariant &value)
+{
+ for (int i=0; i<m_tree->topLevelItemCount(); i++) {
+ PropertyViewItem *item = static_cast<PropertyViewItem *>(m_tree->topLevelItem(i));
+ if (item->property.name() == name)
+ item->setText(1, value.toString());
+ }
+}
+
+void PropertyView::setPropertyIsWatched(const QString &name, bool watched)
+{
+ for (int i=0; i<m_tree->topLevelItemCount(); i++) {
+ PropertyViewItem *item = static_cast<PropertyViewItem *>(m_tree->topLevelItem(i));
+ if (item->property.name() == name) {
+ if (watched)
+ item->setCheckState(0, Qt::Checked);
+ else
+ item->setCheckState(0, Qt::Unchecked);
+ }
+ }
+}
+
+void PropertyView::itemDoubleClicked(QTreeWidgetItem *i)
+{
+ PropertyViewItem *item = static_cast<PropertyViewItem *>(i);
+ if (!item->property.name().isEmpty())
+ emit propertyDoubleClicked(item->property);
+}
+
+QT_END_NAMESPACE
+
+#include "propertyview.moc"
diff --git a/tools/qmldebugger/propertyview.h b/tools/qmldebugger/propertyview.h
new file mode 100644
index 0000000..92200fa
--- /dev/null
+++ b/tools/qmldebugger/propertyview.h
@@ -0,0 +1,40 @@
+#ifndef PROPERTYVIEW_H
+#define PROPERTYVIEW_H
+
+#include <QtGui/qwidget.h>
+#include <QtCore/qpointer.h>
+#include <QtDeclarative/qmldebug.h>
+
+QT_BEGIN_NAMESPACE
+
+class QTreeWidget;
+class QTreeWidgetItem;
+
+class PropertyView : public QWidget
+{
+ Q_OBJECT
+public:
+ PropertyView(QWidget *parent = 0);
+
+ void setObject(const QmlDebugObjectReference &object);
+ const QmlDebugObjectReference &object() const;
+
+ void updateProperty(const QString &name, const QVariant &value);
+ void setPropertyIsWatched(const QString &name, bool watched);
+
+ void clear();
+
+signals:
+ void propertyDoubleClicked(const QmlDebugPropertyReference &property);
+
+private slots:
+ void itemDoubleClicked(QTreeWidgetItem *);
+
+private:
+ QmlDebugObjectReference m_object;
+ QTreeWidget *m_tree;
+};
+
+QT_END_NAMESPACE
+
+#endif // PROPERTYVIEW_H
diff --git a/tools/qmldebugger/qmldebugger.pro b/tools/qmldebugger/qmldebugger.pro
index 3935351..b177875 100644
--- a/tools/qmldebugger/qmldebugger.pro
+++ b/tools/qmldebugger/qmldebugger.pro
@@ -3,8 +3,15 @@ QT += network declarative
contains(QT_CONFIG, opengles2)|contains(QT_CONFIG, opengles1): QT += opengl
# Input
-HEADERS += canvasframerate.h engine.h
-SOURCES += main.cpp canvasframerate.cpp engine.cpp
+HEADERS += canvasframerate.h \
+ watchtablemodel.h \
+ propertyview.h \
+ engine.h
+SOURCES += main.cpp \
+ canvasframerate.cpp \
+ watchtablemodel.cpp \
+ propertyview.cpp \
+ engine.cpp
RESOURCES += qmldebugger.qrc
OTHER_FILES += engines.qml
diff --git a/tools/qmldebugger/watchtablemodel.cpp b/tools/qmldebugger/watchtablemodel.cpp
new file mode 100644
index 0000000..f9defc4
--- /dev/null
+++ b/tools/qmldebugger/watchtablemodel.cpp
@@ -0,0 +1,168 @@
+#include "watchtablemodel.h"
+
+#include <QtCore/qdebug.h>
+#include <QtDeclarative/qmldebug.h>
+#include <QtDeclarative/qmlmetatype.h>
+
+QT_BEGIN_NAMESPACE
+
+
+WatchTableModel::WatchTableModel(QObject *parent)
+ : QAbstractTableModel(parent)
+{
+}
+
+void WatchTableModel::addWatch(QmlDebugWatch *watch, const QString &title)
+{
+ QString property;
+ if (qobject_cast<QmlDebugPropertyWatch *>(watch))
+ property = qobject_cast<QmlDebugPropertyWatch *>(watch)->name();
+
+ int col = columnCount(QModelIndex());
+ beginInsertColumns(QModelIndex(), col, col);
+
+ WatchedEntity e;
+ e.title = title;
+ e.hasFirstValue = false;
+ e.property = property;
+ e.watch = watch;
+ m_columns.append(e);
+
+ endInsertColumns();
+}
+
+void WatchTableModel::removeWatch(QmlDebugWatch *watch)
+{
+ int column = columnForWatch(watch);
+ if (column == -1)
+ return;
+
+ WatchedEntity entity = m_columns.takeAt(column);
+
+ for (QList<Value>::Iterator iter = m_values.begin(); iter != m_values.end();) {
+ if (iter->column == column) {
+ iter = m_values.erase(iter);
+ } else {
+ if(iter->column > column)
+ --iter->column;
+ ++iter;
+ }
+ }
+
+ reset();
+}
+
+void WatchTableModel::updateWatch(QmlDebugWatch *watch, const QVariant &value)
+{
+ int column = columnForWatch(watch);
+ if (column == -1)
+ return;
+
+ addValue(column, value);
+
+ if (!m_columns[column].hasFirstValue) {
+ m_columns[column].hasFirstValue = true;
+ m_values[m_values.count() - 1].first = true;
+ }
+}
+
+QmlDebugWatch *WatchTableModel::findWatch(int column) const
+{
+ if (column < m_columns.count())
+ return m_columns.at(column).watch;
+ return 0;
+}
+
+QmlDebugWatch *WatchTableModel::findWatch(int objectDebugId, const QString &property) const
+{
+ for (int i=0; i<m_columns.count(); i++) {
+ if (m_columns[i].watch->objectDebugId() == objectDebugId
+ && m_columns[i].property == property) {
+ return m_columns[i].watch;
+ }
+ }
+ return 0;
+}
+
+int WatchTableModel::rowCount(const QModelIndex &) const
+{
+ return m_values.count();
+}
+
+int WatchTableModel::columnCount(const QModelIndex &) const
+{
+ return m_columns.count();
+}
+
+QVariant WatchTableModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (orientation == Qt::Horizontal) {
+ if (section < m_columns.count() && role == Qt::DisplayRole)
+ return m_columns.at(section).title;
+ } else {
+ if (role == Qt::DisplayRole)
+ return section + 1;
+ }
+ return QVariant();
+}
+
+QVariant WatchTableModel::data(const QModelIndex &idx, int role) const
+{
+ if (m_values.at(idx.row()).column == idx.column()) {
+ if (role == Qt::DisplayRole) {
+ const QVariant &value = m_values.at(idx.row()).variant;
+ QString str = value.toString();
+
+ if (str.isEmpty() && QmlMetaType::isObject(value.userType())) {
+ QObject *o = QmlMetaType::toQObject(value);
+ if(o) {
+ QString objectName = o->objectName();
+ if(objectName.isEmpty())
+ objectName = QLatin1String("<unnamed>");
+ str = QLatin1String(o->metaObject()->className()) +
+ QLatin1String(": ") + objectName;
+ }
+ }
+
+ if(str.isEmpty()) {
+ QDebug d(&str);
+ d << value;
+ }
+ return QVariant(str);
+ } else if(role == Qt::BackgroundRole) {
+ if(m_values.at(idx.row()).first)
+ return QColor(Qt::green);
+ else
+ return QVariant();
+ } else {
+ return QVariant();
+ }
+ } else {
+ return QVariant();
+ }
+}
+
+int WatchTableModel::columnForWatch(QmlDebugWatch *watch) const
+{
+ for (int i=0; i<m_columns.count(); i++) {
+ if (m_columns.at(i).watch == watch)
+ return i;
+ }
+ return -1;
+}
+
+void WatchTableModel::addValue(int column, const QVariant &value)
+{
+ int row = columnCount(QModelIndex());
+ beginInsertRows(QModelIndex(), row, row);
+
+ Value v;
+ v.column = column;
+ v.variant = value;
+ v.first = false;
+ m_values.append(v);
+
+ endInsertRows();
+}
+
+QT_END_NAMESPACE
diff --git a/tools/qmldebugger/watchtablemodel.h b/tools/qmldebugger/watchtablemodel.h
new file mode 100644
index 0000000..47c654c
--- /dev/null
+++ b/tools/qmldebugger/watchtablemodel.h
@@ -0,0 +1,57 @@
+#ifndef WATCHTABLEMODEL_H
+#define WATCHTABLEMODEL_H
+
+#include <QWidget>
+#include <QtCore/qpointer.h>
+#include <QtCore/qlist.h>
+#include <QAbstractTableModel>
+
+QT_BEGIN_NAMESPACE
+
+class QmlDebugWatch;
+
+class WatchTableModel : public QAbstractTableModel
+{
+ Q_OBJECT
+public:
+ WatchTableModel(QObject *parent = 0);
+
+ void addWatch(QmlDebugWatch *watch, const QString &title);
+ void removeWatch(QmlDebugWatch *watch);
+
+ void updateWatch(QmlDebugWatch *watch, const QVariant &value);
+
+ QmlDebugWatch *findWatch(int column) const;
+ QmlDebugWatch *findWatch(int objectDebugId, const QString &property) const;
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+
+private:
+ int columnForWatch(QmlDebugWatch *watch) const;
+ void addValue(int column, const QVariant &value);
+
+ struct WatchedEntity
+ {
+ QString title;
+ bool hasFirstValue;
+ QString property;
+ QPointer<QmlDebugWatch> watch;
+ };
+
+ struct Value {
+ int column;
+ QVariant variant;
+ bool first;
+ };
+
+ QList<WatchedEntity> m_columns;
+ QList<Value> m_values;
+};
+
+
+QT_END_NAMESPACE
+
+#endif // WATCHTABLEMODEL_H