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 @@ ...@@ -29,7 +29,7 @@
#include "project.h" #include "project.h"
#include "target.h" #include "target.h"
#include "buildconfiguration.h" #include "buildconfiguration.h"
#include "buildconfigurationmodel.h" #include "projectconfigurationmodel.h"
#include "session.h" #include "session.h"
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
...@@ -218,7 +218,7 @@ void BuildSettingsWidget::updateBuildSettings() ...@@ -218,7 +218,7 @@ void BuildSettingsWidget::updateBuildSettings()
void BuildSettingsWidget::currentIndexChanged(int index) void BuildSettingsWidget::currentIndexChanged(int index)
{ {
auto model = static_cast<BuildConfigurationModel *>(m_buildConfigurationComboBox->model()); 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); 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 @@ ...@@ -23,9 +23,13 @@
** **
****************************************************************************/ ****************************************************************************/
#include "buildconfigurationmodel.h" #include "projectconfigurationmodel.h"
#include "target.h"
#include "buildconfiguration.h" #include "buildconfiguration.h"
#include "deployconfiguration.h"
#include "runconfiguration.h"
#include "target.h"
#include "projectconfiguration.h"
#include <utils/algorithm.h> #include <utils/algorithm.h>
...@@ -43,77 +47,80 @@ using namespace ProjectExplorer; ...@@ -43,77 +47,80 @@ using namespace ProjectExplorer;
TODO might it possible to share code without making the code a complete mess. TODO might it possible to share code without making the code a complete mess.
*/ */
class BuildConfigurationComparer namespace {
{
public: const auto ComparisonOperator =
bool operator()(BuildConfiguration *a, BuildConfiguration *b) [](const ProjectConfiguration *a, const ProjectConfiguration *b) {
{
return a->displayName() < b->displayName(); return a->displayName() < b->displayName();
} };
};
} // namespace
BuildConfigurationModel::BuildConfigurationModel(Target *target, QObject *parent) ProjectConfigurationModel::ProjectConfigurationModel(Target *target, FilterFunction filter,
: QAbstractListModel(parent), QObject *parent) :
m_target(target) QAbstractListModel(parent),
m_target(target),
m_filter(filter)
{ {
m_buildConfigurations = m_target->buildConfigurations(); m_projectConfigurations = Utils::filtered(m_target->projectConfigurations(), m_filter);
Utils::sort(m_buildConfigurations, BuildConfigurationComparer()); Utils::sort(m_projectConfigurations, ComparisonOperator);
connect(target, &Target::addedBuildConfiguration, connect(target, &Target::addedProjectConfiguration,
this, &BuildConfigurationModel::addedBuildConfiguration); this, &ProjectConfigurationModel::addedProjectConfiguration);
connect(target, &Target::removedBuildConfiguration, connect(target, &Target::removedProjectConfiguration,
this, &BuildConfigurationModel::removedBuildConfiguration); this, &ProjectConfigurationModel::removedProjectConfiguration);
foreach (BuildConfiguration *bc, m_buildConfigurations) foreach (ProjectConfiguration *pc, m_projectConfigurations)
connect(bc, &ProjectConfiguration::displayNameChanged, connect(pc, &ProjectConfiguration::displayNameChanged,
this, &BuildConfigurationModel::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; return parent.isValid() ? 0 : 1;
} }
void BuildConfigurationModel::displayNameChanged() void ProjectConfigurationModel::displayNameChanged()
{ {
auto rc = qobject_cast<BuildConfiguration *>(sender()); auto pc = qobject_cast<ProjectConfiguration *>(sender());
if (!rc) if (!pc)
return; return;
BuildConfigurationComparer compare;
// Find the old position // 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 // We need to move up
int newPos = oldPos - 1; 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;
} }
++newPos; ++newPos;
beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos); beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos);
m_buildConfigurations.insert(newPos, rc); m_projectConfigurations.insert(newPos, pc);
m_buildConfigurations.removeAt(oldPos + 1); m_projectConfigurations.removeAt(oldPos + 1);
endMoveRows(); endMoveRows();
// Not only did we move, we also changed... // Not only did we move, we also changed...
emit dataChanged(index(newPos, 0), index(newPos,0)); emit dataChanged(index(newPos, 0), index(newPos,0));
} else if (oldPos < m_buildConfigurations.size() - 1 } else if (oldPos < m_projectConfigurations.size() - 1
&& compare(m_buildConfigurations.at(oldPos + 1), m_buildConfigurations.at(oldPos))) { && ComparisonOperator(m_projectConfigurations.at(oldPos + 1), m_projectConfigurations.at(oldPos))) {
// We need to move down // We need to move down
int newPos = oldPos + 1; int newPos = oldPos + 1;
while (newPos < m_buildConfigurations.size() while (newPos < m_projectConfigurations.size()
&& compare(m_buildConfigurations.at(newPos), m_buildConfigurations.at(oldPos))) { && ComparisonOperator(m_projectConfigurations.at(newPos), m_projectConfigurations.at(oldPos))) {
++newPos; ++newPos;
} }
beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos); beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos);
m_buildConfigurations.insert(newPos, rc); m_projectConfigurations.insert(newPos, pc);
m_buildConfigurations.removeAt(oldPos); m_projectConfigurations.removeAt(oldPos);
endMoveRows(); endMoveRows();
// We need to subtract one since removing at the old place moves the newIndex down // We need to subtract one since removing at the old place moves the newIndex down
...@@ -123,62 +130,89 @@ void BuildConfigurationModel::displayNameChanged() ...@@ -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) { if (role == Qt::DisplayRole) {
const int row = index.row(); const int row = index.row();
if (row < m_buildConfigurations.size()) if (row < m_projectConfigurations.size())
return m_buildConfigurations.at(row)->displayName(); return m_projectConfigurations.at(row)->displayName();
} }
return QVariant(); return QVariant();
} }
BuildConfiguration *BuildConfigurationModel::buildConfigurationAt(int i) ProjectConfiguration *ProjectConfigurationModel::projectConfigurationAt(int i)
{ {
if (i > m_buildConfigurations.size() || i < 0) if (i > m_projectConfigurations.size() || i < 0)
return 0; return nullptr;
return m_buildConfigurations.at(i); 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) if (idx.row() > m_projectConfigurations.size() || idx.row() < 0)
return 0; return nullptr;
return m_buildConfigurations.at(idx.row()); 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) if (idx == -1)
return QModelIndex(); return QModelIndex();
return index(idx, 0); 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 // Find the right place to insert
BuildConfigurationComparer compare;
int i = 0; int i = 0;
for (; i < m_buildConfigurations.size(); ++i) { for (; i < m_projectConfigurations.size(); ++i) {
if (compare(bc, m_buildConfigurations.at(i))) if (ComparisonOperator(pc, m_projectConfigurations.at(i)))
break; break;
} }
beginInsertRows(QModelIndex(), i, i); beginInsertRows(QModelIndex(), i, i);
m_buildConfigurations.insert(i, bc); m_projectConfigurations.insert(i, pc);
endInsertRows(); endInsertRows();
connect(pc, &ProjectConfiguration::displayNameChanged,
connect(bc, &ProjectConfiguration::displayNameChanged, this, &ProjectConfigurationModel::displayNameChanged);
this, &BuildConfigurationModel::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); beginRemoveRows(QModelIndex(), i, i);
m_buildConfigurations.removeAt(i); m_projectConfigurations.removeAt(i);