diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/qmldebugger/expressionquerywidget.cpp | 216 | ||||
-rw-r--r-- | tools/qmldebugger/expressionquerywidget.h | 62 | ||||
-rw-r--r-- | tools/qmldebugger/objectpropertiesview.cpp | 23 | ||||
-rw-r--r-- | tools/qmldebugger/objecttree.cpp | 10 | ||||
-rw-r--r-- | tools/qmldebugger/objecttree.h | 6 | ||||
-rw-r--r-- | tools/qmldebugger/qmldebugger.cpp | 4 | ||||
-rw-r--r-- | tools/qmldebugger/qmldebugger.pri | 6 | ||||
-rw-r--r-- | tools/qmldebugger/watchtable.cpp | 3 | ||||
-rw-r--r-- | tools/qmlviewer/qmlviewer.cpp | 8 |
9 files changed, 321 insertions, 17 deletions
diff --git a/tools/qmldebugger/expressionquerywidget.cpp b/tools/qmldebugger/expressionquerywidget.cpp new file mode 100644 index 0000000..b29b465 --- /dev/null +++ b/tools/qmldebugger/expressionquerywidget.cpp @@ -0,0 +1,216 @@ +#include <QtGui/qlabel.h> +#include <QtGui/qtextedit.h> +#include <QtGui/qlineedit.h> +#include <QtGui/qpushbutton.h> +#include <QtGui/qevent.h> +#include <QtGui/qgroupbox.h> +#include <QtGui/qtextobject.h> +#include <QtGui/qlayout.h> + +#include "expressionquerywidget.h" + +ExpressionQueryWidget::ExpressionQueryWidget(QmlEngineDebug *client, QWidget *parent) + : QWidget(parent), + m_style(Compact), + m_client(client), + m_query(0), + m_groupBox(0), + m_textEdit(new QTextEdit), + m_lineEdit(0), + m_button(0) +{ + m_prompt = QLatin1String(">> "); + + m_groupBox = new QGroupBox; + QVBoxLayout *vbox = new QVBoxLayout(m_groupBox); + vbox->addWidget(m_textEdit); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->addWidget(m_groupBox); + + updateTitle(); + + if (m_style == Compact) { + QHBoxLayout *hbox = new QHBoxLayout; + m_button = new QPushButton(tr("Execute")); + m_button->setEnabled(false); + connect(m_button, SIGNAL(clicked()), SLOT(executeExpression())); + m_lineEdit = new QLineEdit; + connect(m_lineEdit, SIGNAL(returnPressed()), SLOT(executeExpression())); + connect(m_lineEdit, SIGNAL(textChanged(QString)), SLOT(lineEditTextChanged(QString))); + hbox->addWidget(new QLabel(tr("Expression:"))); + hbox->addWidget(m_lineEdit); + hbox->addWidget(m_button); + vbox->addLayout(hbox); + + m_textEdit->setReadOnly(true); + m_lineEdit->installEventFilter(this); + } else { + m_textEdit->installEventFilter(this); + } +} + +void ExpressionQueryWidget::updateTitle() +{ + if (m_currObject.debugId() < 0) { + m_groupBox->setTitle(tr("Expression queries")); + } else { + QString desc = QLatin1String("<") + + m_currObject.className() + QLatin1String(": ") + + (m_currObject.name().isEmpty() ? QLatin1String("<unnamed>") : m_currObject.name()) + + QLatin1String(">"); + m_groupBox->setTitle(tr("Expression queries (using context for %1)" + , "Selected object").arg(desc)); + } +} + +void ExpressionQueryWidget::appendPrompt() +{ + m_textEdit->moveCursor(QTextCursor::End); + + if (m_style == Compact) { + m_textEdit->insertPlainText("\n"); + } else { + m_textEdit->setTextColor(Qt::gray); + m_textEdit->append(m_prompt); + } +} + +void ExpressionQueryWidget::setCurrentObject(const QmlDebugObjectReference &obj) +{ + m_currObject = obj; + updateTitle(); +} + +void ExpressionQueryWidget::checkCurrentContext() +{ + m_textEdit->moveCursor(QTextCursor::End); + + if (m_currObject.debugId() != -1 && m_currObject.debugId() != m_objectAtLastFocus.debugId()) + showCurrentContext(); + m_objectAtLastFocus = m_currObject; +} + +void ExpressionQueryWidget::showCurrentContext() +{ + m_textEdit->moveCursor(QTextCursor::End); + m_textEdit->setTextColor(Qt::darkGreen); + m_textEdit->append(m_currObject.className() + + QLatin1String(": ") + + (m_currObject.name().isEmpty() ? QLatin1String("<unnamed>") : m_currObject.name())); + appendPrompt(); +} + +void ExpressionQueryWidget::executeExpression() +{ + if (m_style == Compact) + m_expr = m_lineEdit->text().trimmed(); + else + m_expr = m_expr.trimmed(); + + if (!m_expr.isEmpty() && m_currObject.debugId() != -1) { + if (m_query) + delete m_query; + m_query = m_client->queryExpressionResult(m_currObject.debugId(), m_expr, this); + if (!m_query->isWaiting()) + showResult(); + else + QObject::connect(m_query, SIGNAL(stateChanged(State)), + this, SLOT(showResult())); + + m_lastExpr = m_expr; + if (m_lineEdit) + m_lineEdit->clear(); + } +} + +void ExpressionQueryWidget::showResult() +{ + if (m_query) { + m_textEdit->moveCursor(QTextCursor::End); + QString result; + if (m_query->result().isNull()) + result = QLatin1String("<no value>"); + else + result = m_query->result().toString(); + + if (m_style == Compact) { + m_textEdit->setTextColor(Qt::black); + m_textEdit->setFontWeight(QFont::Bold); + m_textEdit->insertPlainText(m_expr + " : "); + m_textEdit->setFontWeight(QFont::Normal); + m_textEdit->insertPlainText(result); + } else { + m_textEdit->append(result); + } + appendPrompt(); + m_expr.clear(); + } +} + +void ExpressionQueryWidget::lineEditTextChanged(const QString &s) +{ + if (m_button) + m_button->setEnabled(!s.isEmpty()); +} + +bool ExpressionQueryWidget::eventFilter(QObject *obj, QEvent *event) +{ + if (obj == m_textEdit) { + switch (event->type()) { + case QEvent::KeyPress: + { + QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); + int key = keyEvent->key(); + if (key == Qt::Key_Return || key == Qt::Key_Enter) { + executeExpression(); + return true; + } else if (key == Qt::Key_Backspace) { + // ensure m_expr doesn't contain backspace characters + QTextCursor cursor = m_textEdit->textCursor(); + bool atLastLine = !(cursor.block().next().isValid()); + if (!atLastLine) + return true; + if (cursor.columnNumber() <= m_prompt.count()) + return true; + cursor.deletePreviousChar(); + m_expr = cursor.block().text().mid(m_prompt.count()); + return true; + } else { + m_textEdit->moveCursor(QTextCursor::End); + m_textEdit->setTextColor(Qt::black); + m_expr += keyEvent->text(); + } + break; + } + case QEvent::FocusIn: + checkCurrentContext(); + m_textEdit->moveCursor(QTextCursor::End); + break; + default: + break; + } + } else if (obj == m_lineEdit) { + switch (event->type()) { + case QEvent::KeyPress: + { + QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); + int key = keyEvent->key(); + if (key == Qt::Key_Up && m_lineEdit->text() != m_lastExpr) { + m_expr = m_lineEdit->text(); + if (!m_lastExpr.isEmpty()) + m_lineEdit->setText(m_lastExpr); + } else if (key == Qt::Key_Down) { + m_lineEdit->setText(m_expr); + } + break; + } + case QEvent::FocusIn: + checkCurrentContext(); + break; + default: + break; + } + } + return QWidget::eventFilter(obj, event); +} diff --git a/tools/qmldebugger/expressionquerywidget.h b/tools/qmldebugger/expressionquerywidget.h new file mode 100644 index 0000000..8db8f9f --- /dev/null +++ b/tools/qmldebugger/expressionquerywidget.h @@ -0,0 +1,62 @@ +#ifndef EXPRESSIONQUERYWIDGET_H +#define EXPRESSIONQUERYWIDGET_H + +#include <QWidget> + +#include <QtDeclarative/qmldebug.h> + +QT_BEGIN_NAMESPACE + +class QGroupBox; +class QTextEdit; +class QLineEdit; +class QPushButton; + +class ExpressionQueryWidget : public QWidget +{ + Q_OBJECT +public: + enum Style { + Compact, + Shell + }; + + ExpressionQueryWidget(QmlEngineDebug *client, QWidget *parent = 0); + +protected: + bool eventFilter(QObject *obj, QEvent *event); + +public slots: + void setCurrentObject(const QmlDebugObjectReference &obj); + +private slots: + void executeExpression(); + void showResult(); + void lineEditTextChanged(const QString &s); + +private: + void appendPrompt(); + void checkCurrentContext(); + void showCurrentContext(); + void updateTitle(); + + Style m_style; + + QmlEngineDebug *m_client; + QmlDebugExpressionQuery *m_query; + QGroupBox *m_groupBox; + QTextEdit *m_textEdit; + QLineEdit *m_lineEdit; + QPushButton *m_button; + QString m_prompt; + QString m_expr; + QString m_lastExpr; + + QmlDebugObjectReference m_currObject; + QmlDebugObjectReference m_objectAtLastFocus; +}; + +QT_END_NAMESPACE + +#endif + diff --git a/tools/qmldebugger/objectpropertiesview.cpp b/tools/qmldebugger/objectpropertiesview.cpp index f725194..61afe3f 100644 --- a/tools/qmldebugger/objectpropertiesview.cpp +++ b/tools/qmldebugger/objectpropertiesview.cpp @@ -22,12 +22,12 @@ public: }; PropertiesViewItem::PropertiesViewItem(QTreeWidget *widget) -: QTreeWidgetItem(widget) + : QTreeWidgetItem(widget) { } PropertiesViewItem::PropertiesViewItem(QTreeWidgetItem *parent) -: QTreeWidgetItem(parent) + : QTreeWidgetItem(parent) { } @@ -108,8 +108,10 @@ void ObjectPropertiesView::setObject(const QmlDebugObjectReference &object) item->setText(0, p.name()); item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - if (!p.hasNotifySignal()) - item->setForeground(0, Qt::lightGray); + if (!p.hasNotifySignal()) { + item->setForeground(0, Qt::gray); + item->setForeground(1, Qt::gray); + } if (!p.binding().isEmpty()) { PropertiesViewItem *binding = new PropertiesViewItem(item); @@ -159,15 +161,22 @@ void ObjectPropertiesView::valueChanged(const QByteArray &name, const QVariant & { for (int i=0; i<m_tree->topLevelItemCount(); i++) { PropertiesViewItem *item = static_cast<PropertiesViewItem *>(m_tree->topLevelItem(i)); - if (item->property.name() == name) - item->setText(1, value.toString()); + if (item->property.name() == name) { + if (value.isNull()) { + item->setText(1, QLatin1String("<null>") + + QLatin1String(" : ") + + item->property.valueTypeName()); + } else { + item->setText(1, value.toString()); + } + } } } void ObjectPropertiesView::itemActivated(QTreeWidgetItem *i) { PropertiesViewItem *item = static_cast<PropertiesViewItem *>(i); - if (!item->property.name().isEmpty() && item->property.hasNotifySignal()) + if (!item->property.name().isEmpty()) emit activated(m_object, item->property); } diff --git a/tools/qmldebugger/objecttree.cpp b/tools/qmldebugger/objecttree.cpp index f68e7f1..0b92ceb 100644 --- a/tools/qmldebugger/objecttree.cpp +++ b/tools/qmldebugger/objecttree.cpp @@ -19,8 +19,8 @@ ObjectTree::ObjectTree(QmlEngineDebug *client, QWidget *parent) { setHeaderHidden(true); - connect(this, SIGNAL(itemClicked(QTreeWidgetItem *, int)), - this, SLOT(handleItemClicked(QTreeWidgetItem *))); + connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), + this, SLOT(currentItemChanged(QTreeWidgetItem *))); } void ObjectTree::reload(int objectDebugId) @@ -38,7 +38,7 @@ void ObjectTree::reload(int objectDebugId) this, SLOT(objectFetched())); } -void ObjectTree::selectObject(int debugId) +void ObjectTree::setCurrentObject(int debugId) { QTreeWidgetItem *item = findItemByObjectId(debugId); if (item) { @@ -57,14 +57,14 @@ void ObjectTree::objectFetched() m_query = 0; } -void ObjectTree::handleItemClicked(QTreeWidgetItem *item) +void ObjectTree::currentItemChanged(QTreeWidgetItem *item) { QmlDebugObjectReference obj = item->data(0, Qt::UserRole).value<QmlDebugObjectReference>(); if (obj.debugId() < 0) { qWarning("QML Object Tree: bad object id"); return; } - emit objectSelected(obj); + emit currentObjectChanged(obj); } void ObjectTree::buildTree(const QmlDebugObjectReference &obj, QTreeWidgetItem *parent) diff --git a/tools/qmldebugger/objecttree.h b/tools/qmldebugger/objecttree.h index bba6c08..3c0a5c6 100644 --- a/tools/qmldebugger/objecttree.h +++ b/tools/qmldebugger/objecttree.h @@ -20,19 +20,19 @@ public: ObjectTree(QmlEngineDebug *client, QWidget *parent = 0); signals: - void objectSelected(const QmlDebugObjectReference &); + void currentObjectChanged(const QmlDebugObjectReference &); void expressionWatchRequested(const QmlDebugObjectReference &, const QString &); public slots: void reload(int objectDebugId); - void selectObject(int debugId); + void setCurrentObject(int debugId); protected: virtual void mousePressEvent(QMouseEvent *); private slots: void objectFetched(); - void handleItemClicked(QTreeWidgetItem *); + void currentItemChanged(QTreeWidgetItem *); private: QTreeWidgetItem *findItemByObjectId(int debugId) const; diff --git a/tools/qmldebugger/qmldebugger.cpp b/tools/qmldebugger/qmldebugger.cpp index 0f0fc03..e0a76b6 100644 --- a/tools/qmldebugger/qmldebugger.cpp +++ b/tools/qmldebugger/qmldebugger.cpp @@ -57,6 +57,10 @@ QmlDebugger::QmlDebugger(QWidget *parent) QObject::connect(&client, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectionError(QAbstractSocket::SocketError))); + + + m_tabs->setCurrentIndex(1); + connectToHost(); } void QmlDebugger::setHost(const QString &host) diff --git a/tools/qmldebugger/qmldebugger.pri b/tools/qmldebugger/qmldebugger.pri index ce36381..c49d334 100644 --- a/tools/qmldebugger/qmldebugger.pri +++ b/tools/qmldebugger/qmldebugger.pri @@ -7,7 +7,8 @@ HEADERS += $$PWD/qmldebugger.h \ $$PWD/watchtable.h \ $$PWD/engine.h \ $$PWD/objecttree.h \ - $$PWD/objectpropertiesview.h + $$PWD/objectpropertiesview.h \ + $$PWD/expressionquerywidget.h SOURCES += $$PWD/qmldebugger.cpp \ $$PWD/main.cpp \ @@ -15,7 +16,8 @@ SOURCES += $$PWD/qmldebugger.cpp \ $$PWD/watchtable.cpp \ $$PWD/engine.cpp \ $$PWD/objecttree.cpp \ - $$PWD/objectpropertiesview.cpp + $$PWD/objectpropertiesview.cpp \ + $$PWD/expressionquerywidget.cpp RESOURCES += $$PWD/qmldebugger.qrc diff --git a/tools/qmldebugger/watchtable.cpp b/tools/qmldebugger/watchtable.cpp index e4163dc..512bfb2 100644 --- a/tools/qmldebugger/watchtable.cpp +++ b/tools/qmldebugger/watchtable.cpp @@ -193,6 +193,9 @@ void WatchTableModel::addValue(int column, const QVariant &value) void WatchTableModel::togglePropertyWatch(const QmlDebugObjectReference &object, const QmlDebugPropertyReference &property) { + if (!property.hasNotifySignal()) + return; + QmlDebugWatch *watch = findWatch(object.debugId(), property.name()); if (watch) { // watch will be deleted in watchStateChanged() diff --git a/tools/qmlviewer/qmlviewer.cpp b/tools/qmlviewer/qmlviewer.cpp index 07b68ea..a8034cf 100644 --- a/tools/qmlviewer/qmlviewer.cpp +++ b/tools/qmlviewer/qmlviewer.cpp @@ -630,6 +630,11 @@ void QmlViewer::openQml(const QString& fileName) QUrl url(fileName); QFileInfo fi(fileName); if (fi.exists()) { + if (fi.suffix().toLower() != QLatin1String("qml")) { + qWarning() << "qmlviewer cannot open non-QML file" << fileName; + return; + } + url = QUrl::fromLocalFile(fi.absoluteFilePath()); QmlContext *ctxt = canvas->rootContext(); QDir dir(fi.path()+"/dummydata", "*.qml"); @@ -658,6 +663,9 @@ void QmlViewer::openQml(const QString& fileName) dummyData->setParent(this); } } + } else { + qWarning() << "qmlviewer cannot find file:" << fileName; + return; } canvas->setUrl(url); |