Files
qt-creator/src/plugins/perfprofiler/perfprofilertool.cpp
hjk e109b731ad Utils: Rename FilePathList to simply FilePaths
The exact storage type does not really matter here.

Change-Id: Iefec40f0f5909c8e7ba3415db4a11962694e1b38
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
2019-12-18 08:43:18 +00:00

716 lines
27 KiB
C++

/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "perfconfigwidget.h"
#include "perfloaddialog.h"
#include "perfprofilerplugin.h"
#include "perfprofilerruncontrol.h"
#include "perfprofilertool.h"
#include "perfrunconfigurationaspect.h"
#include "perfsettings.h"
#include "perftracepointdialog.h"
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/imode.h>
#include <coreplugin/messagebox.h>
#include <coreplugin/modemanager.h>
#include <debugger/analyzer/analyzerconstants.h>
#include <debugger/analyzer/analyzermanager.h>
#include <debugger/debuggericons.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h>
#include <projectexplorer/target.h>
#include <qtsupport/qtkitinformation.h>
#include <utils/algorithm.h>
#include <utils/fancymainwindow.h>
#include <utils/utilsicons.h>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QMenu>
#include <QMessageBox>
using namespace Core;
using namespace ProjectExplorer;
using namespace Debugger;
using namespace PerfProfiler::Constants;
using namespace Utils;
using namespace std::placeholders;
namespace PerfProfiler {
namespace Internal {
static PerfProfilerTool *s_instance;
PerfProfilerTool::PerfProfilerTool()
{
s_instance = this;
m_traceManager = new PerfProfilerTraceManager(this);
m_traceManager->registerFeatures(PerfEventType::allFeatures(),
nullptr,
std::bind(&PerfProfilerTool::initialize, this),
std::bind(&PerfProfilerTool::finalize, this),
std::bind(&PerfProfilerTool::clearUi, this));
m_modelManager = new PerfTimelineModelManager(m_traceManager);
m_zoomControl = new Timeline::TimelineZoomControl(this);
ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER);
ActionContainer *options = ActionManager::createMenu(Constants::PerfOptionsMenuId);
options->menu()->setTitle(tr("Performance Analyzer Options"));
menu->addMenu(options, Debugger::Constants::G_ANALYZER_OPTIONS);
options->menu()->setEnabled(true);
const Core::Context globalContext(Core::Constants::C_GLOBAL);
m_loadPerfData = new QAction(tr("Load perf.data File"), options);
Core::Command *command = Core::ActionManager::registerAction(
m_loadPerfData, Constants::PerfProfilerTaskLoadPerf, globalContext);
connect(m_loadPerfData, &QAction::triggered, this, &PerfProfilerTool::showLoadPerfDialog);
options->addAction(command);
m_loadTrace = new QAction(tr("Load Trace File"), options);
command = Core::ActionManager::registerAction(m_loadTrace, Constants::PerfProfilerTaskLoadTrace,
globalContext);
connect(m_loadTrace, &QAction::triggered, this, &PerfProfilerTool::showLoadTraceDialog);
options->addAction(command);
m_saveTrace = new QAction(tr("Save Trace File"), options);
command = Core::ActionManager::registerAction(m_saveTrace, Constants::PerfProfilerTaskSaveTrace,
globalContext);
connect(m_saveTrace, &QAction::triggered, this, &PerfProfilerTool::showSaveTraceDialog);
options->addAction(command);
m_limitToRange = new QAction(tr("Limit to Range Selected in Timeline"), options);
command = Core::ActionManager::registerAction(m_limitToRange, Constants::PerfProfilerTaskLimit,
globalContext);
connect(m_limitToRange, &QAction::triggered, this, [this]() {
m_traceManager->restrictByFilter(m_traceManager->rangeAndThreadFilter(
m_zoomControl->selectionStart(),
m_zoomControl->selectionEnd()));
});
options->addAction(command);
m_showFullRange = new QAction(tr("Show Full Range"), options);
command = Core::ActionManager::registerAction(m_showFullRange,
Constants::PerfProfilerTaskFullRange,
globalContext);
connect(m_showFullRange, &QAction::triggered, this, [this]() {
m_traceManager->restrictByFilter(m_traceManager->rangeAndThreadFilter(-1, -1));
});
options->addAction(command);
QAction *tracePointsAction = new QAction(tr("Create Memory Trace Points"), options);
tracePointsAction->setIcon(Debugger::Icons::TRACEPOINT_TOOLBAR.icon());
tracePointsAction->setIconVisibleInMenu(false);
tracePointsAction->setToolTip(tr("Create trace points for memory profiling on the target "
"device."));
command = Core::ActionManager::registerAction(tracePointsAction,
Constants::PerfProfilerTaskTracePoints,
globalContext);
connect(tracePointsAction, &QAction::triggered, this, &PerfProfilerTool::createTracePoints);
options->addAction(command);
m_tracePointsButton = new QToolButton;
m_tracePointsButton->setDefaultAction(tracePointsAction);
auto action = new QAction(tr("Performance Analyzer"), this);
action->setToolTip(tr("Finds performance bottlenecks."));
menu->addAction(ActionManager::registerAction(action, Constants::PerfProfilerLocalActionId),
Debugger::Constants::G_ANALYZER_TOOLS);
QObject::connect(action, &QAction::triggered, this, [this] {
m_perspective.select();
ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::PERFPROFILER_RUN_MODE);
});
m_startAction = Debugger::createStartAction();
m_stopAction = Debugger::createStopAction();
QObject::connect(m_startAction, &QAction::triggered, action, &QAction::triggered);
QObject::connect(m_startAction, &QAction::changed, action, [action, tracePointsAction, this] {
action->setEnabled(m_startAction->isEnabled());
tracePointsAction->setEnabled(m_startAction->isEnabled());
});
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions,
this, &PerfProfilerTool::updateRunActions);
m_recordButton = new QToolButton;
m_clearButton = new QToolButton;
m_filterButton = new QToolButton;
m_filterMenu = new QMenu(m_filterButton);
m_aggregateButton = new QToolButton;
m_recordedLabel = new QLabel;
m_recordedLabel->setProperty("panelwidget", true);
m_delayLabel = new QLabel;
m_delayLabel->setProperty("panelwidget", true);
m_perspective.setAboutToActivateCallback([this]() { createViews(); });
updateRunActions();
}
void PerfProfilerTool::createViews()
{
m_traceView = new PerfProfilerTraceView(nullptr, this);
m_traceView->setWindowTitle(tr("Timeline"));
connect(m_traceView, &PerfProfilerTraceView::gotoSourceLocation,
this, &PerfProfilerTool::gotoSourceLocation);
m_statisticsView = new PerfProfilerStatisticsView(nullptr, this);
m_statisticsView->setWindowTitle(tr("Statistics"));
m_flameGraphView = new PerfProfilerFlameGraphView(nullptr, this);
m_flameGraphView->setWindowTitle(tr("Flame Graph"));
connect(m_statisticsView, &PerfProfilerStatisticsView::gotoSourceLocation,
this, &PerfProfilerTool::gotoSourceLocation);
connect(m_flameGraphView, &PerfProfilerFlameGraphView::gotoSourceLocation,
this, &PerfProfilerTool::gotoSourceLocation);
if (m_traceView->isUsable()) {
m_perspective.addWindow(m_traceView, Perspective::SplitVertical, nullptr);
m_perspective.addWindow(m_flameGraphView, Perspective::AddToTab, m_traceView);
} else {
m_perspective.addWindow(m_flameGraphView, Perspective::SplitVertical, nullptr);
}
m_perspective.addWindow(m_statisticsView, Perspective::AddToTab, m_flameGraphView);
connect(m_statisticsView, &PerfProfilerStatisticsView::typeSelected,
m_traceView, &PerfProfilerTraceView::selectByTypeId);
connect(m_flameGraphView, &PerfProfilerFlameGraphView::typeSelected,
m_traceView, &PerfProfilerTraceView::selectByTypeId);
connect(m_traceView, &PerfProfilerTraceView::typeSelected,
m_statisticsView, &PerfProfilerStatisticsView::selectByTypeId);
connect(m_flameGraphView, &PerfProfilerFlameGraphView::typeSelected,
m_statisticsView, &PerfProfilerStatisticsView::selectByTypeId);
connect(m_traceView, &PerfProfilerTraceView::typeSelected,
m_flameGraphView, &PerfProfilerFlameGraphView::selectByTypeId);
connect(m_statisticsView, &PerfProfilerStatisticsView::typeSelected,
m_flameGraphView, &PerfProfilerFlameGraphView::selectByTypeId);
// Clear settings if the statistics or flamegraph view isn't there yet.
QSettings *settings = Core::ICore::settings();
settings->beginGroup(QLatin1String("AnalyzerViewSettings_") +
QLatin1String(Constants::PerfProfilerPerspectiveId));
if (!settings->contains(m_statisticsView->objectName())
|| !settings->contains(m_flameGraphView->objectName())) {
settings->remove(QString());
}
settings->endGroup();
m_recordButton->setCheckable(true);
QMenu *recordMenu = new QMenu(m_recordButton);
connect(recordMenu, &QMenu::aboutToShow, recordMenu, [recordMenu] {
recordMenu->hide();
PerfSettings *settings = nullptr;
Target *target = SessionManager::startupTarget();
if (target) {
if (auto runConfig = target->activeRunConfiguration())
settings = runConfig->currentSettings<PerfSettings>(Constants::PerfSettingsId);
}
PerfConfigWidget *widget = new PerfConfigWidget(
settings ? settings : PerfProfilerPlugin::globalSettings(),
Core::ICore::dialogParent());
widget->setTracePointsButtonVisible(true);
widget->setTarget(target);
widget->setWindowFlags(Qt::Dialog);
widget->setAttribute(Qt::WA_DeleteOnClose);
widget->show();
}, Qt::QueuedConnection);
m_recordButton->setPopupMode(QToolButton::MenuButtonPopup);
m_recordButton->setMenu(recordMenu);
setRecording(true);
connect(m_recordButton, &QAbstractButton::clicked, this, &PerfProfilerTool::setRecording);
m_clearButton->setIcon(Utils::Icons::CLEAN_TOOLBAR.icon());
m_clearButton->setToolTip(tr("Discard data."));
connect(m_clearButton, &QAbstractButton::clicked, this, &PerfProfilerTool::clear);
m_filterButton->setIcon(Utils::Icons::FILTER.icon());
m_filterButton->setPopupMode(QToolButton::InstantPopup);
m_filterButton->setProperty("noArrow", true);
m_filterButton->setMenu(m_filterMenu);
m_aggregateButton->setIcon(Utils::Icons::EXPAND_ALL_TOOLBAR.icon());
m_aggregateButton->setCheckable(true);
setAggregated(false);
connect(m_aggregateButton, &QAbstractButton::toggled, this, &PerfProfilerTool::setAggregated);
m_recordedLabel->setIndent(10);
connect(m_clearButton, &QAbstractButton::clicked, m_recordedLabel, &QLabel::clear);
m_delayLabel->setIndent(10);
connect(m_traceManager, &PerfProfilerTraceManager::error, this, [](const QString &message) {
QMessageBox *errorDialog = new QMessageBox(ICore::mainWindow());
errorDialog->setIcon(QMessageBox::Warning);
errorDialog->setWindowTitle(tr("Performance Analyzer"));
errorDialog->setText(message);
errorDialog->setStandardButtons(QMessageBox::Ok);
errorDialog->setDefaultButton(QMessageBox::Ok);
errorDialog->setModal(false);
errorDialog->show();
});
connect(m_traceManager, &PerfProfilerTraceManager::loadFinished, this, [this]() {
m_readerRunning = false;
updateRunActions();
});
connect(m_traceManager, &PerfProfilerTraceManager::saveFinished, this, [this]() {
setToolActionsEnabled(true);
});
connect(this, &PerfProfilerTool::aggregatedChanged,
m_traceManager, &PerfProfilerTraceManager::setAggregateAddresses);
QMenu *menu1 = new QMenu(m_traceView);
addLoadSaveActionsToMenu(menu1);
connect(menu1->addAction(tr("Limit to Selected Range")), &QAction::triggered,
m_limitToRange, &QAction::trigger);
menu1->addAction(m_showFullRange);
connect(menu1->addAction(tr("Reset Zoom")), &QAction::triggered, this, [this](){
m_zoomControl->setRange(m_zoomControl->traceStart(), m_zoomControl->traceEnd());
});
m_traceView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_traceView, &QWidget::customContextMenuRequested,
menu1, [menu1, this](const QPoint &pos) {
menu1->exec(m_traceView->mapToGlobal(pos));
});
menu1 = new QMenu(m_statisticsView);
addLoadSaveActionsToMenu(menu1);
connect(menu1->addAction(tr("Limit to Range Selected in Timeline")), &QAction::triggered,
m_limitToRange, &QAction::trigger);
connect(menu1->addAction(tr("Show Full Range")), &QAction::triggered,
m_showFullRange, &QAction::trigger);
connect(menu1->addAction(tr("Copy Table")), &QAction::triggered,
m_statisticsView, &PerfProfilerStatisticsView::copyFocusedTableToClipboard);
QAction *copySelection = menu1->addAction(tr("Copy Row"));
connect(copySelection, &QAction::triggered,
m_statisticsView, &PerfProfilerStatisticsView::copyFocusedSelectionToClipboard);
m_statisticsView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_statisticsView, &QWidget::customContextMenuRequested,
menu1, [this, menu1, copySelection](const QPoint &pos) {
copySelection->setEnabled(m_statisticsView->focusedTableHasValidSelection());
menu1->exec(m_statisticsView->mapToGlobal(pos));
});
menu1 = new QMenu(m_flameGraphView);
addLoadSaveActionsToMenu(menu1);
connect(menu1->addAction(tr("Limit to Range Selected in Timeline")), &QAction::triggered,
m_limitToRange, &QAction::trigger);
connect(menu1->addAction(tr("Show Full Range")), &QAction::triggered,
m_showFullRange, &QAction::trigger);
QAction *resetAction = menu1->addAction(tr("Reset Flame Graph"));
connect(resetAction, &QAction::triggered,
m_flameGraphView, &PerfProfilerFlameGraphView::resetRoot);
m_flameGraphView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_flameGraphView, &QWidget::customContextMenuRequested,
menu1, [this, menu1, resetAction](const QPoint &pos) {
resetAction->setEnabled(m_flameGraphView->isZoomed());
menu1->exec(m_flameGraphView->mapToGlobal(pos));
});
m_perspective.addToolBarAction(m_startAction);
m_perspective.addToolBarAction(m_stopAction);
m_perspective.addToolBarWidget(m_recordButton);
m_perspective.addToolBarWidget(m_clearButton);
m_perspective.addToolBarWidget(m_filterButton);
m_perspective.addToolBarWidget(m_aggregateButton);
m_perspective.addToolBarWidget(m_recordedLabel);
m_perspective.addToolBarWidget(m_delayLabel);
m_perspective.addToolBarWidget(m_tracePointsButton);
m_perspective.setAboutToActivateCallback(Perspective::Callback());
}
PerfProfilerTool *PerfProfilerTool::instance()
{
return s_instance;
}
PerfProfilerTraceManager *PerfProfilerTool::traceManager() const
{
return m_traceManager;
}
void PerfProfilerTool::addLoadSaveActionsToMenu(QMenu *menu)
{
menu->addAction(m_loadPerfData);
menu->addAction(m_loadTrace);
menu->addAction(m_saveTrace);
}
void PerfProfilerTool::createTracePoints()
{
PerfTracePointDialog dialog;
dialog.exec();
}
void PerfProfilerTool::initialize()
{
clearUi();
setToolActionsEnabled(false);
}
void PerfProfilerTool::finalize()
{
const qint64 startTime = m_traceManager->traceStart();
const qint64 endTime = m_traceManager->traceEnd();
QTC_ASSERT(endTime >= startTime, return);
m_zoomControl->setTrace(startTime, endTime);
m_zoomControl->setRange(startTime, startTime + (endTime - startTime) / 10);
updateTime(m_zoomControl->traceDuration(), -1);
updateFilterMenu();
updateRunActions();
setToolActionsEnabled(true);
}
void PerfProfilerTool::startLoading()
{
m_readerRunning = true;
}
void PerfProfilerTool::onReaderFinished()
{
m_readerRunning = false;
if (m_traceManager->traceDuration() <= 0) {
QMessageBox::warning(Core::ICore::mainWindow(),
tr("No Data Loaded"),
tr("The profiler did not produce any samples. "
"Make sure that you are running a recent Linux kernel and that "
"the \"perf\" utility is available and generates useful call "
"graphs."));
clear();
} else {
m_traceManager->finalize();
}
}
void PerfProfilerTool::onRunControlStarted()
{
m_processRunning = true;
updateRunActions();
}
void PerfProfilerTool::onRunControlFinished()
{
m_processRunning = false;
updateRunActions();
}
void PerfProfilerTool::onReaderStarted()
{
m_traceManager->initialize();
}
void PerfProfilerTool::onWorkerCreation(RunControl *runControl)
{
populateFileFinder(runControl->project(), runControl->kit());
}
void PerfProfilerTool::updateRunActions()
{
m_stopAction->setEnabled(m_processRunning);
if (m_readerRunning || m_processRunning) {
m_startAction->setEnabled(false);
m_startAction->setToolTip(tr("A performance analysis is still in progress."));
m_loadPerfData->setEnabled(false);
m_loadTrace->setEnabled(false);
} else {
QString whyNot = tr("Start a performance analysis.");
bool canRun = ProjectExplorerPlugin::canRunStartupProject(
ProjectExplorer::Constants::PERFPROFILER_RUN_MODE, &whyNot);
m_startAction->setToolTip(whyNot);
m_startAction->setEnabled(canRun);
m_loadPerfData->setEnabled(true);
m_loadTrace->setEnabled(true);
}
m_saveTrace->setEnabled(!m_traceManager->isEmpty());
}
void PerfProfilerTool::setToolActionsEnabled(bool on)
{
m_limitToRange->setEnabled(on);
m_showFullRange->setEnabled(on);
m_clearButton->setEnabled(on);
m_filterButton->setEnabled(on);
m_aggregateButton->setEnabled(on);
m_filterMenu->setEnabled(on);
if (m_traceView)
m_traceView->setEnabled(on);
if (m_statisticsView)
m_statisticsView->setEnabled(on);
if (m_flameGraphView)
m_flameGraphView->setEnabled(on);
}
PerfTimelineModelManager *PerfProfilerTool::modelManager() const
{
return m_modelManager;
}
Timeline::TimelineZoomControl *PerfProfilerTool::zoomControl() const
{
return m_zoomControl;
}
bool PerfProfilerTool::isRecording() const
{
return m_recordButton->isChecked();
}
static bool operator<(const PerfProfilerTraceManager::Thread &a,
const PerfProfilerTraceManager::Thread &b)
{
return a.tid < b.tid;
}
void PerfProfilerTool::updateFilterMenu()
{
m_filterMenu->clear();
QAction *enableAll = m_filterMenu->addAction(tr("Enable All"));
QAction *disableAll = m_filterMenu->addAction(tr("Disable All"));
m_filterMenu->addSeparator();
QList<PerfProfilerTraceManager::Thread> threads = m_traceManager->threads().values();
std::sort(threads.begin(), threads.end());
for (const PerfProfilerTraceManager::Thread &thread : qAsConst(threads)) {
QAction *action = m_filterMenu->addAction(
QString::fromLatin1("%1 (%2)")
.arg(QString::fromUtf8(m_traceManager->string(thread.name)))
.arg(thread.tid));
action->setCheckable(true);
action->setData(thread.tid);
action->setChecked(thread.enabled);
if (thread.tid == 0) {
action->setEnabled(false);
} else {
connect(action, &QAction::toggled, this, [this, action](bool checked) {
m_traceManager->setThreadEnabled(action->data().toUInt(), checked);
});
connect(enableAll, &QAction::triggered,
action, [action]() { action->setChecked(true); });
connect(disableAll, &QAction::triggered,
action, [action]() { action->setChecked(false); });
}
}
}
void PerfProfilerTool::gotoSourceLocation(QString filePath, int lineNumber, int columnNumber)
{
if (lineNumber < 0 || filePath.isEmpty())
return;
QFileInfo fi(filePath);
if (!fi.isAbsolute() || !fi.exists() || !fi.isReadable()) {
fi.setFile(m_fileFinder.findFile(filePath).first().toString());
if (!fi.exists() || !fi.isReadable())
return;
}
// The text editors count columns starting with 0, but the ASTs store the
// location starting with 1, therefore the -1.
EditorManager::openEditorAt(fi.filePath(), lineNumber, columnNumber - 1, Core::Id(),
EditorManager::DoNotSwitchToDesignMode
| EditorManager::DoNotSwitchToEditMode);
}
static Utils::FilePaths collectQtIncludePaths(const ProjectExplorer::Kit *kit)
{
QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(kit);
if (qt == nullptr)
return Utils::FilePaths();
Utils::FilePaths paths{qt->headerPath()};
QDirIterator dit(paths.first().toString(), QStringList(), QDir::Dirs | QDir::NoDotAndDotDot,
QDirIterator::Subdirectories);
while (dit.hasNext()) {
dit.next();
paths << Utils::FilePath::fromString(dit.filePath());
}
return paths;
}
static Utils::FilePath sysroot(const Kit *kit)
{
return SysRootKitAspect::sysRoot(kit);
}
static Utils::FilePaths sourceFiles(const Project *currentProject = nullptr)
{
Utils::FilePaths sourceFiles;
// Have the current project first.
if (currentProject)
sourceFiles.append(currentProject->files(Project::SourceFiles));
const QList<Project *> projects = SessionManager::projects();
for (const Project *project : projects) {
if (project != currentProject)
sourceFiles.append(project->files(Project::SourceFiles));
}
return sourceFiles;
}
void PerfProfilerTool::showLoadPerfDialog()
{
m_perspective.select();
PerfLoadDialog dlg(Core::ICore::mainWindow());
if (dlg.exec() != PerfLoadDialog::Accepted)
return;
startLoading();
Kit *kit = dlg.kit();
m_fileFinder.setAdditionalSearchDirectories(collectQtIncludePaths(kit));
m_fileFinder.setSysroot(sysroot(kit));
m_fileFinder.setProjectFiles(sourceFiles());
m_traceManager->loadFromPerfData(dlg.traceFilePath(), dlg.executableDirPath(), kit);
}
void PerfProfilerTool::showLoadTraceDialog()
{
m_perspective.select();
QString filename = QFileDialog::getOpenFileName(
ICore::mainWindow(), tr("Load Trace File"),
"", tr("Trace File (*.ptq)"));
if (filename.isEmpty())
return;
startLoading();
const Project *currentProject = SessionManager::startupProject();
const Target *target = currentProject ? currentProject->activeTarget() : nullptr;
const Kit *kit = target ? target->kit() : nullptr;
populateFileFinder(currentProject, kit);
m_traceManager->loadFromTraceFile(filename);
}
void PerfProfilerTool::showSaveTraceDialog()
{
m_perspective.select();
QString filename = QFileDialog::getSaveFileName(
ICore::mainWindow(), tr("Save Trace File"),
"", tr("Trace File (*.ptq)"));
if (filename.isEmpty())
return;
if (!filename.endsWith(".ptq"))
filename += ".ptq";
setToolActionsEnabled(false);
m_traceManager->saveToTraceFile(filename);
}
void PerfProfilerTool::setAggregated(bool aggregated)
{
m_aggregateButton->setChecked(aggregated);
m_aggregateButton->setToolTip(aggregated ? tr("Show all addresses.")
: tr("Aggregate by functions."));
emit aggregatedChanged(aggregated);
}
void PerfProfilerTool::setRecording(bool recording)
{
const static QIcon recordOn = Debugger::Icons::RECORD_ON.icon();
const static QIcon recordOff = Debugger::Icons::RECORD_OFF.icon();
m_recordButton->setIcon(recording ? recordOn : recordOff);
m_recordButton->setChecked(recording);
m_recordButton->setToolTip(recording ? tr("Stop collecting profile data.") :
tr("Collect profile data."));
emit recordingChanged(recording);
}
void PerfProfilerTool::updateTime(qint64 duration, qint64 delay)
{
qint64 e9 = 1e9, e8 = 1e8, ten = 10; // compiler would cast to double
if (duration > 0)
m_recordedLabel->setText(tr("Recorded: %1.%2s").arg(duration / e9)
.arg(qAbs(duration / e8) % ten));
else if (duration == 0)
m_recordedLabel->clear();
if (delay > 0)
m_delayLabel->setText(tr("Processing delay: %1.%2s").arg(delay / e9)
.arg(qAbs(delay / e8) % ten));
else if (delay == 0)
m_delayLabel->clear();
}
void PerfProfilerTool::populateFileFinder(const Project *project, const Kit *kit)
{
m_fileFinder.setProjectFiles(sourceFiles(project));
if (project)
m_fileFinder.setProjectDirectory(project->projectDirectory());
if (kit) {
m_fileFinder.setAdditionalSearchDirectories(collectQtIncludePaths(kit));
m_fileFinder.setSysroot(sysroot(kit));
}
}
void PerfProfilerTool::clear()
{
clearData();
clearUi();
}
void PerfProfilerTool::clearData()
{
m_traceManager->clearAll();
m_traceManager->setAggregateAddresses(m_aggregateButton->isChecked());
m_zoomControl->clear();
}
void PerfProfilerTool::clearUi()
{
if (m_traceView)
m_traceView->clear();
updateTime(0, 0);
updateFilterMenu();
updateRunActions();
}
} // namespace Internal
} // namespace PerfProfiler