forked from qt-creator/qt-creator
RemoteLinux: Let user override deployment data
That is, instead of what is specified in the project files of the respective build system, let the user manually set the data in the deploy configuration. This is intended as a last resort for use in project managers that are not able to deduce any deployment information from the project. Fixes: QTCREATORBUG-21854 Change-Id: I2fefb89a4aa846e52aeca69749ca03534f4f0a67 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -39,6 +39,8 @@ namespace ProjectExplorer {
|
||||
|
||||
const char BUILD_STEP_LIST_COUNT[] = "ProjectExplorer.BuildConfiguration.BuildStepListCount";
|
||||
const char BUILD_STEP_LIST_PREFIX[] = "ProjectExplorer.BuildConfiguration.BuildStepList.";
|
||||
const char USES_DEPLOYMENT_DATA[] = "ProjectExplorer.DeployConfiguration.CustomDataEnabled";
|
||||
const char DEPLOYMENT_DATA[] = "ProjectExplorer.DeployConfiguration.CustomData";
|
||||
|
||||
DeployConfiguration::DeployConfiguration(Target *target, Core::Id id)
|
||||
: ProjectConfiguration(target, id),
|
||||
@@ -67,11 +69,11 @@ const BuildStepList *DeployConfiguration::stepList() const
|
||||
return &m_stepList;
|
||||
}
|
||||
|
||||
QWidget *DeployConfiguration::createConfigWidget() const
|
||||
QWidget *DeployConfiguration::createConfigWidget()
|
||||
{
|
||||
if (!m_configWidgetCreator)
|
||||
return nullptr;
|
||||
return m_configWidgetCreator(target());
|
||||
return m_configWidgetCreator(this);
|
||||
}
|
||||
|
||||
QVariantMap DeployConfiguration::toMap() const
|
||||
@@ -79,6 +81,13 @@ QVariantMap DeployConfiguration::toMap() const
|
||||
QVariantMap map(ProjectConfiguration::toMap());
|
||||
map.insert(QLatin1String(BUILD_STEP_LIST_COUNT), 1);
|
||||
map.insert(QLatin1String(BUILD_STEP_LIST_PREFIX) + QLatin1Char('0'), m_stepList.toMap());
|
||||
map.insert(USES_DEPLOYMENT_DATA, usesCustomDeploymentData());
|
||||
QVariantMap deployData;
|
||||
for (int i = 0; i < m_customDeploymentData.fileCount(); ++i) {
|
||||
const DeployableFile &f = m_customDeploymentData.fileAt(i);
|
||||
deployData.insert(f.localFilePath().toString(), f.remoteDirectory());
|
||||
}
|
||||
map.insert(DEPLOYMENT_DATA, deployData);
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -103,6 +112,10 @@ bool DeployConfiguration::fromMap(const QVariantMap &map)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_usesCustomDeploymentData = map.value(USES_DEPLOYMENT_DATA, false).toBool();
|
||||
const QVariantMap deployData = map.value(DEPLOYMENT_DATA).toMap();
|
||||
for (auto it = deployData.begin(); it != deployData.end(); ++it)
|
||||
m_customDeploymentData.addFile(it.key(), it.value().toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -157,14 +170,16 @@ bool DeployConfigurationFactory::canHandle(Target *target) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeployConfigurationFactory::setConfigWidgetCreator(const std::function<QWidget *(Target *)> &configWidgetCreator)
|
||||
void DeployConfigurationFactory::setConfigWidgetCreator(const DeployConfiguration::WidgetCreator &configWidgetCreator)
|
||||
{
|
||||
m_configWidgetCreator = configWidgetCreator;
|
||||
}
|
||||
|
||||
void DeployConfigurationFactory::setUseDeploymentDataView()
|
||||
{
|
||||
m_configWidgetCreator = [](Target *target) { return new Internal::DeploymentDataView(target); };
|
||||
m_configWidgetCreator = [](DeployConfiguration *dc) {
|
||||
return new Internal::DeploymentDataView(dc);
|
||||
};
|
||||
}
|
||||
|
||||
void DeployConfigurationFactory::setConfigBaseId(Core::Id deployConfigBaseId)
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "projectexplorer_export.h"
|
||||
|
||||
#include "buildsteplist.h"
|
||||
#include "deploymentdata.h"
|
||||
#include "projectconfiguration.h"
|
||||
|
||||
namespace ProjectExplorer {
|
||||
@@ -50,16 +51,25 @@ public:
|
||||
BuildStepList *stepList();
|
||||
const BuildStepList *stepList() const;
|
||||
|
||||
QWidget *createConfigWidget() const;
|
||||
QWidget *createConfigWidget();
|
||||
|
||||
bool fromMap(const QVariantMap &map) override;
|
||||
QVariantMap toMap() const override;
|
||||
|
||||
bool isActive() const override;
|
||||
|
||||
bool usesCustomDeploymentData() const { return m_usesCustomDeploymentData; }
|
||||
void setUseCustomDeploymentData(bool enabled) { m_usesCustomDeploymentData = enabled; }
|
||||
|
||||
DeploymentData customDeploymentData() const { return m_customDeploymentData; }
|
||||
void setCustomDeploymentData(const DeploymentData &data) { m_customDeploymentData = data; }
|
||||
|
||||
private:
|
||||
BuildStepList m_stepList;
|
||||
std::function<QWidget *(Target *)> m_configWidgetCreator;
|
||||
using WidgetCreator = std::function<QWidget *(DeployConfiguration *)>;
|
||||
WidgetCreator m_configWidgetCreator;
|
||||
DeploymentData m_customDeploymentData;
|
||||
bool m_usesCustomDeploymentData = false;
|
||||
};
|
||||
|
||||
class PROJECTEXPLORER_EXPORT DeployConfigurationFactory
|
||||
@@ -90,7 +100,7 @@ public:
|
||||
|
||||
bool canHandle(ProjectExplorer::Target *target) const;
|
||||
|
||||
void setConfigWidgetCreator(const std::function<QWidget *(Target *)> &configWidgetCreator);
|
||||
void setConfigWidgetCreator(const DeployConfiguration::WidgetCreator &configWidgetCreator);
|
||||
void setUseDeploymentDataView();
|
||||
|
||||
using PostRestore = std::function<void(DeployConfiguration *dc, const QVariantMap &)>;
|
||||
@@ -108,7 +118,7 @@ private:
|
||||
QList<Core::Id> m_supportedTargetDeviceTypes;
|
||||
QList<BuildStepList::StepCreationInfo> m_initialSteps;
|
||||
QString m_defaultDisplayName;
|
||||
std::function<QWidget *(Target *)> m_configWidgetCreator;
|
||||
DeployConfiguration::WidgetCreator m_configWidgetCreator;
|
||||
PostRestore m_postRestore;
|
||||
};
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "deploymentdataview.h"
|
||||
|
||||
#include "buildsystem.h"
|
||||
#include "deployconfiguration.h"
|
||||
#include "deploymentdata.h"
|
||||
#include "target.h"
|
||||
|
||||
@@ -33,8 +34,11 @@
|
||||
#include <utils/treemodel.h>
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QLabel>
|
||||
#include <QCheckBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QTreeView>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
@@ -47,19 +51,41 @@ class DeploymentDataItem : public TreeItem
|
||||
{
|
||||
public:
|
||||
DeploymentDataItem() = default;
|
||||
DeploymentDataItem(const DeployableFile &file) : file(file) {}
|
||||
DeploymentDataItem(const DeployableFile &file, bool isEditable)
|
||||
: file(file), isEditable(isEditable) {}
|
||||
|
||||
QVariant data(int column, int role) const
|
||||
Qt::ItemFlags flags(int column) const override
|
||||
{
|
||||
if (role == Qt::DisplayRole)
|
||||
Qt::ItemFlags f = TreeItem::flags(column);
|
||||
if (isEditable)
|
||||
f |= Qt::ItemIsEditable;
|
||||
return f;
|
||||
}
|
||||
|
||||
QVariant data(int column, int role) const override
|
||||
{
|
||||
if (role == Qt::DisplayRole || role == Qt::EditRole)
|
||||
return column == 0 ? file.localFilePath().toUserOutput() : file.remoteDirectory();
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool setData(int column, const QVariant &data, int role) override
|
||||
{
|
||||
if (role != Qt::EditRole)
|
||||
return false;
|
||||
if (column == 0)
|
||||
file = DeployableFile(data.toString(), file.remoteDirectory());
|
||||
else if (column == 1)
|
||||
file = DeployableFile(file.localFilePath().toString(), data.toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
DeployableFile file;
|
||||
bool isEditable = false;
|
||||
};
|
||||
|
||||
|
||||
DeploymentDataView::DeploymentDataView(Target *target)
|
||||
DeploymentDataView::DeploymentDataView(DeployConfiguration *dc)
|
||||
{
|
||||
auto model = new TreeModel<DeploymentDataItem>(this);
|
||||
model->setHeader({tr("Local File Path"), tr("Remote Directory")});
|
||||
@@ -71,18 +97,33 @@ DeploymentDataView::DeploymentDataView(Target *target)
|
||||
view->setUniformRowHeights(true);
|
||||
view->setModel(model);
|
||||
|
||||
const auto buttonsLayout = new QVBoxLayout;
|
||||
const auto addButton = new QPushButton(tr("Add"));
|
||||
const auto removeButton = new QPushButton(tr("Remove"));
|
||||
buttonsLayout->addWidget(addButton);
|
||||
buttonsLayout->addWidget(removeButton);
|
||||
buttonsLayout->addStretch(1);
|
||||
|
||||
const auto viewLayout = new QHBoxLayout;
|
||||
viewLayout->addWidget(view);
|
||||
viewLayout->addLayout(buttonsLayout);
|
||||
|
||||
auto label = new QLabel(tr("Files to deploy:"), this);
|
||||
const auto sourceCheckBox = new QCheckBox(tr("Override deployment data from build system"));
|
||||
sourceCheckBox->setChecked(dc->usesCustomDeploymentData());
|
||||
|
||||
auto layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(label);
|
||||
layout->addWidget(view);
|
||||
layout->addWidget(sourceCheckBox);
|
||||
layout->addLayout(viewLayout);
|
||||
|
||||
auto updatModel = [this, target, model, view] {
|
||||
const auto updateModel = [dc, model, view] {
|
||||
model->clear();
|
||||
QTC_ASSERT(target->buildSystem(), return);
|
||||
for (const DeployableFile &file : target->buildSystem()->deploymentData().allFiles())
|
||||
model->rootItem()->appendChild(new DeploymentDataItem(file));
|
||||
for (const DeployableFile &file : dc->target()->deploymentData().allFiles()) {
|
||||
model->rootItem()->appendChild(
|
||||
new DeploymentDataItem(file, dc->usesCustomDeploymentData()));
|
||||
}
|
||||
|
||||
QHeaderView *header = view->header();
|
||||
header->setSectionResizeMode(0, QHeaderView::Interactive);
|
||||
@@ -93,8 +134,53 @@ DeploymentDataView::DeploymentDataView(Target *target)
|
||||
header->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||
};
|
||||
|
||||
connect(target, &Target::deploymentDataChanged, this, updatModel);
|
||||
updatModel();
|
||||
const auto deploymentDataFromModel = [model] {
|
||||
DeploymentData deployData;
|
||||
for (int i = 0; i < model->rowCount(); ++i) {
|
||||
const auto item = static_cast<DeploymentDataItem *>(
|
||||
model->itemForIndex(model->index(i, 0)));
|
||||
if (!item->file.localFilePath().isEmpty() && !item->file.remoteDirectory().isEmpty())
|
||||
deployData.addFile(item->file);
|
||||
}
|
||||
return deployData;
|
||||
};
|
||||
|
||||
const auto updateButtons = [dc, view, addButton, removeButton] {
|
||||
addButton->setEnabled(dc->usesCustomDeploymentData());
|
||||
removeButton->setEnabled(dc->usesCustomDeploymentData()
|
||||
&& view->selectionModel()->hasSelection());
|
||||
};
|
||||
|
||||
connect(dc->target(), &Target::deploymentDataChanged, this, [dc, updateModel] {
|
||||
if (!dc->usesCustomDeploymentData())
|
||||
updateModel();
|
||||
});
|
||||
connect(sourceCheckBox, &QCheckBox::toggled, this, [dc, updateModel, updateButtons](bool checked) {
|
||||
dc->setUseCustomDeploymentData(checked);
|
||||
updateModel();
|
||||
updateButtons();
|
||||
});
|
||||
connect(addButton, &QPushButton::clicked, this, [model, view] {
|
||||
const auto newItem = new DeploymentDataItem(DeployableFile(), true);
|
||||
model->rootItem()->appendChild(newItem);
|
||||
view->edit(model->indexForItem(newItem));
|
||||
});
|
||||
connect(removeButton, &QPushButton::clicked, this, [dc, model, view, deploymentDataFromModel] {
|
||||
const QModelIndexList selectedIndexes = view->selectionModel()->selectedIndexes();
|
||||
if (!selectedIndexes.isEmpty()) {
|
||||
model->destroyItem(model->itemForIndex(selectedIndexes.first()));
|
||||
dc->setCustomDeploymentData(deploymentDataFromModel());
|
||||
}
|
||||
});
|
||||
connect(model, &QAbstractItemModel::dataChanged, this, [dc, deploymentDataFromModel] {
|
||||
if (dc->usesCustomDeploymentData())
|
||||
dc->setCustomDeploymentData(deploymentDataFromModel());
|
||||
});
|
||||
connect(view->selectionModel(), &QItemSelectionModel::selectionChanged, this, [updateButtons] {
|
||||
updateButtons();
|
||||
});
|
||||
updateModel();
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
} // Internal
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
namespace ProjectExplorer {
|
||||
|
||||
class Target;
|
||||
class DeployConfiguration;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
@@ -38,7 +38,7 @@ class DeploymentDataView : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DeploymentDataView(Target *target);
|
||||
explicit DeploymentDataView(DeployConfiguration *dc);
|
||||
};
|
||||
|
||||
} // Internal
|
||||
|
||||
@@ -221,6 +221,14 @@ BuildSystem *Target::fallbackBuildSystem() const
|
||||
}
|
||||
|
||||
DeploymentData Target::deploymentData() const
|
||||
{
|
||||
const DeployConfiguration * const dc = activeDeployConfiguration();
|
||||
if (dc && dc->usesCustomDeploymentData())
|
||||
return dc->customDeploymentData();
|
||||
return buildSystemDeploymentData();
|
||||
}
|
||||
|
||||
DeploymentData Target::buildSystemDeploymentData() const
|
||||
{
|
||||
QTC_ASSERT(buildSystem(), return {});
|
||||
return buildSystem()->deploymentData();
|
||||
|
||||
@@ -115,6 +115,7 @@ public:
|
||||
BuildSystem *fallbackBuildSystem() const;
|
||||
|
||||
DeploymentData deploymentData() const;
|
||||
DeploymentData buildSystemDeploymentData() const;
|
||||
const QList<BuildTargetInfo> applicationTargets() const;
|
||||
BuildTargetInfo buildTarget(const QString &buildKey) const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user