Commit 12a02c75 authored by Kai Koehne's avatar Kai Koehne

QmlProfiler: Add attach/detach menu entry

This allows one to also profile apps on device (as long as there
is a working TCP/IP connection).
parent 02ea9144
......@@ -18,7 +18,8 @@ SOURCES += \
qmlprofilertool.cpp \
qmlprofilerengine.cpp \
tracewindow.cpp \
timelineview.cpp
timelineview.cpp \
qmlprofilerattachdialog.cpp
HEADERS += \
qmlprofilerconstants.h \
......@@ -27,7 +28,8 @@ HEADERS += \
qmlprofilertool.h \
qmlprofilerengine.h \
tracewindow.h \
timelineview.h
timelineview.h \
qmlprofilerattachdialog.h
RESOURCES += \
qml/qml.qrc
......@@ -42,3 +44,6 @@ OTHER_FILES += \
RecordButton.qml \
ToolButton.qml \
MainView.js
FORMS += \
qmlprofilerattachdialog.ui
#include "qmlprofilerattachdialog.h"
#include "ui_qmlprofilerattachdialog.h"
namespace QmlProfiler {
namespace Internal {
QmlProfilerAttachDialog::QmlProfilerAttachDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::QmlProfilerAttachDialog)
{
ui->setupUi(this);
}
QmlProfilerAttachDialog::~QmlProfilerAttachDialog()
{
delete ui;
}
QString QmlProfilerAttachDialog::address() const
{
return ui->addressLineEdit->text();
}
uint QmlProfilerAttachDialog::port() const
{
return ui->portSpinBox->value();
}
void QmlProfilerAttachDialog::setAddress(const QString &address)
{
ui->addressLineEdit->setText(address);
}
void QmlProfilerAttachDialog::setPort(uint port)
{
ui->portSpinBox->setValue(port);
}
} // namespace Internal
} // namespace QmlProfiler
#ifndef QMLPROFILERATTACHDIALOG_H
#define QMLPROFILERATTACHDIALOG_H
#include <QDialog>
namespace QmlProfiler {
namespace Internal {
namespace Ui {
class QmlProfilerAttachDialog;
}
class QmlProfilerAttachDialog : public QDialog
{
Q_OBJECT
public:
explicit QmlProfilerAttachDialog(QWidget *parent = 0);
~QmlProfilerAttachDialog();
QString address() const;
uint port() const;
void setAddress(const QString &address);
void setPort(uint port);
private:
Ui::QmlProfilerAttachDialog *ui;
};
} // namespace Internal
} // namespace QmlProfiler
#endif // QMLPROFILERATTACHDIALOG_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmlProfiler::Internal::QmlProfilerAttachDialog</class>
<widget class="QDialog" name="QmlProfiler::Internal::QmlProfilerAttachDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>164</width>
<height>96</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="addressLabel">
<property name="text">
<string>Address:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="addressLineEdit">
<property name="text">
<string>127.0.0.1</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="portLabel">
<property name="text">
<string>Port:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="portSpinBox">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>65535</number>
</property>
<property name="value">
<number>3768</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QmlProfiler::Internal::QmlProfilerAttachDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QmlProfiler::Internal::QmlProfilerAttachDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
......@@ -37,11 +37,9 @@
namespace QmlProfiler {
namespace Constants {
const char * const ACTION_ID = "QmlProfilerPlugin.Action";
const char * const MENU_ID = "QmlProfilerPlugin.Menu";
const char * const ATTACH = "Menu.Analyzer.Attach";
} // namespace QmlProfiler
} // namespace Constants
} // namespace QmlProfiler
#endif // QMLPROFILERCONSTANTS_H
......@@ -69,6 +69,7 @@ public:
~QmlProfilerEnginePrivate() {}
bool launchperfmonitor();
bool attach(const QString &address, uint port);
QmlProfilerEngine *q;
......@@ -178,3 +179,21 @@ bool QmlProfilerEngine::QmlProfilerEnginePrivate::launchperfmonitor()
return true;
}
......@@ -34,6 +34,8 @@
#include "qmlprofilertool.h"
#include "qmlprofilerengine.h"
#include "qmlprofilerplugin.h"
#include "qmlprofilerconstants.h"
#include "qmlprofilerattachdialog.h"
#include "tracewindow.h"
#include <private/qdeclarativedebugclient_p.h>
......@@ -56,7 +58,11 @@
#include <projectexplorer/target.h>
#include <texteditor/itexteditor.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h>
#include <QtCore/QFile>
......@@ -107,6 +113,9 @@ public:
QmlProfilerOutputPaneAdapter *m_outputPaneAdapter;
ProjectExplorer::Project *m_project;
Utils::FileInProjectFinder m_projectFinder;
ProjectExplorer::RunConfiguration *m_runConfiguration;
bool m_isAttached;
QAction *m_attachAction;
};
QmlProfilerTool::QmlProfilerTool(QObject *parent)
......@@ -116,6 +125,9 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
d->m_traceWindow = 0;
d->m_outputPaneAdapter = 0;
d->m_project = 0;
d->m_runConfiguration = 0;
d->m_isAttached = false;
d->m_attachAction = 0;
}
QmlProfilerTool::~QmlProfilerTool()
......@@ -148,6 +160,7 @@ IAnalyzerEngine *QmlProfilerTool::createEngine(const AnalyzerStartParameters &sp
{
QmlProfilerEngine *engine = new QmlProfilerEngine(sp, runConfiguration);
d->m_runConfiguration = runConfiguration;
d->m_project = runConfiguration->target()->project();
if (d->m_project) {
d->m_projectFinder.setProjectDirectory(d->m_project->projectDirectory());
......@@ -159,8 +172,6 @@ IAnalyzerEngine *QmlProfilerTool::createEngine(const AnalyzerStartParameters &sp
connect(engine, SIGNAL(processTerminated()), this, SLOT(disconnectClient()));
connect(engine, SIGNAL(stopRecording()), this, SLOT(stopRecording()));
connect(d->m_traceWindow, SIGNAL(viewUpdated()), engine, SLOT(viewUpdated()));
connect(d->m_traceWindow, SIGNAL(gotoSourceLocation(QString,int)), this, SLOT(gotoSourceLocation(QString,int)));
connect(d->m_traceWindow, SIGNAL(timeChanged(qreal)), this, SLOT(updateTimer(qreal)));
return engine;
}
......@@ -178,6 +189,22 @@ void QmlProfilerTool::initialize(ExtensionSystem::IPlugin */*plugin*/)
d->m_client = new QDeclarativeDebugConnection;
d->m_traceWindow = new TraceWindow();
d->m_traceWindow->reset(d->m_client);
connect(d->m_traceWindow, SIGNAL(gotoSourceLocation(QString,int)), this, SLOT(gotoSourceLocation(QString,int)));
connect(d->m_traceWindow, SIGNAL(timeChanged(qreal)), this, SLOT(updateTimer(qreal)));
Core::ICore *core = Core::ICore::instance();
Core::ActionManager *am = core->actionManager();
Core::ActionContainer *manalyzer = am->actionContainer(Analyzer::Constants::M_DEBUG_ANALYZER);
const Core::Context globalcontext(Core::Constants::C_GLOBAL);
d->m_attachAction = new QAction(tr("Attach ..."), manalyzer);
Core::Command *command = am->registerAction(d->m_attachAction,
Constants::ATTACH, globalcontext);
command->setAttribute(Core::Command::CA_UpdateText);
manalyzer->addAction(command, Analyzer::Constants::G_ANALYZER_STARTSTOP);
connect(d->m_attachAction, SIGNAL(triggered()), this, SLOT(attach()));
updateAttachAction();
}
void QmlProfilerTool::extensionsInitialized()
......@@ -285,3 +312,36 @@ bool QmlProfilerTool::canRunRemotely() const
// TODO: Is this correct?
return true;
}
void QmlProfilerTool::attach()
{
if (!d->m_isAttached) {
QmlProfilerAttachDialog dialog;
int result = dialog.exec();
if (result == QDialog::Rejected)
return;
port = dialog.port();
host = dialog.address();
connectClient();
AnalyzerManager::instance()->showMode();
} else {
stopRecording();
}
d->m_isAttached = !d->m_isAttached;
updateAttachAction();
}
void QmlProfilerTool::updateAttachAction()
{
if (d->m_attachAction) {
if (d->m_isAttached) {
d->m_attachAction->setText(tr("Detach"));
} else {
d->m_attachAction->setText(tr("Attach..."));
}
}
}
......@@ -82,6 +82,8 @@ public:
private slots:
void updateProjectFileList();
void attach();
void updateAttachAction();
private:
class QmlProfilerToolPrivate;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment