diff options
author | Bea Lam <bea.lam@nokia.com> | 2009-10-27 05:45:53 (GMT) |
---|---|---|
committer | Bea Lam <bea.lam@nokia.com> | 2009-10-27 05:45:53 (GMT) |
commit | 07bdaf208962b1c8605736f30920f4e6dfb0418e (patch) | |
tree | e38f4cf7d29310df9d9b80e216cd3a7ee037c08c /tools | |
parent | cc4bca61687f6441984ccc58ad177d24b6d3e92f (diff) | |
download | Qt-07bdaf208962b1c8605736f30920f4e6dfb0418e.zip Qt-07bdaf208962b1c8605736f30920f4e6dfb0418e.tar.gz Qt-07bdaf208962b1c8605736f30920f4e6dfb0418e.tar.bz2 |
Add qmldebugger/creatorplugin
Diffstat (limited to 'tools')
-rw-r--r-- | tools/qmldebugger/creatorplugin/QmlInspector.pluginspec | 28 | ||||
-rw-r--r-- | tools/qmldebugger/creatorplugin/README | 5 | ||||
-rw-r--r-- | tools/qmldebugger/creatorplugin/creatorplugin.pro | 29 | ||||
-rw-r--r-- | tools/qmldebugger/creatorplugin/images/logo.png | bin | 0 -> 2662 bytes | |||
-rw-r--r-- | tools/qmldebugger/creatorplugin/inspectoroutputpane.cpp | 108 | ||||
-rw-r--r-- | tools/qmldebugger/creatorplugin/inspectoroutputpane.h | 55 | ||||
-rw-r--r-- | tools/qmldebugger/creatorplugin/qmlinspector.h | 25 | ||||
-rw-r--r-- | tools/qmldebugger/creatorplugin/qmlinspector.qrc | 6 | ||||
-rw-r--r-- | tools/qmldebugger/creatorplugin/qmlinspectormode.cpp | 495 | ||||
-rw-r--r-- | tools/qmldebugger/creatorplugin/qmlinspectormode.h | 91 | ||||
-rw-r--r-- | tools/qmldebugger/creatorplugin/qmlinspectorplugin.cpp | 138 | ||||
-rw-r--r-- | tools/qmldebugger/creatorplugin/qmlinspectorplugin.h | 50 | ||||
-rw-r--r-- | tools/qmldebugger/creatorplugin/runcontrol.cpp | 135 | ||||
-rw-r--r-- | tools/qmldebugger/creatorplugin/runcontrol.h | 65 | ||||
-rw-r--r-- | tools/qmldebugger/qmldebugger.pro | 10 |
15 files changed, 1240 insertions, 0 deletions
diff --git a/tools/qmldebugger/creatorplugin/QmlInspector.pluginspec b/tools/qmldebugger/creatorplugin/QmlInspector.pluginspec new file mode 100644 index 0000000..cdba135 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/QmlInspector.pluginspec @@ -0,0 +1,28 @@ +<plugin name="QmlInspector" version="1.3.80" compatVersion="1.3.80"> + <vendor>Nokia Corporation</vendor> + <copyright>(C) 2008-2009 Nokia Corporation</copyright> + <license> +Commercial Usage + +Licensees holding valid Qt Commercial licenses may use this plugin in +accordance with the Qt Commercial License Agreement provided with the +Software or, alternatively, in accordance with the terms contained in +a written agreement between you and Nokia. + +GNU Lesser General Public License Usage + +Alternatively, this plugin may be used under the terms of the GNU Lesser +General Public License version 2.1 as published by the Free Software +Foundation. 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.</license> + <description>Qml support</description> + <url>http://qt.nokia.com</url> + <dependencyList> + <dependency name="QmlProjectManager" version="1.3.80"/> + <dependency name="ProjectExplorer" version="1.3.80"/> + <dependency name="CppTools" version="1.3.80"/> + <dependency name="CppEditor" version="1.3.80"/> + <dependency name="Help" version="1.3.80"/> + </dependencyList> +</plugin>
\ No newline at end of file diff --git a/tools/qmldebugger/creatorplugin/README b/tools/qmldebugger/creatorplugin/README new file mode 100644 index 0000000..e7e205e --- /dev/null +++ b/tools/qmldebugger/creatorplugin/README @@ -0,0 +1,5 @@ +To enable this project, qmldebugger.pro requires that these two environment +variables be defined: + +CREATOR_SRC_DIR -> source directory for Qt Creator +CREATOR_BUILD_DIR -> build directory for Qt Creator diff --git a/tools/qmldebugger/creatorplugin/creatorplugin.pro b/tools/qmldebugger/creatorplugin/creatorplugin.pro new file mode 100644 index 0000000..d191a37 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/creatorplugin.pro @@ -0,0 +1,29 @@ +TEMPLATE = lib +TARGET = QmlInspector + +INCLUDEPATH += . +DEPENDPATH += . + +include(../standalone/qmldebugger.pri) + +HEADERS += qmlinspectorplugin.h \ + qmlinspector.h \ + qmlinspectormode.h \ + inspectoroutputpane.h \ + runcontrol.h + +SOURCES += qmlinspectorplugin.cpp \ + qmlinspectormode.cpp \ + inspectoroutputpane.cpp \ + runcontrol.cpp + +OTHER_FILES += QmlInspector.pluginspec +RESOURCES += qmlinspector.qrc + +IDE_BUILD_TREE=$$(CREATOR_BUILD_DIR) + +include($$(CREATOR_SRC_DIR)/src/qtcreatorplugin.pri) +include($$(CREATOR_SRC_DIR)/src/plugins/projectexplorer/projectexplorer.pri) +include($$(CREATOR_SRC_DIR)/src/plugins/coreplugin/coreplugin.pri) +LIBS += -L$$(CREATOR_BUILD_DIR)/lib/qtcreator + diff --git a/tools/qmldebugger/creatorplugin/images/logo.png b/tools/qmldebugger/creatorplugin/images/logo.png Binary files differnew file mode 100644 index 0000000..5ac14a5 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/images/logo.png diff --git a/tools/qmldebugger/creatorplugin/inspectoroutputpane.cpp b/tools/qmldebugger/creatorplugin/inspectoroutputpane.cpp new file mode 100644 index 0000000..d3f9913 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/inspectoroutputpane.cpp @@ -0,0 +1,108 @@ +#include <QtGui/qtextedit.h> + +#include "inspectoroutputpane.h" + +InspectorOutputPane::InspectorOutputPane(QObject *parent) + : Core::IOutputPane(parent), + m_textEdit(new QTextEdit) +{ +} + +InspectorOutputPane::~InspectorOutputPane() +{ + delete m_textEdit; +} + +QWidget *InspectorOutputPane::outputWidget(QWidget *parent) +{ + Q_UNUSED(parent); + return m_textEdit; +} + +QList<QWidget*> InspectorOutputPane::toolBarWidgets() const +{ + return QList<QWidget *>(); +} + +QString InspectorOutputPane::name() const +{ + return tr("Inspector Output"); +} + +int InspectorOutputPane::priorityInStatusBar() const +{ + return 1; +} + +void InspectorOutputPane::clearContents() +{ + m_textEdit->clear(); +} + +void InspectorOutputPane::visibilityChanged(bool visible) +{ + Q_UNUSED(visible); +} + +void InspectorOutputPane::setFocus() +{ + m_textEdit->setFocus(); +} + +bool InspectorOutputPane::hasFocus() +{ + return m_textEdit->hasFocus(); +} + +bool InspectorOutputPane::canFocus() +{ + return true; +} + +bool InspectorOutputPane::canNavigate() +{ + return false; +} + +bool InspectorOutputPane::canNext() +{ + return false; +} + +bool InspectorOutputPane::canPrevious() +{ + return false; +} + +void InspectorOutputPane::goToNext() +{ +} + +void InspectorOutputPane::goToPrev() +{ +} + +void InspectorOutputPane::addOutput(RunControl *, const QString &text) +{ + m_textEdit->insertPlainText(text); + m_textEdit->moveCursor(QTextCursor::End); +} + +void InspectorOutputPane::addOutputInline(RunControl *, const QString &text) +{ + m_textEdit->insertPlainText(text); + m_textEdit->moveCursor(QTextCursor::End); +} + +void InspectorOutputPane::addErrorOutput(RunControl *, const QString &text) +{ + m_textEdit->append(text); + m_textEdit->moveCursor(QTextCursor::End); +} + +void InspectorOutputPane::addInspectorStatus(const QString &text) +{ + m_textEdit->append(text); + m_textEdit->moveCursor(QTextCursor::End); +} + diff --git a/tools/qmldebugger/creatorplugin/inspectoroutputpane.h b/tools/qmldebugger/creatorplugin/inspectoroutputpane.h new file mode 100644 index 0000000..60c648a --- /dev/null +++ b/tools/qmldebugger/creatorplugin/inspectoroutputpane.h @@ -0,0 +1,55 @@ +#ifndef INSPECTOROUTPUTPANE_H +#define INSPECTOROUTPUTPANE_H + +#include <QtCore/QObject> + +#include <coreplugin/ioutputpane.h> + + +QT_BEGIN_NAMESPACE + +class QTextEdit; + +class RunControl; + +class InspectorOutputPane : public Core::IOutputPane +{ + Q_OBJECT +public: + InspectorOutputPane(QObject *parent = 0); + virtual ~InspectorOutputPane(); + + virtual QWidget *outputWidget(QWidget *parent); + virtual QList<QWidget*> toolBarWidgets() const; + virtual QString name() const; + + virtual int priorityInStatusBar() const; + + virtual void clearContents(); + virtual void visibilityChanged(bool visible); + + virtual void setFocus(); + virtual bool hasFocus(); + virtual bool canFocus(); + + virtual bool canNavigate(); + virtual bool canNext(); + virtual bool canPrevious(); + virtual void goToNext(); + virtual void goToPrev(); + +public slots: + void addOutput(RunControl *, const QString &text); + void addOutputInline(RunControl *, const QString &text); + + void addErrorOutput(RunControl *, const QString &text); + void addInspectorStatus(const QString &text); + +private: + QTextEdit *m_textEdit; +}; + +QT_END_NAMESPACE + +#endif + diff --git a/tools/qmldebugger/creatorplugin/qmlinspector.h b/tools/qmldebugger/creatorplugin/qmlinspector.h new file mode 100644 index 0000000..98b9cbe --- /dev/null +++ b/tools/qmldebugger/creatorplugin/qmlinspector.h @@ -0,0 +1,25 @@ +#ifndef QMLINSPECTOR_H +#define QMLINSPECTOR_H + +#include <QString> + +namespace QmlInspector { + namespace Constants { + const char * const RUN = "QmlInspector.Run"; + const char * const STOP = "QmlInspector.Stop"; + + const char * const C_INSPECTOR = "QmlInspector"; + }; + + class StartParameters + { + public: + StartParameters() : port(0) {} + ~StartParameters() {} + + QString address; + quint16 port; + }; +}; + +#endif diff --git a/tools/qmldebugger/creatorplugin/qmlinspector.qrc b/tools/qmldebugger/creatorplugin/qmlinspector.qrc new file mode 100644 index 0000000..45e8dda --- /dev/null +++ b/tools/qmldebugger/creatorplugin/qmlinspector.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/qmlinspector" > + <file>images/logo.png</file> + </qresource> +</RCC> + diff --git a/tools/qmldebugger/creatorplugin/qmlinspectormode.cpp b/tools/qmldebugger/creatorplugin/qmlinspectormode.cpp new file mode 100644 index 0000000..9367b19 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/qmlinspectormode.cpp @@ -0,0 +1,495 @@ +#include <QtCore/QStringList> +#include <QtCore/QtPlugin> +#include <QtCore/QDebug> + +#include <QtGui/qtoolbutton.h> +#include <QtGui/qtoolbar.h> +#include <QtGui/qboxlayout.h> +#include <QtGui/qlabel.h> +#include <QtGui/qdockwidget.h> +#include <QtGui/qaction.h> +#include <QtGui/qlineedit.h> +#include <QtGui/qlabel.h> +#include <QtGui/qspinbox.h> + +#include <coreplugin/basemode.h> +#include <coreplugin/findplaceholder.h> +#include <coreplugin/minisplitter.h> +#include <coreplugin/outputpane.h> +#include <coreplugin/rightpane.h> +#include <coreplugin/navigationwidget.h> +#include <coreplugin/icore.h> +#include <coreplugin/coreconstants.h> +#include <coreplugin/uniqueidmanager.h> + +#include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/actionmanager/actionmanager.h> + +#include <projectexplorer/runconfiguration.h> +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/project.h> + +#include <utils/styledbar.h> +#include <utils/fancymainwindow.h> + +#include <QtDeclarative/qmldebug.h> +#include <QtDeclarative/qmldebugclient.h> + +#include "../standalone/objectpropertiesview.h" +#include "../standalone/objecttree.h" +#include "../standalone/watchtable.h" +#include "../standalone/canvasframerate.h" +#include "../standalone/expressionquerywidget.h" + +#include "qmlinspector.h" +#include "qmlinspectormode.h" + +QT_BEGIN_NAMESPACE + + +class EngineSpinBox : public QSpinBox +{ + Q_OBJECT +public: + struct EngineInfo + { + QString name; + int id; + }; + + EngineSpinBox(QWidget *parent = 0); + + void addEngine(int engine, const QString &name); + void clearEngines(); + +protected: + virtual QString textFromValue(int value) const; + virtual int valueFromText(const QString &text) const; + +private: + QList<EngineInfo> m_engines; +}; + +EngineSpinBox::EngineSpinBox(QWidget *parent) + : QSpinBox(parent) +{ + setEnabled(false); + setReadOnly(true); + setRange(0, 0); +} + +void EngineSpinBox::addEngine(int engine, const QString &name) +{ + EngineInfo info; + info.id = engine; + if (name.isEmpty()) + info.name = tr("Engine %1", "engine number").arg(engine); + else + info.name = name; + m_engines << info; + + setRange(0, m_engines.count()-1); +} + +void EngineSpinBox::clearEngines() +{ + m_engines.clear(); +} + +QString EngineSpinBox::textFromValue(int value) const +{ + for (int i=0; i<m_engines.count(); i++) { + if (m_engines[i].id == value) + return m_engines[i].name; + } + return QLatin1String("<None>"); +} + +int EngineSpinBox::valueFromText(const QString &text) const +{ + for (int i=0; i<m_engines.count(); i++) { + if (m_engines[i].name == text) + return m_engines[i].id; + } + return -1; +} + + +QmlInspectorMode::QmlInspectorMode(QObject *parent) + : Core::BaseMode(parent), + m_conn(0), + m_client(0), + m_engineQuery(0), + m_contextQuery(0) +{ + m_watchTableModel = new WatchTableModel(0, this); + + initActions(); + setWidget(createModeWindow()); + + setName(tr("QML Inspect")); + setIcon(QIcon(":/qmlinspector/images/logo.png")); + setUniqueModeName("QML_INSPECT_MODE"); +} + +quint16 QmlInspectorMode::viewerPort() const +{ + return m_portSpinBox->value(); +} + +void QmlInspectorMode::connectToViewer() +{ + if (m_conn && m_conn->state() != QAbstractSocket::UnconnectedState) + return; + + delete m_client; m_client = 0; + + if (m_conn) { + m_conn->disconnectFromHost(); + delete m_conn; + } + + m_conn = new QmlDebugConnection(this); + connect(m_conn, SIGNAL(stateChanged(QAbstractSocket::SocketState)), + SLOT(connectionStateChanged())); + connect(m_conn, SIGNAL(error(QAbstractSocket::SocketError)), + SLOT(connectionError())); + m_conn->connectToHost(m_addressEdit->text(), m_portSpinBox->value()); +} + +void QmlInspectorMode::disconnectFromViewer() +{ + m_conn->disconnectFromHost(); +} + +void QmlInspectorMode::connectionStateChanged() +{ + switch (m_conn->state()) { + default: + case QAbstractSocket::UnconnectedState: + emit statusMessage(tr("[Inspector] disconnected\n\n")); + m_addressEdit->setEnabled(true); + m_portSpinBox->setEnabled(true); + break; + case QAbstractSocket::HostLookupState: + emit statusMessage(tr("[Inspector] resolving host...")); + break; + case QAbstractSocket::ConnectingState: + emit statusMessage(tr("[Inspector] connecting to debug server...")); + break; + case QAbstractSocket::ConnectedState: + { + emit statusMessage(tr("[Inspector] connected\n")); + m_addressEdit->setEnabled(false); + m_portSpinBox->setEnabled(false); + + if (!m_client) { + m_client = new QmlEngineDebug(m_conn, this); + m_objectTreeWidget->setEngineDebug(m_client); + m_propertiesWidget->setEngineDebug(m_client); + m_watchTableModel->setEngineDebug(m_client); + m_expressionWidget->setEngineDebug(m_client); + } + + m_objectTreeWidget->clear(); + m_propertiesWidget->clear(); + m_expressionWidget->clear(); + m_watchTableModel->removeAllWatches(); + m_frameRateWidget->reset(m_conn); + + reloadEngines(); + break; + } + case QAbstractSocket::ClosingState: + emit statusMessage(tr("[Inspector] closing...")); + break; + } +} + +void QmlInspectorMode::connectionError() +{ + emit statusMessage(tr("[Inspector] error: (%1) %2", "%1=error code, %2=error message") + .arg(m_conn->error()).arg(m_conn->errorString())); +} + +void QmlInspectorMode::initActions() +{ + m_actions.startAction = new QAction(tr("Start Inspector"), this); + m_actions.startAction->setIcon(QIcon(ProjectExplorer::Constants::ICON_RUN)); + + m_actions.stopAction = new QAction(tr("Stop Inspector"), this); + m_actions.stopAction->setIcon(QIcon(ProjectExplorer::Constants::ICON_STOP)); + + Core::ICore *core = Core::ICore::instance(); + Core::ActionManager *am = core->actionManager(); + Core::UniqueIDManager *uidm = core->uniqueIDManager(); + + QList<int> context; + context << uidm->uniqueIdentifier(QmlInspector::Constants::C_INSPECTOR); + + am->registerAction(m_actions.startAction, QmlInspector::Constants::RUN, context); + connect(m_actions.startAction, SIGNAL(triggered()), SIGNAL(startViewer())); + + am->registerAction(m_actions.stopAction, QmlInspector::Constants::STOP, context); + connect(m_actions.stopAction, SIGNAL(triggered()), SIGNAL(stopViewer())); +} + + +QToolButton *QmlInspectorMode::createToolButton(QAction *action) +{ + QToolButton *button = new QToolButton; + button->setDefaultAction(action); + return button; +} + +QWidget *QmlInspectorMode::createMainView() +{ + initWidgets(); + + Utils::FancyMainWindow *mainWindow = new Utils::FancyMainWindow; + mainWindow->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); + mainWindow->setDocumentMode(true); + + QBoxLayout *editorHolderLayout = new QVBoxLayout; + editorHolderLayout->setMargin(0); + editorHolderLayout->setSpacing(0); + + QWidget *editorAndFindWidget = new QWidget; + editorAndFindWidget->setLayout(editorHolderLayout); + editorHolderLayout->addWidget(new Core::EditorManagerPlaceHolder(this)); + editorHolderLayout->addWidget(new Core::FindToolBarPlaceHolder(editorAndFindWidget)); + + Utils::StyledBar *treeOptionBar = new Utils::StyledBar; + QHBoxLayout *treeOptionBarLayout = new QHBoxLayout(treeOptionBar); + treeOptionBarLayout->setContentsMargins(5, 0, 5, 0); + treeOptionBarLayout->setSpacing(5); + treeOptionBarLayout->addWidget(new QLabel(tr("QML engine:"))); + treeOptionBarLayout->addWidget(m_engineSpinBox); + + QWidget *treeWindow = new QWidget; + QVBoxLayout *treeWindowLayout = new QVBoxLayout(treeWindow); + treeWindowLayout->setMargin(0); + treeWindowLayout->setSpacing(0); + treeWindowLayout->addWidget(treeOptionBar); + treeWindowLayout->addWidget(m_objectTreeWidget); + + Core::MiniSplitter *documentAndTree = new Core::MiniSplitter; + documentAndTree->addWidget(editorAndFindWidget); + documentAndTree->addWidget(new Core::RightPanePlaceHolder(this)); + documentAndTree->addWidget(treeWindow); + documentAndTree->setStretchFactor(0, 2); + documentAndTree->setStretchFactor(1, 0); + documentAndTree->setStretchFactor(2, 0); + + Utils::StyledBar *configBar = new Utils::StyledBar; + configBar->setProperty("topBorder", true); + + QHBoxLayout *configBarLayout = new QHBoxLayout(configBar); + configBarLayout->setMargin(0); + configBarLayout->setSpacing(5); + + Core::ICore *core = Core::ICore::instance(); + Core::ActionManager *am = core->actionManager(); + configBarLayout->addWidget(createToolButton(am->command(QmlInspector::Constants::RUN)->action())); + configBarLayout->addWidget(createToolButton(am->command(QmlInspector::Constants::STOP)->action())); + configBarLayout->addWidget(m_addressEdit); + configBarLayout->addWidget(m_portSpinBox); + configBarLayout->addStretch(); + + QWidget *widgetAboveTabs = new QWidget; + QVBoxLayout *widgetAboveTabsLayout = new QVBoxLayout(widgetAboveTabs); + widgetAboveTabsLayout->setMargin(0); + widgetAboveTabsLayout->setSpacing(0); + widgetAboveTabsLayout->addWidget(documentAndTree); + widgetAboveTabsLayout->addWidget(configBar); + + Core::MiniSplitter *mainSplitter = new Core::MiniSplitter(Qt::Vertical); + mainSplitter->addWidget(widgetAboveTabs); + mainSplitter->addWidget(createBottomWindow()); + mainSplitter->setStretchFactor(0, 3); + mainSplitter->setStretchFactor(1, 1); + + QWidget *centralWidget = new QWidget; + QVBoxLayout *centralLayout = new QVBoxLayout(centralWidget); + centralLayout->setMargin(0); + centralLayout->setSpacing(0); + centralLayout->addWidget(mainSplitter); + + mainWindow->setCentralWidget(centralWidget); + + return mainWindow; +} + +QWidget *QmlInspectorMode::createBottomWindow() +{ + Utils::FancyMainWindow *win = new Utils::FancyMainWindow; + win->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); + win->setDocumentMode(true); + win->setTrackingEnabled(true); + + Core::MiniSplitter *leftSplitter = new Core::MiniSplitter(Qt::Vertical); + leftSplitter->addWidget(m_propertiesWidget); + leftSplitter->addWidget(m_expressionWidget); + leftSplitter->setStretchFactor(0, 2); + leftSplitter->setStretchFactor(1, 1); + + Core::MiniSplitter *propSplitter = new Core::MiniSplitter(Qt::Horizontal); + propSplitter->addWidget(leftSplitter); + propSplitter->addWidget(m_watchTableView); + propSplitter->setStretchFactor(0, 2); + propSplitter->setStretchFactor(1, 1); + propSplitter->setWindowTitle(tr("Properties and Watchers")); + + QDockWidget *propertiesDock = win->addDockForWidget(propSplitter); + win->addDockWidget(Qt::TopDockWidgetArea, propertiesDock); + + QDockWidget *frameRateDock = win->addDockForWidget(m_frameRateWidget); + win->addDockWidget(Qt::TopDockWidgetArea, frameRateDock); + + // stack the dock widgets as tabs + win->tabifyDockWidget(frameRateDock, propertiesDock); + + return win; +} + +QWidget *QmlInspectorMode::createModeWindow() +{ + // right-side window with editor, output etc. + Core::MiniSplitter *mainWindowSplitter = new Core::MiniSplitter; + mainWindowSplitter->addWidget(createMainView()); + mainWindowSplitter->addWidget(new Core::OutputPanePlaceHolder(this)); + mainWindowSplitter->setStretchFactor(0, 10); + mainWindowSplitter->setStretchFactor(1, 0); + mainWindowSplitter->setOrientation(Qt::Vertical); + + // navigation + right-side window + Core::MiniSplitter *splitter = new Core::MiniSplitter; + splitter->addWidget(new Core::NavigationWidgetPlaceHolder(this)); + splitter->addWidget(mainWindowSplitter); + splitter->setStretchFactor(0, 0); + splitter->setStretchFactor(1, 1); + return splitter; +} + +void QmlInspectorMode::initWidgets() +{ + m_objectTreeWidget = new ObjectTree; + m_propertiesWidget = new ObjectPropertiesView; + m_watchTableView = new WatchTableView(m_watchTableModel); + m_frameRateWidget = new CanvasFrameRate; + m_expressionWidget = new ExpressionQueryWidget; + + // FancyMainWindow uses widgets' window titles for tab labels + m_objectTreeWidget->setWindowTitle(tr("Object Tree")); + m_frameRateWidget->setWindowTitle(tr("Frame rate")); + + m_watchTableView->setModel(m_watchTableModel); + WatchTableHeaderView *header = new WatchTableHeaderView(m_watchTableModel); + m_watchTableView->setHorizontalHeader(header); + + connect(m_objectTreeWidget, SIGNAL(currentObjectChanged(QmlDebugObjectReference)), + m_propertiesWidget, SLOT(reload(QmlDebugObjectReference))); + connect(m_objectTreeWidget, SIGNAL(expressionWatchRequested(QmlDebugObjectReference,QString)), + m_watchTableModel, SLOT(expressionWatchRequested(QmlDebugObjectReference,QString))); + + connect(m_propertiesWidget, SIGNAL(activated(QmlDebugObjectReference,QmlDebugPropertyReference)), + m_watchTableModel, SLOT(togglePropertyWatch(QmlDebugObjectReference,QmlDebugPropertyReference))); + + connect(m_watchTableModel, SIGNAL(watchCreated(QmlDebugWatch*)), + m_propertiesWidget, SLOT(watchCreated(QmlDebugWatch*))); + + connect(m_watchTableModel, SIGNAL(rowsInserted(QModelIndex,int,int)), + m_watchTableView, SLOT(scrollToBottom())); + + connect(m_watchTableView, SIGNAL(objectActivated(int)), + m_objectTreeWidget, SLOT(setCurrentObject(int))); + + connect(m_objectTreeWidget, SIGNAL(currentObjectChanged(QmlDebugObjectReference)), + m_expressionWidget, SLOT(setCurrentObject(QmlDebugObjectReference))); + + m_addressEdit = new QLineEdit; + m_addressEdit->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + m_addressEdit->setText("127.0.0.1"); + + m_portSpinBox = new QSpinBox; + m_portSpinBox->setMinimum(1024); + m_portSpinBox->setMaximum(20000); + m_portSpinBox->setValue(3768); + + m_engineSpinBox = new EngineSpinBox; + m_engineSpinBox->setEnabled(false); + connect(m_engineSpinBox, SIGNAL(valueChanged(int)), + SLOT(queryEngineContext(int))); +} + +void QmlInspectorMode::reloadEngines() +{ + if (m_engineQuery) { + emit statusMessage("[Inspector] Waiting for response to previous engine query"); + return; + } + + m_engineSpinBox->setEnabled(false); + + m_engineQuery = m_client->queryAvailableEngines(this); + if (!m_engineQuery->isWaiting()) + enginesChanged(); + else + QObject::connect(m_engineQuery, SIGNAL(stateChanged(State)), + this, SLOT(enginesChanged())); +} + +void QmlInspectorMode::enginesChanged() +{ + m_engineSpinBox->clearEngines(); + + QList<QmlDebugEngineReference> engines = m_engineQuery->engines(); + delete m_engineQuery; m_engineQuery = 0; + + if (engines.isEmpty()) + qWarning("qmldebugger: no engines found!"); + + m_engineSpinBox->setEnabled(true); + + for (int i=0; i<engines.count(); i++) + m_engineSpinBox->addEngine(engines.at(i).debugId(), engines.at(i).name()); + + if (engines.count() > 0) { + m_engineSpinBox->setValue(engines.at(0).debugId()); + queryEngineContext(engines.at(0).debugId()); + } +} + +void QmlInspectorMode::queryEngineContext(int id) +{ + if (id < 0) + return; + + if (m_contextQuery) { + delete m_contextQuery; + m_contextQuery = 0; + } + + m_contextQuery = m_client->queryRootContexts(QmlDebugEngineReference(id), this); + if (!m_contextQuery->isWaiting()) + contextChanged(); + else + QObject::connect(m_contextQuery, SIGNAL(stateChanged(State)), + this, SLOT(contextChanged())); +} + +void QmlInspectorMode::contextChanged() +{ + //dump(m_contextQuery->rootContext(), 0); + + foreach (const QmlDebugObjectReference &object, m_contextQuery->rootContext().objects()) + m_objectTreeWidget->reload(object.debugId()); + + delete m_contextQuery; m_contextQuery = 0; +} + +QT_END_NAMESPACE + +#include "qmlinspectormode.moc" + diff --git a/tools/qmldebugger/creatorplugin/qmlinspectormode.h b/tools/qmldebugger/creatorplugin/qmlinspectormode.h new file mode 100644 index 0000000..c70d630 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/qmlinspectormode.h @@ -0,0 +1,91 @@ +#ifndef QMLINSPECTORMODE_H +#define QMLINSPECTORMODE_H + +#include <QAction> + +#include <coreplugin/basemode.h> +#include <QtCore/QObject> + +QT_BEGIN_NAMESPACE + +class QToolButton; +class QLineEdit; +class QSpinBox; +class QLabel; + +class QmlEngineDebug; +class QmlDebugConnection; +class QmlDebugEnginesQuery; +class QmlDebugRootContextQuery; +class ObjectTree; +class WatchTableModel; +class WatchTableView; +class ObjectPropertiesView; +class CanvasFrameRate; +class ExpressionQueryWidget; +class EngineSpinBox; + + +class QmlInspectorMode : public Core::BaseMode +{ + Q_OBJECT + +public: + QmlInspectorMode(QObject *parent = 0); + + + quint16 viewerPort() const; + +signals: + void startViewer(); + void stopViewer(); + void statusMessage(const QString &text); + +public slots: + void connectToViewer(); // using host, port from widgets + void disconnectFromViewer(); + +private slots: + void connectionStateChanged(); + void connectionError(); + void reloadEngines(); + void enginesChanged(); + void queryEngineContext(int); + void contextChanged(); + +private: + struct Actions { + QAction *startAction; + QAction *stopAction; + }; + + void initActions(); + QWidget *createModeWindow(); + QWidget *createMainView(); + void initWidgets(); + QWidget *createBottomWindow(); + QToolButton *createToolButton(QAction *action); + + Actions m_actions; + + QmlDebugConnection *m_conn; + QmlEngineDebug *m_client; + + QmlDebugEnginesQuery *m_engineQuery; + QmlDebugRootContextQuery *m_contextQuery; + + ObjectTree *m_objectTreeWidget; + ObjectPropertiesView *m_propertiesWidget; + WatchTableModel *m_watchTableModel; + WatchTableView *m_watchTableView; + CanvasFrameRate *m_frameRateWidget; + ExpressionQueryWidget *m_expressionWidget; + + QLineEdit *m_addressEdit; + QSpinBox *m_portSpinBox; + EngineSpinBox *m_engineSpinBox; +}; + +QT_END_NAMESPACE + +#endif diff --git a/tools/qmldebugger/creatorplugin/qmlinspectorplugin.cpp b/tools/qmldebugger/creatorplugin/qmlinspectorplugin.cpp new file mode 100644 index 0000000..c743974 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/qmlinspectorplugin.cpp @@ -0,0 +1,138 @@ +#include <QtCore/QStringList> +#include <QtCore/QtPlugin> +#include <QtCore/QDebug> + +#include <coreplugin/icore.h> + +#include <projectexplorer/runconfiguration.h> +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/project.h> + +#include <coreplugin/coreconstants.h> +#include <coreplugin/uniqueidmanager.h> + +#include <extensionsystem/pluginmanager.h> + +#include <QtDeclarative/qmldebug.h> +#include <QtDeclarative/qmldebugclient.h> + +#include "runcontrol.h" +#include "qmlinspector.h" +#include "qmlinspectormode.h" +#include "inspectoroutputpane.h" +#include "qmlinspectorplugin.h" + +QT_BEGIN_NAMESPACE + + +QmlInspectorPlugin::QmlInspectorPlugin() + : m_inspectMode(0), + m_runControl(0) +{ +} + +QmlInspectorPlugin::~QmlInspectorPlugin() +{ +} + +void QmlInspectorPlugin::shutdown() +{ + removeObject(m_inspectMode); + delete m_inspectMode; + m_inspectMode = 0; + + removeObject(m_outputPane); + delete m_outputPane; + m_outputPane = 0; +} + +bool QmlInspectorPlugin::initialize(const QStringList &arguments, QString *errorString) +{ + Q_UNUSED(arguments); + Q_UNUSED(errorString); + + Core::ICore *core = Core::ICore::instance(); + Core::UniqueIDManager *uidm = core->uniqueIDManager(); + + QList<int> modeContext; + modeContext.append(uidm->uniqueIdentifier(QmlInspector::Constants::C_INSPECTOR)); + + QList<int> inspectorContext; + inspectorContext.append(uidm->uniqueIdentifier(Core::Constants::C_EDITORMANAGER)); + inspectorContext.append(uidm->uniqueIdentifier(QmlInspector::Constants::C_INSPECTOR)); + inspectorContext.append(uidm->uniqueIdentifier(Core::Constants::C_NAVIGATION_PANE)); + + m_inspectMode = new QmlInspectorMode(this); + connect(m_inspectMode, SIGNAL(startViewer()), SLOT(startViewer())); + connect(m_inspectMode, SIGNAL(stopViewer()), SLOT(stopViewer())); + m_inspectMode->setContext(modeContext); + addObject(m_inspectMode); + + m_outputPane = new InspectorOutputPane; + addObject(m_outputPane); + + connect(m_inspectMode, SIGNAL(statusMessage(QString)), + m_outputPane, SLOT(addInspectorStatus(QString))); + + m_runControlFactory = new QmlInspectorRunControlFactory(this); + addAutoReleasedObject(m_runControlFactory); + + return true; +} + +void QmlInspectorPlugin::extensionsInitialized() +{ +} + +void QmlInspectorPlugin::startViewer() +{ + stopViewer(); + + ProjectExplorer::Project *project = 0; + ProjectExplorer::ProjectExplorerPlugin *plugin = ProjectExplorer::ProjectExplorerPlugin::instance(); + if (plugin) + project = plugin->currentProject(); + if (!project) { + qDebug() << "No project loaded"; // TODO should this just run the debugger without a viewer? + return; + } + + QSharedPointer<ProjectExplorer::RunConfiguration> rc = project->activeRunConfiguration(); + + QmlInspector::StartParameters sp; + sp.port = m_inspectMode->viewerPort(); + + m_runControl = m_runControlFactory->create(rc, ProjectExplorer::Constants::RUNMODE, sp); + + if (m_runControl) { + connect(m_runControl, SIGNAL(started()), m_inspectMode, SLOT(connectToViewer())); + connect(m_runControl, SIGNAL(finished()), m_inspectMode, SLOT(disconnectFromViewer())); + + connect(m_runControl, SIGNAL(addToOutputWindow(RunControl*,QString)), + m_outputPane, SLOT(addOutput(RunControl*,QString))); + connect(m_runControl, SIGNAL(addToOutputWindowInline(RunControl*,QString)), + m_outputPane, SLOT(addOutputInline(RunControl*,QString))); + connect(m_runControl, SIGNAL(error(RunControl*,QString)), + m_outputPane, SLOT(addErrorOutput(RunControl*,QString))); + + m_runControl->start(); + m_outputPane->popup(false); + } + +} + +void QmlInspectorPlugin::stopViewer() +{ + if (m_runControl) { + m_runControl->stop(); + m_runControl->deleteLater(); + m_runControl = 0; + } +} + + +Q_EXPORT_PLUGIN(QmlInspectorPlugin) + +QT_END_NAMESPACE + diff --git a/tools/qmldebugger/creatorplugin/qmlinspectorplugin.h b/tools/qmldebugger/creatorplugin/qmlinspectorplugin.h new file mode 100644 index 0000000..b0237e2 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/qmlinspectorplugin.h @@ -0,0 +1,50 @@ +#ifndef QMLINSPECTORPLUGIN_H +#define QMLINSPECTORPLUGIN_H + +#include <extensionsystem/iplugin.h> + +#include <QtCore/QObject> +#include <QtCore/QPointer> + +QT_BEGIN_NAMESPACE + +class QStringList; + + +class QmlInspectorRunControlFactory; +class QmlInspectorMode; +class InspectorOutputPane; + +namespace ProjectExplorer +{ + class RunControl; +} + +class QmlInspectorPlugin : public ExtensionSystem::IPlugin +{ + Q_OBJECT + +public: + QmlInspectorPlugin(); + ~QmlInspectorPlugin(); + + virtual bool initialize(const QStringList &arguments, QString *errorString); + virtual void extensionsInitialized(); + virtual void shutdown(); + +private slots: + void startViewer(); + void stopViewer(); + +private: + QmlInspectorMode *m_inspectMode; + InspectorOutputPane *m_outputPane; + + QmlInspectorRunControlFactory *m_runControlFactory; + QPointer<ProjectExplorer::RunControl> m_runControl; +}; + + +QT_END_NAMESPACE + +#endif // QMLINSPECTORPLUGIN_H diff --git a/tools/qmldebugger/creatorplugin/runcontrol.cpp b/tools/qmldebugger/creatorplugin/runcontrol.cpp new file mode 100644 index 0000000..11c7165 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/runcontrol.cpp @@ -0,0 +1,135 @@ +#include <QtCore/qdebug.h> +#include <QtCore/qtimer.h> + +#include <projectexplorer/applicationlauncher.h> +#include <projectexplorer/applicationrunconfiguration.h> +#include <projectexplorer/projectexplorerconstants.h> + +#include "runcontrol.h" + +using namespace ProjectExplorer; + + +QmlInspectorRunControlFactory::QmlInspectorRunControlFactory(QObject *parent) + : ProjectExplorer::IRunControlFactory(parent) +{ +} + +bool QmlInspectorRunControlFactory::canRun(const QSharedPointer<RunConfiguration> &runConfiguration, const QString &mode) const +{ + Q_UNUSED(runConfiguration); + if (mode != ProjectExplorer::Constants::RUNMODE) + return false; + return true; +} + +ProjectExplorer::RunControl *QmlInspectorRunControlFactory::create(const QSharedPointer<RunConfiguration> &runConfiguration, const QString &mode) +{ + Q_UNUSED(mode); + return new QmlInspectorRunControl(runConfiguration); +} + +ProjectExplorer::RunControl *QmlInspectorRunControlFactory::create(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, +const QString &mode, const QmlInspector::StartParameters &sp) +{ + Q_UNUSED(mode); + return new QmlInspectorRunControl(runConfiguration, sp); +} + +QString QmlInspectorRunControlFactory::displayName() const +{ + return tr("Qml Inspector"); +} + +QWidget *QmlInspectorRunControlFactory::configurationWidget(const QSharedPointer<RunConfiguration> &runConfiguration) +{ + Q_UNUSED(runConfiguration); + return 0; +} + + + +QmlInspectorRunControl::QmlInspectorRunControl(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, +const QmlInspector::StartParameters &sp) + : ProjectExplorer::RunControl(runConfiguration), + m_running(false), + m_viewerLauncher(0), + m_startParams(sp) +{ +} + +QmlInspectorRunControl::~QmlInspectorRunControl() +{ +} + +void QmlInspectorRunControl::start() +{ + if (m_running || m_viewerLauncher) + return; + + m_viewerLauncher = new ProjectExplorer::ApplicationLauncher(this); + connect(m_viewerLauncher, SIGNAL(applicationError(QString)), SLOT(applicationError(QString))); + connect(m_viewerLauncher, SIGNAL(processExited(int)), SLOT(viewerExited())); + connect(m_viewerLauncher, SIGNAL(appendOutput(QString)), SLOT(appendOutput(QString))); + connect(m_viewerLauncher, SIGNAL(bringToForegroundRequested(qint64)), + this, SLOT(appStarted())); + + QSharedPointer<LocalApplicationRunConfiguration> rc = + runConfiguration().objectCast<LocalApplicationRunConfiguration>(); + if (rc.isNull()) { // TODO + return; + } + + ProjectExplorer::Environment env = rc->environment(); + env.set("QML_DEBUG_SERVER_PORT", QString::number(m_startParams.port)); + + QStringList arguments = rc->commandLineArguments(); + arguments << QLatin1String("-stayontop"); + + m_viewerLauncher->setEnvironment(env.toStringList()); + m_viewerLauncher->setWorkingDirectory(rc->workingDirectory()); + + m_running = true; + + m_viewerLauncher->start(static_cast<ApplicationLauncher::Mode>(rc->runMode()), + rc->executable(), arguments); +} + +void QmlInspectorRunControl::stop() +{ + if (m_viewerLauncher->isRunning()) + m_viewerLauncher->stop(); +} + +bool QmlInspectorRunControl::isRunning() const +{ + return m_running; +} + +void QmlInspectorRunControl::appStarted() +{ + QTimer::singleShot(500, this, SLOT(delayedStart())); +} + +void QmlInspectorRunControl::appendOutput(const QString &s) +{ + emit addToOutputWindow(this, s); +} + +void QmlInspectorRunControl::delayedStart() +{ + emit started(); +} + +void QmlInspectorRunControl::viewerExited() +{ + m_running = false; + emit finished(); + + deleteLater(); +} + +void QmlInspectorRunControl::applicationError(const QString &s) +{ + emit error(this, s); +} diff --git a/tools/qmldebugger/creatorplugin/runcontrol.h b/tools/qmldebugger/creatorplugin/runcontrol.h new file mode 100644 index 0000000..b2976f6 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/runcontrol.h @@ -0,0 +1,65 @@ +#ifndef QMLINSPECTORRUNCONTROL_H +#define QMLINSPECTORRUNCONTROL_H + +#include <QtCore/qobject.h> + +#include <projectexplorer/runconfiguration.h> + +#include "qmlinspector.h" + +namespace ProjectExplorer { + class ApplicationLauncher; +} + +class QmlInspectorRunControlFactory : public ProjectExplorer::IRunControlFactory +{ + Q_OBJECT + +public: + explicit QmlInspectorRunControlFactory(QObject *parent); + + virtual bool canRun( + const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, + const QString &mode) const; + + virtual ProjectExplorer::RunControl *create( + const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, + const QString &mode); + + ProjectExplorer::RunControl *create( + const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, + const QString &mode, + const QmlInspector::StartParameters &sp); + + virtual QString displayName() const; + + virtual QWidget *configurationWidget(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration); +}; + +class QmlInspectorRunControl : public ProjectExplorer::RunControl +{ + Q_OBJECT + +public: + explicit QmlInspectorRunControl(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, + const QmlInspector::StartParameters &sp = QmlInspector::StartParameters()); + ~QmlInspectorRunControl(); + + virtual void start(); + virtual void stop(); + virtual bool isRunning() const; + +private slots: + void appendOutput(const QString &s); + void appStarted(); + void delayedStart(); + void viewerExited(); + void applicationError(const QString &error); + +private: + bool m_running; + ProjectExplorer::ApplicationLauncher *m_viewerLauncher; + QmlInspector::StartParameters m_startParams; +}; + +#endif diff --git a/tools/qmldebugger/qmldebugger.pro b/tools/qmldebugger/qmldebugger.pro new file mode 100644 index 0000000..2dd353a --- /dev/null +++ b/tools/qmldebugger/qmldebugger.pro @@ -0,0 +1,10 @@ +TEMPLATE = subdirs +CONFIG += ordered + +SUBDIRS = standalone + +CREATOR_SRC = $$(CREATOR_SRC_DIR) +CREATOR_BUILD = $$(CREATOR_BUILD_DIR) +!isEmpty(CREATOR_SRC):!isEmpty(CREATOR_BUILD) { + SUBDIRS += creatorplugin +} |