Commit 92e301a0 authored by hjk's avatar hjk

Debugger: Merge debug mode and analyze mode

On the user-visible side, only the 'Analyze' mode button disappears,
and instead a combobox to switch between different tools in appears
in the Debug mode toolbar.

Internally, that's quite some re-organzition: The centralized
'Analyze mode is busy' flag is gone, allowing us to run e.g.
ClangStaticAnalyzer and MemCheck in parallel.

Analyzer tools and debugger now share the same mechanism to
generate/load/save dock widgets.

Analyzer tools now create and handle their own start/stop button
when appropriate. In general, Analyzer tools can create/handle more
than one run control at a time.

Further consolidation is possible, e.g. RunControl state handling
could be merged into the base ProjectExplorer::RunControl to
avoid the still existing duplication in ~15 instances.

Change-Id: I91e5940ebc4211f98056d507cf2f7b5f8efe7f07
Reviewed-by: default avatarChristian Stenger <christian.stenger@theqtcompany.com>
parent c326011f
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include <QDir> #include <QDir>
#include <QTcpServer> #include <QTcpServer>
using namespace Analyzer; using namespace Debugger;
using namespace ProjectExplorer; using namespace ProjectExplorer;
namespace Android { namespace Android {
...@@ -48,7 +48,7 @@ namespace Internal { ...@@ -48,7 +48,7 @@ namespace Internal {
RunControl *AndroidAnalyzeSupport::createAnalyzeRunControl(AndroidRunConfiguration *runConfig, RunControl *AndroidAnalyzeSupport::createAnalyzeRunControl(AndroidRunConfiguration *runConfig,
Core::Id runMode) Core::Id runMode)
{ {
AnalyzerRunControl *runControl = AnalyzerManager::createRunControl(runConfig, runMode); AnalyzerRunControl *runControl = Debugger::createAnalyzerRunControl(runConfig, runMode);
QTC_ASSERT(runControl, return 0); QTC_ASSERT(runControl, return 0);
AnalyzerConnection connection; AnalyzerConnection connection;
if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include "androidrunconfiguration.h" #include "androidrunconfiguration.h"
#include <qmldebug/qmloutputparser.h> #include <qmldebug/qmloutputparser.h>
namespace Analyzer { class AnalyzerRunControl; } namespace Debugger { class AnalyzerRunControl; }
namespace ProjectExplorer { class RunControl; } namespace ProjectExplorer { class RunControl; }
namespace Android { namespace Android {
...@@ -43,7 +43,7 @@ class AndroidAnalyzeSupport : public QObject ...@@ -43,7 +43,7 @@ class AndroidAnalyzeSupport : public QObject
public: public:
AndroidAnalyzeSupport(AndroidRunConfiguration *runConfig, AndroidAnalyzeSupport(AndroidRunConfiguration *runConfig,
Analyzer::AnalyzerRunControl *runControl); Debugger::AnalyzerRunControl *runControl);
static ProjectExplorer::RunControl *createAnalyzeRunControl(AndroidRunConfiguration *runConfig, static ProjectExplorer::RunControl *createAnalyzeRunControl(AndroidRunConfiguration *runConfig,
Core::Id runMode); Core::Id runMode);
......
...@@ -50,7 +50,6 @@ ...@@ -50,7 +50,6 @@
#include <QApplication> #include <QApplication>
using namespace Analyzer;
using namespace Debugger; using namespace Debugger;
using namespace ProjectExplorer; using namespace ProjectExplorer;
......
...@@ -44,8 +44,8 @@ public: ...@@ -44,8 +44,8 @@ public:
QString message; QString message;
QString extendedMessage; QString extendedMessage;
Analyzer::DiagnosticLocation location; Debugger::DiagnosticLocation location;
QList<Analyzer::DiagnosticLocation> ranges; QList<Debugger::DiagnosticLocation> ranges;
int depth; int depth;
}; };
...@@ -59,7 +59,7 @@ public: ...@@ -59,7 +59,7 @@ public:
QString type; QString type;
QString issueContextKind; QString issueContextKind;
QString issueContext; QString issueContext;
Analyzer::DiagnosticLocation location; Debugger::DiagnosticLocation location;
QList<ExplainingStep> explainingSteps; QList<ExplainingStep> explainingSteps;
}; };
......
...@@ -168,7 +168,7 @@ static QString createExplainingStepToolTipString(const ExplainingStep &step) ...@@ -168,7 +168,7 @@ static QString createExplainingStepToolTipString(const ExplainingStep &step)
return html; return html;
} }
static QString createLocationString(const Analyzer::DiagnosticLocation &location) static QString createLocationString(const Debugger::DiagnosticLocation &location)
{ {
const QString filePath = location.filePath; const QString filePath = location.filePath;
const QString lineNumber = QString::number(location.line); const QString lineNumber = QString::number(location.line);
...@@ -224,10 +224,10 @@ DiagnosticItem::DiagnosticItem(const Diagnostic &diag) : m_diagnostic(diag) ...@@ -224,10 +224,10 @@ DiagnosticItem::DiagnosticItem(const Diagnostic &diag) : m_diagnostic(diag)
appendChild(new ExplainingStepItem(s)); appendChild(new ExplainingStepItem(s));
} }
QVariant locationData(int role, const Analyzer::DiagnosticLocation &location) QVariant locationData(int role, const Debugger::DiagnosticLocation &location)
{ {
switch (role) { switch (role) {
case Analyzer::DetailedErrorView::LocationRole: case Debugger::DetailedErrorView::LocationRole:
return QVariant::fromValue(location); return QVariant::fromValue(location);
case Qt::ToolTipRole: case Qt::ToolTipRole:
return location.filePath.isEmpty() ? QVariant() : QVariant(location.filePath); return location.filePath.isEmpty() ? QVariant() : QVariant(location.filePath);
...@@ -238,12 +238,12 @@ QVariant locationData(int role, const Analyzer::DiagnosticLocation &location) ...@@ -238,12 +238,12 @@ QVariant locationData(int role, const Analyzer::DiagnosticLocation &location)
QVariant DiagnosticItem::data(int column, int role) const QVariant DiagnosticItem::data(int column, int role) const
{ {
if (column == Analyzer::DetailedErrorView::LocationColumn) if (column == Debugger::DetailedErrorView::LocationColumn)
return locationData(role, m_diagnostic.location); return locationData(role, m_diagnostic.location);
// DiagnosticColumn // DiagnosticColumn
switch (role) { switch (role) {
case Analyzer::DetailedErrorView::FullTextRole: case Debugger::DetailedErrorView::FullTextRole:
return fullText(m_diagnostic); return fullText(m_diagnostic);
case ClangStaticAnalyzerDiagnosticModel::DiagnosticRole: case ClangStaticAnalyzerDiagnosticModel::DiagnosticRole:
return QVariant::fromValue(m_diagnostic); return QVariant::fromValue(m_diagnostic);
...@@ -262,12 +262,12 @@ ExplainingStepItem::ExplainingStepItem(const ExplainingStep &step) : m_step(step ...@@ -262,12 +262,12 @@ ExplainingStepItem::ExplainingStepItem(const ExplainingStep &step) : m_step(step
QVariant ExplainingStepItem::data(int column, int role) const QVariant ExplainingStepItem::data(int column, int role) const
{ {
if (column == Analyzer::DetailedErrorView::LocationColumn) if (column == Debugger::DetailedErrorView::LocationColumn)
return locationData(role, m_step.location); return locationData(role, m_step.location);
// DiagnosticColumn // DiagnosticColumn
switch (role) { switch (role) {
case Analyzer::DetailedErrorView::FullTextRole: case Debugger::DetailedErrorView::FullTextRole:
return fullText(static_cast<DiagnosticItem *>(parent())->diagnostic()); return fullText(static_cast<DiagnosticItem *>(parent())->diagnostic());
case ClangStaticAnalyzerDiagnosticModel::DiagnosticRole: case ClangStaticAnalyzerDiagnosticModel::DiagnosticRole:
return QVariant::fromValue(static_cast<DiagnosticItem *>(parent())->diagnostic()); return QVariant::fromValue(static_cast<DiagnosticItem *>(parent())->diagnostic());
......
...@@ -52,7 +52,7 @@ public: ...@@ -52,7 +52,7 @@ public:
QList<Diagnostic> diagnostics() const; QList<Diagnostic> diagnostics() const;
enum ItemRole { enum ItemRole {
DiagnosticRole = Analyzer::DetailedErrorView::FullTextRole + 1 DiagnosticRole = Debugger::DetailedErrorView::FullTextRole + 1
}; };
}; };
......
...@@ -36,13 +36,13 @@ ...@@ -36,13 +36,13 @@
#include <QAction> #include <QAction>
#include <QDebug> #include <QDebug>
using namespace Analyzer; using namespace Debugger;
namespace ClangStaticAnalyzer { namespace ClangStaticAnalyzer {
namespace Internal { namespace Internal {
ClangStaticAnalyzerDiagnosticView::ClangStaticAnalyzerDiagnosticView(QWidget *parent) ClangStaticAnalyzerDiagnosticView::ClangStaticAnalyzerDiagnosticView(QWidget *parent)
: Analyzer::DetailedErrorView(parent) : Debugger::DetailedErrorView(parent)
{ {
m_suppressAction = new QAction(tr("Suppress this diagnostic"), this); m_suppressAction = new QAction(tr("Suppress this diagnostic"), this);
connect(m_suppressAction, &QAction::triggered, [this](bool) { suppressCurrentDiagnostic(); }); connect(m_suppressAction, &QAction::triggered, [this](bool) { suppressCurrentDiagnostic(); });
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
namespace ClangStaticAnalyzer { namespace ClangStaticAnalyzer {
namespace Internal { namespace Internal {
class ClangStaticAnalyzerDiagnosticView : public Analyzer::DetailedErrorView class ClangStaticAnalyzerDiagnosticView : public Debugger::DetailedErrorView
{ {
Q_OBJECT Q_OBJECT
......
...@@ -55,8 +55,8 @@ private: ...@@ -55,8 +55,8 @@ private:
void readDiagnosticsDict(); void readDiagnosticsDict();
QList<ExplainingStep> readPathArray(); QList<ExplainingStep> readPathArray();
ExplainingStep readPathDict(); ExplainingStep readPathDict();
Analyzer::DiagnosticLocation readLocationDict(bool elementIsRead = false); Debugger::DiagnosticLocation readLocationDict(bool elementIsRead = false);
QList<Analyzer::DiagnosticLocation> readRangesArray(); QList<Debugger::DiagnosticLocation> readRangesArray();
QString readString(); QString readString();
QStringList readStringArray(); QStringList readStringArray();
...@@ -284,9 +284,9 @@ ExplainingStep ClangStaticAnalyzerLogFileReader::readPathDict() ...@@ -284,9 +284,9 @@ ExplainingStep ClangStaticAnalyzerLogFileReader::readPathDict()
return explainingStep; return explainingStep;
} }
Analyzer::DiagnosticLocation ClangStaticAnalyzerLogFileReader::readLocationDict(bool elementIsRead) Debugger::DiagnosticLocation ClangStaticAnalyzerLogFileReader::readLocationDict(bool elementIsRead)
{ {
Analyzer::DiagnosticLocation location; Debugger::DiagnosticLocation location;
if (elementIsRead) { if (elementIsRead) {
QTC_ASSERT(m_xml.isStartElement() && m_xml.name() == QLatin1String("dict"), QTC_ASSERT(m_xml.isStartElement() && m_xml.name() == QLatin1String("dict"),
return location); return location);
...@@ -317,14 +317,14 @@ Analyzer::DiagnosticLocation ClangStaticAnalyzerLogFileReader::readLocationDict( ...@@ -317,14 +317,14 @@ Analyzer::DiagnosticLocation ClangStaticAnalyzerLogFileReader::readLocationDict(
if (lineOk && columnOk && fileIndexOk) { if (lineOk && columnOk && fileIndexOk) {
QTC_ASSERT(fileIndex < m_referencedFiles.size(), return location); QTC_ASSERT(fileIndex < m_referencedFiles.size(), return location);
location = Analyzer::DiagnosticLocation(m_referencedFiles.at(fileIndex), line, column); location = Debugger::DiagnosticLocation(m_referencedFiles.at(fileIndex), line, column);
} }
return location; return location;
} }
QList<Analyzer::DiagnosticLocation> ClangStaticAnalyzerLogFileReader::readRangesArray() QList<Debugger::DiagnosticLocation> ClangStaticAnalyzerLogFileReader::readRangesArray()
{ {
QList<Analyzer::DiagnosticLocation> result; QList<Debugger::DiagnosticLocation> result;
// It's an array of arrays... // It's an array of arrays...
QTC_ASSERT(m_xml.readNextStartElement() && m_xml.name() == QLatin1String("array"), QTC_ASSERT(m_xml.readNextStartElement() && m_xml.name() == QLatin1String("array"),
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
#include <QtPlugin> #include <QtPlugin>
using namespace Analyzer; using namespace Debugger;
namespace ClangStaticAnalyzer { namespace ClangStaticAnalyzer {
namespace Internal { namespace Internal {
...@@ -122,36 +122,10 @@ bool ClangStaticAnalyzerPlugin::initialize(const QStringList &arguments, QString ...@@ -122,36 +122,10 @@ bool ClangStaticAnalyzerPlugin::initialize(const QStringList &arguments, QString
panelFactory->setSimpleCreateWidgetFunction<ProjectSettingsWidget>(QIcon()); panelFactory->setSimpleCreateWidgetFunction<ProjectSettingsWidget>(QIcon());
ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory); ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory);
auto tool = m_analyzerTool = new ClangStaticAnalyzerTool(this); m_analyzerTool = new ClangStaticAnalyzerTool(this);
addAutoReleasedObject(new ClangStaticAnalyzerRunControlFactory(m_analyzerTool)); addAutoReleasedObject(new ClangStaticAnalyzerRunControlFactory(m_analyzerTool));
addAutoReleasedObject(new ClangStaticAnalyzerOptionsPage); addAutoReleasedObject(new ClangStaticAnalyzerOptionsPage);
AnalyzerManager::registerToolbar(ClangStaticAnalyzerPerspectiveId, tool->createWidgets());
auto runControlCreator = [tool](ProjectExplorer::RunConfiguration *runConfiguration,
Core::Id runMode) {
return tool->createRunControl(runConfiguration, runMode);
};
const QString toolTip = tr("Clang Static Analyzer uses the analyzer from the clang project "
"to find bugs.");
AnalyzerManager::registerPerspective(ClangStaticAnalyzerPerspectiveId, {
{ ClangStaticAnalyzerDockId, Core::Id(), Perspective::SplitVertical }
});
ActionDescription desc;
desc.setText(tr("Clang Static Analyzer"));
desc.setToolTip(toolTip);
desc.setRunMode(Constants::CLANGSTATICANALYZER_RUN_MODE);
desc.setPerspectiveId(ClangStaticAnalyzerPerspectiveId);
desc.setRunControlCreator(runControlCreator);
desc.setCustomToolStarter([tool](ProjectExplorer::RunConfiguration *rc) {
tool->startTool(rc);
});
desc.setMenuGroup(Analyzer::Constants::G_ANALYZER_TOOLS);
AnalyzerManager::registerAction(ClangStaticAnalyzerActionId, desc);
return true; return true;
} }
......
...@@ -304,12 +304,12 @@ static Core::Id toolchainType(ProjectExplorer::RunConfiguration *runConfiguratio ...@@ -304,12 +304,12 @@ static Core::Id toolchainType(ProjectExplorer::RunConfiguration *runConfiguratio
return ToolChainKitInformation::toolChain(runConfiguration->target()->kit())->typeId(); return ToolChainKitInformation::toolChain(runConfiguration->target()->kit())->typeId();
} }
bool ClangStaticAnalyzerRunControl::startEngine() void ClangStaticAnalyzerRunControl::start()
{ {
m_success = false; m_success = false;
emit starting(); emit starting();
QTC_ASSERT(m_projectInfo.isValid(), emit finished(); return false); QTC_ASSERT(m_projectInfo.isValid(), emit finished(); return);
const Utils::FileName projectFile = m_projectInfo.project()->projectFilePath(); const Utils::FileName projectFile = m_projectInfo.project()->projectFilePath();
appendMessage(tr("Running Clang Static Analyzer on %1").arg(projectFile.toUserOutput()) appendMessage(tr("Running Clang Static Analyzer on %1").arg(projectFile.toUserOutput())
+ QLatin1Char('\n'), Utils::NormalMessageFormat); + QLatin1Char('\n'), Utils::NormalMessageFormat);
...@@ -324,7 +324,7 @@ bool ClangStaticAnalyzerRunControl::startEngine() ...@@ -324,7 +324,7 @@ bool ClangStaticAnalyzerRunControl::startEngine()
appendMessage(errorMessage + QLatin1Char('\n'), Utils::ErrorMessageFormat); appendMessage(errorMessage + QLatin1Char('\n'), Utils::ErrorMessageFormat);
AnalyzerUtils::logToIssuesPane(Task::Error, errorMessage); AnalyzerUtils::logToIssuesPane(Task::Error, errorMessage);
emit finished(); emit finished();
return false; return;
} }
m_clangExecutable = executable; m_clangExecutable = executable;
...@@ -337,7 +337,7 @@ bool ClangStaticAnalyzerRunControl::startEngine() ...@@ -337,7 +337,7 @@ bool ClangStaticAnalyzerRunControl::startEngine()
appendMessage(errorMessage + QLatin1Char('\n'), Utils::ErrorMessageFormat); appendMessage(errorMessage + QLatin1Char('\n'), Utils::ErrorMessageFormat);
AnalyzerUtils::logToIssuesPane(Task::Error, errorMessage); AnalyzerUtils::logToIssuesPane(Task::Error, errorMessage);
emit finished(); emit finished();
return false; return;
} }
m_clangLogFileDir = temporaryDir.path(); m_clangLogFileDir = temporaryDir.path();
...@@ -364,19 +364,22 @@ bool ClangStaticAnalyzerRunControl::startEngine() ...@@ -364,19 +364,22 @@ bool ClangStaticAnalyzerRunControl::startEngine()
qCDebug(LOG) << "Environment:" << m_environment; qCDebug(LOG) << "Environment:" << m_environment;
m_runners.clear(); m_runners.clear();
const int parallelRuns = ClangStaticAnalyzerSettings::instance()->simultaneousProcesses(); const int parallelRuns = ClangStaticAnalyzerSettings::instance()->simultaneousProcesses();
QTC_ASSERT(parallelRuns >= 1, emit finished(); return false); QTC_ASSERT(parallelRuns >= 1, emit finished(); return);
m_success = true; m_success = true;
m_running = true;
if (m_unitsToProcess.isEmpty()) { if (m_unitsToProcess.isEmpty()) {
finalize(); finalize();
return false; return;
} }
emit started();
while (m_runners.size() < parallelRuns && !m_unitsToProcess.isEmpty()) while (m_runners.size() < parallelRuns && !m_unitsToProcess.isEmpty())
analyzeNextFile(); analyzeNextFile();
return true;
} }
void ClangStaticAnalyzerRunControl::stopEngine() RunControl::StopResult ClangStaticAnalyzerRunControl::stop()
{ {
QSetIterator<ClangStaticAnalyzerRunner *> i(m_runners); QSetIterator<ClangStaticAnalyzerRunner *> i(m_runners);
while (i.hasNext()) { while (i.hasNext()) {
...@@ -389,7 +392,14 @@ void ClangStaticAnalyzerRunControl::stopEngine() ...@@ -389,7 +392,14 @@ void ClangStaticAnalyzerRunControl::stopEngine()
appendMessage(tr("Clang Static Analyzer stopped by user.") + QLatin1Char('\n'), appendMessage(tr("Clang Static Analyzer stopped by user.") + QLatin1Char('\n'),
Utils::NormalMessageFormat); Utils::NormalMessageFormat);
m_progress.reportFinished(); m_progress.reportFinished();
m_running = false;
emit finished(); emit finished();
return RunControl::StoppedSynchronously;
}
bool ClangStaticAnalyzerRunControl::isRunning() const
{
return m_running;
} }
void ClangStaticAnalyzerRunControl::analyzeNextFile() void ClangStaticAnalyzerRunControl::analyzeNextFile()
...@@ -479,7 +489,6 @@ void ClangStaticAnalyzerRunControl::handleFinished() ...@@ -479,7 +489,6 @@ void ClangStaticAnalyzerRunControl::handleFinished()
void ClangStaticAnalyzerRunControl::onProgressCanceled() void ClangStaticAnalyzerRunControl::onProgressCanceled()
{ {
Analyzer::AnalyzerManager::stopTool();
m_progress.reportCanceled(); m_progress.reportCanceled();
m_progress.reportFinished(); m_progress.reportFinished();
} }
......
...@@ -48,7 +48,7 @@ struct AnalyzeUnit { ...@@ -48,7 +48,7 @@ struct AnalyzeUnit {
}; };
typedef QList<AnalyzeUnit> AnalyzeUnits; typedef QList<AnalyzeUnit> AnalyzeUnits;
class ClangStaticAnalyzerRunControl : public Analyzer::AnalyzerRunControl class ClangStaticAnalyzerRunControl : public Debugger::AnalyzerRunControl
{ {
Q_OBJECT Q_OBJECT
...@@ -57,8 +57,9 @@ public: ...@@ -57,8 +57,9 @@ public:
Core::Id runMode, Core::Id runMode,
const CppTools::ProjectInfo &projectInfo); const CppTools::ProjectInfo &projectInfo);
bool startEngine() override; void start() override;
void stopEngine() override; StopResult stop() override;
bool isRunning() const override;
bool success() const { return m_success; } // For testing. bool success() const { return m_success; } // For testing.
...@@ -93,6 +94,7 @@ private: ...@@ -93,6 +94,7 @@ private:
int m_filesAnalyzed; int m_filesAnalyzed;
int m_filesNotAnalyzed; int m_filesNotAnalyzed;
bool m_success; bool m_success;
bool m_running = false;
}; };
} // namespace Internal } // namespace Internal
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
using namespace Analyzer; using namespace Debugger;
using namespace ProjectExplorer; using namespace ProjectExplorer;
namespace ClangStaticAnalyzer { namespace ClangStaticAnalyzer {
...@@ -115,7 +115,7 @@ RunControl *ClangStaticAnalyzerRunControlFactory::create(RunConfiguration *runCo ...@@ -115,7 +115,7 @@ RunControl *ClangStaticAnalyzerRunControlFactory::create(RunConfiguration *runCo
return 0; return 0;
} }
return AnalyzerManager::createRunControl(runConfiguration, runMode); return Debugger::createAnalyzerRunControl(runConfiguration, runMode);
} }
} // namespace Internal } // namespace Internal
......
...@@ -53,8 +53,9 @@ ...@@ -53,8 +53,9 @@
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
#include <QToolButton> #include <QToolButton>
using namespace Analyzer; using namespace Debugger;
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils;
namespace ClangStaticAnalyzer { namespace ClangStaticAnalyzer {
namespace Internal { namespace Internal {
...@@ -69,14 +70,6 @@ ClangStaticAnalyzerTool::ClangStaticAnalyzerTool(QObject *parent) ...@@ -69,14 +70,6 @@ ClangStaticAnalyzerTool::ClangStaticAnalyzerTool(QObject *parent)
, m_running(false) , m_running(false)
{ {
setObjectName(QLatin1String("ClangStaticAnalyzerTool")); setObjectName(QLatin1String("ClangStaticAnalyzerTool"));
}
QWidget *ClangStaticAnalyzerTool::createWidgets()
{
QTC_ASSERT(!m_diagnosticView, return 0);
QTC_ASSERT(!m_diagnosticModel, return 0);
QTC_ASSERT(!m_goBack, return 0);
QTC_ASSERT(!m_goNext, return 0);
// //
// Diagnostic View // Diagnostic View
...@@ -104,27 +97,19 @@ QWidget *ClangStaticAnalyzerTool::createWidgets() ...@@ -104,27 +97,19 @@ QWidget *ClangStaticAnalyzerTool::createWidgets()
this, &ClangStaticAnalyzerTool::handleStateUpdate); this, &ClangStaticAnalyzerTool::handleStateUpdate);
} }
AnalyzerManager::registerDockWidget(ClangStaticAnalyzerDockId, m_diagnosticView);
// //
// Toolbar widget // Toolbar widget
// //
QHBoxLayout *layout = new QHBoxLayout;
layout->setMargin(0);
layout->setSpacing(0);
QAction *action = 0; m_startAction = Debugger::createStartAction();
QToolButton *button = 0; m_stopAction = Debugger::createStopAction();
// Go to previous diagnostic // Go to previous diagnostic
action = new QAction(this); auto action = new QAction(this);
action->setDisabled(true); action->setDisabled(true);
action->setIcon(Core::Icons::PREV.icon()); action->setIcon(Core::Icons::PREV.icon());
action->setToolTip(tr("Go to previous bug.")); action->setToolTip(tr("Go to previous bug."));
connect(action, &QAction::triggered, m_diagnosticView, &DetailedErrorView::goBack); connect(action, &QAction::triggered, m_diagnosticView, &DetailedErrorView::goBack);
button = new QToolButton;
button->setDefaultAction(action);
layout->addWidget(button);
m_goBack = action; m_goBack = action;
// Go to next diagnostic // Go to next diagnostic
...@@ -133,17 +118,41 @@ QWidget *ClangStaticAnalyzerTool::createWidgets() ...@@ -133,17 +118,41 @@ QWidget *ClangStaticAnalyzerTool::createWidgets()
action->setIcon(Core::Icons::NEXT.icon()); action->setIcon(Core::Icons::NEXT.icon());
action->setToolTip(tr("Go to next bug.")); action->setToolTip(tr("Go to next bug."));
connect(action, &QAction::triggered, m_diagnosticView, &DetailedErrorView::goNext); connect(action, &QAction::triggered, m_diagnosticView, &DetailedErrorView::goNext);
button = new QToolButton;
button->setDefaultAction(action);
layout->addWidget(button);
m_goNext = action; m_goNext = action;
layout->addStretch(); const QString toolTip = tr("Clang Static Analyzer uses the analyzer from the clang project "
"to find bugs.");
QWidget *toolbarWidget = new QWidget;
toolbarWidget->setObjectName(QLatin1String("ClangStaticAnalyzerToolBarWidget")); Debugger::registerPerspective(ClangStaticAnalyzerPerspectiveId, {
toolbarWidget->setLayout(layout); tr("Clang Static Analyzer"),
return toolbarWidget; {{ ClangStaticAnalyzerDockId, m_diagnosticView, {}, Perspective::SplitVertical }}
});
ActionDescription desc;
desc.setText(tr("Clang Static Analyzer"));
desc.setToolTip(toolTip);
desc.setRunMode(Constants