summaryrefslogtreecommitdiffstats
path: root/tools/qmldebugger/standalone/objecttree.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/qmldebugger/standalone/objecttree.cpp')
-rw-r--r--tools/qmldebugger/standalone/objecttree.cpp231
1 files changed, 231 insertions, 0 deletions
diff --git a/tools/qmldebugger/standalone/objecttree.cpp b/tools/qmldebugger/standalone/objecttree.cpp
new file mode 100644
index 0000000..cf467f2
--- /dev/null
+++ b/tools/qmldebugger/standalone/objecttree.cpp
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt QML Debugger of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtGui/qevent.h>
+#include <QtGui/qmenu.h>
+#include <QtGui/qaction.h>
+
+#include <QInputDialog>
+
+#include <private/qmldebugservice_p.h>
+#include <private/qmldebug_p.h>
+#include <private/qmldebugclient_p.h>
+
+#include "objecttree.h"
+
+Q_DECLARE_METATYPE(QmlDebugObjectReference)
+
+ObjectTree::ObjectTree(QmlEngineDebug *client, QWidget *parent)
+ : QTreeWidget(parent),
+ m_client(client),
+ m_query(0)
+{
+ setHeaderHidden(true);
+ setMinimumWidth(250);
+ setExpandsOnDoubleClick(false);
+
+ connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
+ SLOT(currentItemChanged(QTreeWidgetItem *)));
+ connect(this, SIGNAL(itemActivated(QTreeWidgetItem *, int)),
+ SLOT(activated(QTreeWidgetItem *)));
+}
+
+void ObjectTree::setEngineDebug(QmlEngineDebug *client)
+{
+ m_client = client;
+}
+
+void ObjectTree::reload(int objectDebugId)
+{
+ if (!m_client)
+ return;
+
+ if (m_query) {
+ delete m_query;
+ m_query = 0;
+ }
+
+ m_query = m_client->queryObjectRecursive(QmlDebugObjectReference(objectDebugId), this);
+ if (!m_query->isWaiting())
+ objectFetched();
+ else
+ QObject::connect(m_query, SIGNAL(stateChanged(QmlDebugQuery::State)),
+ this, SLOT(objectFetched()));
+}
+
+void ObjectTree::setCurrentObject(int debugId)
+{
+ QTreeWidgetItem *item = findItemByObjectId(debugId);
+ if (item) {
+ setCurrentItem(item);
+ scrollToItem(item);
+ item->setExpanded(true);
+ }
+}
+
+void ObjectTree::objectFetched()
+{
+ dump(m_query->object(), 0);
+ buildTree(m_query->object(), 0);
+ setCurrentItem(topLevelItem(0));
+
+ delete m_query;
+ m_query = 0;
+}
+
+void ObjectTree::currentItemChanged(QTreeWidgetItem *item)
+{
+ if (!item)
+ return;
+
+ QmlDebugObjectReference obj = item->data(0, Qt::UserRole).value<QmlDebugObjectReference>();
+ if (obj.debugId() >= 0)
+ emit currentObjectChanged(obj);
+}
+
+void ObjectTree::activated(QTreeWidgetItem *item)
+{
+ if (!item)
+ return;
+
+ QmlDebugObjectReference obj = item->data(0, Qt::UserRole).value<QmlDebugObjectReference>();
+ if (obj.debugId() >= 0)
+ emit activated(obj);
+}
+
+void ObjectTree::buildTree(const QmlDebugObjectReference &obj, QTreeWidgetItem *parent)
+{
+ if (!parent)
+ clear();
+
+ QTreeWidgetItem *item = parent ? new QTreeWidgetItem(parent) : new QTreeWidgetItem(this);
+ item->setText(0, obj.className());
+ item->setData(0, Qt::UserRole, qVariantFromValue(obj));
+
+ if (parent && obj.contextDebugId() >= 0
+ && obj.contextDebugId() != parent->data(0, Qt::UserRole
+ ).value<QmlDebugObjectReference>().contextDebugId()) {
+ QmlDebugFileReference source = obj.source();
+ if (!source.url().isEmpty()) {
+ QString toolTipString = QLatin1String("URL: ") + source.url().toString();
+ item->setToolTip(0, toolTipString);
+ }
+ item->setForeground(0, QColor("orange"));
+ } else {
+ item->setExpanded(true);
+ }
+
+ if (obj.contextDebugId() < 0)
+ item->setForeground(0, Qt::lightGray);
+
+ for (int ii = 0; ii < obj.children().count(); ++ii)
+ buildTree(obj.children().at(ii), item);
+}
+
+void ObjectTree::dump(const QmlDebugContextReference &ctxt, int ind)
+{
+ QByteArray indent(ind * 4, ' ');
+ qWarning().nospace() << indent.constData() << ctxt.debugId() << " "
+ << qPrintable(ctxt.name());
+
+ for (int ii = 0; ii < ctxt.contexts().count(); ++ii)
+ dump(ctxt.contexts().at(ii), ind + 1);
+
+ for (int ii = 0; ii < ctxt.objects().count(); ++ii)
+ dump(ctxt.objects().at(ii), ind);
+}
+
+void ObjectTree::dump(const QmlDebugObjectReference &obj, int ind)
+{
+ QByteArray indent(ind * 4, ' ');
+ qWarning().nospace() << indent.constData() << qPrintable(obj.className())
+ << " " << qPrintable(obj.name()) << " "
+ << obj.debugId();
+
+ for (int ii = 0; ii < obj.children().count(); ++ii)
+ dump(obj.children().at(ii), ind + 1);
+}
+
+QTreeWidgetItem *ObjectTree::findItemByObjectId(int debugId) const
+{
+ for (int i=0; i<topLevelItemCount(); i++) {
+ QTreeWidgetItem *item = findItem(topLevelItem(i), debugId);
+ if (item)
+ return item;
+ }
+
+ return 0;
+}
+
+QTreeWidgetItem *ObjectTree::findItem(QTreeWidgetItem *item, int debugId) const
+{
+ if (item->data(0, Qt::UserRole).value<QmlDebugObjectReference>().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 ObjectTree::mousePressEvent(QMouseEvent *me)
+{
+ QTreeWidget::mousePressEvent(me);
+ if (!currentItem())
+ return;
+ if(me->button() == Qt::RightButton && me->type() == QEvent::MouseButtonPress) {
+ QAction action(tr("Add watch..."), 0);
+ QList<QAction *> actions;
+ actions << &action;
+ QmlDebugObjectReference obj =
+ currentItem()->data(0, Qt::UserRole).value<QmlDebugObjectReference>();
+ if (QMenu::exec(actions, me->globalPos())) {
+ bool ok = false;
+ QString watch = QInputDialog::getText(this, tr("Watch expression"),
+ tr("Expression:"), QLineEdit::Normal, QString(), &ok);
+ if (ok && !watch.isEmpty())
+ emit expressionWatchRequested(obj, watch);
+ }
+ }
+}