Commit a8d7e15a authored by Nikolai Kosjar's avatar Nikolai Kosjar Committed by hjk

Valgrind: Add action to load external log file

...for the memcheck and callgrind tool.

Task-number: QTCREATORBUG-10057

Change-Id: I23dd3ad47f0498af37787bf54e76b09852cb327c
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent e8b25ac3
......@@ -41,6 +41,7 @@
#include <valgrind/callgrind/callgrindfunction.h>
#include <valgrind/callgrind/callgrindfunctioncall.h>
#include <valgrind/callgrind/callgrindparsedata.h>
#include <valgrind/callgrind/callgrindparser.h>
#include <valgrind/callgrind/callgrindproxymodel.h>
#include <valgrind/callgrind/callgrindstackbrowser.h>
#include <valgrind/valgrindplugin.h>
......@@ -74,10 +75,12 @@
#include <QCheckBox>
#include <QComboBox>
#include <QDockWidget>
#include <QFileDialog>
#include <QGraphicsItem>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QMenu>
#include <QMessageBox>
#include <QSortFilterProxyModel>
#include <QToolBar>
#include <QToolButton>
......@@ -124,6 +127,7 @@ signals:
public slots:
void slotClear();
void slotRequestDump();
void loadExternalXmlLogFile();
void selectFunction(const Valgrind::Callgrind::Function *);
void setCostFormat(Valgrind::Internal::CostDelegate::CostFormat format);
......@@ -158,6 +162,7 @@ public slots:
void showParserResults(const Valgrind::Callgrind::ParseData *data);
void takeParserData(CallgrindRunControl *rc);
void takeParserData(ParseData *data);
void engineStarting(const Analyzer::AnalyzerRunControl *);
void engineFinished();
......@@ -198,6 +203,7 @@ public:
QVector<CallgrindTextMark *> m_textMarks;
QAction *m_loadExternalLogFile;
QAction *m_dumpAction;
QAction *m_resetAction;
QAction *m_pauseAction;
......@@ -562,6 +568,11 @@ void CallgrindTool::startTool(StartMode mode)
d->setBusyCursor(true);
}
void CallgrindTool::loadExternalXmlLogFile()
{
d->loadExternalXmlLogFile();
}
void CallgrindTool::handleShowCostsOfFunction()
{
d->handleShowCostsOfFunction();
......@@ -654,6 +665,14 @@ QWidget *CallgrindToolPrivate::createWidgets()
layout->setSpacing(0);
widget->setLayout(layout);
// load external XML log file
action = new QAction(this);
action->setIcon(QIcon(QLatin1String(Core::Constants::ICON_OPENFILE)));
action->setToolTip(tr("Load External XML Log File."));
connect(action, SIGNAL(triggered(bool)), this, SLOT(loadExternalXmlLogFile()));
layout->addWidget(createToolButton(action));
m_loadExternalLogFile = action;
// dump action
action = new QAction(this);
action->setDisabled(true);
......@@ -810,6 +829,7 @@ void CallgrindToolPrivate::engineStarting(const Analyzer::AnalyzerRunControl *)
// enable/disable actions
m_resetAction->setEnabled(true);
m_dumpAction->setEnabled(true);
m_loadExternalLogFile->setEnabled(false);
clearTextMarks();
slotClear();
}
......@@ -819,6 +839,7 @@ void CallgrindToolPrivate::engineFinished()
// enable/disable actions
m_resetAction->setEnabled(false);
m_dumpAction->setEnabled(false);
m_loadExternalLogFile->setEnabled(true);
const ParseData *data = m_dataModel->parseData();
if (data)
......@@ -913,9 +934,35 @@ void CallgrindToolPrivate::slotRequestDump()
dumpRequested();
}
void CallgrindToolPrivate::loadExternalXmlLogFile()
{
const QString filePath = QFileDialog::getOpenFileName(Core::ICore::mainWindow(),
tr("Open Callgrind XML Log File"));
if (filePath.isEmpty())
return;
QFile logFile(filePath);
if (!logFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
QMessageBox::critical(AnalyzerManager::mainWindow(), tr("Internal Error"),
tr("Failed to open file for reading: %1").arg(filePath));
return;
}
AnalyzerManager::showStatusMessage(tr("Parsing Profile Data..."));
QCoreApplication::processEvents();
Parser parser;
parser.parse(&logFile);
takeParserData(parser.takeData());
}
void CallgrindToolPrivate::takeParserData(CallgrindRunControl *rc)
{
ParseData *data = rc->takeParserData();
takeParserData(rc->takeParserData());
}
void CallgrindToolPrivate::takeParserData(ParseData *data)
{
showParserResults(data);
if (!data)
......
......@@ -53,6 +53,7 @@ public:
QWidget *createWidgets();
void startTool(Analyzer::StartMode mode);
void loadExternalXmlLogFile();
public slots:
void handleShowCostsOfFunction();
......
......@@ -69,6 +69,7 @@
#include <QString>
#include <QLatin1String>
#include <QFileDialog>
#include <QFileInfo>
#include <QFile>
#include <QDir>
......@@ -223,6 +224,31 @@ void MemcheckTool::settingsDestroyed(QObject *settings)
m_settings = ValgrindPlugin::globalSettings();
}
void MemcheckTool::updateFromSettings()
{
foreach (QAction *action, m_errorFilterActions) {
bool contained = true;
foreach (const QVariant &v, action->data().toList()) {
bool ok;
int kind = v.toInt(&ok);
if (ok && !m_settings->visibleErrorKinds().contains(kind))
contained = false;
}
action->setChecked(contained);
}
m_filterProjectAction->setChecked(!m_settings->filterExternalIssues());
m_errorView->settingsChanged(m_settings);
connect(m_settings, SIGNAL(visibleErrorKindsChanged(QList<int>)),
m_errorProxyModel, SLOT(setAcceptedKinds(QList<int>)));
m_errorProxyModel->setAcceptedKinds(m_settings->visibleErrorKinds());
connect(m_settings, SIGNAL(filterExternalIssuesChanged(bool)),
m_errorProxyModel, SLOT(setFilterExternalIssues(bool)));
m_errorProxyModel->setFilterExternalIssues(m_settings->filterExternalIssues());
}
void MemcheckTool::maybeActiveRunConfigurationChanged()
{
ValgrindBaseSettings *settings = 0;
......@@ -249,27 +275,7 @@ void MemcheckTool::maybeActiveRunConfigurationChanged()
QTC_ASSERT(m_settings, return);
connect(m_settings, SIGNAL(destroyed(QObject*)), SLOT(settingsDestroyed(QObject*)));
foreach (QAction *action, m_errorFilterActions) {
bool contained = true;
foreach (const QVariant &v, action->data().toList()) {
bool ok;
int kind = v.toInt(&ok);
if (ok && !m_settings->visibleErrorKinds().contains(kind))
contained = false;
}
action->setChecked(contained);
}
m_filterProjectAction->setChecked(!m_settings->filterExternalIssues());
m_errorView->settingsChanged(m_settings);
connect(m_settings, SIGNAL(visibleErrorKindsChanged(QList<int>)),
m_errorProxyModel, SLOT(setAcceptedKinds(QList<int>)));
m_errorProxyModel->setAcceptedKinds(m_settings->visibleErrorKinds());
connect(m_settings, SIGNAL(filterExternalIssuesChanged(bool)),
m_errorProxyModel, SLOT(setFilterExternalIssues(bool)));
m_errorProxyModel->setFilterExternalIssues(m_settings->filterExternalIssues());
updateFromSettings();
}
RunMode MemcheckTool::runMode() const
......@@ -371,6 +377,16 @@ QWidget *MemcheckTool::createWidgets()
layout->setMargin(0);
layout->setSpacing(0);
// Load external XML log file
action = new QAction(this);
action->setIcon(QIcon(QLatin1String(Core::Constants::ICON_OPENFILE)));
action->setToolTip(tr("Load External XML Log File."));
connect(action, SIGNAL(triggered(bool)), this, SLOT(loadExternalXmlLogFile()));
button = new QToolButton;
button->setDefaultAction(action);
layout->addWidget(button);
m_loadExternalLogFile = action;
// Go to previous leak.
action = new QAction(this);
action->setDisabled(true);
......@@ -429,7 +445,7 @@ AnalyzerRunControl *MemcheckTool::createRunControl(const AnalyzerStartParameters
this, SLOT(parserError(Valgrind::XmlProtocol::Error)));
connect(engine, SIGNAL(internalParserError(QString)),
this, SLOT(internalParserError(QString)));
connect(engine, SIGNAL(finished()), this, SLOT(finished()));
connect(engine, SIGNAL(finished()), this, SLOT(engineFinished()));
return engine;
}
......@@ -437,6 +453,7 @@ void MemcheckTool::engineStarting(const AnalyzerRunControl *engine)
{
setBusyCursor(true);
clearErrorView();
m_loadExternalLogFile->setDisabled(true);
QString dir;
if (RunConfiguration *rc = engine->runConfiguration())
......@@ -468,6 +485,42 @@ void MemcheckTool::suppressionActionTriggered()
Core::EditorManager::openEditorAt(file, 0);
}
void MemcheckTool::loadExternalXmlLogFile()
{
const QString filePath = QFileDialog::getOpenFileName(Core::ICore::mainWindow(),
tr("Open Memcheck XML Log File"));
if (filePath.isEmpty())
return;
QFile *logFile = new QFile(filePath);
if (!logFile->open(QIODevice::ReadOnly | QIODevice::Text)) {
delete logFile;
QMessageBox::critical(m_errorView, tr("Internal Error"),
tr("Failed to open file for reading: %1").arg(filePath));
return;
}
setBusyCursor(true);
clearErrorView();
m_loadExternalLogFile->setDisabled(true);
if (!m_settings || m_settings != ValgrindPlugin::globalSettings()) {
m_settings = ValgrindPlugin::globalSettings();
m_errorView->settingsChanged(m_settings);
updateFromSettings();
}
ThreadedParser *parser = new ThreadedParser;
connect(parser, SIGNAL(error(Valgrind::XmlProtocol::Error)),
this, SLOT(parserError(Valgrind::XmlProtocol::Error)));
connect(parser, SIGNAL(internalError(QString)),
this, SLOT(internalParserError(QString)));
connect(parser, SIGNAL(finished()), this, SLOT(loadingExternalXmlLogFileFinished()));
connect(parser, SIGNAL(finished()), parser, SLOT(deleteLater()));
parser->parse(logFile); // ThreadedParser owns the file
}
void MemcheckTool::parserError(const Valgrind::XmlProtocol::Error &error)
{
m_errorModel->addError(error);
......@@ -510,16 +563,30 @@ void MemcheckTool::updateErrorFilter()
m_settings->setVisibleErrorKinds(errorKinds);
}
void MemcheckTool::finished()
int MemcheckTool::updateUiAfterFinishedHelper()
{
const int issuesFound = m_errorModel->rowCount();
m_goBack->setEnabled(issuesFound > 1);
m_goNext->setEnabled(issuesFound > 1);
m_loadExternalLogFile->setEnabled(true);
setBusyCursor(false);
return issuesFound;
}
void MemcheckTool::engineFinished()
{
const int issuesFound = updateUiAfterFinishedHelper();
AnalyzerManager::showStatusMessage(issuesFound > 0
? AnalyzerManager::tr("Memory Analyzer Tool finished, %n issues were found.", 0, issuesFound)
: AnalyzerManager::tr("Memory Analyzer Tool finished, no issues were found."));
}
setBusyCursor(false);
void MemcheckTool::loadingExternalXmlLogFileFinished()
{
const int issuesFound = updateUiAfterFinishedHelper();
AnalyzerManager::showStatusMessage(issuesFound > 0
? AnalyzerManager::tr("Log file processed, %n issues were found.", 0, issuesFound)
: AnalyzerManager::tr("Log file processed, no issues were found."));
}
void MemcheckTool::setBusyCursor(bool busy)
......
......@@ -88,13 +88,16 @@ private slots:
void maybeActiveRunConfigurationChanged();
void engineStarting(const Analyzer::AnalyzerRunControl *engine);
void finished();
void engineFinished();
void loadingExternalXmlLogFileFinished();
void parserError(const Valgrind::XmlProtocol::Error &error);
void internalParserError(const QString &errorString);
void updateErrorFilter();
void suppressionActionTriggered();
void loadExternalXmlLogFile();
private:
ToolMode toolMode() const;
QWidget *createWidgets();
......@@ -104,6 +107,8 @@ private:
ProjectExplorer::RunConfiguration *runConfiguration = 0);
void clearErrorView();
void updateFromSettings();
int updateUiAfterFinishedHelper();
private:
ValgrindBaseSettings *m_settings;
......@@ -118,6 +123,7 @@ private:
QAction *m_filterProjectAction;
QList<QAction *> m_suppressionActions;
QAction *m_suppressionSeparator;
QAction *m_loadExternalLogFile;
QAction *m_goBack;
QAction *m_goNext;
};
......
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