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 "projectexplorer.h"
#include "projectexplorersettings.h" #include "projectexplorersettings.h"
#include "runconfiguration.h" #include "runconfiguration.h"
#include "target.h"
#include <utils/utilsicons.h> #include <utils/utilsicons.h>
#include <utils/fancylineedit.h> #include <utils/fancylineedit.h>
@@ -293,59 +294,260 @@ void ArgumentsAspect::addToMainConfigurationWidget(QWidget *parent, QFormLayout
layout->addRow(tr("Command line arguments:"), m_chooser); 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 \class ProjectExplorer::ExecutableAspect
*/ */
ExecutableAspect::ExecutableAspect(RunConfiguration *runConfig, bool isRemote, const QString &label) ExecutableAspect::ExecutableAspect(RunConfiguration *rc)
: IRunConfigurationAspect(runConfig), m_isRemote(isRemote), m_labelString(label) : IRunConfigurationAspect(rc), m_executable(rc)
{ {
setDisplayName(tr("Executable")); setDisplayName(tr("Executable"));
setId("ExecutableAspect"); 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; QTC_ASSERT(!m_alternativeExecutable, return);
if (m_executableDisplay) m_alternativeExecutable = new BaseStringAspect(runConfiguration());
m_executableDisplay->setText(executableText()); 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()) if (m_alternativeExecutable && m_alternativeExecutable->isChecked())
return tr("<unknown>"); return m_alternativeExecutable->fileName();
if (m_isRemote)
return m_executable.toString(); return m_executable.fileName();
return m_executable.toUserOutput();
} }
void ExecutableAspect::addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout) void ExecutableAspect::addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout)
{ {
QTC_CHECK(!m_executableDisplay); m_executable.addToMainConfigurationWidget(parent, layout);
m_executableDisplay = new QLabel(parent); if (m_alternativeExecutable)
m_executableDisplay->setTextInteractionFlags(Qt::TextSelectableByMouse); m_alternativeExecutable->addToMainConfigurationWidget(parent, layout);
m_executableDisplay->setText(executableText()); }
QString labelText = m_labelString; void ExecutableAspect::setLabelText(const QString &labelText)
if (labelText.isEmpty()) {
labelText = m_isRemote ? tr("Remote Executable") : tr("Executable"); m_executable.setLabelText(labelText);
layout->addRow(labelText + ':', m_executableDisplay); }
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 \class ProjectExplorer::BaseBoolAspect
*/ */
BaseBoolAspect::BaseBoolAspect(RunConfiguration *runConfig, const QString &key) : BaseBoolAspect::BaseBoolAspect(RunConfiguration *runConfig, const QString &settingsKey)
IRunConfigurationAspect(runConfig) : IRunConfigurationAspect(runConfig)
{ {
setSettingsKey(key); setSettingsKey(settingsKey);
} }
void BaseBoolAspect::addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout) void BaseBoolAspect::addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout)

View File

@@ -29,10 +29,12 @@
#include "applicationlauncher.h" #include "applicationlauncher.h"
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/osspecificaspects.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QCheckBox; class QCheckBox;
class QLabel; class QLabel;
class QLineEdit;
class QFormLayout; class QFormLayout;
class QToolButton; class QToolButton;
QT_END_NAMESPACE QT_END_NAMESPACE
@@ -79,7 +81,8 @@ class PROJECTEXPLORER_EXPORT WorkingDirectoryAspect : public IRunConfigurationAs
Q_OBJECT Q_OBJECT
public: public:
explicit WorkingDirectoryAspect(RunConfiguration *runConfig, const QString &settingsKey); explicit WorkingDirectoryAspect(RunConfiguration *runConfig,
const QString &settingsKey = QString());
void addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout); void addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout);
@@ -107,7 +110,7 @@ class PROJECTEXPLORER_EXPORT ArgumentsAspect : public IRunConfigurationAspect
Q_OBJECT Q_OBJECT
public: public:
explicit ArgumentsAspect(RunConfiguration *runConfig, const QString &settingsKey); explicit ArgumentsAspect(RunConfiguration *runConfig, const QString &settingsKey = QString());
void addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout); void addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout);
@@ -127,49 +130,27 @@ private:
QPointer<Utils::FancyLineEdit> m_chooser; 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 class PROJECTEXPLORER_EXPORT BaseBoolAspect : public IRunConfigurationAspect
{ {
Q_OBJECT Q_OBJECT
public: public:
BaseBoolAspect(RunConfiguration *rc, const QString &settingsKey); explicit BaseBoolAspect(RunConfiguration *rc, const QString &settingsKey = QString());
void addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout); void addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout);
bool value() const; bool value() const;
void setValue(bool val); void setValue(bool val);
void setLabel(const QString &label); void setLabel(const QString &label);
void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override;
signals: signals:
void changed(); void changed();
private: private:
void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override;
bool m_value = false; bool m_value = false;
QString m_label; QString m_label;
QPointer<QCheckBox> m_checkBox; // Owned by RunConfigWidget QPointer<QCheckBox> m_checkBox; // Owned by RunConfigWidget
@@ -191,4 +172,85 @@ public:
UseDyldSuffixAspect(RunConfiguration *rc, const QString &settingsKey); 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 } // namespace ProjectExplorer

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -51,47 +51,39 @@ public:
{ {
auto fl = new QFormLayout(this); auto fl = new QFormLayout(this);
auto remoteExeLabel = new QLabel(RemoteLinuxCustomRunConfiguration::tr("Remote executable:")); runConfig->extraAspect<ExecutableAspect>()->addToMainConfigurationWidget(this, fl);
auto remoteExeLineEdit = new QLineEdit; runConfig->extraAspect<SymbolFileAspect>()->addToMainConfigurationWidget(this, fl);
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<ArgumentsAspect>()->addToMainConfigurationWidget(this, fl); runConfig->extraAspect<ArgumentsAspect>()->addToMainConfigurationWidget(this, fl);
runConfig->extraAspect<WorkingDirectoryAspect>()->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) RemoteLinuxCustomRunConfiguration::RemoteLinuxCustomRunConfiguration(Target *target)
: RunConfiguration(target, runConfigId()) : 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 ArgumentsAspect(this, "RemoteLinux.CustomRunConfig.Arguments"));
addExtraAspect(new WorkingDirectoryAspect(this, "RemoteLinux.CustomRunConfig.WorkingDirectory")); addExtraAspect(new WorkingDirectoryAspect(this, "RemoteLinux.CustomRunConfig.WorkingDirectory"));
addExtraAspect(new RemoteLinuxEnvironmentAspect(this)); addExtraAspect(new RemoteLinuxEnvironmentAspect(this));
setDefaultDisplayName(runConfigDefaultDisplayName()); setDefaultDisplayName(runConfigDefaultDisplayName());
setOutputFormatter<QtSupport::QtOutputFormatter>(); setOutputFormatter<QtSupport::QtOutputFormatter>();
} }
bool RemoteLinuxCustomRunConfiguration::isConfigured() const bool RemoteLinuxCustomRunConfiguration::isConfigured() const
{ {
return !m_remoteExecutable.isEmpty(); return !extraAspect<ExecutableAspect>()->executable().isEmpty();
} }
RunConfiguration::ConfigurationState RunConfiguration::ConfigurationState
@@ -115,19 +107,13 @@ QWidget *RemoteLinuxCustomRunConfiguration::createConfigurationWidget()
Runnable RemoteLinuxCustomRunConfiguration::runnable() const Runnable RemoteLinuxCustomRunConfiguration::runnable() const
{ {
StandardRunnable r; StandardRunnable r;
r.executable = extraAspect<ExecutableAspect>()->executable().toString();
r.environment = extraAspect<RemoteLinuxEnvironmentAspect>()->environment(); r.environment = extraAspect<RemoteLinuxEnvironmentAspect>()->environment();
r.executable = m_remoteExecutable;
r.commandLineArguments = extraAspect<ArgumentsAspect>()->arguments(); r.commandLineArguments = extraAspect<ArgumentsAspect>()->arguments();
r.workingDirectory = extraAspect<WorkingDirectoryAspect>()->workingDirectory().toString(); r.workingDirectory = extraAspect<WorkingDirectoryAspect>()->workingDirectory().toString();
return r; return r;
} }
void RemoteLinuxCustomRunConfiguration::setRemoteExecutableFilePath(const QString &executable)
{
m_remoteExecutable = executable;
setDisplayName(runConfigDefaultDisplayName());
}
Core::Id RemoteLinuxCustomRunConfiguration::runConfigId() Core::Id RemoteLinuxCustomRunConfiguration::runConfigId()
{ {
return "RemoteLinux.CustomRunConfig"; return "RemoteLinux.CustomRunConfig";
@@ -135,38 +121,12 @@ Core::Id RemoteLinuxCustomRunConfiguration::runConfigId()
QString RemoteLinuxCustomRunConfiguration::runConfigDefaultDisplayName() QString RemoteLinuxCustomRunConfiguration::runConfigDefaultDisplayName()
{ {
QString display = m_remoteExecutable.isEmpty() QString remoteExecutable = extraAspect<ExecutableAspect>()->executable().toString();
? tr("Custom Executable") : tr("Run \"%1\"").arg(m_remoteExecutable); QString display = remoteExecutable.isEmpty()
? tr("Custom Executable") : tr("Run \"%1\"").arg(remoteExecutable);
return RunConfigurationFactory::decoratedTargetName(display, target()); 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::RemoteLinuxCustomRunConfigurationFactory() RemoteLinuxCustomRunConfigurationFactory::RemoteLinuxCustomRunConfigurationFactory()

View File

@@ -36,25 +36,13 @@ class RemoteLinuxCustomRunConfiguration : public ProjectExplorer::RunConfigurati
public: public:
explicit RemoteLinuxCustomRunConfiguration(ProjectExplorer::Target *target); explicit RemoteLinuxCustomRunConfiguration(ProjectExplorer::Target *target);
bool fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override;
bool isConfigured() const override; bool isConfigured() const override;
ConfigurationState ensureConfigured(QString *errorMessage) override; ConfigurationState ensureConfigured(QString *errorMessage) override;
QWidget *createConfigurationWidget() override; QWidget *createConfigurationWidget() override;
ProjectExplorer::Runnable runnable() const 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(); static Core::Id runConfigId();
QString runConfigDefaultDisplayName(); QString runConfigDefaultDisplayName();
private:
QString m_localExecutable;
QString m_remoteExecutable;
}; };
class RemoteLinuxCustomRunConfigurationFactory : public ProjectExplorer::FixedRunConfigurationFactory class RemoteLinuxCustomRunConfigurationFactory : public ProjectExplorer::FixedRunConfigurationFactory

View File

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

View File

@@ -27,7 +27,6 @@
#include "remotelinux_constants.h" #include "remotelinux_constants.h"
#include "remotelinuxenvironmentaspect.h" #include "remotelinuxenvironmentaspect.h"
#include "remotelinuxrunconfigurationwidget.h"
#include <projectexplorer/buildtargetinfo.h> #include <projectexplorer/buildtargetinfo.h>
#include <projectexplorer/deploymentdata.h> #include <projectexplorer/deploymentdata.h>
@@ -36,32 +35,15 @@
#include <projectexplorer/runconfigurationaspects.h> #include <projectexplorer/runconfigurationaspects.h>
#include <projectexplorer/runnables.h> #include <projectexplorer/runnables.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <qtsupport/qtoutputformatter.h> #include <qtsupport/qtoutputformatter.h>
#include <utils/qtcprocess.h>
#include <QFormLayout>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;
namespace RemoteLinux { 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::RemoteLinuxRunConfiguration(Target *target)
: RemoteLinuxRunConfiguration(target, IdPrefix) : RemoteLinuxRunConfiguration(target, IdPrefix)
@@ -69,62 +51,69 @@ RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *target)
} }
RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *target, Core::Id id) 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)); auto symbolsAspect = new SymbolFileAspect(this);
addExtraAspect(new WorkingDirectoryAspect(this, WorkingDirectoryKey)); 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>(); setOutputFormatter<QtSupport::QtOutputFormatter>();
connect(target, &Target::deploymentDataChanged, connect(target, &Target::deploymentDataChanged,
this, &RemoteLinuxRunConfiguration::handleBuildSystemDataUpdated); this, &RemoteLinuxRunConfiguration::updateTargetInformation);
connect(target, &Target::applicationTargetsChanged, connect(target, &Target::applicationTargetsChanged,
this, &RemoteLinuxRunConfiguration::handleBuildSystemDataUpdated); this, &RemoteLinuxRunConfiguration::updateTargetInformation);
// Handles device changes, etc. connect(target->project(), &Project::parsingFinished,
this, &RemoteLinuxRunConfiguration::updateTargetInformation);
connect(target, &Target::kitChanged, connect(target, &Target::kitChanged,
this, &RemoteLinuxRunConfiguration::handleBuildSystemDataUpdated); this, &RemoteLinuxRunConfiguration::updateTargetInformation);
}
RemoteLinuxRunConfiguration::~RemoteLinuxRunConfiguration()
{
delete d;
} }
QWidget *RemoteLinuxRunConfiguration::createConfigurationWidget() 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 Runnable RemoteLinuxRunConfiguration::runnable() const
{ {
StandardRunnable r; StandardRunnable r;
r.environment = extraAspect<RemoteLinuxEnvironmentAspect>()->environment(); r.environment = extraAspect<RemoteLinuxEnvironmentAspect>()->environment();
r.executable = remoteExecutableFilePath(); r.executable = extraAspect<ExecutableAspect>()->executable().toString();
r.commandLineArguments = extraAspect<ArgumentsAspect>()->arguments(); r.commandLineArguments = extraAspect<ArgumentsAspect>()->arguments();
r.workingDirectory = extraAspect<WorkingDirectoryAspect>()->workingDirectory().toString(); r.workingDirectory = extraAspect<WorkingDirectoryAspect>()->workingDirectory().toString();
return r; 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()); setDefaultDisplayName(defaultDisplayName());
return true;
} }
QString RemoteLinuxRunConfiguration::defaultDisplayName() const QString RemoteLinuxRunConfiguration::defaultDisplayName() const
@@ -132,47 +121,15 @@ QString RemoteLinuxRunConfiguration::defaultDisplayName() const
return RunConfigurationFactory::decoratedTargetName(buildKey(), target()); 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 extraAspect<ExecutableAspect>()->setExecutable(FileName::fromString(depFile.remoteFilePath()));
{ extraAspect<SymbolFileAspect>()->setValue(localExecutable);
return target()->deploymentData().deployableForLocalFile(localExecutableFilePath())
.remoteFilePath();
}
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(); emit enabledChanged();
} }

View File

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