File indexing completed on 2024-04-21 04:36:01
0001 /* This file is part of KDevelop 0002 Copyright 2002 Harald Fernengel <harry@kdevelop.org> 0003 Copyright 2007 Hamish Rodda <rodda@kde.org> 0004 Copyright 2016-2017 Anton Anikin <anton@anikin.xyz> 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public 0008 License as published by the Free Software Foundation; either 0009 version 2 of the License, or (at your option) any later version. 0010 0011 This program is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 General Public License for more details. 0015 0016 You should have received a copy of the GNU General Public License 0017 along with this program; see the file COPYING. If not, write to 0018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #include "plugin.h" 0023 0024 #include "globalconfigpage.h" 0025 0026 #include "debug.h" 0027 #include "job.h" 0028 #include "launchmode.h" 0029 #include "problemmodel.h" 0030 #include "toolviewfactory.h" 0031 0032 #include "tools/cachegrind/cachegrind_tool.h" 0033 #include "tools/callgrind/callgrind_tool.h" 0034 #include "tools/drd/drd_tool.h" 0035 #include "tools/helgrind/helgrind_tool.h" 0036 #include "tools/massif/massif_tool.h" 0037 #include "tools/memcheck/memcheck_tool.h" 0038 0039 #include <execute/iexecuteplugin.h> 0040 #include <interfaces/ilauncher.h> 0041 #include <interfaces/iplugincontroller.h> 0042 #include <interfaces/launchconfigurationtype.h> 0043 #include <qtcompat_p.h> 0044 #include <shell/core.h> 0045 #include <shell/launchconfiguration.h> 0046 #include <shell/runcontroller.h> 0047 0048 #include <KActionCollection> 0049 #include <KPluginFactory> 0050 0051 K_PLUGIN_FACTORY_WITH_JSON(ValgrindFactory, "kdevvalgrind.json", registerPlugin<Valgrind::Plugin>();) 0052 0053 namespace Valgrind 0054 { 0055 0056 Plugin* Plugin::m_self = nullptr; 0057 0058 Plugin::Plugin(QObject* parent, const QVariantList&) 0059 : IPlugin("kdevvalgrind", parent) 0060 , m_toolViewFactory(new ToolViewFactory) 0061 , m_launchMode(new LaunchMode) 0062 , m_problemModel(new ProblemModel) 0063 , m_isRunning(false) 0064 { 0065 m_self = this; 0066 setXMLFile("kdevvalgrind.rc"); 0067 0068 core()->uiController()->addToolView(i18n("Valgrind"), m_toolViewFactory); 0069 core()->runController()->addLaunchMode(m_launchMode.data()); 0070 0071 m_tools += MemcheckTool::self(); 0072 m_tools += CachegrindTool::self(); 0073 m_tools += CallgrindTool::self(); 0074 m_tools += HelgrindTool::self(); 0075 m_tools += DrdTool::self(); 0076 m_tools += MassifTool::self(); 0077 0078 for (auto tool : qAsConst(m_tools)) { 0079 auto action = new QAction(i18n("Run %1", tool->fullName()), this); 0080 connect(action, &QAction::triggered, this, [this, tool]() { 0081 executeDefaultLaunch(tool->id()); 0082 }); 0083 actionCollection()->addAction(tool->menuActionName(), action); 0084 } 0085 0086 auto pluginController = core()->pluginController(); 0087 const auto plugins = pluginController->allPluginsForExtension(QStringLiteral("org.kdevelop.IExecutePlugin")); 0088 for (auto plugin : plugins) { 0089 setupExecutePlugin(plugin, true); 0090 } 0091 0092 connect(pluginController, &KDevelop::IPluginController::pluginLoaded, 0093 this, [this](KDevelop::IPlugin* plugin) { 0094 setupExecutePlugin(plugin, true); 0095 }); 0096 0097 connect(pluginController, &KDevelop::IPluginController::unloadingPlugin, 0098 this, [this](KDevelop::IPlugin* plugin) { 0099 setupExecutePlugin(plugin, false); 0100 }); 0101 } 0102 0103 Plugin::~Plugin() 0104 { 0105 m_self = nullptr; 0106 } 0107 0108 Plugin* Plugin::self() 0109 { 0110 return m_self; 0111 } 0112 0113 void Plugin::unload() 0114 { 0115 core()->uiController()->removeToolView(m_toolViewFactory); 0116 m_problemModel.reset(nullptr); 0117 0118 const auto plugins = core()->pluginController()->allPluginsForExtension(QStringLiteral("org.kdevelop.IExecutePlugin")); 0119 for (auto plugin : plugins) { 0120 setupExecutePlugin(plugin, false); 0121 } 0122 Q_ASSERT(m_launchers.isEmpty()); 0123 0124 core()->runController()->removeLaunchMode(m_launchMode.data()); 0125 m_launchMode.reset(nullptr); 0126 0127 qDeleteAll(m_tools); 0128 } 0129 0130 void Plugin::setupExecutePlugin(KDevelop::IPlugin* plugin, bool load) 0131 { 0132 if (plugin == this) { 0133 return; 0134 } 0135 0136 auto iface = plugin->extension<IExecutePlugin>(); 0137 if (!iface) { 0138 return; 0139 } 0140 0141 auto type = core()->runController()->launchConfigurationTypeForId(iface->nativeAppConfigTypeId()); 0142 Q_ASSERT(type); 0143 0144 if (load) { 0145 for (auto tool : qAsConst(m_tools)) { 0146 auto launcher = tool->createLauncher(); 0147 m_launchers.insert(plugin, launcher); 0148 type->addLauncher(launcher); 0149 } 0150 } 0151 0152 else { 0153 auto pluginLaunchers = m_launchers.values(plugin); 0154 for (auto launcher : pluginLaunchers) { 0155 Q_ASSERT(launcher); 0156 0157 m_launchers.remove(plugin, launcher); 0158 type->removeLauncher(launcher); 0159 delete launcher; 0160 } 0161 } 0162 } 0163 0164 int Plugin::configPages() const 0165 { 0166 return 1; 0167 } 0168 0169 KDevelop::ConfigPage* Plugin::configPage(int number, QWidget* parent) 0170 { 0171 if (number) { 0172 return nullptr; 0173 } 0174 0175 return new GlobalConfigPage(this, parent); 0176 } 0177 0178 Valgrind::LaunchMode* Plugin::launchMode() const 0179 { 0180 return m_launchMode.data(); 0181 } 0182 0183 ProblemModel* Plugin::problemModel() const 0184 { 0185 return m_problemModel.data(); 0186 } 0187 0188 void Plugin::jobReadyToStart(Job* job) 0189 { 0190 m_isRunning = true; 0191 0192 const auto actions = actionCollection()->actions(); 0193 for (auto action : actions) { 0194 action->setEnabled(false); 0195 } 0196 0197 Q_ASSERT(job); 0198 if (!job->tool()->hasView()) { 0199 m_problemModel->reset(job->tool()); 0200 } 0201 } 0202 0203 void Plugin::jobReadyToFinish(Job* job, bool ok) 0204 { 0205 if (!ok) { 0206 return; 0207 } 0208 0209 Q_ASSERT(job); 0210 if (job->tool()->hasView()) { 0211 emit addView(job->createView(), job->statusName()); 0212 0213 core()->uiController()->findToolView(i18n("Valgrind"), m_toolViewFactory); 0214 } else { 0215 m_problemModel->show(); 0216 } 0217 } 0218 0219 void Plugin::jobFinished(KJob* job) 0220 { 0221 Q_UNUSED(job); 0222 0223 const auto actions = actionCollection()->actions(); 0224 for (auto action : actions) { 0225 action->setEnabled(true); 0226 } 0227 m_isRunning = false; 0228 } 0229 0230 bool Plugin::isRunning() 0231 { 0232 return m_isRunning; 0233 } 0234 0235 void Plugin::executeDefaultLaunch(const QString& launcherId) 0236 { 0237 auto runController = KDevelop::Core::self()->runControllerInternal(); 0238 Q_ASSERT(runController); 0239 0240 if (runController->launchConfigurations().isEmpty()) { 0241 runController->showConfigurationDialog(); 0242 } 0243 0244 auto defaultLaunch = runController->defaultLaunch(); 0245 if (defaultLaunch) { 0246 defaultLaunch->setLauncherForMode(m_launchMode->id(), launcherId); 0247 runController->executeDefaultLaunch(m_launchMode->id()); 0248 } 0249 } 0250 0251 } 0252 0253 #include "plugin.moc"