diff --git a/analyzers/CMakeLists.txt b/analyzers/CMakeLists.txt --- a/analyzers/CMakeLists.txt +++ b/analyzers/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(cppcheck) +add_subdirectory(heaptrack) diff --git a/analyzers/heaptrack/CMakeLists.txt b/analyzers/heaptrack/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/CMakeLists.txt @@ -0,0 +1,38 @@ +add_definitions(-DTRANSLATION_DOMAIN=\"kdevheaptrack\") + +set(kdevheaptrack_SRCS + debug.cpp + job.cpp + plugin.cpp + utils.cpp + visualizer.cpp + + config/globalconfigpage.cpp +) +ki18n_wrap_ui(kdevheaptrack_UI_SRCS + config/globalconfigpage.ui +) +kconfig_add_kcfg_files(kdevheaptrack_CONFIG_SRCS + config/globalsettings.kcfgc +) +add_library(kdevheaptrack_config STATIC + ${kdevheaptrack_CONFIG_SRCS} +) +target_link_libraries(kdevheaptrack_config + KDev::Shell +) +kdevplatform_add_plugin(kdevheaptrack + JSON kdevheaptrack.json + SOURCES ${kdevheaptrack_SRCS} ${kdevheaptrack_UI_SRCS} +) +target_link_libraries(kdevheaptrack + kdevheaptrack_config + KDev::Project +) +if(KF5SysGuard_FOUND) + target_link_libraries(kdevheaptrack + kdevdebuggercommon + KF5::ProcessUi + ) +endif() +install(FILES kdevheaptrack.rc DESTINATION ${KXMLGUI_INSTALL_DIR}/kdevheaptrack) diff --git a/analyzers/heaptrack/config/globalconfigpage.h b/analyzers/heaptrack/config/globalconfigpage.h new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/config/globalconfigpage.h @@ -0,0 +1,42 @@ +/* This file is part of KDevelop + Copyright 2017 Anton Anikin + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include + +namespace Heaptrack +{ + +class GlobalConfigPage: public KDevelop::ConfigPage +{ + Q_OBJECT + +public: + GlobalConfigPage(KDevelop::IPlugin* plugin, QWidget* parent); + ~GlobalConfigPage() override = default; + + KDevelop::ConfigPage::ConfigPageType configPageType() const override; + + QString name() const override; + QString fullName() const override; + QIcon icon() const override; +}; + +} diff --git a/analyzers/heaptrack/config/globalconfigpage.cpp b/analyzers/heaptrack/config/globalconfigpage.cpp new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/config/globalconfigpage.cpp @@ -0,0 +1,55 @@ +/* This file is part of KDevelop + Copyright 2017 Anton Anikin + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "globalconfigpage.h" +#include "ui_globalconfigpage.h" + +#include "globalsettings.h" + +namespace Heaptrack +{ + +GlobalConfigPage::GlobalConfigPage(KDevelop::IPlugin* plugin, QWidget* parent) + : ConfigPage(plugin, GlobalSettings::self(), parent) +{ + Ui::GlobalConfigPage ui; + ui.setupUi(this); +} + +KDevelop::ConfigPage::ConfigPageType GlobalConfigPage::configPageType() const +{ + return KDevelop::ConfigPage::AnalyzerConfigPage; +} + +QString GlobalConfigPage::name() const +{ + return i18n("Heaptrack"); +} + +QString GlobalConfigPage::fullName() const +{ + return i18n("Configure Heaptrack Settings"); +} + +QIcon GlobalConfigPage::icon() const +{ + return QIcon::fromTheme(QStringLiteral("office-chart-area")); +} + +} diff --git a/analyzers/heaptrack/config/globalconfigpage.ui b/analyzers/heaptrack/config/globalconfigpage.ui new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/config/globalconfigpage.ui @@ -0,0 +1,89 @@ + + + Heaptrack::GlobalConfigPage + + + + 0 + 0 + 450 + 213 + + + + Cppcheck Settings + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Executables + + + + + + Heaptrack: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_heaptrackExecutable + + + + + + + + + + Visualizer: + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 68 + + + + + + + + + KUrlRequester + QWidget +
kurlrequester.h
+ 1 +
+
+ + +
diff --git a/analyzers/heaptrack/config/globalsettings.kcfg b/analyzers/heaptrack/config/globalsettings.kcfg new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/config/globalsettings.kcfg @@ -0,0 +1,20 @@ + + + + "utils.h" + + + + + findExecutable(QStringLiteral("heaptrack")) + + + + findExecutable(QStringLiteral("heaptrack_gui")) + + + + diff --git a/analyzers/heaptrack/config/globalsettings.kcfgc b/analyzers/heaptrack/config/globalsettings.kcfgc new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/config/globalsettings.kcfgc @@ -0,0 +1,4 @@ +File=globalsettings.kcfg +NameSpace=Heaptrack +ClassName=GlobalSettings +Singleton=true diff --git a/analyzers/heaptrack/debug.h b/analyzers/heaptrack/debug.h new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/debug.h @@ -0,0 +1,24 @@ +/* This file is part of KDevelop + Copyright 2017 Anton Anikin + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include + +Q_DECLARE_LOGGING_CATEGORY(KDEV_HEAPTRACK) diff --git a/analyzers/heaptrack/debug.cpp b/analyzers/heaptrack/debug.cpp new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/debug.cpp @@ -0,0 +1,22 @@ +/* This file is part of KDevelop + Copyright 2017 Anton Anikin + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "debug.h" + +Q_LOGGING_CATEGORY(KDEV_HEAPTRACK, "kdevelop.analyzers.heaptrack") diff --git a/analyzers/heaptrack/job.h b/analyzers/heaptrack/job.h new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/job.h @@ -0,0 +1,64 @@ +/* This file is part of KDevelop + Copyright 2017 Anton Anikin + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include +#include + +namespace KDevelop +{ + class ILaunchConfiguration; +} + +namespace Heaptrack +{ + +class Job : public KDevelop::OutputExecuteJob, public KDevelop::IStatus +{ + Q_OBJECT + Q_INTERFACES(KDevelop::IStatus) + +public: + explicit Job(KDevelop::ILaunchConfiguration* launchConfig); + explicit Job(long int pid); + ~Job() override; + + void start() override; + + QString statusName() const override; + QString resultsFile() const; + +signals: + void clearMessage(KDevelop::IStatus*) override; + void hideProgress(KDevelop::IStatus*) override; + void showErrorMessage(const QString& message, int timeout = 0) override; + void showMessage(KDevelop::IStatus*, const QString& message, int timeout = 0) override; + void showProgress(KDevelop::IStatus*, int minimum, int maximum, int value) override; + +protected: + void setup(); + void postProcessStdout(const QStringList& lines) override; + + long int m_pid; + QString m_analyzedExecutable; + QString m_resultsFile; +}; + +} diff --git a/analyzers/heaptrack/job.cpp b/analyzers/heaptrack/job.cpp new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/job.cpp @@ -0,0 +1,151 @@ +/* This file is part of KDevelop + Copyright 2017 Anton Anikin + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "job.h" + +#include "debug.h" +#include "globalsettings.h" +#include "utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace Heaptrack +{ + +Job::Job(KDevelop::ILaunchConfiguration* launchConfig) + : m_pid(-1) +{ + Q_ASSERT(launchConfig); + + auto pluginController = KDevelop::ICore::self()->pluginController(); + auto iface = pluginController->pluginForExtension(QStringLiteral("org.kdevelop.IExecutePlugin"))->extension(); + Q_ASSERT(iface); + + QString envProfile = iface->environmentProfileName(launchConfig); + if (envProfile.isEmpty()) { + envProfile = KDevelop::EnvironmentProfileList(KSharedConfig::openConfig()).defaultProfileName(); + } + setEnvironmentProfile(envProfile); + + QString errorString; + + m_analyzedExecutable = iface->executable(launchConfig, errorString).toLocalFile(); + if (!errorString.isEmpty()) { + setError(-1); + setErrorText(errorString); + } + + QStringList analyzedExecutableArguments = iface->arguments(launchConfig, errorString); + if (!errorString.isEmpty()) { + setError(-1); + setErrorText(errorString); + } + + QUrl workDir = iface->workingDirectory(launchConfig); + if (workDir.isEmpty() || !workDir.isValid()) { + workDir = QUrl::fromLocalFile(QFileInfo(m_analyzedExecutable).absolutePath()); + } + setWorkingDirectory(workDir); + + *this << KDevelop::Path(GlobalSettings::heaptrackExecutable()).toLocalFile(); + *this << m_analyzedExecutable; + *this << analyzedExecutableArguments; + + setup(); +} + +Job::Job(long int pid) + : m_pid(pid) +{ + *this << KDevelop::Path(GlobalSettings::heaptrackExecutable()).toLocalFile(); + *this << QStringLiteral("-p"); + *this << QString::number(m_pid); + + setup(); +} + +void Job::setup() +{ + setProperties(DisplayStdout); + setProperties(DisplayStderr); + setProperties(PostProcessOutput); + + setCapabilities(Killable); + setStandardToolView(KDevelop::IOutputView::TestView); + setBehaviours(KDevelop::IOutputView::AutoScroll); + + KDevelop::ICore::self()->uiController()->registerStatus(this); + connect(this, &Job::finished, this, [this]() { + emit hideProgress(this); + }); +} + +Job::~Job() +{ +} + +QString Job::statusName() const +{ + QString target = m_pid < 0 ? QFileInfo(m_analyzedExecutable).fileName() + : QString("PID: %1").arg(m_pid); + return i18n("Heaptrack Analysis (%1)", target); +} + +QString Job::resultsFile() const +{ + return m_resultsFile; +} + +void Job::start() +{ + emit showProgress(this, 0, 0, 0); + OutputExecuteJob::start(); +} + +void Job::postProcessStdout(const QStringList& lines) +{ + static const auto resultRegex = + QRegularExpression(QStringLiteral("heaptrack output will be written to \\\"(.+)\\\"")); + + if (m_resultsFile.isEmpty()) { + QRegularExpressionMatch match; + for (const QString & line : lines) { + match = resultRegex.match(line); + if (match.hasMatch()) { + m_resultsFile = match.captured(1); + break; + } + } + } + + OutputExecuteJob::postProcessStdout(lines); +} + +} diff --git a/analyzers/heaptrack/kdevheaptrack.json b/analyzers/heaptrack/kdevheaptrack.json new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/kdevheaptrack.json @@ -0,0 +1,33 @@ +{ + "GenericName": "Heaptrack Support", + "GenericName[x-test]": "xxHeaptrack Supportxx", + + "KPlugin": { + "Authors": [ + { + "Name": "Anton Anikin", + "Name[x-test]": "xxAnton Anikinxx" + } + ], + + "Category": "Analyzers", + "Icon": "office-chart-area", + "Id": "kdevheaptrack", + "License": "GPL", + "ServiceTypes": [ + "KDevelop/Plugin" + ], + + "Name": "Heaptrack Support", + "Name[x-test]": "xxHeaptrack Supportxx", + + "Description": "This plugin integrates Heaptrack to KDevelop", + "Description[x-test]": "xxThis plugin integrates Heaptrack to KDevelopkxx" + }, + + "X-KDevelop-Category": "Global", + "X-KDevelop-Mode": "GUI", + "X-KDevelop-IRequired": [ + "org.kdevelop.IExecutePlugin" + ] +} diff --git a/analyzers/heaptrack/kdevheaptrack.rc b/analyzers/heaptrack/kdevheaptrack.rc new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/kdevheaptrack.rc @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/analyzers/heaptrack/plugin.h b/analyzers/heaptrack/plugin.h new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/plugin.h @@ -0,0 +1,50 @@ +/* This file is part of KDevelop + Copyright 2017 Anton Anikin + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include + +class KJob; + +namespace Heaptrack +{ + +class Plugin : public KDevelop::IPlugin +{ + Q_OBJECT + +public: + Plugin(QObject* parent, const QVariantList& = QVariantList()); + ~Plugin() override; + + int configPages() const override; + KDevelop::ConfigPage* configPage(int number, QWidget* parent) override; + +private: + void launchHeaptrack(); + void attachHeaptrack(); + + void jobFinished(KJob* job); + + QAction* m_launchAction; + QAction* m_attachAction; +}; + +} diff --git a/analyzers/heaptrack/plugin.cpp b/analyzers/heaptrack/plugin.cpp new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/plugin.cpp @@ -0,0 +1,158 @@ +/* This file is part of KDevelop + Copyright 2017 Anton Anikin + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "plugin.h" + +#include "config/globalconfigpage.h" +#include "debug.h" +#include "job.h" +#include "utils.h" +#include "visualizer.h" + +#include "config.h" +#if KF5SysGuard_FOUND +#include "debuggers/common/dialogs/processselection.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +K_PLUGIN_FACTORY_WITH_JSON(HeaptrackFactory, "kdevheaptrack.json", registerPlugin();) + +namespace Heaptrack +{ + +Plugin::Plugin(QObject* parent, const QVariantList&) + : IPlugin(QStringLiteral("kdevheaptrack"), parent) +{ + setComponentName(QStringLiteral("kdevheaptrack"), i18n("Heaptrack Analyzer")); + setXMLFile(QStringLiteral("kdevheaptrack.rc")); + + m_launchAction = new QAction( + QIcon::fromTheme(QStringLiteral("office-chart-area")), + i18n("Run Heaptrack Analysis"), + this); + + connect(m_launchAction, &QAction::triggered, this, &Plugin::launchHeaptrack); + actionCollection()->addAction(QStringLiteral("heaptrack_launch"), m_launchAction); + +#if KF5SysGuard_FOUND + m_attachAction = new QAction( + QIcon::fromTheme(QStringLiteral("office-chart-area")), + i18n("Attach to Process with Heaptrack"), + this); + + connect(m_attachAction, &QAction::triggered, this, &Plugin::attachHeaptrack); + actionCollection()->addAction(QStringLiteral("heaptrack_attach"), m_attachAction); +#endif +} + +Plugin::~Plugin() +{ +} + +void Plugin::launchHeaptrack() +{ + auto runController = KDevelop::Core::self()->runControllerInternal(); + Q_ASSERT(runController); + + auto defaultLaunch = runController->defaultLaunch(); + if (!defaultLaunch) { + return; + } + + auto pluginController = core()->self()->pluginController(); + auto iface = pluginController->pluginForExtension(QStringLiteral("org.kdevelop.IExecutePlugin"))->extension(); + Q_ASSERT(iface); + + auto heaptrackJob = new Job(defaultLaunch); + connect(heaptrackJob, &Job::finished, this, &Plugin::jobFinished); + + QList jobList; + if (KJob* depJob = iface->dependencyJob(defaultLaunch)) { + jobList += depJob; + } + jobList += heaptrackJob; + + auto ecJob = new KDevelop::ExecuteCompositeJob(runController, jobList); + ecJob->setObjectName(heaptrackJob->statusName()); + runController->registerJob(ecJob); + + m_launchAction->setEnabled(false); +} + +void Plugin::attachHeaptrack() +{ +#if KF5SysGuard_FOUND + KDevMI::ProcessSelectionDialog dlg(activeMainWindow()); + if (!dlg.exec() || !dlg.pidSelected()) { + return; + } + + auto heaptrackJob = new Job(dlg.pidSelected()); + connect(heaptrackJob, &Job::finished, this, &Plugin::jobFinished); + + heaptrackJob->setObjectName(heaptrackJob->statusName()); + core()->runController()->registerJob(heaptrackJob); + + m_launchAction->setEnabled(false); +#endif +} + +void Plugin::jobFinished(KJob* kjob) +{ + auto job = static_cast(kjob); + Q_ASSERT(job); + + if (job->status() == KDevelop::OutputExecuteJob::JobStatus::JobSucceeded) { + auto visualizer = new Visualizer(job->resultsFile(), this); + visualizer->start(); + } else { + QFile::remove(job->resultsFile()); + } + + m_launchAction->setEnabled(true); +} + +int Plugin::configPages() const +{ + return 1; +} + +KDevelop::ConfigPage* Plugin::configPage(int number, QWidget* parent) +{ + if (number) { + return nullptr; + } + + return new GlobalConfigPage(this, parent); +} + +} + +#include "plugin.moc" diff --git a/analyzers/heaptrack/utils.h b/analyzers/heaptrack/utils.h new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/utils.h @@ -0,0 +1,31 @@ +/* This file is part of KDevelop + Copyright 2017 Anton Anikin + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include + +class QWidget; + +namespace Heaptrack +{ + QString findExecutable(const QString& fallbackExecutablePath); + + QWidget* activeMainWindow(); +} diff --git a/analyzers/heaptrack/utils.cpp b/analyzers/heaptrack/utils.cpp new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/utils.cpp @@ -0,0 +1,40 @@ +/* This file is part of KDevelop + Copyright 2017 Anton Anikin + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "utils.h" + +#include +#include +#include + +#include + +namespace Heaptrack +{ + QString findExecutable(const QString& fallbackExecutablePath) + { + QString executablePath = QStandardPaths::findExecutable(fallbackExecutablePath); + return executablePath.isEmpty() ? fallbackExecutablePath : executablePath; + } + + QWidget* activeMainWindow() + { + return KDevelop::ICore::self()->uiController()->activeMainWindow(); + } +} diff --git a/analyzers/heaptrack/visualizer.h b/analyzers/heaptrack/visualizer.h new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/visualizer.h @@ -0,0 +1,42 @@ +/* This file is part of KDevelop + Copyright 2017 Anton Anikin + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include + +namespace Heaptrack +{ + +class Visualizer : public QProcess +{ + Q_OBJECT + +public: + /// Creates new Heaptrack visualizer (heaptrack_gui) process. Executable path is taken + /// from plugin settings, results (data) file - from passed resultsFile parameter. After + /// process finishing the results file will be automatically removed. + Visualizer(const QString& resultsFile, QObject* parent); + ~Visualizer() override; + +protected: + QString m_resultsFile; +}; + +} diff --git a/analyzers/heaptrack/visualizer.cpp b/analyzers/heaptrack/visualizer.cpp new file mode 100644 --- /dev/null +++ b/analyzers/heaptrack/visualizer.cpp @@ -0,0 +1,67 @@ +/* This file is part of KDevelop + Copyright 2017 Anton Anikin + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "visualizer.h" + +#include "debug.h" +#include "globalsettings.h" +#include "utils.h" + +#include +#include +#include + +#include + +namespace Heaptrack +{ + +Visualizer::Visualizer(const QString& resultsFile, QObject* parent) + : QProcess(parent) + , m_resultsFile(resultsFile) +{ + connect(this, &QProcess::errorOccurred, this, [this](QProcess::ProcessError error) { + QString errorMessage; + if (error == QProcess::FailedToStart) { + errorMessage += i18n("Failed to start visualizer from \"%1\".", program()); + errorMessage += QStringLiteral("\n\n"); + errorMessage += i18n("Check your settings and install the visualizer if necessary."); + } else { + errorMessage += i18n("Error during visualizer execution:"); + errorMessage += QStringLiteral("\n\n"); + errorMessage += errorString(); + } + KMessageBox::error(activeMainWindow(), errorMessage, i18n("Heaptrack Error")); + }); + + connect(this, static_cast(&QProcess::finished), + this, [this]() { + deleteLater(); + }); + + setProgram(KDevelop::Path(GlobalSettings::heaptrackGuiExecutable()).toLocalFile()); + setArguments({ resultsFile }); +} + +Visualizer::~Visualizer() +{ + QFile::remove(m_resultsFile); +} + +}