forked from qt-creator/qt-creator
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).
This commit is contained in:
@@ -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
|
||||
|
||||
40
src/plugins/qmlprofiler/qmlprofilerattachdialog.cpp
Normal file
40
src/plugins/qmlprofiler/qmlprofilerattachdialog.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#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
|
||||
34
src/plugins/qmlprofiler/qmlprofilerattachdialog.h
Normal file
34
src/plugins/qmlprofiler/qmlprofilerattachdialog.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#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
|
||||
109
src/plugins/qmlprofiler/qmlprofilerattachdialog.ui
Normal file
109
src/plugins/qmlprofiler/qmlprofilerattachdialog.ui
Normal file
@@ -0,0 +1,109 @@
|
||||
<?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;
|
||||
|
||||
Reference in New Issue
Block a user