ProjectExplorer: Rework executable display handling in runconfigs

The basic idea is to provide an easy-to-configure reusable
building block to provide an "Executable" in a run configuration.

This patch here extracts some generic from the previous
ExecutableAspect into a BaseStringAspect and bases the new
ExecutableAspect implementation on it. It also adds the
the ability to make it editable or to manually override an
executable, and adds a SymbolFile aspect for the accompanying
sources of debug information.

Use in RemoteLinux and Qnx for starters and demonstration purposes.
In the end the Qnx runconfiguration widget does not depend on the
RemoteLinux implementation anymore by replacing the previous
code-sharing-by-inheritance by direct (and less) code.

Change-Id: I91b55820455256a8526e39458364b6cb74e63cd7
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
hjk
2018-04-16 13:28:47 +02:00
parent ef660d8bd0
commit 4b9945c329
15 changed files with 429 additions and 533 deletions

View File

@@ -30,6 +30,7 @@
#include "projectexplorer.h"
#include "projectexplorersettings.h"
#include "runconfiguration.h"
#include "target.h"
#include <utils/utilsicons.h>
#include <utils/fancylineedit.h>
@@ -293,59 +294,260 @@ void ArgumentsAspect::addToMainConfigurationWidget(QWidget *parent, QFormLayout
layout->addRow(tr("Command line arguments:"), m_chooser);
}
/*!
\class ProjectExplorer::BaseStringAspect
*/
BaseStringAspect::BaseStringAspect(RunConfiguration *rc)
: IRunConfigurationAspect(rc)
{
}
QString BaseStringAspect::value() const
{
return m_value;
}
void BaseStringAspect::setValue(const QString &value)
{
m_value = value;
update();
}
void BaseStringAspect::fromMap(const QVariantMap &map)
{
if (!settingsKey().isEmpty())
m_value = map.value(settingsKey()).toString();
if (m_checker)
m_checker->fromMap(map);
}
void BaseStringAspect::toMap(QVariantMap &map) const
{
if (!settingsKey().isEmpty())
map.insert(settingsKey(), m_value);
if (m_checker)
m_checker->toMap(map);
}
FileName BaseStringAspect::fileName() const
{
return FileName::fromString(m_value);
}
void BaseStringAspect::setLabelText(const QString &labelText)
{
m_labelText = labelText;
if (m_label)
m_label->setText(labelText);
}
QString BaseStringAspect::labelText() const
{
return m_labelText;
}
void BaseStringAspect::setDisplayFilter(const std::function<QString(const QString &)> &displayFilter)
{
m_displayFilter = displayFilter;
}
bool BaseStringAspect::isChecked() const
{
return !m_checker || m_checker->value();
}
void BaseStringAspect::setDisplayStyle(DisplayStyle displayStyle)
{
m_displayStyle = displayStyle;
}
void BaseStringAspect::setPlaceHolderText(const QString &placeHolderText)
{
m_placeHolderText = placeHolderText;
if (m_lineEditDisplay)
m_lineEditDisplay->setPlaceholderText(placeHolderText);
}
void BaseStringAspect::addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout)
{
QTC_CHECK(!m_label);
m_label = new QLabel(parent);
m_label->setTextInteractionFlags(Qt::TextSelectableByMouse);
auto hbox = new QHBoxLayout;
switch (m_displayStyle) {
case PathChooserDisplay:
m_pathChooserDisplay = new PathChooser(parent);
m_pathChooserDisplay->setExpectedKind(PathChooser::File);
connect(m_pathChooserDisplay, &PathChooser::pathChanged,
this, &BaseStringAspect::setValue);
hbox->addWidget(m_pathChooserDisplay);
break;
case LineEditDisplay:
m_lineEditDisplay = new FancyLineEdit(parent);
m_lineEditDisplay->setPlaceholderText(m_placeHolderText);
connect(m_lineEditDisplay, &FancyLineEdit::textEdited,
this, &BaseStringAspect::setValue);
hbox->addWidget(m_lineEditDisplay);
break;
case LabelDisplay:
m_labelDisplay = new QLabel(parent);
m_labelDisplay->setTextInteractionFlags(Qt::TextSelectableByMouse);
hbox->addWidget(m_labelDisplay);
break;
}
if (m_checker) {
auto form = new QFormLayout;
form->setContentsMargins(0, 0, 0, 0);
form->setFormAlignment(Qt::AlignLeft | Qt::AlignVCenter);
m_checker->addToMainConfigurationWidget(parent, form);
hbox->addLayout(form);
}
layout->addRow(m_label, hbox);
update();
}
void BaseStringAspect::update()
{
const QString displayedString = m_displayFilter ? m_displayFilter(m_value) : m_value;
const bool enabled = !m_checker || m_checker->value();
if (m_pathChooserDisplay) {
m_pathChooserDisplay->setFileName(FileName::fromString(displayedString));
m_pathChooserDisplay->setEnabled(enabled);
}
if (m_lineEditDisplay) {
m_lineEditDisplay->setText(displayedString);
m_lineEditDisplay->setEnabled(enabled);
}
if (m_labelDisplay)
m_labelDisplay->setText(displayedString);
if (m_label)
m_label->setText(m_labelText);
}
void BaseStringAspect::makeCheckable(const QString &checkerLabel, const QString &checkerKey)
{
QTC_ASSERT(!m_checker, return);
m_checker = new BaseBoolAspect(runConfiguration());
m_checker->setLabel(checkerLabel);
m_checker->setSettingsKey(checkerKey);
connect(m_checker, &BaseBoolAspect::changed, this, &BaseStringAspect::update);
update();
}
/*!
\class ProjectExplorer::ExecutableAspect
*/
ExecutableAspect::ExecutableAspect(RunConfiguration *runConfig, bool isRemote, const QString &label)
: IRunConfigurationAspect(runConfig), m_isRemote(isRemote), m_labelString(label)
ExecutableAspect::ExecutableAspect(RunConfiguration *rc)
: IRunConfigurationAspect(rc), m_executable(rc)
{
setDisplayName(tr("Executable"));
setId("ExecutableAspect");
setExecutablePathStyle(HostOsInfo::hostOs());
m_executable.setPlaceHolderText(tr("<unknown>"));
m_executable.setLabelText(tr("Executable:"));
m_executable.setDisplayStyle(BaseStringAspect::LabelDisplay);
}
Utils::FileName ExecutableAspect::executable() const
void ExecutableAspect::setExecutablePathStyle(OsType osType)
{
return m_executable;
if (osType == OsTypeWindows) {
// Stolen from QDir::toNativeSeparators which cannot be used directly as it
// depends on host type, whereas we need a configurable value here.
m_executable.setDisplayFilter([&](const QString &pathName) {
int i = pathName.indexOf(QLatin1Char('/'));
if (i != -1) {
QString n(pathName);
QChar * const data = n.data();
data[i++] = QLatin1Char('\\');
for (; i < n.length(); ++i) {
if (data[i] == QLatin1Char('/'))
data[i] = QLatin1Char('\\');
}
return n;
}
return pathName;
});
} else {
m_executable.setDisplayFilter({});
}
}
void ExecutableAspect::setExecutable(const FileName &executable)
void ExecutableAspect::makeOverridable(const QString &overridingKey, const QString &useOverridableKey)
{
m_executable = executable;
if (m_executableDisplay)
m_executableDisplay->setText(executableText());
QTC_ASSERT(!m_alternativeExecutable, return);
m_alternativeExecutable = new BaseStringAspect(runConfiguration());
m_alternativeExecutable->setDisplayStyle(BaseStringAspect::LineEditDisplay);
m_alternativeExecutable->setLabelText(tr("Alternate executable on device:"));
m_alternativeExecutable->setSettingsKey(overridingKey);
m_alternativeExecutable->makeCheckable(tr("Use this command instead"), useOverridableKey);
}
QString ExecutableAspect::executableText() const
FileName ExecutableAspect::executable() const
{
if (m_executable.isEmpty())
return tr("<unknown>");
if (m_isRemote)
return m_executable.toString();
return m_executable.toUserOutput();
if (m_alternativeExecutable && m_alternativeExecutable->isChecked())
return m_alternativeExecutable->fileName();
return m_executable.fileName();
}
void ExecutableAspect::addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout)
{
QTC_CHECK(!m_executableDisplay);
m_executableDisplay = new QLabel(parent);
m_executableDisplay->setTextInteractionFlags(Qt::TextSelectableByMouse);
m_executableDisplay->setText(executableText());
m_executable.addToMainConfigurationWidget(parent, layout);
if (m_alternativeExecutable)
m_alternativeExecutable->addToMainConfigurationWidget(parent, layout);
}
QString labelText = m_labelString;
if (labelText.isEmpty())
labelText = m_isRemote ? tr("Remote Executable") : tr("Executable");
layout->addRow(labelText + ':', m_executableDisplay);
void ExecutableAspect::setLabelText(const QString &labelText)
{
m_executable.setLabelText(labelText);
}
void ExecutableAspect::setPlaceHolderText(const QString &placeHolderText)
{
m_executable.setPlaceHolderText(placeHolderText);
}
void ExecutableAspect::setExecutable(const FileName &executable)
{
m_executable.setValue(executable.toString());
}
void ExecutableAspect::fromMap(const QVariantMap &map)
{
m_executable.fromMap(map);
if (m_alternativeExecutable)
m_alternativeExecutable->fromMap(map);
}
void ExecutableAspect::toMap(QVariantMap &map) const
{
m_executable.toMap(map);
if (m_alternativeExecutable)
m_alternativeExecutable->toMap(map);
}
/*!
\class ProjectExplorer::BaseBoolAspect
*/
BaseBoolAspect::BaseBoolAspect(RunConfiguration *runConfig, const QString &key) :
IRunConfigurationAspect(runConfig)
BaseBoolAspect::BaseBoolAspect(RunConfiguration *runConfig, const QString &settingsKey)
: IRunConfigurationAspect(runConfig)
{
setSettingsKey(key);
setSettingsKey(settingsKey);
}
void BaseBoolAspect::addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout)

View File

@@ -29,10 +29,12 @@
#include "applicationlauncher.h"
#include <utils/fileutils.h>
#include <utils/osspecificaspects.h>
QT_BEGIN_NAMESPACE
class QCheckBox;
class QLabel;
class QLineEdit;
class QFormLayout;
class QToolButton;
QT_END_NAMESPACE
@@ -79,7 +81,8 @@ class PROJECTEXPLORER_EXPORT WorkingDirectoryAspect : public IRunConfigurationAs
Q_OBJECT
public:
explicit WorkingDirectoryAspect(RunConfiguration *runConfig, const QString &settingsKey);
explicit WorkingDirectoryAspect(RunConfiguration *runConfig,
const QString &settingsKey = QString());
void addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout);
@@ -107,7 +110,7 @@ class PROJECTEXPLORER_EXPORT ArgumentsAspect : public IRunConfigurationAspect
Q_OBJECT
public:
explicit ArgumentsAspect(RunConfiguration *runConfig, const QString &settingsKey);
explicit ArgumentsAspect(RunConfiguration *runConfig, const QString &settingsKey = QString());
void addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout);
@@ -127,49 +130,27 @@ private:
QPointer<Utils::FancyLineEdit> m_chooser;
};
class PROJECTEXPLORER_EXPORT ExecutableAspect : public IRunConfigurationAspect
{
Q_OBJECT
public:
ExecutableAspect(RunConfiguration *runConfig,
bool isRemote = false,
const QString &label = QString());
void addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout);
Utils::FileName executable() const;
void setExecutable(const Utils::FileName &executable);
private:
QString executableText() const;
Utils::FileName m_executable;
bool m_isRemote = false;
QString m_labelString;
QPointer<QLabel> m_executableDisplay;
};
class PROJECTEXPLORER_EXPORT BaseBoolAspect : public IRunConfigurationAspect
{
Q_OBJECT
public:
BaseBoolAspect(RunConfiguration *rc, const QString &settingsKey);
explicit BaseBoolAspect(RunConfiguration *rc, const QString &settingsKey = QString());
void addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout);
bool value() const;
void setValue(bool val);
void setLabel(const QString &label);
void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override;
signals:
void changed();
private:
void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override;
bool m_value = false;
QString m_label;
QPointer<QCheckBox> m_checkBox; // Owned by RunConfigWidget
@@ -191,4 +172,85 @@ public:
UseDyldSuffixAspect(RunConfiguration *rc, const QString &settingsKey);
};
class PROJECTEXPLORER_EXPORT BaseStringAspect : public IRunConfigurationAspect
{
Q_OBJECT
public:
explicit BaseStringAspect(RunConfiguration *rc);
void addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout);
QString value() const;
void setValue(const QString &val);
QString labelText() const;
void setLabelText(const QString &labelText);
void setDisplayFilter(const std::function<QString (const QString &)> &displayFilter);
void setPlaceHolderText(const QString &placeHolderText);
bool isChecked() const;
void makeCheckable(const QString &optionalLabel, const QString &optionalBaseKey);
enum DisplayStyle { LabelDisplay, LineEditDisplay, PathChooserDisplay };
void setDisplayStyle(DisplayStyle style);
void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override;
Utils::FileName fileName() const;
void setFileName(const Utils::FileName &val);
private:
void update();
DisplayStyle m_displayStyle = LabelDisplay;
QString m_labelText;
std::function<QString(const QString &)> m_displayFilter;
BaseBoolAspect *m_checker = nullptr;
QString m_value;
QString m_placeHolderText;
QPointer<QLabel> m_label;
QPointer<QLabel> m_labelDisplay;
QPointer<Utils::FancyLineEdit> m_lineEditDisplay;
QPointer<Utils::PathChooser> m_pathChooserDisplay;
};
class PROJECTEXPLORER_EXPORT ExecutableAspect : public IRunConfigurationAspect
{
Q_OBJECT
public:
explicit ExecutableAspect(RunConfiguration *rc);
Utils::FileName executable() const;
void setExecutable(const Utils::FileName &executable);
void makeOverridable(const QString &overridingKey, const QString &useOverridableKey);
void addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout);
void setLabelText(const QString &labelText);
void setPlaceHolderText(const QString &placeHolderText);
void setExecutablePathStyle(Utils::OsType osType);
protected:
void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override;
private:
QString executableText() const;
BaseStringAspect m_executable;
BaseStringAspect *m_alternativeExecutable = nullptr;
};
class PROJECTEXPLORER_EXPORT SymbolFileAspect : public BaseStringAspect
{
Q_OBJECT
public:
SymbolFileAspect(RunConfiguration *rc) : BaseStringAspect(rc) {}
};
} // namespace ProjectExplorer

View File

@@ -45,6 +45,7 @@
#include <projectexplorer/kitchooser.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/runconfigurationaspects.h>
#include <projectexplorer/runnables.h>
#include <projectexplorer/target.h>
#include <projectexplorer/toolchain.h>
@@ -157,7 +158,6 @@ QnxDebugSupport::QnxDebugSupport(RunControl *runControl)
setSolibSearchPath(searchPaths(k));
if (auto qtVersion = dynamic_cast<QnxQtVersion *>(QtSupport::QtKitInformation::qtVersion(k)))
setSysRoot(qtVersion->qnxTarget());
setSymbolFile(runConfig->localExecutableFilePath());
}
@@ -263,8 +263,10 @@ void QnxAttachDebugSupport::showProcessesDialog()
const int pid = process.pid;
// QString projectSourceDirectory = dlg.projectSource();
QString localExecutable = dlg.localExecutable();
if (localExecutable.isEmpty())
localExecutable = runConfig->localExecutableFilePath();
if (localExecutable.isEmpty()) {
if (auto aspect = runConfig->extraAspect<SymbolFileAspect>())
localExecutable = aspect->fileName().toString();
}
auto runControl = new RunControl(runConfig, ProjectExplorer::Constants::DEBUG_RUN_MODE);
auto debugger = new QnxAttachDebugSupport(runControl);

View File

@@ -26,17 +26,12 @@
#include "qnxrunconfiguration.h"
#include "qnxconstants.h"
#include "qnxdevicefactory.h"
#include <projectexplorer/runnables.h>
#include <projectexplorer/target.h>
#include <remotelinux/remotelinuxrunconfigurationwidget.h>
#include <utils/environment.h>
#include <QLabel>
#include <QLineEdit>
#include <QFormLayout>
using namespace ProjectExplorer;
using namespace RemoteLinux;
@@ -44,60 +39,41 @@ using namespace RemoteLinux;
namespace Qnx {
namespace Internal {
const char QtLibPathKey[] = "Qt4ProjectManager.QnxRunConfiguration.QtLibPath";
QnxRunConfiguration::QnxRunConfiguration(Target *target)
: RemoteLinuxRunConfiguration(target, Constants::QNX_QNX_RUNCONFIGURATION_PREFIX)
{}
{
auto libAspect = new QtLibPathAspect(this);
libAspect->setSettingsKey("Qt4ProjectManager.QnxRunConfiguration.QtLibPath");
libAspect->setLabelText(tr("Path to Qt libraries on device"));
addExtraAspect(libAspect);
}
Runnable QnxRunConfiguration::runnable() const
{
auto r = RemoteLinuxRunConfiguration::runnable().as<StandardRunnable>();
if (!m_qtLibPath.isEmpty()) {
r.environment.appendOrSet(QLatin1String("LD_LIBRARY_PATH"),
m_qtLibPath + QLatin1String("/lib:$LD_LIBRARY_PATH"));
r.environment.appendOrSet(QLatin1String("QML_IMPORT_PATH"),
m_qtLibPath + QLatin1String("/imports:$QML_IMPORT_PATH"));
r.environment.appendOrSet(QLatin1String("QML2_IMPORT_PATH"),
m_qtLibPath + QLatin1String("/qml:$QML2_IMPORT_PATH"));
r.environment.appendOrSet(QLatin1String("QT_PLUGIN_PATH"),
m_qtLibPath + QLatin1String("/plugins:$QT_PLUGIN_PATH"));
r.environment.set(QLatin1String("QT_QPA_FONTDIR"),
m_qtLibPath + QLatin1String("/lib/fonts"));
QString libPath = extraAspect<QtLibPathAspect>()->value();
if (!libPath.isEmpty()) {
r.environment.appendOrSet("LD_LIBRARY_PATH", libPath + "/lib:$LD_LIBRARY_PATH");
r.environment.appendOrSet("QML_IMPORT_PATH", libPath + "/imports:$QML_IMPORT_PATH");
r.environment.appendOrSet("QML2_IMPORT_PATH", libPath + "/qml:$QML2_IMPORT_PATH");
r.environment.appendOrSet("QT_PLUGIN_PATH", libPath + "/plugins:$QT_PLUGIN_PATH");
r.environment.set("QT_QPA_FONTDIR", libPath + "/lib/fonts");
}
return r;
}
QWidget *QnxRunConfiguration::createConfigurationWidget()
{
auto rcWidget = qobject_cast<RemoteLinuxRunConfigurationWidget *>
(RemoteLinuxRunConfiguration::createConfigurationWidget());
auto widget = new QWidget;
auto formLayout = new QFormLayout(widget);
auto label = new QLabel(tr("Path to Qt libraries on device:"));
auto lineEdit = new QLineEdit(m_qtLibPath);
extraAspect<ExecutableAspect>()->addToMainConfigurationWidget(widget, formLayout);
extraAspect<SymbolFileAspect>()->addToMainConfigurationWidget(widget, formLayout);
extraAspect<ArgumentsAspect>()->addToMainConfigurationWidget(widget, formLayout);
extraAspect<WorkingDirectoryAspect>()->addToMainConfigurationWidget(widget, formLayout);
extraAspect<QtLibPathAspect>()->addToMainConfigurationWidget(widget, formLayout);
connect(lineEdit, &QLineEdit::textChanged,
this, [this](const QString &path) { m_qtLibPath = path; });
rcWidget->addFormLayoutRow(label, lineEdit);
return rcWidget;
}
QVariantMap QnxRunConfiguration::toMap() const
{
QVariantMap map(RemoteLinuxRunConfiguration::toMap());
map.insert(QLatin1String(QtLibPathKey), m_qtLibPath);
return map;
}
bool QnxRunConfiguration::fromMap(const QVariantMap &map)
{
if (!RemoteLinuxRunConfiguration::fromMap(map))
return false;
m_qtLibPath = map.value(QLatin1String(QtLibPathKey)).toString();
return true;
return wrapWidget(widget);
}
// QnxRunConfigurationFactory

View File

@@ -25,11 +25,20 @@
#pragma once
#include <projectexplorer/runconfigurationaspects.h>
#include <remotelinux/remotelinuxrunconfiguration.h>
namespace Qnx {
namespace Internal {
class QtLibPathAspect : public ProjectExplorer::BaseStringAspect
{
Q_OBJECT
public:
QtLibPathAspect(ProjectExplorer::RunConfiguration *rc) : BaseStringAspect(rc) {}
};
class QnxRunConfiguration : public RemoteLinux::RemoteLinuxRunConfiguration
{
Q_OBJECT
@@ -40,11 +49,6 @@ public:
private:
ProjectExplorer::Runnable runnable() const override;
QWidget *createConfigurationWidget() override;
QVariantMap toMap() const override;
bool fromMap(const QVariantMap &map) override;
QString m_qtLibPath;
};
class QnxRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory

View File

@@ -29,7 +29,9 @@
#include "qnxdeviceprocess.h"
#include "qnxrunconfiguration.h"
#include <projectexplorer/runconfigurationaspects.h>
#include <projectexplorer/runnables.h>
#include <utils/qtcassert.h>
#include <QRegExp>
@@ -44,9 +46,7 @@ Slog2InfoRunner::Slog2InfoRunner(RunControl *runControl)
: RunWorker(runControl)
{
setDisplayName("Slog2InfoRunner");
auto qnxRunConfig = qobject_cast<QnxRunConfiguration *>(runControl->runConfiguration());
QTC_ASSERT(qnxRunConfig, return);
m_applicationId = FileName::fromString(qnxRunConfig->remoteExecutableFilePath()).fileName();
m_applicationId = runControl->runConfiguration()->extraAspect<ExecutableAspect>()->executable().fileName();
// See QTCREATORBUG-10712 for details.
// We need to limit length of ApplicationId to 63 otherwise it would not match one in slog2info.

View File

@@ -14,7 +14,6 @@ HEADERS += \
publickeydeploymentdialog.h \
genericlinuxdeviceconfigurationwizard.h \
genericlinuxdeviceconfigurationfactory.h \
remotelinuxrunconfigurationwidget.h \
remotelinuxdebugsupport.h \
genericlinuxdeviceconfigurationwizardpages.h \
abstractremotelinuxdeploystep.h \
@@ -58,7 +57,6 @@ SOURCES += \
publickeydeploymentdialog.cpp \
genericlinuxdeviceconfigurationwizard.cpp \
genericlinuxdeviceconfigurationfactory.cpp \
remotelinuxrunconfigurationwidget.cpp \
remotelinuxdebugsupport.cpp \
genericlinuxdeviceconfigurationwizardpages.cpp \
abstractremotelinuxdeploystep.cpp \

View File

@@ -91,8 +91,6 @@ Project {
"remotelinuxqmltoolingsupport.h",
"remotelinuxrunconfiguration.cpp",
"remotelinuxrunconfiguration.h",
"remotelinuxrunconfigurationwidget.cpp",
"remotelinuxrunconfigurationwidget.h",
"remotelinuxsignaloperation.cpp",
"remotelinuxsignaloperation.h",
"remotelinuxutils.cpp",

View File

@@ -51,47 +51,39 @@ public:
{
auto fl = new QFormLayout(this);
auto remoteExeLabel = new QLabel(RemoteLinuxCustomRunConfiguration::tr("Remote executable:"));
auto remoteExeLineEdit = new QLineEdit;
remoteExeLineEdit->setText(runConfig->remoteExecutableFilePath());
fl->addRow(remoteExeLabel, remoteExeLineEdit);
auto localExeLabel = new QLabel(RemoteLinuxCustomRunConfiguration::tr("Local executable:"));
auto localExeChooser = new PathChooser;
localExeChooser->setFileName(FileName::fromString(runConfig->localExecutableFilePath()));
fl->addRow(localExeLabel, localExeChooser);
runConfig->extraAspect<ExecutableAspect>()->addToMainConfigurationWidget(this, fl);
runConfig->extraAspect<SymbolFileAspect>()->addToMainConfigurationWidget(this, fl);
runConfig->extraAspect<ArgumentsAspect>()->addToMainConfigurationWidget(this, fl);
runConfig->extraAspect<WorkingDirectoryAspect>()->addToMainConfigurationWidget(this, fl);
localExeChooser->setExpectedKind(PathChooser::File);
localExeChooser->setPath(runConfig->localExecutableFilePath());
connect(localExeChooser, &PathChooser::pathChanged, this,
[runConfig](const QString &path) {
runConfig->setLocalExecutableFilePath(path.trimmed());
});
connect(remoteExeLineEdit, &QLineEdit::textEdited, this,
[runConfig](const QString &path) {
runConfig->setRemoteExecutableFilePath(path.trimmed());
});
}
};
RemoteLinuxCustomRunConfiguration::RemoteLinuxCustomRunConfiguration(Target *target)
: RunConfiguration(target, runConfigId())
{
auto exeAspect = new ExecutableAspect(this);
exeAspect->setSettingsKey("RemoteLinux.CustomRunConfig.RemoteExecutable");
exeAspect->setLabelText(tr("Remote Executable:"));
exeAspect->setExecutablePathStyle(OsTypeLinux);
addExtraAspect(exeAspect);
auto symbolsAspect = new SymbolFileAspect(this);
symbolsAspect->setSettingsKey("RemoteLinux.CustomRunConfig.LocalExecutable");
symbolsAspect->setLabelText(tr("Local executable:"));
symbolsAspect->setDisplayStyle(SymbolFileAspect::PathChooserDisplay);
addExtraAspect(symbolsAspect);
addExtraAspect(new ArgumentsAspect(this, "RemoteLinux.CustomRunConfig.Arguments"));
addExtraAspect(new WorkingDirectoryAspect(this, "RemoteLinux.CustomRunConfig.WorkingDirectory"));
addExtraAspect(new RemoteLinuxEnvironmentAspect(this));
setDefaultDisplayName(runConfigDefaultDisplayName());
setOutputFormatter<QtSupport::QtOutputFormatter>();
}
bool RemoteLinuxCustomRunConfiguration::isConfigured() const
{
return !m_remoteExecutable.isEmpty();
return !extraAspect<ExecutableAspect>()->executable().isEmpty();
}
RunConfiguration::ConfigurationState
@@ -115,19 +107,13 @@ QWidget *RemoteLinuxCustomRunConfiguration::createConfigurationWidget()
Runnable RemoteLinuxCustomRunConfiguration::runnable() const
{
StandardRunnable r;
r.executable = extraAspect<ExecutableAspect>()->executable().toString();
r.environment = extraAspect<RemoteLinuxEnvironmentAspect>()->environment();
r.executable = m_remoteExecutable;
r.commandLineArguments = extraAspect<ArgumentsAspect>()->arguments();
r.workingDirectory = extraAspect<WorkingDirectoryAspect>()->workingDirectory().toString();
return r;
}
void RemoteLinuxCustomRunConfiguration::setRemoteExecutableFilePath(const QString &executable)
{
m_remoteExecutable = executable;
setDisplayName(runConfigDefaultDisplayName());
}
Core::Id RemoteLinuxCustomRunConfiguration::runConfigId()
{
return "RemoteLinux.CustomRunConfig";
@@ -135,38 +121,12 @@ Core::Id RemoteLinuxCustomRunConfiguration::runConfigId()
QString RemoteLinuxCustomRunConfiguration::runConfigDefaultDisplayName()
{
QString display = m_remoteExecutable.isEmpty()
? tr("Custom Executable") : tr("Run \"%1\"").arg(m_remoteExecutable);
QString remoteExecutable = extraAspect<ExecutableAspect>()->executable().toString();
QString display = remoteExecutable.isEmpty()
? tr("Custom Executable") : tr("Run \"%1\"").arg(remoteExecutable);
return RunConfigurationFactory::decoratedTargetName(display, target());
}
static QString localExeKey()
{
return QLatin1String("RemoteLinux.CustomRunConfig.LocalExecutable");
}
static QString remoteExeKey()
{
return QLatin1String("RemoteLinux.CustomRunConfig.RemoteExecutable");
}
bool RemoteLinuxCustomRunConfiguration::fromMap(const QVariantMap &map)
{
if (!RunConfiguration::fromMap(map))
return false;
setLocalExecutableFilePath(map.value(localExeKey()).toString());
setRemoteExecutableFilePath(map.value(remoteExeKey()).toString());
return true;
}
QVariantMap RemoteLinuxCustomRunConfiguration::toMap() const
{
QVariantMap map = RunConfiguration::toMap();
map.insert(localExeKey(), m_localExecutable);
map.insert(remoteExeKey(), m_remoteExecutable);
return map;
}
// RemoteLinuxCustomRunConfigurationFactory
RemoteLinuxCustomRunConfigurationFactory::RemoteLinuxCustomRunConfigurationFactory()

View File

@@ -36,25 +36,13 @@ class RemoteLinuxCustomRunConfiguration : public ProjectExplorer::RunConfigurati
public:
explicit RemoteLinuxCustomRunConfiguration(ProjectExplorer::Target *target);
bool fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override;
bool isConfigured() const override;
ConfigurationState ensureConfigured(QString *errorMessage) override;
QWidget *createConfigurationWidget() override;
ProjectExplorer::Runnable runnable() const override;
QString localExecutableFilePath() const { return m_localExecutable; }
QString remoteExecutableFilePath() const { return m_remoteExecutable; }
void setLocalExecutableFilePath(const QString &executable) { m_localExecutable = executable; }
void setRemoteExecutableFilePath(const QString &executable);
static Core::Id runConfigId();
QString runConfigDefaultDisplayName();
private:
QString m_localExecutable;
QString m_remoteExecutable;
};
class RemoteLinuxCustomRunConfigurationFactory : public ProjectExplorer::FixedRunConfigurationFactory

View File

@@ -25,8 +25,7 @@
#include "remotelinuxdebugsupport.h"
#include "remotelinuxcustomrunconfiguration.h"
#include "remotelinuxrunconfiguration.h"
#include <projectexplorer/runconfigurationaspects.h>
using namespace Debugger;
using namespace ProjectExplorer;
@@ -51,10 +50,8 @@ LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl)
setUseExtendedRemote(true);
RunConfiguration *runConfig = runControl->runConfiguration();
if (auto rlrc = qobject_cast<RemoteLinuxRunConfiguration *>(runConfig))
setSymbolFile(rlrc->localExecutableFilePath());
else if (auto rlrc = qobject_cast<Internal::RemoteLinuxCustomRunConfiguration *>(runConfig))
setSymbolFile(rlrc->localExecutableFilePath());
if (auto aspect = runConfig->extraAspect<SymbolFileAspect>())
setSymbolFile(aspect->fileName().toString());
}
} // namespace Internal

View File

@@ -27,7 +27,6 @@
#include "remotelinux_constants.h"
#include "remotelinuxenvironmentaspect.h"
#include "remotelinuxrunconfigurationwidget.h"
#include <projectexplorer/buildtargetinfo.h>
#include <projectexplorer/deploymentdata.h>
@@ -36,32 +35,15 @@
#include <projectexplorer/runconfigurationaspects.h>
#include <projectexplorer/runnables.h>
#include <projectexplorer/target.h>
#include <qtsupport/qtoutputformatter.h>
#include <utils/qtcprocess.h>
#include <QFormLayout>
using namespace ProjectExplorer;
using namespace Utils;
namespace RemoteLinux {
namespace Internal {
namespace {
const char ArgumentsKey[] = "Qt4ProjectManager.MaemoRunConfiguration.Arguments";
const char UseAlternateExeKey[] = "RemoteLinux.RunConfig.UseAlternateRemoteExecutable";
const char AlternateExeKey[] = "RemoteLinux.RunConfig.AlternateRemoteExecutable";
const char WorkingDirectoryKey[] = "RemoteLinux.RunConfig.WorkingDirectory";
} // anonymous namespace
class RemoteLinuxRunConfigurationPrivate
{
public:
bool useAlternateRemoteExecutable = false;
QString alternateRemoteExecutable;
};
} // namespace Internal
using namespace Internal;
RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *target)
: RemoteLinuxRunConfiguration(target, IdPrefix)
@@ -69,62 +51,69 @@ RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *target)
}
RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *target, Core::Id id)
: RunConfiguration(target, id), d(new RemoteLinuxRunConfigurationPrivate)
: RunConfiguration(target, id)
{
addExtraAspect(new RemoteLinuxEnvironmentAspect(this));
auto exeAspect = new ExecutableAspect(this);
exeAspect->setLabelText(tr("Executable on device:"));
exeAspect->setExecutablePathStyle(OsTypeLinux);
exeAspect->setPlaceHolderText(tr("Remote path not set"));
exeAspect->makeOverridable("RemoteLinux.RunConfig.AlternateRemoteExecutable",
"RemoteLinux.RunConfig.UseAlternateRemoteExecutable");
addExtraAspect(exeAspect);
addExtraAspect(new ArgumentsAspect(this, ArgumentsKey));
addExtraAspect(new WorkingDirectoryAspect(this, WorkingDirectoryKey));
auto symbolsAspect = new SymbolFileAspect(this);
symbolsAspect->setLabelText(tr("Executable on host:"));
symbolsAspect->setDisplayStyle(SymbolFileAspect::LabelDisplay);
addExtraAspect(symbolsAspect);
auto argsAspect = new ArgumentsAspect(this);
argsAspect->setSettingsKey("Qt4ProjectManager.MaemoRunConfiguration.Arguments");
addExtraAspect(argsAspect);
auto wdAspect = new WorkingDirectoryAspect(this);
wdAspect->setSettingsKey("RemoteLinux.RunConfig.WorkingDirectory");
addExtraAspect(wdAspect);
addExtraAspect(new RemoteLinuxEnvironmentAspect(this));
setOutputFormatter<QtSupport::QtOutputFormatter>();
connect(target, &Target::deploymentDataChanged,
this, &RemoteLinuxRunConfiguration::handleBuildSystemDataUpdated);
this, &RemoteLinuxRunConfiguration::updateTargetInformation);
connect(target, &Target::applicationTargetsChanged,
this, &RemoteLinuxRunConfiguration::handleBuildSystemDataUpdated);
// Handles device changes, etc.
this, &RemoteLinuxRunConfiguration::updateTargetInformation);
connect(target->project(), &Project::parsingFinished,
this, &RemoteLinuxRunConfiguration::updateTargetInformation);
connect(target, &Target::kitChanged,
this, &RemoteLinuxRunConfiguration::handleBuildSystemDataUpdated);
}
RemoteLinuxRunConfiguration::~RemoteLinuxRunConfiguration()
{
delete d;
this, &RemoteLinuxRunConfiguration::updateTargetInformation);
}
QWidget *RemoteLinuxRunConfiguration::createConfigurationWidget()
{
return new RemoteLinuxRunConfigurationWidget(this);
auto widget = new QWidget;
auto formLayout = new QFormLayout(widget);
extraAspect<ExecutableAspect>()->addToMainConfigurationWidget(widget, formLayout);
extraAspect<SymbolFileAspect>()->addToMainConfigurationWidget(widget, formLayout);
extraAspect<ArgumentsAspect>()->addToMainConfigurationWidget(widget, formLayout);
extraAspect<WorkingDirectoryAspect>()->addToMainConfigurationWidget(widget, formLayout);
return wrapWidget(widget);
}
Runnable RemoteLinuxRunConfiguration::runnable() const
{
StandardRunnable r;
r.environment = extraAspect<RemoteLinuxEnvironmentAspect>()->environment();
r.executable = remoteExecutableFilePath();
r.executable = extraAspect<ExecutableAspect>()->executable().toString();
r.commandLineArguments = extraAspect<ArgumentsAspect>()->arguments();
r.workingDirectory = extraAspect<WorkingDirectoryAspect>()->workingDirectory().toString();
return r;
}
QVariantMap RemoteLinuxRunConfiguration::toMap() const
void RemoteLinuxRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInfo &)
{
QVariantMap map = RunConfiguration::toMap();
map.insert(QLatin1String(UseAlternateExeKey), d->useAlternateRemoteExecutable);
map.insert(QLatin1String(AlternateExeKey), d->alternateRemoteExecutable);
return map;
}
bool RemoteLinuxRunConfiguration::fromMap(const QVariantMap &map)
{
if (!RunConfiguration::fromMap(map))
return false;
d->useAlternateRemoteExecutable = map.value(QLatin1String(UseAlternateExeKey), false).toBool();
d->alternateRemoteExecutable = map.value(QLatin1String(AlternateExeKey)).toString();
setDefaultDisplayName(defaultDisplayName());
return true;
}
QString RemoteLinuxRunConfiguration::defaultDisplayName() const
@@ -132,47 +121,15 @@ QString RemoteLinuxRunConfiguration::defaultDisplayName() const
return RunConfigurationFactory::decoratedTargetName(buildKey(), target());
}
QString RemoteLinuxRunConfiguration::localExecutableFilePath() const
void RemoteLinuxRunConfiguration::updateTargetInformation()
{
return target()->applicationTargets().targetFilePath(buildKey()).toString();
}
BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(buildKey());
QString localExecutable = bti.targetFilePath.toString();
DeployableFile depFile = target()->deploymentData().deployableForLocalFile(localExecutable);
QString RemoteLinuxRunConfiguration::defaultRemoteExecutableFilePath() const
{
return target()->deploymentData().deployableForLocalFile(localExecutableFilePath())
.remoteFilePath();
}
extraAspect<ExecutableAspect>()->setExecutable(FileName::fromString(depFile.remoteFilePath()));
extraAspect<SymbolFileAspect>()->setValue(localExecutable);
QString RemoteLinuxRunConfiguration::remoteExecutableFilePath() const
{
return d->useAlternateRemoteExecutable
? alternateRemoteExecutable() : defaultRemoteExecutableFilePath();
}
void RemoteLinuxRunConfiguration::setUseAlternateExecutable(bool useAlternate)
{
d->useAlternateRemoteExecutable = useAlternate;
}
bool RemoteLinuxRunConfiguration::useAlternateExecutable() const
{
return d->useAlternateRemoteExecutable;
}
void RemoteLinuxRunConfiguration::setAlternateRemoteExecutable(const QString &exe)
{
d->alternateRemoteExecutable = exe;
}
QString RemoteLinuxRunConfiguration::alternateRemoteExecutable() const
{
return d->alternateRemoteExecutable;
}
void RemoteLinuxRunConfiguration::handleBuildSystemDataUpdated()
{
emit deploySpecsChanged();
emit targetInformationChanged();
emit enabledChanged();
}

View File

@@ -32,9 +32,6 @@
#include <QStringList>
namespace RemoteLinux {
class RemoteLinuxRunConfigurationWidget;
namespace Internal { class RemoteLinuxRunConfigurationPrivate; }
class REMOTELINUX_EXPORT RemoteLinuxRunConfiguration : public ProjectExplorer::RunConfiguration
{
@@ -43,39 +40,21 @@ class REMOTELINUX_EXPORT RemoteLinuxRunConfiguration : public ProjectExplorer::R
public:
explicit RemoteLinuxRunConfiguration(ProjectExplorer::Target *target);
~RemoteLinuxRunConfiguration() override;
QWidget *createConfigurationWidget() override;
ProjectExplorer::Runnable runnable() const override;
QString localExecutableFilePath() const;
QString defaultRemoteExecutableFilePath() const;
QString remoteExecutableFilePath() const;
void setAlternateRemoteExecutable(const QString &exe);
QString alternateRemoteExecutable() const;
void setUseAlternateExecutable(bool useAlternate);
bool useAlternateExecutable() const;
QVariantMap toMap() const override;
static const char *IdPrefix;
signals:
void deploySpecsChanged();
void targetInformationChanged() const;
protected:
// FIXME: Used by QNX, remove.
RemoteLinuxRunConfiguration(ProjectExplorer::Target *target, Core::Id id);
bool fromMap(const QVariantMap &map) override;
void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &) override;
private:
QString defaultDisplayName() const;
void handleBuildSystemDataUpdated();
Internal::RemoteLinuxRunConfigurationPrivate * const d;
void updateTargetInformation();
};
class RemoteLinuxRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory

View File

@@ -1,165 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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
** 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.
**
** 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.
**
****************************************************************************/
#include "remotelinuxrunconfigurationwidget.h"
#include "remotelinuxrunconfiguration.h"
#include <projectexplorer/runconfigurationaspects.h>
#include <utils/detailswidget.h>
#include <utils/utilsicons.h>
#include <QCheckBox>
#include <QDir>
#include <QFormLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
using namespace ProjectExplorer;
namespace RemoteLinux {
namespace Internal {
class RemoteLinuxRunConfigurationWidgetPrivate
{
public:
RemoteLinuxRunConfigurationWidgetPrivate(RemoteLinuxRunConfiguration *runConfig)
: runConfiguration(runConfig)
{
const auto selectable = Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse;
localExecutableLabel.setTextInteractionFlags(selectable);
remoteExecutableLabel.setTextInteractionFlags(selectable);
}
RemoteLinuxRunConfiguration * const runConfiguration;
bool ignoreChange = false;
QLabel localExecutableLabel;
QLabel remoteExecutableLabel;
QCheckBox useAlternateCommandBox;
QLineEdit alternateCommand;
QLabel devConfLabel;
QFormLayout genericWidgetsLayout;
};
} // namespace Internal
using namespace Internal;
RemoteLinuxRunConfigurationWidget::RemoteLinuxRunConfigurationWidget(RemoteLinuxRunConfiguration *runConfiguration)
: d(new RemoteLinuxRunConfigurationWidgetPrivate(runConfiguration))
{
auto mainLayout = new QVBoxLayout(this);
mainLayout->setMargin(0);
auto detailsContainer = new Utils::DetailsWidget(this);
detailsContainer->setState(Utils::DetailsWidget::NoSummary);
auto details = new QWidget(this);
details->setLayout(&d->genericWidgetsLayout);
detailsContainer->setWidget(details);
mainLayout->addWidget(detailsContainer);
d->genericWidgetsLayout.setFormAlignment(Qt::AlignLeft | Qt::AlignVCenter);
d->localExecutableLabel.setText(d->runConfiguration->localExecutableFilePath());
d->genericWidgetsLayout.addRow(tr("Executable on host:"), &d->localExecutableLabel);
d->genericWidgetsLayout.addRow(tr("Executable on device:"), &d->remoteExecutableLabel);
auto altRemoteExeWidget = new QWidget;
auto altRemoteExeLayout = new QHBoxLayout(altRemoteExeWidget);
altRemoteExeLayout->setContentsMargins(0, 0, 0, 0);
d->alternateCommand.setText(d->runConfiguration->alternateRemoteExecutable());
altRemoteExeLayout->addWidget(&d->alternateCommand);
d->useAlternateCommandBox.setText(tr("Use this command instead"));
d->useAlternateCommandBox.setChecked(d->runConfiguration->useAlternateExecutable());
altRemoteExeLayout->addWidget(&d->useAlternateCommandBox);
d->genericWidgetsLayout.addRow(tr("Alternate executable on device:"), altRemoteExeWidget);
d->runConfiguration->extraAspect<ArgumentsAspect>()
->addToMainConfigurationWidget(this, &d->genericWidgetsLayout);
d->runConfiguration->extraAspect<WorkingDirectoryAspect>()
->addToMainConfigurationWidget(this, &d->genericWidgetsLayout);
connect(d->runConfiguration, &RemoteLinuxRunConfiguration::targetInformationChanged,
this, &RemoteLinuxRunConfigurationWidget::updateTargetInformation);
connect(d->runConfiguration, &RemoteLinuxRunConfiguration::deploySpecsChanged,
this, &RemoteLinuxRunConfigurationWidget::handleDeploySpecsChanged);
connect(&d->useAlternateCommandBox, &QCheckBox::toggled,
this, &RemoteLinuxRunConfigurationWidget::handleUseAlternateCommandChanged);
connect(&d->alternateCommand, &QLineEdit::textEdited,
this, &RemoteLinuxRunConfigurationWidget::handleAlternateCommandChanged);
handleDeploySpecsChanged();
handleUseAlternateCommandChanged();
}
RemoteLinuxRunConfigurationWidget::~RemoteLinuxRunConfigurationWidget()
{
delete d;
}
void RemoteLinuxRunConfigurationWidget::addFormLayoutRow(QWidget *label, QWidget *field)
{
d->genericWidgetsLayout.addRow(label, field);
}
void RemoteLinuxRunConfigurationWidget::updateTargetInformation()
{
setLabelText(d->localExecutableLabel,
QDir::toNativeSeparators(d->runConfiguration->localExecutableFilePath()),
tr("Unknown"));
}
void RemoteLinuxRunConfigurationWidget::handleDeploySpecsChanged()
{
setLabelText(d->remoteExecutableLabel, d->runConfiguration->defaultRemoteExecutableFilePath(),
tr("Remote path not set"));
}
void RemoteLinuxRunConfigurationWidget::setLabelText(QLabel &label, const QString &regularText,
const QString &errorText)
{
const QString errorMessage = QLatin1String("<font color=\"red\">") + errorText
+ QLatin1String("</font>");
label.setText(regularText.isEmpty() ? errorMessage : regularText);
}
void RemoteLinuxRunConfigurationWidget::handleUseAlternateCommandChanged()
{
const bool useAltExe = d->useAlternateCommandBox.isChecked();
d->remoteExecutableLabel.setEnabled(!useAltExe);
d->alternateCommand.setEnabled(useAltExe);
d->runConfiguration->setUseAlternateExecutable(useAltExe);
}
void RemoteLinuxRunConfigurationWidget::handleAlternateCommandChanged()
{
d->runConfiguration->setAlternateRemoteExecutable(d->alternateCommand.text().trimmed());
}
} // namespace RemoteLinux

View File

@@ -1,62 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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
** 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.
**
** 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.
**
****************************************************************************/
#pragma once
#include "remotelinux_export.h"
#include <QWidget>
QT_BEGIN_NAMESPACE
class QLabel;
class QVBoxLayout;
QT_END_NAMESPACE
namespace RemoteLinux {
class RemoteLinuxRunConfiguration;
namespace Internal { class RemoteLinuxRunConfigurationWidgetPrivate; }
class REMOTELINUX_EXPORT RemoteLinuxRunConfigurationWidget : public QWidget
{
Q_OBJECT
public:
explicit RemoteLinuxRunConfigurationWidget(RemoteLinuxRunConfiguration *runConfiguration);
~RemoteLinuxRunConfigurationWidget();
void addFormLayoutRow(QWidget *label, QWidget *field);
private:
void updateTargetInformation();
void handleDeploySpecsChanged();
void handleUseAlternateCommandChanged();
void handleAlternateCommandChanged();
void setLabelText(QLabel &label, const QString &regularText, const QString &errorText);
Internal::RemoteLinuxRunConfigurationWidgetPrivate * const d;
};
} // namespace RemoteLinux