Commit 5021a882 authored by Tobias Hunger's avatar Tobias Hunger

ProjectExplorer: Simplify *ConfigurationModels

Do not duplicate the code three times!

Change-Id: Ia2d7656242ae8270f51cd787f1261ff1aa135967
Reviewed-by: Tim Jenssen's avatarTim Jenssen <tim.jenssen@qt.io>
parent f1d735b7
/****************************************************************************
**
** 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 <QAbstractItemModel>
namespace ProjectExplorer {
class Target;
class BuildConfiguration;
// Documentation inside.
class BuildConfigurationModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit BuildConfigurationModel(Target *target, QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
BuildConfiguration *buildConfigurationAt(int i);
BuildConfiguration *buildConfigurationFor(const QModelIndex &idx);
QModelIndex indexFor(BuildConfiguration *rc);
private:
void addedBuildConfiguration(ProjectExplorer::BuildConfiguration*);
void removedBuildConfiguration(ProjectExplorer::BuildConfiguration*);
void displayNameChanged();
Target *m_target;
QList<BuildConfiguration *> m_buildConfigurations;
};
} // namespace ProjectExplorer
......@@ -29,7 +29,7 @@
#include "project.h"
#include "target.h"
#include "buildconfiguration.h"
#include "buildconfigurationmodel.h"
#include "projectconfigurationmodel.h"
#include "session.h"
#include <utils/qtcassert.h>
......@@ -218,7 +218,7 @@ void BuildSettingsWidget::updateBuildSettings()
void BuildSettingsWidget::currentIndexChanged(int index)
{
auto model = static_cast<BuildConfigurationModel *>(m_buildConfigurationComboBox->model());
BuildConfiguration *buildConfiguration = model->buildConfigurationAt(index);
auto buildConfiguration = qobject_cast<BuildConfiguration *>(model->projectConfigurationAt(index));
SessionManager::setActiveBuildConfiguration(m_target, buildConfiguration, SetActive::Cascade);
}
......
/****************************************************************************
**
** 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 "deployconfigurationmodel.h"
#include "target.h"
#include "deployconfiguration.h"
#include <utils/algorithm.h>
using namespace ProjectExplorer;
/*!
\class ProjectExplorer::DeployConfigurationModel
\brief The DeployConfigurationModel class provides a model to represent
the run configurations of a target.
To be used in drop down lists of comboboxes. Automatically adjusts
itself to added and removed deploy configurations.
*/
class DeployConfigurationComparer
{
public:
bool operator()(DeployConfiguration *a, DeployConfiguration *b)
{
return a->displayName() < b->displayName();
}
};
DeployConfigurationModel::DeployConfigurationModel(Target *target, QObject *parent) :
QAbstractListModel(parent),
m_target(target)
{
m_deployConfigurations = m_target->deployConfigurations();
Utils::sort(m_deployConfigurations, DeployConfigurationComparer());
connect(target, &Target::addedDeployConfiguration,
this, &DeployConfigurationModel::addedDeployConfiguration);
connect(target, &Target::removedDeployConfiguration,
this, &DeployConfigurationModel::removedDeployConfiguration);
foreach (DeployConfiguration *dc, m_deployConfigurations) {
connect(dc, &ProjectConfiguration::displayNameChanged,
this, &DeployConfigurationModel::displayNameChanged);
}
}
int DeployConfigurationModel::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : m_deployConfigurations.size();
}
int DeployConfigurationModel::columnCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : 1;
}
void DeployConfigurationModel::displayNameChanged()
{
auto dc = qobject_cast<DeployConfiguration *>(sender());
if (!dc)
return;
DeployConfigurationComparer compare;
// Find the old position
int oldPos = m_deployConfigurations.indexOf(dc);
if (oldPos >= 1 && compare(m_deployConfigurations.at(oldPos), m_deployConfigurations.at(oldPos - 1))) {
// We need to move up
int newPos = oldPos - 1;
while (newPos >= 0 && compare(m_deployConfigurations.at(oldPos), m_deployConfigurations.at(newPos))) {
--newPos;
}
++newPos;
beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos);
m_deployConfigurations.insert(newPos, dc);
m_deployConfigurations.removeAt(oldPos + 1);
endMoveRows();
// Not only did we move, we also changed...
emit dataChanged(index(newPos, 0), index(newPos,0));
} else if (oldPos < m_deployConfigurations.size() - 1
&& compare(m_deployConfigurations.at(oldPos + 1), m_deployConfigurations.at(oldPos))) {
// We need to move down
int newPos = oldPos + 1;
while (newPos < m_deployConfigurations.size()
&& compare(m_deployConfigurations.at(newPos), m_deployConfigurations.at(oldPos))) {
++newPos;
}
beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos);
m_deployConfigurations.insert(newPos, dc);
m_deployConfigurations.removeAt(oldPos);
endMoveRows();
// We need to subtract one since removing at the old place moves the newIndex down
emit dataChanged(index(newPos - 1, 0), index(newPos - 1, 0));
} else {
emit dataChanged(index(oldPos, 0), index(oldPos, 0));
}
}
QVariant DeployConfigurationModel::data(const QModelIndex &index, int role) const
{
if (role == Qt::DisplayRole) {
const int row = index.row();
if (row < m_deployConfigurations.size())
return m_deployConfigurations.at(row)->displayName();
}
return QVariant();
}
DeployConfiguration *DeployConfigurationModel::deployConfigurationAt(int i)
{
if (i > m_deployConfigurations.size() || i < 0)
return nullptr;
return m_deployConfigurations.at(i);
}
DeployConfiguration *DeployConfigurationModel::deployConfigurationFor(const QModelIndex &idx)
{
if (idx.row() > m_deployConfigurations.size() || idx.row() < 0)
return nullptr;
return m_deployConfigurations.at(idx.row());
}
QModelIndex DeployConfigurationModel::indexFor(DeployConfiguration *rc)
{
int idx = m_deployConfigurations.indexOf(rc);
if (idx == -1)
return QModelIndex();
return index(idx, 0);
}
void DeployConfigurationModel::addedDeployConfiguration(DeployConfiguration *dc)
{
// Find the right place to insert
DeployConfigurationComparer compare;
int i = 0;
for (; i < m_deployConfigurations.size(); ++i) {
if (compare(dc, m_deployConfigurations.at(i)))
break;
}
beginInsertRows(QModelIndex(), i, i);
m_deployConfigurations.insert(i, dc);
endInsertRows();
connect(dc, &ProjectConfiguration::displayNameChanged,
this, &DeployConfigurationModel::displayNameChanged);
}
void DeployConfigurationModel::removedDeployConfiguration(DeployConfiguration *dc)
{
int i = m_deployConfigurations.indexOf(dc);
if (i < 0)
return;
beginRemoveRows(QModelIndex(), i, i);
m_deployConfigurations.removeAt(i);
endRemoveRows();
}
/****************************************************************************
**
** 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 <QAbstractItemModel>
namespace ProjectExplorer {
class Target;
class DeployConfiguration;
// Documentation inside.
class DeployConfigurationModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit DeployConfigurationModel(Target *target, QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
DeployConfiguration *deployConfigurationAt(int i);
DeployConfiguration *deployConfigurationFor(const QModelIndex &idx);
QModelIndex indexFor(DeployConfiguration *rc);
private:
void addedDeployConfiguration(ProjectExplorer::DeployConfiguration*);
void removedDeployConfiguration(ProjectExplorer::DeployConfiguration*);
void displayNameChanged();
Target *m_target;
QList<DeployConfiguration *> m_deployConfigurations;
};
} // namespace ProjectExplorer
......@@ -23,9 +23,13 @@
**
****************************************************************************/
#include "buildconfigurationmodel.h"
#include "target.h"
#include "projectconfigurationmodel.h"
#include "buildconfiguration.h"
#include "deployconfiguration.h"
#include "runconfiguration.h"
#include "target.h"
#include "projectconfiguration.h"
#include <utils/algorithm.h>
......@@ -43,77 +47,80 @@ using namespace ProjectExplorer;
TODO might it possible to share code without making the code a complete mess.
*/
class BuildConfigurationComparer
{
public:
bool operator()(BuildConfiguration *a, BuildConfiguration *b)
{
namespace {
const auto ComparisonOperator =
[](const ProjectConfiguration *a, const ProjectConfiguration *b) {
return a->displayName() < b->displayName();
}
};
};
} // namespace
BuildConfigurationModel::BuildConfigurationModel(Target *target, QObject *parent)
: QAbstractListModel(parent),
m_target(target)
ProjectConfigurationModel::ProjectConfigurationModel(Target *target, FilterFunction filter,
QObject *parent) :
QAbstractListModel(parent),
m_target(target),
m_filter(filter)
{
m_buildConfigurations = m_target->buildConfigurations();
Utils::sort(m_buildConfigurations, BuildConfigurationComparer());
m_projectConfigurations = Utils::filtered(m_target->projectConfigurations(), m_filter);
Utils::sort(m_projectConfigurations, ComparisonOperator);
connect(target, &Target::addedBuildConfiguration,
this, &BuildConfigurationModel::addedBuildConfiguration);
connect(target, &Target::removedBuildConfiguration,
this, &BuildConfigurationModel::removedBuildConfiguration);
connect(target, &Target::addedProjectConfiguration,
this, &ProjectConfigurationModel::addedProjectConfiguration);
connect(target, &Target::removedProjectConfiguration,
this, &ProjectConfigurationModel::removedProjectConfiguration);
foreach (BuildConfiguration *bc, m_buildConfigurations)
connect(bc, &ProjectConfiguration::displayNameChanged,
this, &BuildConfigurationModel::displayNameChanged);
foreach (ProjectConfiguration *pc, m_projectConfigurations)
connect(pc, &ProjectConfiguration::displayNameChanged,
this, &ProjectConfigurationModel::displayNameChanged);
}
int BuildConfigurationModel::rowCount(const QModelIndex &parent) const
int ProjectConfigurationModel::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : m_buildConfigurations.size();
return parent.isValid() ? 0 : m_projectConfigurations.size();
}
int BuildConfigurationModel::columnCount(const QModelIndex &parent) const
int ProjectConfigurationModel::columnCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : 1;
}
void BuildConfigurationModel::displayNameChanged()
void ProjectConfigurationModel::displayNameChanged()
{
auto rc = qobject_cast<BuildConfiguration *>(sender());
if (!rc)
auto pc = qobject_cast<ProjectConfiguration *>(sender());
if (!pc)
return;
BuildConfigurationComparer compare;
// Find the old position
int oldPos = m_buildConfigurations.indexOf(rc);
int oldPos = m_projectConfigurations.indexOf(pc);
if (oldPos < 0)
return;
if (oldPos >= 1 && compare(m_buildConfigurations.at(oldPos), m_buildConfigurations.at(oldPos - 1))) {
if (oldPos >= 1 && ComparisonOperator(m_projectConfigurations.at(oldPos), m_projectConfigurations.at(oldPos - 1))) {
// We need to move up
int newPos = oldPos - 1;
while (newPos >= 0 && compare(m_buildConfigurations.at(oldPos), m_buildConfigurations.at(newPos))) {
while (newPos >= 0 && ComparisonOperator(m_projectConfigurations.at(oldPos), m_projectConfigurations.at(newPos))) {
--newPos;
}
++newPos;
beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos);
m_buildConfigurations.insert(newPos, rc);
m_buildConfigurations.removeAt(oldPos + 1);
m_projectConfigurations.insert(newPos, pc);
m_projectConfigurations.removeAt(oldPos + 1);
endMoveRows();
// Not only did we move, we also changed...
emit dataChanged(index(newPos, 0), index(newPos,0));
} else if (oldPos < m_buildConfigurations.size() - 1
&& compare(m_buildConfigurations.at(oldPos + 1), m_buildConfigurations.at(oldPos))) {
} else if (oldPos < m_projectConfigurations.size() - 1
&& ComparisonOperator(m_projectConfigurations.at(oldPos + 1), m_projectConfigurations.at(oldPos))) {
// We need to move down
int newPos = oldPos + 1;
while (newPos < m_buildConfigurations.size()
&& compare(m_buildConfigurations.at(newPos), m_buildConfigurations.at(oldPos))) {
while (newPos < m_projectConfigurations.size()
&& ComparisonOperator(m_projectConfigurations.at(newPos), m_projectConfigurations.at(oldPos))) {
++newPos;
}
beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos);
m_buildConfigurations.insert(newPos, rc);
m_buildConfigurations.removeAt(oldPos);
m_projectConfigurations.insert(newPos, pc);
m_projectConfigurations.removeAt(oldPos);
endMoveRows();
// We need to subtract one since removing at the old place moves the newIndex down
......@@ -123,62 +130,89 @@ void BuildConfigurationModel::displayNameChanged()
}
}
QVariant BuildConfigurationModel::data(const QModelIndex &index, int role) const
QVariant ProjectConfigurationModel::data(const QModelIndex &index, int role) const
{
if (role == Qt::DisplayRole) {
const int row = index.row();
if (row < m_buildConfigurations.size())
return m_buildConfigurations.at(row)->displayName();
if (row < m_projectConfigurations.size())
return m_projectConfigurations.at(row)->displayName();
}
return QVariant();
}
BuildConfiguration *BuildConfigurationModel::buildConfigurationAt(int i)
ProjectConfiguration *ProjectConfigurationModel::projectConfigurationAt(int i)
{
if (i > m_buildConfigurations.size() || i < 0)
return 0;
return m_buildConfigurations.at(i);
if (i > m_projectConfigurations.size() || i < 0)
return nullptr;
return m_projectConfigurations.at(i);
}
BuildConfiguration *BuildConfigurationModel::buildConfigurationFor(const QModelIndex &idx)
ProjectConfiguration *ProjectConfigurationModel::projectConfigurationFor(const QModelIndex &idx)
{
if (idx.row() > m_buildConfigurations.size() || idx.row() < 0)
return 0;
return m_buildConfigurations.at(idx.row());
if (idx.row() > m_projectConfigurations.size() || idx.row() < 0)
return nullptr;
return m_projectConfigurations.at(idx.row());
}
QModelIndex BuildConfigurationModel::indexFor(BuildConfiguration *rc)
QModelIndex ProjectConfigurationModel::indexFor(ProjectConfiguration *pc)
{
int idx = m_buildConfigurations.indexOf(rc);
int idx = m_projectConfigurations.indexOf(pc);
if (idx == -1)
return QModelIndex();
return index(idx, 0);
}
void BuildConfigurationModel::addedBuildConfiguration(BuildConfiguration *bc)
void ProjectConfigurationModel::addedProjectConfiguration(ProjectConfiguration *pc)
{
if (!m_filter(pc))
return;
// Find the right place to insert
BuildConfigurationComparer compare;
int i = 0;
for (; i < m_buildConfigurations.size(); ++i) {
if (compare(bc, m_buildConfigurations.at(i)))
for (; i < m_projectConfigurations.size(); ++i) {
if (ComparisonOperator(pc, m_projectConfigurations.at(i)))
break;
}
beginInsertRows(QModelIndex(), i, i);
m_buildConfigurations.insert(i, bc);
m_projectConfigurations.insert(i, pc);
endInsertRows();
connect(bc, &ProjectConfiguration::displayNameChanged,
this, &BuildConfigurationModel::displayNameChanged);
connect(pc, &ProjectConfiguration::displayNameChanged,
this, &ProjectConfigurationModel::displayNameChanged);
}
void BuildConfigurationModel::removedBuildConfiguration(BuildConfiguration *bc)
void ProjectConfigurationModel::removedProjectConfiguration(ProjectConfiguration *pc)
{
int i = m_buildConfigurations.indexOf(bc);
int i = m_projectConfigurations.indexOf(pc);
if (i < 0)
return;
beginRemoveRows(QModelIndex(), i, i);
m_buildConfigurations.removeAt(i);
m_projectConfigurations.removeAt(i);
endRemoveRows();
}
BuildConfigurationModel::BuildConfigurationModel(Target *t, QObject *parent) :
ProjectConfigurationModel(t,
[](const ProjectConfiguration *pc) {
return qobject_cast<const BuildConfiguration *>(pc) != nullptr;
},
parent)
{ }
DeployConfigurationModel::DeployConfigurationModel(Target *t, QObject *parent) :
ProjectConfigurationModel(t,
[](const ProjectConfiguration *pc) {
return qobject_cast<const DeployConfiguration *>(pc) != nullptr;
},
parent)
{ }
RunConfigurationModel::RunConfigurationModel(Target *t, QObject *parent) :
ProjectConfigurationModel(t,
[](const ProjectConfiguration *pc) {
return qobject_cast<const RunConfiguration *>(pc) != nullptr;
},
parent)
{ }
......@@ -27,32 +27,56 @@
#include <QAbstractItemModel>
#include <functional>
namespace ProjectExplorer {
class Target;
class RunConfiguration;
class ProjectConfiguration;
// Documentation inside.
class RunConfigurationModel : public QAbstractListModel
class ProjectConfigurationModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit RunConfigurationModel(Target *target, QObject *parent = nullptr);
using FilterFunction = std::function<bool(const ProjectConfiguration *)>;
explicit ProjectConfigurationModel(Target *target, FilterFunction filter,
QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
RunConfiguration *runConfigurationAt(int i);
RunConfiguration *runConfigurationFor(const QModelIndex &idx);
QModelIndex indexFor(RunConfiguration *rc);
ProjectConfiguration *projectConfigurationAt(int i);
ProjectConfiguration *projectConfigurationFor(const QModelIndex &idx);
QModelIndex indexFor(ProjectConfiguration *pc);
private:
void addedRunConfiguration(ProjectExplorer::RunConfiguration*);
void removedRunConfiguration(ProjectExplorer::RunConfiguration*);
void addedProjectConfiguration(ProjectConfiguration *pc);
void removedProjectConfiguration(ProjectConfiguration *pc);
void displayNameChanged();
Target *m_target;
QList<RunConfiguration *> m_runConfigurations;
FilterFunction m_filter;
QList<ProjectConfiguration *> m_projectConfigurations;
};
class BuildConfigurationModel : public ProjectConfigurationModel
{
public:
explicit BuildConfigurationModel(Target *t, QObject *parent = nullptr);
};
class DeployConfigurationModel : public ProjectConfigurationModel
{
public:
explicit DeployConfigurationModel(Target *t, QObject *parent = nullptr);
};
class RunConfigurationModel : public ProjectConfigurationModel
{
public:
explicit RunConfigurationModel(Target *t, QObject *parent = nullptr);
};
} // namespace ProjectExplorer
......@@ -33,11 +33,11 @@ HEADERS += projectexplorer.h \
kitmanagerconfigwidget.h \
kitmodel.h \
kitoptionspage.h \
projectconfigurationmodel.h \
buildmanager.h \
buildsteplist.h \
compileoutputwindow.h \
deployconfiguration.h \
deployconfigurationmodel.h \
namedwidget.h \
target.h \
targetsettingspanel.h \
......@@ -94,8 +94,6 @@ HEADERS += projectexplorer.h \
ldparser.h \
linuxiccparser.h \
runconfigurationaspects.h \
runconfigurationmodel.h \
buildconfigurationmodel.h \
processparameters.h \
abstractprocessstep.h \
taskhub.h \
......@@ -163,6 +161,7 @@ SOURCES += projectexplorer.cpp \
environmentaspectwidget.cpp \
gcctoolchain.cpp \
importwidget.cpp \
projectconfigurationmodel.cpp \
runnables.cpp \
localenvironmentaspect.cpp \
osparser.cpp \
......@@ -184,7 +183,6 @@ SOURCES += projectexplorer.cpp \
buildsteplist.cpp \
compileoutputwindow.cpp \
deployconfiguration.cpp \
deployconfigurationmodel.cpp \
namedwidget.cpp \
target.cpp \
targetsettingspanel.cpp \
......@@ -238,8 +236,6 @@ SOURCES += projectexplorer.cpp \
ldparser.cpp \
linuxiccparser.cpp \
runconfigurationaspects.cpp \
runconfigurationmodel.cpp \
buildconfigurationmodel.cpp \
taskhub.cpp \
processparameters.cpp \
appoutputpane.cpp \
......
......@@ -29,7 +29,6 @@ Project {
"appoutputpane.cpp", "appoutputpane.h",
"baseprojectwizarddialog.cpp", "baseprojectwizarddialog.h",
"buildconfiguration.cpp", "buildconfiguration.h",
"buildconfigurationmodel.cpp", "buildconfigurationmodel.h",