CMake: Group entries in project configuration

Change-Id: I6aa797f5ff49a5cc33dfbdf0b25dcd78abbff66e
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Tobias Hunger
2017-09-05 13:55:08 +02:00
parent 8e96bc9176
commit cacb6b17d0
3 changed files with 327 additions and 253 deletions

View File

@@ -139,21 +139,23 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
connect(tree, &Utils::TreeView::activated, connect(tree, &Utils::TreeView::activated,
tree, [tree](const QModelIndex &idx) { tree->edit(idx); }); tree, [tree](const QModelIndex &idx) { tree->edit(idx); });
m_configView = tree; m_configView = tree;
m_configFilterModel->setSourceModel(m_configModel); m_configFilterModel->setSourceModel(m_configModel);
m_configFilterModel->setFilterKeyColumn(2); m_configFilterModel->setFilterKeyColumn(0);
m_configFilterModel->setFilterFixedString(QLatin1String("0")); m_configFilterModel->setFilterRole(ConfigModel::ItemIsAdvancedRole);
m_configFilterModel->setFilterFixedString("0");
m_configTextFilterModel->setSourceModel(m_configFilterModel); m_configTextFilterModel->setSourceModel(m_configFilterModel);
m_configTextFilterModel->setFilterKeyColumn(-1); m_configTextFilterModel->setFilterKeyColumn(-1);
m_configTextFilterModel->setFilterCaseSensitivity(Qt::CaseInsensitive); m_configTextFilterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
m_configView->setModel(m_configTextFilterModel); m_configView->setModel(m_configTextFilterModel);
m_configView->setMinimumHeight(300); m_configView->setMinimumHeight(300);
m_configView->setRootIsDecorated(false);
m_configView->setUniformRowHeights(true); m_configView->setUniformRowHeights(true);
auto stretcher = new Utils::HeaderViewStretcher(m_configView->header(), 1); auto stretcher = new Utils::HeaderViewStretcher(m_configView->header(), 1);
m_configView->setSelectionMode(QAbstractItemView::SingleSelection); m_configView->setSelectionMode(QAbstractItemView::SingleSelection);
m_configView->setSelectionBehavior(QAbstractItemView::SelectItems); m_configView->setSelectionBehavior(QAbstractItemView::SelectItems);
m_configView->setFrameShape(QFrame::NoFrame); m_configView->setFrameShape(QFrame::NoFrame);
m_configView->hideColumn(2); // Hide isAdvanced column
m_configView->setItemDelegate(new ConfigModelItemDelegate(m_configView)); m_configView->setItemDelegate(new ConfigModelItemDelegate(m_configView));
QFrame *findWrapper = Core::ItemViewFind::createSearchableWrapper(m_configView, Core::ItemViewFind::LightColored); QFrame *findWrapper = Core::ItemViewFind::createSearchableWrapper(m_configView, Core::ItemViewFind::LightColored);
findWrapper->setFrameStyle(QFrame::StyledPanel); findWrapper->setFrameStyle(QFrame::StyledPanel);
@@ -311,8 +313,10 @@ void CMakeBuildSettingsWidget::updateButtonState()
void CMakeBuildSettingsWidget::updateAdvancedCheckBox() void CMakeBuildSettingsWidget::updateAdvancedCheckBox()
{ {
// Switch between Qt::DisplayRole (everything is "0") and Qt::EditRole (advanced is "1"). if (m_showAdvancedCheckBox->isChecked())
m_configFilterModel->setFilterRole(m_showAdvancedCheckBox->isChecked() ? Qt::EditRole : Qt::DisplayRole); m_configTextFilterModel->setSourceModel(m_configModel);
else
m_configTextFilterModel->setSourceModel(m_configFilterModel);
} }
void CMakeBuildSettingsWidget::updateFromKit() void CMakeBuildSettingsWidget::updateFromKit()

View File

@@ -25,12 +25,14 @@
#include "configmodel.h" #include "configmodel.h"
#include <utils/asconst.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/theme/theme.h> #include <utils/theme/theme.h>
#include <QCoreApplication> #include <QCoreApplication>
#include <QFont> #include <QFont>
#include <QString>
namespace CMakeProjectManager { namespace CMakeProjectManager {
@@ -41,186 +43,27 @@ static bool isTrue(const QString &value)
|| lower == QStringLiteral("1") || lower == QStringLiteral("yes"); || lower == QStringLiteral("1") || lower == QStringLiteral("yes");
} }
ConfigModel::ConfigModel(QObject *parent) : QAbstractTableModel(parent) ConfigModel::ConfigModel(QObject *parent) : Utils::TreeModel<>(parent)
{ }
int ConfigModel::rowCount(const QModelIndex &parent) const
{ {
return parent.isValid() ? 0 : m_configuration.count(); setHeader({tr("Key"), tr("Value")});
} }
int ConfigModel::columnCount(const QModelIndex &parent) const QVariant ConfigModel::data(const QModelIndex &idx, int role) const
{ {
return parent.isValid() ? 0 : 3; // Hide/show groups according to "isAdvanced" setting:
} Utils::TreeItem *item = static_cast<Utils::TreeItem *>(idx.internalPointer());
if (role == ItemIsAdvancedRole && item->childCount() > 0) {
Qt::ItemFlags ConfigModel::flags(const QModelIndex &index) const const bool hasNormalChildren = item->findAnyChild([](const Utils::TreeItem *ti) {
{ if (auto cmti = dynamic_cast<const Internal::ConfigModelTreeItem*>(ti))
QTC_ASSERT(index.model() == this, return Qt::NoItemFlags); return !cmti->dataItem->isAdvanced;
QTC_ASSERT(index.isValid(), return Qt::NoItemFlags);
QTC_ASSERT(index.column() >= 0 && index.column() < columnCount(QModelIndex()), return Qt::NoItemFlags);
QTC_ASSERT(index.row() >= 0 && index.row() < rowCount(QModelIndex()), return Qt::NoItemFlags);
const InternalDataItem &item = itemAtRow(index.row());
if (index.column() == 1) {
if (item.type == DataItem::BOOLEAN)
return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable;
else
return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
} else {
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
if (item.isUserNew)
return flags |= Qt::ItemIsEditable;
return flags;
}
}
QVariant ConfigModel::data(const QModelIndex &index, int role) const
{
QTC_ASSERT(index.model() == this, return QVariant());
QTC_ASSERT(index.isValid(), return QVariant());
QTC_ASSERT(index.row() >= 0 && index.row() < rowCount(QModelIndex()), return QVariant());
QTC_ASSERT(index.column() >= 0 && index.column() < columnCount(QModelIndex()), return QVariant());
const InternalDataItem &item = m_configuration[index.row()];
if (index.column() < 2) {
switch (role) {
case ItemTypeRole:
return item.type;
case ItemValuesRole:
return item.values;
}
}
switch (index.column()) {
case 0:
switch (role) {
case Qt::DisplayRole:
return item.key.isEmpty() ? tr("<UNSET>") : item.key;
case Qt::EditRole:
return item.key;
case Qt::ToolTipRole:
return item.toolTip();
case Qt::FontRole: {
QFont font;
font.setItalic(item.isCMakeChanged);
font.setBold(item.isUserNew);
font.setStrikeOut(!item.inCMakeCache && !item.isUserNew);
return font;
}
default:
return QVariant();
}
case 1: {
const QString value = item.currentValue();
const QString kitValue = m_kitConfiguartion.value(item.key);
switch (role) {
case Qt::CheckStateRole:
return (item.type == DataItem::BOOLEAN)
? QVariant(isTrue(value) ? Qt::Checked : Qt::Unchecked) : QVariant();
case Qt::DisplayRole:
return value;
case Qt::EditRole:
return (item.type == DataItem::BOOLEAN) ? QVariant(isTrue(value)) : QVariant(value);
case Qt::FontRole: {
QFont font;
font.setBold(item.isUserChanged || item.isUserNew);
font.setItalic(item.isCMakeChanged);
return font;
}
case Qt::ForegroundRole:
return Utils::creatorTheme()->color((!kitValue.isNull() && kitValue != value)
? Utils::Theme::TextColorHighlight : Utils::Theme::TextColorNormal);
case Qt::ToolTipRole: {
QString tooltip = item.toolTip();
const QString kitValue = m_kitConfiguartion.value(item.key);
if (!kitValue.isNull()) {
if (!tooltip.isEmpty())
tooltip.append("<br>");
tooltip.append(tr("Kit value: %1").arg(kitValue));
}
return tooltip;
}
default:
return QVariant();
}
}
case 2:
switch (role) {
case Qt::EditRole:
return "0";
case Qt::DisplayRole:
return QString::fromLatin1(item.isAdvanced ? "1" : "0");
case Qt::CheckStateRole:
return item.isAdvanced ? Qt::Checked : Qt::Unchecked;
default:
return QVariant();
}
default:
return QVariant();
}
}
bool ConfigModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
QTC_ASSERT(index.model() == this, return false);
QTC_ASSERT(index.isValid(), return false);
QTC_ASSERT(index.row() >= 0 && index.row() < rowCount(QModelIndex()), return false);
QTC_ASSERT(index.column() >= 0 && index.column() < 2, return false);
QString newValue = value.toString();
if (role == Qt::CheckStateRole) {
if (index.column() != 1)
return false;
newValue = QString::fromLatin1(value.toInt() == 0 ? "OFF" : "ON");
} else if (role != Qt::EditRole) {
return false;
}
InternalDataItem &item = itemAtRow(index.row());
switch (index.column()) {
case 0:
if (!item.key.isEmpty() && !item.isUserNew)
return false;
item.key = newValue;
item.isUserNew = true;
item.isUserChanged = false;
emit dataChanged(index, index);
return true;
case 1:
if (item.value == newValue) {
item.newValue.clear();
item.isUserChanged = false;
} else {
item.newValue = newValue;
item.isUserChanged = true;
}
emit dataChanged(index, index);
return true;
case 2:
default:
return false; return false;
}) != nullptr;
return hasNormalChildren ? "0" : "1";
} }
return Utils::TreeModel<>::data(idx, role);
} }
QVariant ConfigModel::headerData(int section, Qt::Orientation orientation, int role) const ConfigModel::~ConfigModel() = default;
{
if (orientation == Qt::Vertical || role != Qt::DisplayRole)
return QVariant();
switch (section) {
case 0:
return tr("Setting");
case 1:
return tr("Value");
case 2:
return tr("Advanced");
default:
return QVariant();
}
}
void ConfigModel::appendConfiguration(const QString &key, void ConfigModel::appendConfiguration(const QString &key,
const QString &value, const QString &value,
@@ -238,70 +81,33 @@ void ConfigModel::appendConfiguration(const QString &key,
InternalDataItem internalItem(item); InternalDataItem internalItem(item);
internalItem.isUserNew = true; internalItem.isUserNew = true;
beginResetModel(); if (m_kitConfiguration.contains(key))
internalItem.kitValue = m_kitConfiguration.value(key);
m_configuration.append(internalItem); m_configuration.append(internalItem);
endResetModel(); setConfiguration(m_configuration);
} }
void ConfigModel::setConfiguration(const QList<ConfigModel::DataItem> &config) void ConfigModel::setConfiguration(const QList<DataItem> &config)
{ {
QList<DataItem> tmp = config; setConfiguration(Utils::transform(config, [](const DataItem &di) { return InternalDataItem(di); }));
Utils::sort(tmp,
[](const ConfigModel::DataItem &i, const ConfigModel::DataItem &j) {
return i.key < j.key;
});
auto newIt = tmp.constBegin();
auto newEndIt = tmp.constEnd();
auto oldIt = m_configuration.constBegin();
auto oldEndIt = m_configuration.constEnd();
QList<InternalDataItem> result;
while (newIt != newEndIt && oldIt != oldEndIt) {
if (newIt->isHidden) {
++newIt;
} else if (newIt->key < oldIt->key) {
// Add new entry:
result << InternalDataItem(*newIt);
++newIt;
} else if (newIt->key > oldIt->key) {
// Keep old user settings, but skip other entries:
if (oldIt->isUserChanged || oldIt->isUserNew)
result << InternalDataItem(*oldIt);
++oldIt;
} else {
// merge old/new entry:
InternalDataItem item(*newIt);
item.newValue = (newIt->value != oldIt->newValue) ? oldIt->newValue : QString();
item.isCMakeChanged = (oldIt->value != newIt->value);
item.isUserChanged = !item.newValue.isEmpty() && (item.newValue != item.value);
result << item;
++newIt;
++oldIt;
}
}
// Add remaining new entries:
for (; newIt != newEndIt; ++newIt) {
if (newIt->isHidden)
continue;
result << InternalDataItem(*newIt);
}
beginResetModel();
m_configuration = result;
endResetModel();
} }
void ConfigModel::setKitConfiguration(const QHash<QString, QString> &kitConfig) void ConfigModel::setKitConfiguration(const QHash<QString, QString> &kitConfig)
{ {
m_kitConfiguartion = kitConfig; m_kitConfiguration = kitConfig;
for (InternalDataItem &i : m_configuration) {
if (m_kitConfiguration.contains(i.key)) {
i.kitValue = m_kitConfiguration.value(i.key);
}
}
setConfiguration(m_configuration);
} }
void ConfigModel::flush() void ConfigModel::flush()
{ {
beginResetModel(); setConfiguration(QList<InternalDataItem>());
m_configuration.clear();
endResetModel();
} }
void ConfigModel::resetAllChanges() void ConfigModel::resetAllChanges()
@@ -310,14 +116,12 @@ void ConfigModel::resetAllChanges()
= Utils::filtered(m_configuration, = Utils::filtered(m_configuration,
[](const InternalDataItem &i) { return !i.isUserNew; }); [](const InternalDataItem &i) { return !i.isUserNew; });
beginResetModel(); setConfiguration(Utils::transform(tmp, [](const InternalDataItem &i) {
m_configuration = Utils::transform(tmp, [](const InternalDataItem &i) -> InternalDataItem {
InternalDataItem ni(i); InternalDataItem ni(i);
ni.newValue.clear(); ni.newValue.clear();
ni.isUserChanged = false; ni.isUserChanged = false;
return ni; return ni;
}); }));
endResetModel();
} }
bool ConfigModel::hasChanges() const bool ConfigModel::hasChanges() const
@@ -344,16 +148,101 @@ QList<ConfigModel::DataItem> ConfigModel::configurationChanges() const
}); });
} }
ConfigModel::InternalDataItem &ConfigModel::itemAtRow(int row) void ConfigModel::setConfiguration(const QList<ConfigModel::InternalDataItem> &config)
{ {
QTC_CHECK(row >= 0); QList<InternalDataItem> tmp = config;
return m_configuration[row]; Utils::sort(tmp,
[](const ConfigModel::InternalDataItem &i, const ConfigModel::InternalDataItem &j) {
return i.key < j.key;
});
auto newIt = tmp.constBegin();
auto newEndIt = tmp.constEnd();
auto oldIt = m_configuration.constBegin();
auto oldEndIt = m_configuration.constEnd();
QList<InternalDataItem> result;
while (newIt != newEndIt && oldIt != oldEndIt) {
if (newIt->isHidden) {
++newIt;
} else if (newIt->key < oldIt->key) {
// Add new entry:
result << *newIt;
++newIt;
} else if (newIt->key > oldIt->key) {
// Keep old user settings, but skip other entries:
if (oldIt->isUserChanged || oldIt->isUserNew)
result << InternalDataItem(*oldIt);
++oldIt;
} else {
// merge old/new entry:
InternalDataItem item(*newIt);
item.newValue = (newIt->value != oldIt->newValue) ? oldIt->newValue : QString();
item.isCMakeChanged = (oldIt->value != newIt->value);
item.isUserChanged = !item.newValue.isEmpty() && (item.newValue != item.value);
result << item;
++newIt;
++oldIt;
}
}
// Add remaining new entries:
for (; newIt != newEndIt; ++newIt) {
if (newIt->isHidden)
continue;
result << InternalDataItem(*newIt);
}
m_configuration = result;
generateTree();
} }
const ConfigModel::InternalDataItem &ConfigModel::itemAtRow(int row) const static QString prefix(const QString &key)
{ {
QTC_CHECK(row >= 0); int pos = key.indexOf('_');
return m_configuration[row]; if (pos > 0)
return key.left(pos);
return key;
}
void ConfigModel::generateTree()
{
QList<QString> prefixList;
// Generate nodes for *all* prefixes
QHash<QString, QList<Utils::TreeItem *>> prefixes;
for (const InternalDataItem &di : m_configuration) {
const QString p = prefix(di.key);
if (!prefixes.contains(p)) {
prefixes.insert(p, {});
prefixList.append(p);
}
}
// Fill prefix nodes:
for (InternalDataItem &di : m_configuration)
prefixes[prefix(di.key)].append(new Internal::ConfigModelTreeItem(&di));
Utils::TreeItem *root = new Utils::TreeItem;
for (const QString &p : Utils::asConst(prefixList)) {
const QList<Utils::TreeItem *> &prefixItemList = prefixes.value(p);
QTC_ASSERT(!prefixItemList.isEmpty(), continue);
if (prefixItemList.count() == 1) {
root->appendChild(prefixItemList.at(0));
} else {
Utils::TreeItem *sti = new Utils::StaticTreeItem(p);
for (Utils::TreeItem *const ti : prefixItemList)
sti->appendChild(ti);
root->appendChild(sti);
}
prefixes.remove(p);
}
QTC_CHECK(prefixes.isEmpty());
setRootItem(root);
} }
ConfigModel::InternalDataItem::InternalDataItem(const ConfigModel::DataItem &item) : DataItem(item) ConfigModel::InternalDataItem::InternalDataItem(const ConfigModel::DataItem &item) : DataItem(item)
@@ -361,13 +250,18 @@ ConfigModel::InternalDataItem::InternalDataItem(const ConfigModel::DataItem &ite
QString ConfigModel::InternalDataItem::toolTip() const QString ConfigModel::InternalDataItem::toolTip() const
{ {
QStringList tooltip(description); QString desc = description;
if (isAdvanced)
desc += QCoreApplication::translate("CMakeProjectManager::ConfigModel", " (ADVANCED)");
QStringList tooltip(desc);
if (inCMakeCache) { if (inCMakeCache) {
if (value != newValue) if (value != newValue)
tooltip << QCoreApplication::translate("CMakeProjectManager", "Current CMake: %1").arg(value); tooltip << QCoreApplication::translate("CMakeProjectManager", "Current CMake: %1").arg(value);
} else { } else {
tooltip << QCoreApplication::translate("CMakeProjectManager", "Not in CMakeCache.txt").arg(value); tooltip << QCoreApplication::translate("CMakeProjectManager", "Not in CMakeCache.txt").arg(value);
} }
if (!kitValue.isEmpty())
tooltip << QCoreApplication::translate("CMakeProjectManager::ConfigModel", "Current Kit: %1").arg(kitValue);
return tooltip.join("<br>"); return tooltip.join("<br>");
} }
@@ -376,4 +270,158 @@ QString ConfigModel::InternalDataItem::currentValue() const
return isUserChanged ? newValue : value; return isUserChanged ? newValue : value;
} }
namespace Internal {
ConfigModelTreeItem::~ConfigModelTreeItem() = default;
QVariant ConfigModelTreeItem::data(int column, int role) const
{
QTC_ASSERT(column >= 0 && column < 2, return QVariant());
QTC_ASSERT(dataItem, return QVariant());
if (firstChild()) {
// Node with children: Only ever show name:
if (column == 0)
return dataItem->key;
return QVariant();
}
// Leaf node:
if (role == ConfigModel::ItemTypeRole)
return dataItem->type;
if (role == ConfigModel::ItemValuesRole)
return dataItem->values;
if (role == ConfigModel::ItemIsAdvancedRole)
return dataItem->isAdvanced ? "1" : "0";
switch (column) {
case 0:
switch (role) {
case Qt::DisplayRole:
return dataItem->key.isEmpty() ? QCoreApplication::translate("CMakeProjectManager::ConfigModel", "<UNSET>") : dataItem->key;
case Qt::EditRole:
return dataItem->key;
case Qt::ToolTipRole:
return toolTip();
case Qt::FontRole: {
QFont font;
font.setItalic(dataItem->isCMakeChanged);
font.setBold(dataItem->isUserNew);
font.setStrikeOut(!dataItem->inCMakeCache && !dataItem->isUserNew);
return font;
}
default:
return QVariant();
}
case 1: {
const QString value = currentValue();
switch (role) {
case Qt::CheckStateRole:
return (dataItem->type == ConfigModel::DataItem::BOOLEAN)
? QVariant(isTrue(value) ? Qt::Checked : Qt::Unchecked) : QVariant();
case Qt::DisplayRole:
return value;
case Qt::EditRole:
return (dataItem->type == ConfigModel::DataItem::BOOLEAN) ? QVariant(isTrue(value)) : QVariant(value);
case Qt::FontRole: {
QFont font;
font.setBold(dataItem->isUserChanged || dataItem->isUserNew);
font.setItalic(dataItem->isCMakeChanged);
return font;
}
case Qt::ForegroundRole:
return Utils::creatorTheme()->color((!dataItem->kitValue.isNull() && dataItem->kitValue != value)
? Utils::Theme::TextColorHighlight : Utils::Theme::TextColorNormal);
case Qt::ToolTipRole: {
return toolTip();
}
default:
return QVariant();
}
}
default:
return QVariant();
}
}
bool ConfigModelTreeItem::setData(int column, const QVariant &value, int role)
{
QTC_ASSERT(column >= 0 && column < 2, return false);
QTC_ASSERT(dataItem, return false);
QString newValue = value.toString();
if (role == Qt::CheckStateRole) {
if (column != 1)
return false;
newValue = QString::fromLatin1(value.toInt() == 0 ? "OFF" : "ON");
} else if (role != Qt::EditRole) {
return false;
}
switch (column) {
case 0:
if (!dataItem->key.isEmpty() && !dataItem->isUserNew)
return false;
dataItem->key = newValue;
dataItem->isUserNew = true;
dataItem->isUserChanged = false;
return true;
case 1:
if (dataItem->value == newValue) {
dataItem->newValue.clear();
dataItem->isUserChanged = false;
} else {
dataItem->newValue = newValue;
dataItem->isUserChanged = true;
}
return true;
default:
return false;
}
}
Qt::ItemFlags ConfigModelTreeItem::flags(int column) const
{
if (column < 0 || column >= 2)
return Qt::NoItemFlags;
QTC_ASSERT(dataItem, return Qt::NoItemFlags);
if (column == 1) {
if (dataItem->type == ConfigModel::DataItem::BOOLEAN)
return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable;
else
return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
} else {
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
if (dataItem->isUserNew)
return flags |= Qt::ItemIsEditable;
return flags;
}
}
QString ConfigModelTreeItem::toolTip() const
{
QTC_ASSERT(dataItem, return QString());
QStringList tooltip(dataItem->description);
if (!dataItem->kitValue.isEmpty())
tooltip << QCoreApplication::translate("CMakeProjectManager", "Value requested by Kit: %1").arg(dataItem->kitValue);
if (dataItem->inCMakeCache) {
if (dataItem->value != dataItem->newValue)
tooltip << QCoreApplication::translate("CMakeProjectManager", "Current CMake: %1").arg(dataItem->value);
} else {
tooltip << QCoreApplication::translate("CMakeProjectManager", "Not in CMakeCache.txt");
}
return tooltip.join("<br>");
}
QString ConfigModelTreeItem::currentValue() const
{
QTC_ASSERT(dataItem, return QString());
return dataItem->isUserChanged ? dataItem->newValue : dataItem->value;
}
} // namespace Internal
} // namespace CMakeProjectManager } // namespace CMakeProjectManager

View File

@@ -26,17 +26,21 @@
#pragma once #pragma once
#include <QAbstractTableModel> #include <QAbstractTableModel>
#include <utils/treemodel.h>
namespace CMakeProjectManager { namespace CMakeProjectManager {
class ConfigModel : public QAbstractTableModel namespace Internal { class ConfigModelTreeItem; }
class ConfigModel : public Utils::TreeModel<>
{ {
Q_OBJECT Q_OBJECT
public: public:
enum Roles { enum Roles {
ItemTypeRole = Qt::UserRole, ItemTypeRole = Qt::UserRole,
ItemValuesRole ItemValuesRole,
ItemIsAdvancedRole
}; };
class DataItem { class DataItem {
@@ -54,14 +58,9 @@ public:
}; };
explicit ConfigModel(QObject *parent = nullptr); explicit ConfigModel(QObject *parent = nullptr);
~ConfigModel() override;
// QAbstractItemModel interface QVariant data(const QModelIndex &idx, int role) const final;
int rowCount(const QModelIndex &parent) const override;
int columnCount(const QModelIndex &parent) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
QVariant data(const QModelIndex &index, int role) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
void appendConfiguration(const QString &key, void appendConfiguration(const QString &key,
const QString &value = QString(), const QString &value = QString(),
@@ -92,12 +91,35 @@ private:
bool isUserNew = false; bool isUserNew = false;
bool isCMakeChanged = false; bool isCMakeChanged = false;
QString newValue; QString newValue;
QString kitValue;
}; };
InternalDataItem &itemAtRow(int row); void setConfiguration(const QList<InternalDataItem> &config);
const InternalDataItem &itemAtRow(int row) const; void generateTree();
QList<InternalDataItem> m_configuration; QList<InternalDataItem> m_configuration;
QHash<QString, QString> m_kitConfiguartion; QHash<QString, QString> m_kitConfiguration;
friend class Internal::ConfigModelTreeItem;
}; };
namespace Internal {
class ConfigModelTreeItem : public Utils::TreeItem
{
public:
ConfigModelTreeItem(ConfigModel::InternalDataItem *di = nullptr) : dataItem(di) {}
virtual ~ConfigModelTreeItem() override;
QVariant data(int column, int role) const final;
bool setData(int column, const QVariant &data, int role) final;
Qt::ItemFlags flags(int column) const final;
QString toolTip() const;
QString currentValue() const;
ConfigModel::InternalDataItem *dataItem;
};
} // namespace Internal
} // namespace CMakeProjectManager } // namespace CMakeProjectManager