Commit 83951574 authored by Daniel Teske's avatar Daniel Teske
Browse files

Project: Add a option to synchronize kits and build/deploy across projects



This is far from perfect but seems to work. Further work could add more
fine grained control over which projects are affected by the automatic
synchronize. Also there might be a few cases where the switching is
over zealous or missing.

Change-Id: I26ad3d59431251564917e4b408c66695dc454823
Task-number: QTCREATORBUG-5823
Reviewed-by: default avatarTobias Hunger <tobias.hunger@theqtcompany.com>
parent d5707e0e
......@@ -35,6 +35,7 @@
#include "target.h"
#include "buildconfiguration.h"
#include "buildconfigurationmodel.h"
#include "session.h"
#include <utils/qtcassert.h>
#include <coreplugin/icore.h>
......@@ -223,7 +224,7 @@ void BuildSettingsWidget::currentIndexChanged(int index)
{
BuildConfigurationModel *model = static_cast<BuildConfigurationModel *>(m_buildConfigurationComboBox->model());
BuildConfiguration *buildConfiguration = model->buildConfigurationAt(index);
m_target->setActiveBuildConfiguration(buildConfiguration);
SessionManager::setActiveBuildConfiguration(m_target, buildConfiguration, SetActive::Cascade);
}
void BuildSettingsWidget::updateActiveConfiguration()
......@@ -259,7 +260,7 @@ void BuildSettingsWidget::createConfiguration(BuildInfo *info)
return;
m_target->addBuildConfiguration(bc);
m_target->setActiveBuildConfiguration(bc);
SessionManager::setActiveBuildConfiguration(m_target, bc, SetActive::Cascade);
info->displayName = originalDisplayName;
}
......@@ -327,7 +328,7 @@ void BuildSettingsWidget::cloneConfiguration(BuildConfiguration *sourceConfigura
bc->setDisplayName(name);
m_target->addBuildConfiguration(bc);
m_target->setActiveBuildConfiguration(bc);
SessionManager::setActiveBuildConfiguration(m_target, bc, SetActive::Cascade);
}
void BuildSettingsWidget::deleteConfiguration(BuildConfiguration *deleteConfiguration)
......
......@@ -40,7 +40,8 @@
#include <QSize>
#include <QCoreApplication>
#include <QHBoxLayout>
#include <QCheckBox>
#include <QGridLayout>
#include <QTreeView>
#include <QSpacerItem>
#include <QMessageBox>
......@@ -223,13 +224,20 @@ DependenciesWidget::DependenciesWidget(Project *project, QWidget *parent)
QWidget *detailsWidget = new QWidget(m_detailsContainer);
m_detailsContainer->setWidget(detailsWidget);
QHBoxLayout *layout = new QHBoxLayout(detailsWidget);
QGridLayout *layout = new QGridLayout(detailsWidget);
layout->setContentsMargins(0, -1, 0, -1);
DependenciesView *treeView = new DependenciesView(this);
treeView->setModel(m_model);
treeView->setHeaderHidden(true);
layout->addWidget(treeView);
layout->addSpacerItem(new QSpacerItem(0, 0 , QSizePolicy::Expanding, QSizePolicy::Fixed));
layout->addWidget(treeView, 0 ,0);
layout->addItem(new QSpacerItem(0, 0 , QSizePolicy::Expanding, QSizePolicy::Fixed), 0, 1);
m_cascadeSetActiveCheckBox = new QCheckBox;
m_cascadeSetActiveCheckBox->setText(tr("Synchronize active kit, build, and deploy configuration between projects."));
m_cascadeSetActiveCheckBox->setChecked(SessionManager::isProjectConfigurationCascading());
connect(m_cascadeSetActiveCheckBox, &QCheckBox::toggled,
SessionManager::instance(), &SessionManager::setProjectConfigurationCascading);
layout->addWidget(m_cascadeSetActiveCheckBox, 1, 0, 2, 1);
}
} // namespace Internal
......
......@@ -35,6 +35,10 @@
#include <QTreeView>
QT_BEGIN_NAMESPACE
class QCheckBox;
QT_END_NAMESPACE
namespace Utils { class DetailsWidget; }
namespace ProjectExplorer {
......@@ -96,6 +100,7 @@ private:
Project *m_project;
DependenciesModel *m_model;
Utils::DetailsWidget *m_detailsContainer;
QCheckBox *m_cascadeSetActiveCheckBox;
};
} // namespace Internal
......
......@@ -960,17 +960,18 @@ void MiniProjectTargetSelector::doLayout(bool keepSize)
void MiniProjectTargetSelector::setActiveTarget(ProjectConfiguration *pc)
{
m_project->setActiveTarget(static_cast<Target *>(pc));
SessionManager::setActiveTarget(m_project, static_cast<Target *>(pc),
SetActive::Cascade);
}
void MiniProjectTargetSelector::setActiveBuildConfiguration(ProjectConfiguration *pc)
{
m_target->setActiveBuildConfiguration(static_cast<BuildConfiguration *>(pc));
SessionManager::setActiveBuildConfiguration(m_target, static_cast<BuildConfiguration *>(pc), SetActive::Cascade);
}
void MiniProjectTargetSelector::setActiveDeployConfiguration(ProjectConfiguration *pc)
{
m_target->setActiveDeployConfiguration(static_cast<DeployConfiguration *>(pc));
SessionManager::setActiveDeployConfiguration(m_target, static_cast<DeployConfiguration *>(pc), SetActive::Cascade);
}
void MiniProjectTargetSelector::setActiveRunConfiguration(ProjectConfiguration *pc)
......
......@@ -35,6 +35,7 @@
#include "editorconfiguration.h"
#include "projectexplorer.h"
#include "target.h"
#include "session.h"
#include "settingsaccessor.h"
#include <coreplugin/idocument.h>
......@@ -200,11 +201,11 @@ bool Project::removeTarget(Target *target)
if (target == activeTarget()) {
if (d->m_targets.size() == 1)
setActiveTarget(0);
SessionManager::setActiveTarget(this, 0, SetActive::Cascade);
else if (d->m_targets.first() == target)
setActiveTarget(d->m_targets.at(1));
SessionManager::setActiveTarget(this, d->m_targets.at(1), SetActive::Cascade);
else
setActiveTarget(d->m_targets.at(0));
SessionManager::setActiveTarget(this, d->m_targets.at(0), SetActive::Cascade);
}
emit aboutToRemoveTarget(target);
......
......@@ -64,6 +64,7 @@ class ProjectPrivate;
class PROJECTEXPLORER_EXPORT Project
: public QObject
{
friend class SessionManager; // for setActiveTarget
Q_OBJECT
public:
......@@ -96,7 +97,6 @@ public:
QList<Target *> targets() const;
// Note: activeTarget can be 0 (if no targets are defined).
Target *activeTarget() const;
void setActiveTarget(Target *target);
Target *target(Core::Id id) const;
Target *target(Kit *k) const;
virtual bool supportsKit(Kit *k, QString *errorMessage = 0) const;
......@@ -185,6 +185,7 @@ private slots:
void onBuildDirectoryChanged();
private:
void setActiveTarget(Target *target);
ProjectPrivate *d;
};
......
......@@ -37,6 +37,7 @@
#include "runconfiguration.h"
#include "target.h"
#include "project.h"
#include "session.h"
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/projectexplorer.h>
......@@ -364,9 +365,10 @@ void RunSettingsWidget::currentDeployConfigurationChanged(int index)
if (m_ignoreChange)
return;
if (index == -1)
m_target->setActiveDeployConfiguration(0);
SessionManager::setActiveDeployConfiguration(m_target, 0, SetActive::Cascade);
else
m_target->setActiveDeployConfiguration(m_deployConfigurationModel->deployConfigurationAt(index));
SessionManager::setActiveDeployConfiguration(m_target, m_deployConfigurationModel->deployConfigurationAt(index),
SetActive::Cascade);
}
void RunSettingsWidget::aboutToShowDeployMenu()
......@@ -390,7 +392,7 @@ void RunSettingsWidget::aboutToShowDeployMenu()
return;
QTC_CHECK(!newDc || newDc->id() == id);
m_target->addDeployConfiguration(newDc);
m_target->setActiveDeployConfiguration(newDc);
SessionManager::setActiveDeployConfiguration(m_target, newDc, SetActive::Cascade);
m_removeDeployToolButton->setEnabled(m_target->deployConfigurations().size() > 1);
});
}
......
......@@ -31,6 +31,10 @@
#include "session.h"
#include "project.h"
#include "target.h"
#include "kit.h"
#include "buildconfiguration.h"
#include "deployconfiguration.h"
#include "projectexplorer.h"
#include "nodesvisitor.h"
#include "editorconfiguration.h"
......@@ -112,6 +116,7 @@ public:
mutable QHash<Project *, QStringList> m_projectFileCache;
bool m_loadingSession;
bool m_casadeSetActive;
Project *m_startupProject;
QList<Project *> m_projects;
QStringList m_failedProjects;
......@@ -275,6 +280,98 @@ void SessionManager::removeDependency(Project *project, Project *depProject)
emit m_instance->dependencyChanged(project, depProject);
}
bool SessionManager::isProjectConfigurationCascading()
{
return d->m_casadeSetActive;
}
void SessionManager::setProjectConfigurationCascading(bool b)
{
d->m_casadeSetActive = b;
markSessionFileDirty();
}
void SessionManager::setActiveTarget(Project *project, Target *target, SetActive cascade)
{
QTC_ASSERT(project, return);
project->setActiveTarget(target);
if (!target) // never cascade setting no target
return;
if (cascade != SetActive::Cascade || !d->m_casadeSetActive)
return;
Core::Id kitId = target->kit()->id();
foreach (Project *otherProject, SessionManager::projects()) {
if (otherProject == project)
continue;
foreach (Target *otherTarget, otherProject->targets()) {
if (otherTarget->kit()->id() == kitId) {
otherProject->setActiveTarget(otherTarget);
break;
}
}
}
}
void SessionManager::setActiveBuildConfiguration(Target *target, BuildConfiguration *bc, SetActive cascade)
{
QTC_ASSERT(target, return);
target->setActiveBuildConfiguration(bc);
if (!bc)
return;
if (cascade != SetActive::Cascade || !d->m_casadeSetActive)
return;
Core::Id kitId = target->kit()->id();
QString name = bc->displayName(); // We match on displayname
foreach (Project *otherProject, SessionManager::projects()) {
if (otherProject == target->project())
continue;
Target *otherTarget = otherProject->activeTarget();
if (otherTarget->kit()->id() != kitId)
continue;
foreach (BuildConfiguration *otherBc, otherTarget->buildConfigurations()) {
if (otherBc->displayName() == name) {
otherTarget->setActiveBuildConfiguration(otherBc);
break;
}
}
}
}
void SessionManager::setActiveDeployConfiguration(Target *target, DeployConfiguration *dc, SetActive cascade)
{
QTC_ASSERT(target, return);
target->setActiveDeployConfiguration(dc);
if (!dc)
return;
if (cascade != SetActive::Cascade || !d->m_casadeSetActive)
return;
Core::Id kitId = target->kit()->id();
QString name = dc->displayName(); // We match on displayname
foreach (Project *otherProject, SessionManager::projects()) {
if (otherProject == target->project())
continue;
Target *otherTarget = otherProject->activeTarget();
if (otherTarget->kit()->id() != kitId)
continue;
foreach (DeployConfiguration *otherDc, otherTarget->deployConfigurations()) {
if (otherDc->displayName() == name) {
otherTarget->setActiveDeployConfiguration(otherDc);
break;
}
}
}
}
void SessionManager::setStartupProject(Project *startupProject)
{
if (debug)
......@@ -388,6 +485,7 @@ bool SessionManager::save()
projectFiles << failed;
data.insert(QLatin1String("ProjectList"), projectFiles);
data.insert(QLatin1String("CascadeSetActive"), d->m_casadeSetActive);
QMap<QString, QVariant> depMap;
QMap<QString, QStringList>::const_iterator i = d->m_depMap.constBegin();
......@@ -943,6 +1041,7 @@ bool SessionManager::loadSession(const QString &session)
d->m_failedProjects.clear();
d->m_depMap.clear();
d->m_values.clear();
d->m_casadeSetActive = false;
d->m_sessionName = session;
delete d->m_writer;
......@@ -994,6 +1093,9 @@ bool SessionManager::loadSession(const QString &session)
ModeManager::activateMode(Id(Core::Constants::MODE_EDIT));
ModeManager::setFocusToCurrentMode();
}
d->m_casadeSetActive = reader.restoreValue(QLatin1String("CascadeSetActive"), false).toBool();
emit m_instance->sessionLoaded(session);
// Starts a event loop, better do that at the very end
......
......@@ -54,9 +54,14 @@ class IEditor;
namespace ProjectExplorer {
class Project;
class Target;
class BuildConfiguration;
class DeployConfiguration;
class Node;
class SessionNode;
enum class SetActive { Cascade, NoCascade };
class PROJECTEXPLORER_EXPORT SessionManager : public QObject
{
Q_OBJECT
......@@ -98,6 +103,13 @@ public:
static bool addDependency(Project *project, Project *depProject);
static void removeDependency(Project *project, Project *depProject);
static bool isProjectConfigurationCascading();
static void setProjectConfigurationCascading(bool b);
static void setActiveTarget(Project *p, Target *t, SetActive cascade);
static void setActiveBuildConfiguration(Target *t, BuildConfiguration *bc, SetActive cascade);
static void setActiveDeployConfiguration(Target *t, DeployConfiguration *dc, SetActive cascade);
static Utils::FileName sessionNameToFileName(const QString &session);
static Project *startupProject();
......
......@@ -40,6 +40,7 @@
#include "deployconfiguration.h"
#include "project.h"
#include "runconfiguration.h"
#include "session.h"
#include <limits>
#include <coreplugin/coreconstants.h>
......@@ -276,9 +277,9 @@ bool Target::removeBuildConfiguration(BuildConfiguration *configuration)
if (activeBuildConfiguration() == configuration) {
if (d->m_buildConfigurations.isEmpty())
setActiveBuildConfiguration(0);
SessionManager::setActiveBuildConfiguration(this, 0, SetActive::Cascade);
else
setActiveBuildConfiguration(d->m_buildConfigurations.at(0));
SessionManager::setActiveBuildConfiguration(this, d->m_buildConfigurations.at(0), SetActive::Cascade);
}
delete configuration;
......@@ -349,9 +350,10 @@ bool Target::removeDeployConfiguration(DeployConfiguration *dc)
if (activeDeployConfiguration() == dc) {
if (d->m_deployConfigurations.isEmpty())
setActiveDeployConfiguration(0);
SessionManager::setActiveDeployConfiguration(this, 0, SetActive::Cascade);
else
setActiveDeployConfiguration(d->m_deployConfigurations.at(0));
SessionManager::setActiveDeployConfiguration(this, d->m_deployConfigurations.at(0),
SetActive::Cascade);
}
delete dc;
......
......@@ -55,6 +55,7 @@ class TargetPrivate;
class PROJECTEXPLORER_EXPORT Target : public ProjectConfiguration
{
friend class SessionManager; // for setActiveBuild and setActiveDeployConfiguration
Q_OBJECT
public:
......@@ -72,7 +73,6 @@ public:
QList<BuildConfiguration *> buildConfigurations() const;
BuildConfiguration *activeBuildConfiguration() const;
void setActiveBuildConfiguration(BuildConfiguration *configuration);
// DeployConfiguration
void addDeployConfiguration(DeployConfiguration *dc);
......@@ -80,7 +80,6 @@ public:
QList<DeployConfiguration *> deployConfigurations() const;
DeployConfiguration *activeDeployConfiguration() const;
void setActiveDeployConfiguration(DeployConfiguration *configuration);
void setDeploymentData(const DeploymentData &deploymentData);
DeploymentData deploymentData() const;
......@@ -179,6 +178,8 @@ private slots:
void handleKitRemoval(ProjectExplorer::Kit *k);
private:
void setActiveBuildConfiguration(BuildConfiguration *configuration);
void setActiveDeployConfiguration(DeployConfiguration *configuration);
TargetPrivate *d;
friend class Project;
......
......@@ -40,6 +40,7 @@
#include "projectwindow.h"
#include "propertiespanel.h"
#include "runsettingspropertiespage.h"
#include "session.h"
#include "target.h"
#include "targetsettingswidget.h"
......@@ -290,8 +291,7 @@ void TargetSettingsPanelWidget::currentTargetChanged(int targetIndex, int subInd
delete m_panelWidgets[1];
m_panelWidgets[1] = runPanel;
m_project->setActiveTarget(target);
SessionManager::setActiveTarget(m_project, target, SetActive::Cascade);
}
void TargetSettingsPanelWidget::menuShown(int targetIndex)
......@@ -307,7 +307,7 @@ void TargetSettingsPanelWidget::changeActionTriggered(QAction *action)
if (newTarget) {
m_project->addTarget(newTarget);
m_project->setActiveTarget(newTarget);
SessionManager::setActiveTarget(m_project, newTarget, SetActive::Cascade);
m_project->removeTarget(sourceTarget);
}
}
......@@ -319,7 +319,7 @@ void TargetSettingsPanelWidget::duplicateActionTriggered(QAction *action)
if (newTarget) {
m_project->addTarget(newTarget);
m_project->setActiveTarget(newTarget);
SessionManager::setActiveTarget(m_project, newTarget, SetActive::Cascade);
}
}
......@@ -363,12 +363,12 @@ Target *TargetSettingsPanelWidget::cloneTarget(Target *sourceTarget, Kit *k)
newBc->setDisplayName(sourceBc->displayName());
newTarget->addBuildConfiguration(newBc);
if (sourceTarget->activeBuildConfiguration() == sourceBc)
newTarget->setActiveBuildConfiguration(newBc);
SessionManager::setActiveBuildConfiguration(newTarget, newBc, SetActive::NoCascade);
}
if (!newTarget->activeBuildConfiguration()) {
QList<BuildConfiguration *> bcs = newTarget->buildConfigurations();
if (!bcs.isEmpty())
newTarget->setActiveBuildConfiguration(bcs.first());
SessionManager::setActiveBuildConfiguration(newTarget, bcs.first(), SetActive::NoCascade);
}
foreach (DeployConfiguration *sourceDc, sourceTarget->deployConfigurations()) {
......@@ -385,12 +385,12 @@ Target *TargetSettingsPanelWidget::cloneTarget(Target *sourceTarget, Kit *k)
newDc->setDisplayName(sourceDc->displayName());
newTarget->addDeployConfiguration(newDc);
if (sourceTarget->activeDeployConfiguration() == sourceDc)
newTarget->setActiveDeployConfiguration(newDc);
SessionManager::setActiveDeployConfiguration(newTarget, newDc, SetActive::NoCascade);
}
if (!newTarget->activeBuildConfiguration()) {
QList<DeployConfiguration *> dcs = newTarget->deployConfigurations();
if (!dcs.isEmpty())
newTarget->setActiveDeployConfiguration(dcs.first());
SessionManager::setActiveDeployConfiguration(newTarget, dcs.first(), SetActive::NoCascade);
}
foreach (RunConfiguration *sourceRc, sourceTarget->runConfigurations()) {
......@@ -671,9 +671,11 @@ void TargetSettingsPanelWidget::importTarget(const Utils::FileName &path)
QTC_ASSERT(bc, continue);
target->addBuildConfiguration(bc);
}
m_project->setActiveTarget(target);
SessionManager::setActiveTarget(m_project, target, SetActive::Cascade);
if (target && bc)
target->setActiveBuildConfiguration(bc);
SessionManager::setActiveBuildConfiguration(target, bc, SetActive::Cascade);
qDeleteAll(toImport);
}
......
......@@ -36,6 +36,7 @@
#include "importwidget.h"
#include "project.h"
#include "projectexplorerconstants.h"
#include "session.h"
#include "target.h"
#include "targetsetupwidget.h"
......@@ -576,7 +577,7 @@ bool TargetSetupPage::setupProject(Project *project)
if (m_importer)
activeTarget = m_importer->preferredTarget(project->targets());
if (activeTarget)
project->setActiveTarget(activeTarget);
SessionManager::setActiveTarget(project, activeTarget, SetActive::NoCascade);
return true;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment