2013-03-27 13:03:15 +01:00
|
|
|
/****************************************************************************
|
|
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2013-03-27 13:03:15 +01:00
|
|
|
**
|
|
|
|
|
** 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
|
2016-01-15 14:57:40 +01:00
|
|
|
** 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.
|
2013-03-27 13:03:15 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** 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.
|
2013-03-27 13:03:15 +01:00
|
|
|
**
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "debuggerrunconfigurationaspect.h"
|
|
|
|
|
|
|
|
|
|
#include "debuggerconstants.h"
|
|
|
|
|
|
2020-02-17 14:25:30 +01:00
|
|
|
#include <coreplugin/helpmanager.h>
|
2013-03-27 13:03:15 +01:00
|
|
|
#include <coreplugin/icontext.h>
|
2013-03-27 17:17:24 +01:00
|
|
|
#include <coreplugin/icore.h>
|
2020-02-17 14:25:30 +01:00
|
|
|
#include <projectexplorer/buildconfiguration.h>
|
|
|
|
|
#include <projectexplorer/buildstep.h>
|
|
|
|
|
#include <projectexplorer/buildsteplist.h>
|
2013-04-05 13:20:52 +02:00
|
|
|
#include <projectexplorer/kitinformation.h>
|
2013-03-27 13:03:15 +01:00
|
|
|
#include <projectexplorer/project.h>
|
|
|
|
|
#include <projectexplorer/projectexplorerconstants.h>
|
2013-03-27 17:17:24 +01:00
|
|
|
#include <projectexplorer/runconfiguration.h>
|
2013-03-27 13:03:15 +01:00
|
|
|
#include <projectexplorer/target.h>
|
2020-02-17 14:25:30 +01:00
|
|
|
#include <qtsupport/qtbuildaspects.h>
|
2013-03-27 13:03:15 +01:00
|
|
|
|
2020-09-18 12:11:40 +02:00
|
|
|
#include <utils/layoutbuilder.h>
|
|
|
|
|
|
2013-03-27 17:17:24 +01:00
|
|
|
#include <QCheckBox>
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
#include <QFormLayout>
|
|
|
|
|
#include <QLabel>
|
2019-09-30 11:26:32 +02:00
|
|
|
#include <QTextEdit>
|
2013-03-27 17:17:24 +01:00
|
|
|
|
2019-09-30 14:00:58 +02:00
|
|
|
using namespace Debugger::Internal;
|
2020-09-18 12:11:40 +02:00
|
|
|
using namespace ProjectExplorer;
|
|
|
|
|
using namespace Utils;
|
2014-03-26 11:23:04 +01:00
|
|
|
|
2013-03-27 13:03:15 +01:00
|
|
|
namespace Debugger {
|
2013-03-27 17:17:24 +01:00
|
|
|
namespace Internal {
|
|
|
|
|
|
2019-09-30 14:00:58 +02:00
|
|
|
enum DebuggerLanguageStatus {
|
|
|
|
|
DisabledLanguage = 0,
|
|
|
|
|
EnabledLanguage,
|
|
|
|
|
AutoEnabledLanguage
|
|
|
|
|
};
|
2013-03-27 17:17:24 +01:00
|
|
|
|
2020-09-18 12:11:40 +02:00
|
|
|
class DebuggerLanguageAspect : public BaseAspect
|
2013-03-27 17:17:24 +01:00
|
|
|
{
|
|
|
|
|
public:
|
2019-09-30 14:00:58 +02:00
|
|
|
DebuggerLanguageAspect() = default;
|
|
|
|
|
|
2019-10-15 17:20:51 +02:00
|
|
|
void addToLayout(LayoutBuilder &builder) override;
|
2019-09-30 14:00:58 +02:00
|
|
|
|
|
|
|
|
bool value() const;
|
|
|
|
|
void setValue(bool val);
|
|
|
|
|
|
|
|
|
|
void setAutoSettingsKey(const QString &settingsKey);
|
|
|
|
|
void setLabel(const QString &label);
|
|
|
|
|
void setInfoLabelText(const QString &text) { m_infoLabelText = text; }
|
2013-03-27 17:17:24 +01:00
|
|
|
|
2019-09-30 14:00:58 +02:00
|
|
|
void setClickCallBack(const std::function<void (bool)> &clickCallBack)
|
|
|
|
|
{
|
|
|
|
|
m_clickCallBack = clickCallBack;
|
|
|
|
|
}
|
2014-03-26 11:23:04 +01:00
|
|
|
|
2019-09-30 14:00:58 +02:00
|
|
|
void fromMap(const QVariantMap &map) override;
|
|
|
|
|
void toMap(QVariantMap &map) const override;
|
2013-03-27 17:17:24 +01:00
|
|
|
|
|
|
|
|
public:
|
2019-09-30 14:00:58 +02:00
|
|
|
DebuggerLanguageStatus m_value = AutoEnabledLanguage;
|
|
|
|
|
bool m_defaultValue = false;
|
|
|
|
|
QString m_label;
|
|
|
|
|
QString m_infoLabelText;
|
|
|
|
|
QPointer<QCheckBox> m_checkBox; // Owned by configuration widget
|
|
|
|
|
QPointer<QLabel> m_infoLabel; // Owned by configuration widget
|
|
|
|
|
QString m_autoSettingsKey;
|
|
|
|
|
|
|
|
|
|
std::function<void(bool)> m_clickCallBack;
|
2013-03-27 17:17:24 +01:00
|
|
|
};
|
|
|
|
|
|
2019-10-15 17:20:51 +02:00
|
|
|
void DebuggerLanguageAspect::addToLayout(LayoutBuilder &builder)
|
2013-03-27 17:17:24 +01:00
|
|
|
{
|
2019-09-30 14:00:58 +02:00
|
|
|
QTC_CHECK(!m_checkBox);
|
2019-10-15 17:20:51 +02:00
|
|
|
m_checkBox = new QCheckBox(m_label);
|
2019-09-30 14:00:58 +02:00
|
|
|
m_checkBox->setChecked(m_value);
|
2022-01-20 11:52:30 +01:00
|
|
|
m_checkBox->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
|
2019-09-30 14:00:58 +02:00
|
|
|
|
|
|
|
|
QTC_CHECK(m_clickCallBack);
|
|
|
|
|
connect(m_checkBox, &QAbstractButton::clicked, this, m_clickCallBack, Qt::QueuedConnection);
|
|
|
|
|
|
|
|
|
|
connect(m_checkBox.data(), &QAbstractButton::clicked, this, [this] {
|
|
|
|
|
m_value = m_checkBox->isChecked() ? EnabledLanguage : DisabledLanguage;
|
|
|
|
|
emit changed();
|
|
|
|
|
});
|
2020-03-20 09:57:15 +01:00
|
|
|
builder.addItem(QString());
|
2019-10-15 17:20:51 +02:00
|
|
|
builder.addItem(m_checkBox.data());
|
2019-09-30 14:00:58 +02:00
|
|
|
|
|
|
|
|
if (!m_infoLabelText.isEmpty()) {
|
|
|
|
|
QTC_CHECK(!m_infoLabel);
|
2019-10-15 17:20:51 +02:00
|
|
|
m_infoLabel = new QLabel(m_infoLabelText);
|
2019-09-30 14:00:58 +02:00
|
|
|
connect(m_infoLabel, &QLabel::linkActivated, [](const QString &link) {
|
|
|
|
|
Core::HelpManager::showHelpUrl(link);
|
|
|
|
|
});
|
2019-10-15 17:20:51 +02:00
|
|
|
builder.addItem(m_infoLabel.data());
|
2019-09-30 14:00:58 +02:00
|
|
|
}
|
2014-03-26 11:23:04 +01:00
|
|
|
}
|
2013-04-09 15:33:52 +02:00
|
|
|
|
2019-09-30 14:00:58 +02:00
|
|
|
void DebuggerLanguageAspect::setAutoSettingsKey(const QString &settingsKey)
|
2014-03-26 11:23:04 +01:00
|
|
|
{
|
2019-09-30 14:00:58 +02:00
|
|
|
m_autoSettingsKey = settingsKey;
|
2013-04-09 15:33:52 +02:00
|
|
|
}
|
|
|
|
|
|
2019-09-30 14:00:58 +02:00
|
|
|
void DebuggerLanguageAspect::fromMap(const QVariantMap &map)
|
2013-04-09 15:33:52 +02:00
|
|
|
{
|
2019-09-30 14:00:58 +02:00
|
|
|
const bool val = map.value(settingsKey(), false).toBool();
|
|
|
|
|
const bool autoVal = map.value(m_autoSettingsKey, false).toBool();
|
|
|
|
|
m_value = autoVal ? AutoEnabledLanguage : val ? EnabledLanguage : DisabledLanguage;
|
|
|
|
|
}
|
2013-04-09 15:33:52 +02:00
|
|
|
|
2019-09-30 14:00:58 +02:00
|
|
|
void DebuggerLanguageAspect::toMap(QVariantMap &data) const
|
|
|
|
|
{
|
|
|
|
|
data.insert(settingsKey(), m_value == EnabledLanguage);
|
|
|
|
|
data.insert(m_autoSettingsKey, m_value == AutoEnabledLanguage);
|
2013-03-27 17:17:24 +01:00
|
|
|
}
|
|
|
|
|
|
2019-09-30 14:00:58 +02:00
|
|
|
|
|
|
|
|
bool DebuggerLanguageAspect::value() const
|
2013-03-27 17:17:24 +01:00
|
|
|
{
|
2019-09-30 14:00:58 +02:00
|
|
|
return m_value;
|
2013-03-27 17:17:24 +01:00
|
|
|
}
|
|
|
|
|
|
2019-09-30 14:00:58 +02:00
|
|
|
void DebuggerLanguageAspect::setValue(bool value)
|
2014-03-26 11:15:09 +01:00
|
|
|
{
|
2019-09-30 14:00:58 +02:00
|
|
|
m_value = value ? EnabledLanguage : DisabledLanguage;
|
|
|
|
|
if (m_checkBox)
|
|
|
|
|
m_checkBox->setChecked(m_value);
|
2013-03-27 17:17:24 +01:00
|
|
|
}
|
|
|
|
|
|
2019-09-30 14:00:58 +02:00
|
|
|
void DebuggerLanguageAspect::setLabel(const QString &label)
|
2013-03-27 17:17:24 +01:00
|
|
|
{
|
2019-09-30 14:00:58 +02:00
|
|
|
m_label = label;
|
2013-03-27 17:17:24 +01:00
|
|
|
}
|
|
|
|
|
|
2019-09-30 14:00:58 +02:00
|
|
|
} // Internal
|
2013-03-27 13:03:15 +01:00
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\class Debugger::DebuggerRunConfigurationAspect
|
|
|
|
|
*/
|
|
|
|
|
|
2018-09-12 11:48:32 +02:00
|
|
|
DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(Target *target)
|
|
|
|
|
: m_target(target)
|
2013-03-27 13:03:15 +01:00
|
|
|
{
|
2013-08-12 17:04:10 +02:00
|
|
|
setId("DebuggerAspect");
|
|
|
|
|
setDisplayName(tr("Debugger settings"));
|
2019-09-30 14:00:58 +02:00
|
|
|
|
|
|
|
|
setConfigWidgetCreator([this] {
|
2021-03-11 19:02:42 +01:00
|
|
|
Layouting::Form builder;
|
2020-07-29 09:06:24 +02:00
|
|
|
builder.addRow(m_cppAspect);
|
|
|
|
|
builder.addRow(m_qmlAspect);
|
|
|
|
|
builder.addRow(m_overrideStartupAspect);
|
2019-09-30 14:00:58 +02:00
|
|
|
|
|
|
|
|
static const QByteArray env = qgetenv("QTC_DEBUGGER_MULTIPROCESS");
|
2019-11-07 12:22:29 +01:00
|
|
|
if (env.toInt())
|
2020-07-29 09:06:24 +02:00
|
|
|
builder.addRow(m_multiProcessAspect);
|
2021-03-11 19:02:42 +01:00
|
|
|
return builder.emerge(false);
|
2019-09-30 14:00:58 +02:00
|
|
|
});
|
|
|
|
|
|
2022-04-08 11:35:54 +02:00
|
|
|
addDataExtractor(this, &DebuggerRunConfigurationAspect::useCppDebugger, &Data::useCppDebugger);
|
|
|
|
|
addDataExtractor(this, &DebuggerRunConfigurationAspect::useQmlDebugger, &Data::useQmlDebugger);
|
|
|
|
|
addDataExtractor(this, &DebuggerRunConfigurationAspect::useMultiProcess, &Data::useMultiProcess);
|
|
|
|
|
addDataExtractor(this, &DebuggerRunConfigurationAspect::overrideStartup, &Data::overrideStartup);
|
|
|
|
|
|
2019-09-30 14:00:58 +02:00
|
|
|
m_cppAspect = new DebuggerLanguageAspect;
|
|
|
|
|
m_cppAspect->setLabel(tr("Enable C++"));
|
|
|
|
|
m_cppAspect->setSettingsKey("RunConfiguration.UseCppDebugger");
|
|
|
|
|
m_cppAspect->setAutoSettingsKey("RunConfiguration.UseCppDebuggerAuto");
|
|
|
|
|
|
|
|
|
|
m_qmlAspect = new DebuggerLanguageAspect;
|
|
|
|
|
m_qmlAspect->setLabel(tr("Enable QML"));
|
|
|
|
|
m_qmlAspect->setSettingsKey("RunConfiguration.UseQmlDebugger");
|
|
|
|
|
m_qmlAspect->setAutoSettingsKey("RunConfiguration.UseQmlDebuggerAuto");
|
|
|
|
|
m_qmlAspect->setInfoLabelText(tr("<a href=\""
|
|
|
|
|
"qthelp://org.qt-project.qtcreator/doc/creator-debugging-qml.html"
|
|
|
|
|
"\">What are the prerequisites?</a>"));
|
|
|
|
|
|
|
|
|
|
// Make sure at least one of the debuggers is set to be active.
|
|
|
|
|
m_cppAspect->setClickCallBack([this](bool on) {
|
|
|
|
|
if (!on && !m_qmlAspect->value())
|
|
|
|
|
m_qmlAspect->setValue(true);
|
|
|
|
|
});
|
|
|
|
|
m_qmlAspect->setClickCallBack([this](bool on) {
|
|
|
|
|
if (!on && !m_cppAspect->value())
|
|
|
|
|
m_cppAspect->setValue(true);
|
|
|
|
|
});
|
|
|
|
|
|
2020-08-13 09:16:00 +02:00
|
|
|
m_multiProcessAspect = new BoolAspect;
|
2019-09-30 14:00:58 +02:00
|
|
|
m_multiProcessAspect->setSettingsKey("RunConfiguration.UseMultiProcess");
|
2019-11-26 17:11:01 +01:00
|
|
|
m_multiProcessAspect->setLabel(tr("Enable Debugging of Subprocesses"),
|
2020-08-13 09:16:00 +02:00
|
|
|
BoolAspect::LabelPlacement::AtCheckBox);
|
2019-09-30 14:00:58 +02:00
|
|
|
|
2020-08-13 09:16:00 +02:00
|
|
|
m_overrideStartupAspect = new StringAspect;
|
2019-09-30 14:00:58 +02:00
|
|
|
m_overrideStartupAspect->setSettingsKey("RunConfiguration.OverrideDebuggerStartup");
|
2020-08-13 09:16:00 +02:00
|
|
|
m_overrideStartupAspect->setDisplayStyle(StringAspect::TextEditDisplay);
|
2019-09-30 14:00:58 +02:00
|
|
|
m_overrideStartupAspect->setLabelText(tr("Additional startup commands:"));
|
2013-03-27 13:03:15 +01:00
|
|
|
}
|
|
|
|
|
|
2019-10-17 17:58:22 +02:00
|
|
|
DebuggerRunConfigurationAspect::~DebuggerRunConfigurationAspect()
|
|
|
|
|
{
|
|
|
|
|
delete m_cppAspect;
|
|
|
|
|
delete m_qmlAspect;
|
|
|
|
|
delete m_multiProcessAspect;
|
|
|
|
|
delete m_overrideStartupAspect;
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-27 13:03:15 +01:00
|
|
|
void DebuggerRunConfigurationAspect::setUseQmlDebugger(bool value)
|
|
|
|
|
{
|
2019-09-30 14:00:58 +02:00
|
|
|
m_qmlAspect->setValue(value);
|
2013-03-27 13:03:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DebuggerRunConfigurationAspect::useCppDebugger() const
|
|
|
|
|
{
|
2019-09-30 14:00:58 +02:00
|
|
|
if (m_cppAspect->m_value == AutoEnabledLanguage)
|
2018-09-12 09:31:45 +02:00
|
|
|
return m_target->project()->projectLanguages().contains(
|
2017-01-30 14:59:10 +01:00
|
|
|
ProjectExplorer::Constants::CXX_LANGUAGE_ID);
|
2019-09-30 14:00:58 +02:00
|
|
|
return m_cppAspect->m_value == EnabledLanguage;
|
2013-03-27 13:03:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DebuggerRunConfigurationAspect::useQmlDebugger() const
|
|
|
|
|
{
|
2019-09-30 14:00:58 +02:00
|
|
|
if (m_qmlAspect->m_value == AutoEnabledLanguage) {
|
2018-09-12 09:31:45 +02:00
|
|
|
const Core::Context languages = m_target->project()->projectLanguages();
|
2017-01-30 14:59:10 +01:00
|
|
|
if (!languages.contains(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID))
|
2015-12-11 10:43:47 +01:00
|
|
|
return false;
|
|
|
|
|
|
2014-03-26 11:23:04 +01:00
|
|
|
//
|
2019-11-28 16:58:42 +01:00
|
|
|
// Try to find a build configuration to check whether qml debugging is enabled there
|
2018-09-12 09:31:45 +02:00
|
|
|
if (BuildConfiguration *bc = m_target->activeBuildConfiguration()) {
|
2020-02-17 14:25:30 +01:00
|
|
|
const auto aspect = bc->aspect<QtSupport::QmlDebuggingAspect>();
|
2021-02-22 07:41:51 +01:00
|
|
|
return aspect && aspect->value() == TriState::Enabled;
|
2014-03-26 11:23:04 +01:00
|
|
|
}
|
|
|
|
|
|
2017-01-30 14:59:10 +01:00
|
|
|
return !languages.contains(ProjectExplorer::Constants::CXX_LANGUAGE_ID);
|
2014-02-07 11:54:18 +01:00
|
|
|
}
|
2019-09-30 14:00:58 +02:00
|
|
|
return m_qmlAspect->m_value == EnabledLanguage;
|
2013-03-27 13:03:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DebuggerRunConfigurationAspect::useMultiProcess() const
|
|
|
|
|
{
|
2019-09-30 14:00:58 +02:00
|
|
|
return m_multiProcessAspect->value();
|
2013-03-27 13:03:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerRunConfigurationAspect::setUseMultiProcess(bool value)
|
|
|
|
|
{
|
2019-09-30 14:00:58 +02:00
|
|
|
m_multiProcessAspect->setValue(value);
|
2013-03-27 13:03:15 +01:00
|
|
|
}
|
|
|
|
|
|
2019-09-30 11:26:32 +02:00
|
|
|
QString DebuggerRunConfigurationAspect::overrideStartup() const
|
|
|
|
|
{
|
2019-09-30 14:00:58 +02:00
|
|
|
return m_overrideStartupAspect->value();
|
2019-09-30 11:26:32 +02:00
|
|
|
}
|
|
|
|
|
|
2016-01-26 14:09:13 +01:00
|
|
|
int DebuggerRunConfigurationAspect::portsUsedByDebugger() const
|
|
|
|
|
{
|
|
|
|
|
int ports = 0;
|
|
|
|
|
if (useQmlDebugger())
|
|
|
|
|
++ports;
|
|
|
|
|
if (useCppDebugger())
|
|
|
|
|
++ports;
|
|
|
|
|
return ports;
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-12 17:05:52 +02:00
|
|
|
void DebuggerRunConfigurationAspect::toMap(QVariantMap &map) const
|
2013-03-27 13:03:15 +01:00
|
|
|
{
|
2019-09-30 14:00:58 +02:00
|
|
|
m_cppAspect->toMap(map);
|
|
|
|
|
m_qmlAspect->toMap(map);
|
|
|
|
|
m_multiProcessAspect->toMap(map);
|
|
|
|
|
m_overrideStartupAspect->toMap(map);
|
2013-03-27 13:03:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerRunConfigurationAspect::fromMap(const QVariantMap &map)
|
|
|
|
|
{
|
2019-09-30 14:00:58 +02:00
|
|
|
m_cppAspect->fromMap(map);
|
|
|
|
|
m_qmlAspect->fromMap(map);
|
|
|
|
|
m_multiProcessAspect->fromMap(map);
|
|
|
|
|
m_overrideStartupAspect->fromMap(map);
|
2013-03-27 13:03:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Debugger
|