2016-01-27 10:22:07 +01:00
|
|
|
/****************************************************************************
|
|
|
|
|
**
|
|
|
|
|
** 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 "configmodel.h"
|
|
|
|
|
|
|
|
|
|
#include <utils/algorithm.h>
|
2022-01-24 13:41:13 +01:00
|
|
|
#include <utils/macroexpander.h>
|
2016-01-27 10:22:07 +01:00
|
|
|
#include <utils/qtcassert.h>
|
2017-01-18 16:56:00 +01:00
|
|
|
#include <utils/theme/theme.h>
|
2016-01-27 10:22:07 +01:00
|
|
|
|
2016-12-01 15:24:36 +01:00
|
|
|
#include <QCoreApplication>
|
2016-01-27 10:22:07 +01:00
|
|
|
#include <QFont>
|
2017-09-14 15:18:50 +02:00
|
|
|
#include <QSortFilterProxyModel>
|
2016-01-27 10:22:07 +01:00
|
|
|
|
|
|
|
|
namespace CMakeProjectManager {
|
|
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
ConfigModel::ConfigModel(QObject *parent) : Utils::TreeModel<>(parent)
|
2016-01-27 10:22:07 +01:00
|
|
|
{
|
2017-09-05 13:55:08 +02:00
|
|
|
setHeader({tr("Key"), tr("Value")});
|
2016-01-27 10:22:07 +01:00
|
|
|
}
|
|
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
QVariant ConfigModel::data(const QModelIndex &idx, int role) const
|
2016-01-27 10:22:07 +01:00
|
|
|
{
|
2017-09-05 13:55:08 +02:00
|
|
|
// Hide/show groups according to "isAdvanced" setting:
|
2018-11-04 23:09:41 +01:00
|
|
|
auto item = static_cast<const Utils::TreeItem *>(idx.internalPointer());
|
2017-09-05 13:55:08 +02:00
|
|
|
if (role == ItemIsAdvancedRole && item->childCount() > 0) {
|
|
|
|
|
const bool hasNormalChildren = item->findAnyChild([](const Utils::TreeItem *ti) {
|
|
|
|
|
if (auto cmti = dynamic_cast<const Internal::ConfigModelTreeItem*>(ti))
|
|
|
|
|
return !cmti->dataItem->isAdvanced;
|
|
|
|
|
return false;
|
|
|
|
|
}) != nullptr;
|
|
|
|
|
return hasNormalChildren ? "0" : "1";
|
|
|
|
|
}
|
2021-12-28 21:42:29 +01:00
|
|
|
if (role == ItemIsInitialRole && item->childCount() > 0) {
|
|
|
|
|
const bool hasInitialChildren = item->findAnyChild([](const Utils::TreeItem *ti) {
|
|
|
|
|
if (auto cmti = dynamic_cast<const Internal::ConfigModelTreeItem*>(ti))
|
|
|
|
|
return cmti->dataItem->isInitial;
|
|
|
|
|
return false;
|
|
|
|
|
}) != nullptr;
|
|
|
|
|
return hasInitialChildren ? "1" : "0";
|
|
|
|
|
}
|
2017-09-05 13:55:08 +02:00
|
|
|
return Utils::TreeModel<>::data(idx, role);
|
2016-01-27 10:22:07 +01:00
|
|
|
}
|
|
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
ConfigModel::~ConfigModel() = default;
|
|
|
|
|
|
|
|
|
|
void ConfigModel::appendConfiguration(const QString &key,
|
|
|
|
|
const QString &value,
|
2021-12-28 21:42:29 +01:00
|
|
|
const ConfigModel::DataItem::Type type, bool isInitial,
|
2017-09-05 13:55:08 +02:00
|
|
|
const QString &description,
|
|
|
|
|
const QStringList &values)
|
2016-01-27 10:22:07 +01:00
|
|
|
{
|
2017-09-05 13:55:08 +02:00
|
|
|
DataItem item;
|
|
|
|
|
item.key = key;
|
|
|
|
|
item.type = type;
|
|
|
|
|
item.value = value;
|
2021-12-28 21:42:29 +01:00
|
|
|
item.isInitial = isInitial;
|
2017-09-05 13:55:08 +02:00
|
|
|
item.description = description;
|
|
|
|
|
item.values = values;
|
2016-01-27 10:22:07 +01:00
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
InternalDataItem internalItem(item);
|
|
|
|
|
internalItem.isUserNew = true;
|
2016-01-27 10:22:07 +01:00
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
if (m_kitConfiguration.contains(key))
|
2021-12-28 21:42:29 +01:00
|
|
|
internalItem.kitValue = isInitial ? m_kitConfiguration.value(key).first
|
|
|
|
|
: m_kitConfiguration.value(key).second;
|
2017-09-05 13:55:08 +02:00
|
|
|
|
|
|
|
|
m_configuration.append(internalItem);
|
|
|
|
|
setConfiguration(m_configuration);
|
2016-01-27 10:22:07 +01:00
|
|
|
}
|
|
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
void ConfigModel::setConfiguration(const QList<DataItem> &config)
|
2016-01-27 10:22:07 +01:00
|
|
|
{
|
2017-09-05 13:55:08 +02:00
|
|
|
setConfiguration(Utils::transform(config, [](const DataItem &di) { return InternalDataItem(di); }));
|
|
|
|
|
}
|
2016-10-10 09:49:46 +10:00
|
|
|
|
2021-12-28 21:42:29 +01:00
|
|
|
void ConfigModel::setConfigurationFromKit(const KitConfiguration &kitConfig)
|
2017-09-05 13:55:08 +02:00
|
|
|
{
|
|
|
|
|
m_kitConfiguration = kitConfig;
|
2017-01-18 16:56:00 +01:00
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
for (InternalDataItem &i : m_configuration) {
|
2017-09-29 23:34:52 +02:00
|
|
|
if (m_kitConfiguration.contains(i.key))
|
2021-12-28 21:42:29 +01:00
|
|
|
i.kitValue = i.isInitial ? m_kitConfiguration.value(i.key).first
|
|
|
|
|
: m_kitConfiguration.value(i.key).second;
|
2017-09-29 23:34:52 +02:00
|
|
|
}
|
|
|
|
|
setConfiguration(m_configuration);
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
void ConfigModel::flush()
|
2016-01-27 10:22:07 +01:00
|
|
|
{
|
2017-09-05 13:55:08 +02:00
|
|
|
setConfiguration(QList<InternalDataItem>());
|
|
|
|
|
}
|
2016-01-27 10:22:07 +01:00
|
|
|
|
2021-12-28 21:42:29 +01:00
|
|
|
void ConfigModel::resetAllChanges(bool initialParameters)
|
2017-09-05 13:55:08 +02:00
|
|
|
{
|
2021-12-28 21:42:29 +01:00
|
|
|
QList<InternalDataItem> notNew
|
2017-09-05 13:55:08 +02:00
|
|
|
= Utils::filtered(m_configuration,
|
|
|
|
|
[](const InternalDataItem &i) { return !i.isUserNew; });
|
2016-01-27 10:22:07 +01:00
|
|
|
|
2021-12-28 21:42:29 +01:00
|
|
|
notNew = Utils::transform(notNew, [](const InternalDataItem &i) {
|
2017-09-05 13:55:08 +02:00
|
|
|
InternalDataItem ni(i);
|
|
|
|
|
ni.newValue.clear();
|
|
|
|
|
ni.isUserChanged = false;
|
2017-09-27 12:28:11 +02:00
|
|
|
ni.isUnset = false;
|
2017-09-05 13:55:08 +02:00
|
|
|
return ni;
|
2021-12-28 21:42:29 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// add the changes from the other list, which shouldn't get reset
|
|
|
|
|
notNew.append(Utils::filtered(m_configuration, [initialParameters](const InternalDataItem &i) {
|
|
|
|
|
return !(initialParameters ? i.isInitial : !i.isInitial) && i.isUserNew;
|
2017-09-05 13:55:08 +02:00
|
|
|
}));
|
2021-12-28 21:42:29 +01:00
|
|
|
|
|
|
|
|
setConfiguration(notNew);
|
2016-01-27 10:22:07 +01:00
|
|
|
}
|
|
|
|
|
|
2021-12-28 21:42:29 +01:00
|
|
|
bool ConfigModel::hasChanges(bool initialParameters) const
|
2016-01-27 10:22:07 +01:00
|
|
|
{
|
2021-12-28 21:42:29 +01:00
|
|
|
const QList<InternalDataItem> filtered
|
|
|
|
|
= Utils::filtered(m_configuration, [initialParameters](const InternalDataItem &i) {
|
|
|
|
|
return initialParameters ? i.isInitial : !i.isInitial;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return Utils::contains(filtered, [initialParameters](const InternalDataItem &i) {
|
2017-09-27 12:28:11 +02:00
|
|
|
return i.isUserChanged || i.isUserNew || i.isUnset;
|
|
|
|
|
});
|
2016-01-27 10:22:07 +01:00
|
|
|
}
|
|
|
|
|
|
2017-09-14 15:36:18 +02:00
|
|
|
bool ConfigModel::canForceTo(const QModelIndex &idx, const ConfigModel::DataItem::Type type) const
|
2017-09-14 13:16:10 +02:00
|
|
|
{
|
2021-12-22 20:53:11 +01:00
|
|
|
if (idx.model() != const_cast<ConfigModel *>(this))
|
2017-09-14 13:16:10 +02:00
|
|
|
return false;
|
|
|
|
|
Utils::TreeItem *item = itemForIndex(idx);
|
|
|
|
|
auto cmti = dynamic_cast<Internal::ConfigModelTreeItem *>(item);
|
2017-09-14 15:36:18 +02:00
|
|
|
return cmti && (cmti->dataItem->type != type);
|
2017-09-14 13:16:10 +02:00
|
|
|
}
|
|
|
|
|
|
2017-09-14 15:36:18 +02:00
|
|
|
void ConfigModel::forceTo(const QModelIndex &idx, const ConfigModel::DataItem::Type type)
|
2017-09-14 13:16:10 +02:00
|
|
|
{
|
2017-09-14 15:36:18 +02:00
|
|
|
QTC_ASSERT(canForceTo(idx, type), return);
|
2017-09-14 13:16:10 +02:00
|
|
|
Utils::TreeItem *item = itemForIndex(idx);
|
|
|
|
|
auto cmti = dynamic_cast<Internal::ConfigModelTreeItem *>(item);
|
|
|
|
|
|
2017-09-14 15:36:18 +02:00
|
|
|
cmti->dataItem->type = type;
|
|
|
|
|
const QModelIndex valueIdx = idx.sibling(idx.row(), 1);
|
2017-09-14 13:16:10 +02:00
|
|
|
emit dataChanged(valueIdx, valueIdx);
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-27 12:28:11 +02:00
|
|
|
void ConfigModel::toggleUnsetFlag(const QModelIndex &idx)
|
|
|
|
|
{
|
|
|
|
|
Utils::TreeItem *item = itemForIndex(idx);
|
|
|
|
|
auto cmti = dynamic_cast<Internal::ConfigModelTreeItem *>(item);
|
|
|
|
|
|
|
|
|
|
QTC_ASSERT(cmti, return);
|
|
|
|
|
|
|
|
|
|
cmti->dataItem->isUnset = !cmti->dataItem->isUnset;
|
|
|
|
|
const QModelIndex valueIdx = idx.sibling(idx.row(), 1);
|
|
|
|
|
const QModelIndex keyIdx = idx.sibling(idx.row(), 0);
|
|
|
|
|
emit dataChanged(keyIdx, valueIdx);
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-14 15:18:50 +02:00
|
|
|
ConfigModel::DataItem ConfigModel::dataItemFromIndex(const QModelIndex &idx)
|
|
|
|
|
{
|
|
|
|
|
const QAbstractItemModel *m = idx.model();
|
|
|
|
|
QModelIndex mIdx = idx;
|
|
|
|
|
while (auto sfpm = qobject_cast<const QSortFilterProxyModel *>(m)) {
|
|
|
|
|
m = sfpm->sourceModel();
|
|
|
|
|
mIdx = sfpm->mapToSource(mIdx);
|
|
|
|
|
}
|
|
|
|
|
auto model = qobject_cast<const ConfigModel *>(m);
|
|
|
|
|
QTC_ASSERT(model, return DataItem());
|
|
|
|
|
const QModelIndex modelIdx = mIdx;
|
|
|
|
|
|
|
|
|
|
Utils::TreeItem *item = model->itemForIndex(modelIdx);
|
|
|
|
|
auto cmti = dynamic_cast<Internal::ConfigModelTreeItem *>(item);
|
|
|
|
|
|
|
|
|
|
if (cmti && cmti->dataItem) {
|
|
|
|
|
DataItem di;
|
|
|
|
|
di.key = cmti->dataItem->key;
|
|
|
|
|
di.type = cmti->dataItem->type;
|
|
|
|
|
di.isHidden = cmti->dataItem->isHidden;
|
|
|
|
|
di.isAdvanced = cmti->dataItem->isAdvanced;
|
2021-12-28 21:42:29 +01:00
|
|
|
di.isInitial = cmti->dataItem->isInitial;
|
2017-09-14 15:18:50 +02:00
|
|
|
di.inCMakeCache = cmti->dataItem->inCMakeCache;
|
|
|
|
|
di.value = cmti->dataItem->currentValue();
|
|
|
|
|
di.description = cmti->dataItem->description;
|
|
|
|
|
di.values = cmti->dataItem->values;
|
2020-07-09 04:05:44 +02:00
|
|
|
di.isUnset = cmti->dataItem->isUnset;
|
2017-09-14 15:18:50 +02:00
|
|
|
return di;
|
|
|
|
|
}
|
|
|
|
|
return DataItem();
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-29 23:34:52 +02:00
|
|
|
QList<ConfigModel::DataItem> ConfigModel::configurationForCMake() const
|
2017-09-05 13:55:08 +02:00
|
|
|
{
|
|
|
|
|
const QList<InternalDataItem> tmp
|
|
|
|
|
= Utils::filtered(m_configuration, [](const InternalDataItem &i) {
|
2017-09-27 12:28:11 +02:00
|
|
|
return i.isUserChanged || i.isUserNew || !i.inCMakeCache || i.isUnset;
|
2017-09-05 13:55:08 +02:00
|
|
|
});
|
|
|
|
|
return Utils::transform(tmp, [](const InternalDataItem &item) {
|
|
|
|
|
DataItem newItem(item);
|
|
|
|
|
if (item.isUserChanged)
|
|
|
|
|
newItem.value = item.newValue;
|
|
|
|
|
return newItem;
|
|
|
|
|
});
|
2016-05-15 15:57:17 +02:00
|
|
|
}
|
|
|
|
|
|
2017-09-28 11:32:39 +02:00
|
|
|
void ConfigModel::setConfiguration(const CMakeConfig &config)
|
|
|
|
|
{
|
2021-07-06 10:29:29 +02:00
|
|
|
setConfiguration(Utils::transform(config.toList(), [](const CMakeConfigItem &i) {
|
2021-02-24 14:33:38 +01:00
|
|
|
return DataItem(i);
|
2017-09-28 11:32:39 +02:00
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-24 14:33:38 +01:00
|
|
|
void ConfigModel::setBatchEditConfiguration(const CMakeConfig &config)
|
|
|
|
|
{
|
|
|
|
|
for (const auto &c: config) {
|
|
|
|
|
DataItem di(c);
|
|
|
|
|
auto existing = std::find(m_configuration.begin(), m_configuration.end(), di);
|
|
|
|
|
if (existing != m_configuration.end()) {
|
|
|
|
|
existing->isUnset = c.isUnset;
|
|
|
|
|
if (!c.isUnset) {
|
|
|
|
|
existing->isUserChanged = true;
|
|
|
|
|
existing->setType(c.type);
|
|
|
|
|
existing->value = QString::fromUtf8(c.value);
|
|
|
|
|
existing->newValue = existing->value;
|
|
|
|
|
}
|
|
|
|
|
} else if (!c.isUnset) {
|
|
|
|
|
InternalDataItem i(di);
|
|
|
|
|
i.isUserNew = true;
|
|
|
|
|
i.newValue = di.value;
|
|
|
|
|
m_configuration.append(i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
generateTree();
|
|
|
|
|
}
|
2017-09-28 11:32:39 +02:00
|
|
|
|
2021-12-28 21:42:29 +01:00
|
|
|
void ConfigModel::setInitialParametersConfiguration(const CMakeConfig &config)
|
|
|
|
|
{
|
|
|
|
|
for (const auto &c: config) {
|
|
|
|
|
DataItem di(c);
|
|
|
|
|
InternalDataItem i(di);
|
|
|
|
|
i.inCMakeCache = true;
|
|
|
|
|
i.isInitial = true;
|
|
|
|
|
i.newValue = di.value;
|
|
|
|
|
m_configuration.append(i);
|
|
|
|
|
}
|
|
|
|
|
generateTree();
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
void ConfigModel::setConfiguration(const QList<ConfigModel::InternalDataItem> &config)
|
2016-01-27 10:22:07 +01:00
|
|
|
{
|
2022-01-27 12:36:21 +01:00
|
|
|
auto mergeLists = [](const QList<InternalDataItem> &oldList,
|
|
|
|
|
const QList<InternalDataItem> &newList) -> QList<InternalDataItem> {
|
|
|
|
|
auto newIt = newList.constBegin();
|
|
|
|
|
auto newEndIt = newList.constEnd();
|
|
|
|
|
auto oldIt = oldList.constBegin();
|
|
|
|
|
auto oldEndIt = oldList.constEnd();
|
|
|
|
|
|
|
|
|
|
QList<InternalDataItem> result;
|
|
|
|
|
while (newIt != newEndIt && oldIt != oldEndIt) {
|
|
|
|
|
if (oldIt->isUnset) {
|
|
|
|
|
++oldIt;
|
|
|
|
|
} else if (newIt->isHidden || newIt->isUnset) {
|
|
|
|
|
++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.isUserChanged = !item.newValue.isEmpty() && (item.newValue != item.value);
|
|
|
|
|
result << item;
|
|
|
|
|
++newIt;
|
|
|
|
|
++oldIt;
|
|
|
|
|
}
|
2016-01-27 10:22:07 +01:00
|
|
|
}
|
|
|
|
|
|
2022-01-27 12:36:21 +01:00
|
|
|
// Add remaining new entries:
|
|
|
|
|
for (; newIt != newEndIt; ++newIt) {
|
|
|
|
|
if (newIt->isHidden)
|
|
|
|
|
continue;
|
|
|
|
|
result << InternalDataItem(*newIt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
auto isInitial = [](const InternalDataItem &i) { return i.isInitial; };
|
|
|
|
|
|
|
|
|
|
QList<InternalDataItem> initialOld;
|
|
|
|
|
QList<InternalDataItem> currentOld;
|
|
|
|
|
std::tie(initialOld, currentOld) = Utils::partition(m_configuration, isInitial);
|
|
|
|
|
|
|
|
|
|
QList<InternalDataItem> initialNew;
|
|
|
|
|
QList<InternalDataItem> currentNew;
|
|
|
|
|
std::tie(initialNew, currentNew) = Utils::partition(config, isInitial);
|
2016-01-27 10:22:07 +01:00
|
|
|
|
2022-01-27 12:36:21 +01:00
|
|
|
m_configuration = mergeLists(initialOld, initialNew);
|
|
|
|
|
m_configuration.append(mergeLists(currentOld, currentNew));
|
2016-01-27 10:22:07 +01:00
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
generateTree();
|
2017-01-18 16:56:00 +01:00
|
|
|
}
|
|
|
|
|
|
2022-01-24 13:41:13 +01:00
|
|
|
Utils::MacroExpander *ConfigModel::macroExpander() const
|
|
|
|
|
{
|
|
|
|
|
return m_macroExpander;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ConfigModel::setMacroExpander(Utils::MacroExpander *newExpander)
|
|
|
|
|
{
|
|
|
|
|
m_macroExpander = newExpander;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
void ConfigModel::generateTree()
|
2016-01-27 10:22:07 +01:00
|
|
|
{
|
2022-01-24 13:41:13 +01:00
|
|
|
QHash<QString, InternalDataItem> initialHash;
|
|
|
|
|
for (const InternalDataItem &di : m_configuration)
|
|
|
|
|
if (di.isInitial)
|
|
|
|
|
initialHash.insert(di.key, di);
|
|
|
|
|
|
2018-11-04 23:09:41 +01:00
|
|
|
auto root = new Utils::TreeItem;
|
2022-01-24 13:41:13 +01:00
|
|
|
for (InternalDataItem &di : m_configuration) {
|
|
|
|
|
auto it = initialHash.find(di.key);
|
|
|
|
|
if (it != initialHash.end())
|
|
|
|
|
di.initialValue = macroExpander()->expand(it->value);
|
|
|
|
|
|
2021-12-23 17:11:41 +01:00
|
|
|
root->appendChild(new Internal::ConfigModelTreeItem(&di));
|
2022-01-24 13:41:13 +01:00
|
|
|
}
|
2017-09-05 13:55:08 +02:00
|
|
|
setRootItem(root);
|
2016-01-27 10:22:07 +01:00
|
|
|
}
|
|
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
ConfigModel::InternalDataItem::InternalDataItem(const ConfigModel::DataItem &item) : DataItem(item)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
QString ConfigModel::InternalDataItem::currentValue() const
|
2016-01-27 10:22:07 +01:00
|
|
|
{
|
2017-09-27 12:28:11 +02:00
|
|
|
if (isUnset)
|
|
|
|
|
return value;
|
2017-09-05 13:55:08 +02:00
|
|
|
return isUserChanged ? newValue : value;
|
2016-01-27 10:22:07 +01:00
|
|
|
}
|
|
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
namespace Internal {
|
|
|
|
|
|
|
|
|
|
ConfigModelTreeItem::~ConfigModelTreeItem() = default;
|
|
|
|
|
|
|
|
|
|
QVariant ConfigModelTreeItem::data(int column, int role) const
|
2016-01-27 10:22:07 +01:00
|
|
|
{
|
2017-09-05 13:55:08 +02:00
|
|
|
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:
|
2021-12-28 21:42:29 +01:00
|
|
|
if (role == ConfigModel::ItemIsAdvancedRole) {
|
|
|
|
|
if (dataItem->isInitial)
|
|
|
|
|
return "2";
|
2017-09-05 13:55:08 +02:00
|
|
|
return dataItem->isAdvanced ? "1" : "0";
|
2021-12-28 21:42:29 +01:00
|
|
|
}
|
|
|
|
|
if (role == ConfigModel::ItemIsInitialRole) {
|
|
|
|
|
return dataItem->isInitial ? "1" : "0";
|
|
|
|
|
}
|
2017-09-05 13:55:08 +02:00
|
|
|
|
|
|
|
|
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.setBold(dataItem->isUserNew);
|
2017-09-27 12:28:11 +02:00
|
|
|
font.setStrikeOut((!dataItem->inCMakeCache && !dataItem->isUserNew) || dataItem->isUnset);
|
2017-09-05 13:55:08 +02:00
|
|
|
return font;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return QVariant();
|
|
|
|
|
}
|
|
|
|
|
case 1: {
|
|
|
|
|
const QString value = currentValue();
|
2021-07-06 10:58:54 +02:00
|
|
|
const auto boolValue = CMakeConfigItem::toBool(value);
|
2019-06-07 12:51:25 +02:00
|
|
|
const bool isTrue = boolValue.has_value() && boolValue.value();
|
2017-09-05 13:55:08 +02:00
|
|
|
|
|
|
|
|
switch (role) {
|
|
|
|
|
case Qt::CheckStateRole:
|
|
|
|
|
return (dataItem->type == ConfigModel::DataItem::BOOLEAN)
|
2019-06-07 12:51:25 +02:00
|
|
|
? QVariant(isTrue ? Qt::Checked : Qt::Unchecked) : QVariant();
|
2017-09-05 13:55:08 +02:00
|
|
|
case Qt::DisplayRole:
|
|
|
|
|
return value;
|
|
|
|
|
case Qt::EditRole:
|
2019-06-07 12:51:25 +02:00
|
|
|
return (dataItem->type == ConfigModel::DataItem::BOOLEAN) ? QVariant(isTrue) : QVariant(value);
|
2017-09-05 13:55:08 +02:00
|
|
|
case Qt::FontRole: {
|
|
|
|
|
QFont font;
|
2017-09-27 12:28:11 +02:00
|
|
|
font.setBold((dataItem->isUserChanged || dataItem->isUserNew) && !dataItem->isUnset);
|
|
|
|
|
font.setStrikeOut((!dataItem->inCMakeCache && !dataItem->isUserNew) || dataItem->isUnset);
|
2017-09-05 13:55:08 +02:00
|
|
|
return font;
|
|
|
|
|
}
|
2022-01-24 13:41:13 +01:00
|
|
|
case Qt::ForegroundRole: {
|
|
|
|
|
bool mismatch = false;
|
|
|
|
|
if (dataItem->isInitial)
|
|
|
|
|
mismatch = !dataItem->kitValue.isEmpty() && dataItem->kitValue != value;
|
|
|
|
|
else
|
|
|
|
|
mismatch = !dataItem->initialValue.isEmpty() && dataItem->initialValue != value;
|
|
|
|
|
return Utils::creatorTheme()->color(mismatch ? Utils::Theme::TextColorHighlight
|
|
|
|
|
: Utils::Theme::TextColorNormal);
|
|
|
|
|
}
|
2017-09-05 13:55:08 +02:00
|
|
|
case Qt::ToolTipRole: {
|
|
|
|
|
return toolTip();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return QVariant();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return QVariant();
|
|
|
|
|
}
|
2016-01-27 10:22:07 +01:00
|
|
|
}
|
|
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
bool ConfigModelTreeItem::setData(int column, const QVariant &value, int role)
|
2016-01-27 10:22:07 +01:00
|
|
|
{
|
2017-09-05 13:55:08 +02:00
|
|
|
QTC_ASSERT(column >= 0 && column < 2, return false);
|
|
|
|
|
QTC_ASSERT(dataItem, return false);
|
2017-09-27 12:28:11 +02:00
|
|
|
if (dataItem->isUnset)
|
|
|
|
|
return false;
|
2017-09-05 13:55:08 +02:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
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;
|
|
|
|
|
}
|
2016-01-27 10:22:07 +01:00
|
|
|
}
|
|
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
Qt::ItemFlags ConfigModelTreeItem::flags(int column) const
|
2016-01-27 10:22:07 +01:00
|
|
|
{
|
2017-09-05 13:55:08 +02:00
|
|
|
if (column < 0 || column >= 2)
|
|
|
|
|
return Qt::NoItemFlags;
|
2016-01-27 10:22:07 +01:00
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
QTC_ASSERT(dataItem, return Qt::NoItemFlags);
|
2016-01-27 10:22:07 +01:00
|
|
|
|
2017-09-27 12:28:11 +02:00
|
|
|
if (dataItem->isUnset)
|
|
|
|
|
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
|
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
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
|
2016-12-01 15:24:36 +01:00
|
|
|
{
|
2017-09-05 13:55:08 +02:00
|
|
|
QTC_ASSERT(dataItem, return QString());
|
2022-01-24 13:41:13 +01:00
|
|
|
QStringList tooltip;
|
|
|
|
|
if (!dataItem->description.isEmpty())
|
|
|
|
|
tooltip << dataItem->description;
|
|
|
|
|
|
|
|
|
|
if (dataItem->isInitial) {
|
|
|
|
|
if (!dataItem->kitValue.isEmpty())
|
|
|
|
|
tooltip << QCoreApplication::translate("CMakeProjectManager", "<p>Kit: <b>%1</b></p>")
|
|
|
|
|
.arg(dataItem->kitValue);
|
|
|
|
|
|
2022-01-28 15:41:32 +01:00
|
|
|
tooltip << QCoreApplication::translate("CMakeProjectManager",
|
|
|
|
|
"<p>Initial Configuration: <b>%1</b></p>")
|
|
|
|
|
.arg(dataItem->currentValue());
|
2022-01-24 13:41:13 +01:00
|
|
|
} else {
|
|
|
|
|
if (!dataItem->initialValue.isEmpty())
|
|
|
|
|
tooltip << QCoreApplication::translate("CMakeProjectManager",
|
|
|
|
|
"<p>Initial Configuration: <b>%1</b></p>")
|
|
|
|
|
.arg(dataItem->initialValue);
|
|
|
|
|
|
|
|
|
|
if (dataItem->inCMakeCache) {
|
2022-01-28 15:41:32 +01:00
|
|
|
tooltip << QCoreApplication::translate("CMakeProjectManager",
|
|
|
|
|
"<p>Current Configuration: <b>%1</b></p>")
|
|
|
|
|
.arg(dataItem->currentValue());
|
2022-01-24 13:41:13 +01:00
|
|
|
} else {
|
|
|
|
|
tooltip << QCoreApplication::translate("CMakeProjectManager",
|
|
|
|
|
"<p>Not in CMakeCache.txt</p>");
|
|
|
|
|
}
|
2017-01-18 16:56:00 +01:00
|
|
|
}
|
2022-01-24 13:41:13 +01:00
|
|
|
return tooltip.join("");
|
2016-12-01 15:24:36 +01:00
|
|
|
}
|
|
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
QString ConfigModelTreeItem::currentValue() const
|
2017-01-18 16:56:00 +01:00
|
|
|
{
|
2017-09-05 13:55:08 +02:00
|
|
|
QTC_ASSERT(dataItem, return QString());
|
|
|
|
|
return dataItem->isUserChanged ? dataItem->newValue : dataItem->value;
|
2017-01-18 16:56:00 +01:00
|
|
|
}
|
2016-01-27 10:22:07 +01:00
|
|
|
|
2017-09-05 13:55:08 +02:00
|
|
|
} // namespace Internal
|
2017-01-18 16:56:00 +01:00
|
|
|
} // namespace CMakeProjectManager
|