forked from qt-creator/qt-creator
DesignSystem: Enable design system data model editable
Task-number: QDS-13881 Change-Id: Icead4959b098a7b4cf1a440e69ff462d0645be8f Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -83,15 +83,132 @@ QHash<int, QByteArray> CollectionModel::roleNames() const
|
|||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CollectionModel::insertColumns([[maybe_unused]] int column, int count, const QModelIndex &parent)
|
||||||
|
{
|
||||||
|
// Append column only
|
||||||
|
if (parent.isValid() || count < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool addSuccess = false;
|
||||||
|
while (count--)
|
||||||
|
addSuccess |= m_collection->addTheme(QByteArrayLiteral("theme")).has_value();
|
||||||
|
|
||||||
|
if (addSuccess) {
|
||||||
|
beginResetModel();
|
||||||
|
updateCache();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CollectionModel::removeColumns(int column, int count, const QModelIndex &parent)
|
||||||
|
{
|
||||||
|
const auto sentinelIndex = column + count;
|
||||||
|
if (parent.isValid() || column < 0 || count < 1 || sentinelIndex > columnCount(parent))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
beginResetModel();
|
||||||
|
while (column < sentinelIndex)
|
||||||
|
m_collection->removeTheme(m_themeIdList[column++]);
|
||||||
|
|
||||||
|
updateCache();
|
||||||
|
endResetModel();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CollectionModel::removeRows(int row, int count, const QModelIndex &parent)
|
||||||
|
{
|
||||||
|
const auto sentinelIndex = row + count;
|
||||||
|
if (parent.isValid() || row < 0 || count < 1 || sentinelIndex > rowCount(parent))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
beginResetModel();
|
||||||
|
while (row < sentinelIndex) {
|
||||||
|
auto [groupType, name] = m_propertyInfoList[row++];
|
||||||
|
m_collection->removeProperty(groupType, name);
|
||||||
|
}
|
||||||
|
updateCache();
|
||||||
|
endResetModel();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void CollectionModel::updateCache()
|
void CollectionModel::updateCache()
|
||||||
{
|
{
|
||||||
m_themeIdList = m_collection->allThemeIds();
|
m_themeIdList.clear();
|
||||||
|
|
||||||
m_propertyInfoList.clear();
|
m_propertyInfoList.clear();
|
||||||
m_collection->forAllGroups([this](GroupType gt, DSThemeGroup *themeGroup) {
|
|
||||||
for (auto propName : themeGroup->propertyNames())
|
if (m_collection) {
|
||||||
m_propertyInfoList.push_back({gt, propName});
|
m_themeIdList = m_collection->allThemeIds();
|
||||||
});
|
|
||||||
|
m_collection->forAllGroups([this](GroupType gt, DSThemeGroup *themeGroup) {
|
||||||
|
for (auto propName : themeGroup->propertyNames())
|
||||||
|
m_propertyInfoList.push_back({gt, propName});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectionModel::addProperty(GroupType group, const QString &name, const QVariant &value, bool isBinding)
|
||||||
|
{
|
||||||
|
if (m_collection->addProperty(group, {name.toUtf8(), value, isBinding})) {
|
||||||
|
beginResetModel();
|
||||||
|
updateCache();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CollectionModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
|
{
|
||||||
|
switch (role) {
|
||||||
|
case Qt::EditRole: {
|
||||||
|
ThemeProperty p = value.value<ThemeProperty>();
|
||||||
|
const auto [groupType, propName] = m_propertyInfoList[index.row()];
|
||||||
|
p.name = propName;
|
||||||
|
const ThemeId id = m_themeIdList[index.column()];
|
||||||
|
if (m_collection->updateProperty(id, groupType, p)) {
|
||||||
|
beginResetModel();
|
||||||
|
updateCache();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CollectionModel::setHeaderData(int section,
|
||||||
|
Qt::Orientation orientation,
|
||||||
|
const QVariant &value,
|
||||||
|
int role)
|
||||||
|
{
|
||||||
|
if (role != Qt::EditRole)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (section < 0 || (orientation == Qt::Horizontal && section >= columnCount())
|
||||||
|
|| (orientation == Qt::Vertical && section >= rowCount())) {
|
||||||
|
return false; // Out of bounds
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto &newName = value.toString().toUtf8();
|
||||||
|
bool success = false;
|
||||||
|
if (orientation == Qt::Horizontal) {
|
||||||
|
// Theme
|
||||||
|
success = m_collection->renameTheme(findThemeId(section), newName);
|
||||||
|
} else {
|
||||||
|
// Property Name
|
||||||
|
if (auto propInfo = findPropertyName(section)) {
|
||||||
|
auto [groupType, propName] = *propInfo;
|
||||||
|
success = m_collection->renameProperty(groupType, propName, newName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
beginResetModel();
|
||||||
|
updateCache();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
ThemeId CollectionModel::findThemeId(int column) const
|
ThemeId CollectionModel::findThemeId(int column) const
|
||||||
|
@@ -14,11 +14,14 @@ using PropInfo = std::pair<GroupType, PropertyName>;
|
|||||||
|
|
||||||
class CollectionModel : public QAbstractItemModel
|
class CollectionModel : public QAbstractItemModel
|
||||||
{
|
{
|
||||||
enum class Roles { GroupRole = Qt::UserRole + 1, BindingRole };
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum class Roles { GroupRole = Qt::UserRole + 1, BindingRole };
|
||||||
|
|
||||||
CollectionModel(DSThemeManager *collection);
|
CollectionModel(DSThemeManager *collection);
|
||||||
|
|
||||||
|
// QAbstractItemModel Interface
|
||||||
int columnCount(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;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
||||||
@@ -27,10 +30,26 @@ public:
|
|||||||
QVariant headerData(int section,
|
QVariant headerData(int section,
|
||||||
Qt::Orientation orientation,
|
Qt::Orientation orientation,
|
||||||
int role = Qt::DisplayRole) const override;
|
int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
// Add Themes
|
||||||
|
bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||||
|
// Remove Themes
|
||||||
|
bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||||
|
// Remove Properties
|
||||||
|
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||||
|
|
||||||
void updateCache();
|
void updateCache();
|
||||||
|
Q_INVOKABLE void addProperty(GroupType group,
|
||||||
|
const QString &name,
|
||||||
|
const QVariant &value,
|
||||||
|
bool isBinding);
|
||||||
|
// Edit property value
|
||||||
|
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||||
|
// Edit property name / Theme name
|
||||||
|
Q_INVOKABLE bool setHeaderData(int section,
|
||||||
|
Qt::Orientation orientation,
|
||||||
|
const QVariant &value,
|
||||||
|
int role = Qt::EditRole) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ThemeId findThemeId(int column) const;
|
ThemeId findThemeId(int column) const;
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
#include "collectionmodel.h"
|
#include "collectionmodel.h"
|
||||||
|
|
||||||
#include <designsystem/dsconstants.h>
|
#include <designsystem/dsconstants.h>
|
||||||
|
#include <designsystem/dsthememanager.h>
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
@@ -21,30 +22,64 @@ void DesignSystemInterface::loadDesignSystem()
|
|||||||
{
|
{
|
||||||
m_models.clear();
|
m_models.clear();
|
||||||
m_store->load();
|
m_store->load();
|
||||||
emit loadFinished();
|
emit collectionsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
QAbstractItemModel *DesignSystemInterface::model(const QString &typeName)
|
CollectionModel *DesignSystemInterface::model(const QString &typeName)
|
||||||
{
|
{
|
||||||
if (auto collection = m_store->collection(typeName)) {
|
if (auto collection = m_store->collection(typeName)) {
|
||||||
auto itr = m_models.find(typeName);
|
auto itr = m_models.find(typeName);
|
||||||
if (itr != m_models.end())
|
if (itr != m_models.end())
|
||||||
return itr->second.get();
|
return itr->second.get();
|
||||||
|
|
||||||
auto [newItr, success] = m_models.try_emplace(typeName,
|
return createModel(typeName, collection);
|
||||||
std::make_unique<CollectionModel>(*collection));
|
|
||||||
if (success) {
|
|
||||||
// Otherwise the model will be deleted by the QML engine.
|
|
||||||
QQmlEngine::setObjectOwnership(newItr->second.get(), QQmlEngine::CppOwnership);
|
|
||||||
return newItr->second.get();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DesignSystemInterface::addCollection(const QString &name)
|
||||||
|
{
|
||||||
|
if (auto collection = m_store->addCollection(name))
|
||||||
|
emit collectionsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesignSystemInterface::removeCollection(const QString &name)
|
||||||
|
{
|
||||||
|
if (m_store->collection(name)) {
|
||||||
|
m_models.erase(name);
|
||||||
|
m_store->removeCollection(name);
|
||||||
|
emit collectionsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesignSystemInterface::renameCollection(const QString &oldName, const QString &newName)
|
||||||
|
{
|
||||||
|
if (m_store->renameCollection(oldName, newName))
|
||||||
|
emit collectionsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
ThemeProperty DesignSystemInterface::createThemeProperty(const QString &name,
|
||||||
|
const QVariant &value,
|
||||||
|
bool isBinding) const
|
||||||
|
{
|
||||||
|
return {name.toUtf8(), value, isBinding};
|
||||||
|
}
|
||||||
|
|
||||||
QStringList DesignSystemInterface::collections() const
|
QStringList DesignSystemInterface::collections() const
|
||||||
{
|
{
|
||||||
return m_store->collectionNames();
|
return m_store->collectionNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CollectionModel *DesignSystemInterface::createModel(const QString &typeName, DSThemeManager *collection)
|
||||||
|
{
|
||||||
|
auto [newItr, success] = m_models.try_emplace(typeName,
|
||||||
|
std::make_unique<CollectionModel>(collection));
|
||||||
|
if (success) {
|
||||||
|
// Otherwise the model will be deleted by the QML engine.
|
||||||
|
QQmlEngine::setObjectOwnership(newItr->second.get(), QQmlEngine::CppOwnership);
|
||||||
|
return newItr->second.get();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -10,22 +10,35 @@ class QAbstractItemModel;
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
class CollectionModel;
|
class CollectionModel;
|
||||||
|
class DSThemeManager;
|
||||||
|
|
||||||
class DesignSystemInterface : public QObject
|
class DesignSystemInterface : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QStringList collections READ collections NOTIFY loadFinished FINAL)
|
Q_PROPERTY(QStringList collections READ collections NOTIFY collectionsChanged FINAL)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DesignSystemInterface(DSStore *store);
|
DesignSystemInterface(DSStore *store);
|
||||||
~DesignSystemInterface();
|
~DesignSystemInterface();
|
||||||
|
|
||||||
Q_INVOKABLE void loadDesignSystem();
|
Q_INVOKABLE void loadDesignSystem();
|
||||||
Q_INVOKABLE QAbstractItemModel *model(const QString &typeName);
|
Q_INVOKABLE CollectionModel *model(const QString &typeName);
|
||||||
|
|
||||||
|
Q_INVOKABLE void addCollection(const QString &name);
|
||||||
|
Q_INVOKABLE void removeCollection(const QString &name);
|
||||||
|
Q_INVOKABLE void renameCollection(const QString &oldName, const QString &newName);
|
||||||
|
|
||||||
|
Q_INVOKABLE ThemeProperty createThemeProperty(const QString &name,
|
||||||
|
const QVariant &value,
|
||||||
|
bool isBinding = false) const;
|
||||||
|
|
||||||
QStringList collections() const;
|
QStringList collections() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void loadFinished();
|
void collectionsChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CollectionModel *createModel(const QString &typeName, DSThemeManager *collection);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class DSStore *m_store = nullptr;
|
class DSStore *m_store = nullptr;
|
||||||
|
@@ -209,6 +209,30 @@ std::optional<QString> DSStore::typeName(DSThemeManager *collection) const
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DSStore::removeCollection(const QString &name)
|
||||||
|
{
|
||||||
|
return m_collections.erase(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DSStore::renameCollection(const QString &oldName, const QString &newName)
|
||||||
|
{
|
||||||
|
auto itr = m_collections.find(oldName);
|
||||||
|
if (itr == m_collections.end() || oldName == newName)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const QString uniqueTypeName = uniqueCollectionName(newName);
|
||||||
|
|
||||||
|
// newName is mutated to make it unique or compatible. Bail.
|
||||||
|
// Case update is tolerated.
|
||||||
|
if (uniqueTypeName.toLower() != newName.toLower())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto handle = m_collections.extract(oldName);
|
||||||
|
handle.key() = uniqueTypeName;
|
||||||
|
m_collections.insert(std::move(handle));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<Utils::FilePath> DSStore::moduleDirPath() const
|
std::optional<Utils::FilePath> DSStore::moduleDirPath() const
|
||||||
{
|
{
|
||||||
return dsModuleDir(m_ed);
|
return dsModuleDir(m_ed);
|
||||||
@@ -231,13 +255,13 @@ QString DSStore::uniqueCollectionName(const QString &hint) const
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<DSThemeManager *> DSStore::collection(const QString &typeName)
|
DSThemeManager *DSStore::collection(const QString &typeName)
|
||||||
{
|
{
|
||||||
auto itr = m_collections.find(typeName);
|
auto itr = m_collections.find(typeName);
|
||||||
if (itr != m_collections.end())
|
if (itr != m_collections.end())
|
||||||
return &itr->second;
|
return &itr->second;
|
||||||
|
|
||||||
return {};
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<QString> DSStore::loadCollection(const QString &typeName,
|
std::optional<QString> DSStore::loadCollection(const QString &typeName,
|
||||||
|
@@ -33,8 +33,10 @@ public:
|
|||||||
size_t collectionCount() const { return m_collections.size(); }
|
size_t collectionCount() const { return m_collections.size(); }
|
||||||
|
|
||||||
DSThemeManager *addCollection(const QString &qmlTypeName);
|
DSThemeManager *addCollection(const QString &qmlTypeName);
|
||||||
std::optional<DSThemeManager *> collection(const QString &typeName);
|
DSThemeManager *collection(const QString &typeName);
|
||||||
std::optional<QString> typeName(DSThemeManager *collection) const;
|
std::optional<QString> typeName(DSThemeManager *collection) const;
|
||||||
|
bool removeCollection(const QString &name);
|
||||||
|
bool renameCollection(const QString &oldName, const QString &newName);
|
||||||
|
|
||||||
std::optional<Utils::FilePath> moduleDirPath() const;
|
std::optional<Utils::FilePath> moduleDirPath() const;
|
||||||
QStringList collectionNames() const;
|
QStringList collectionNames() const;
|
||||||
|
@@ -96,38 +96,29 @@ bool DSThemeGroup::hasProperty(const PropertyName &name) const
|
|||||||
return m_values.contains(name);
|
return m_values.contains(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSThemeGroup::updateProperty(ThemeId theme, PropertyName newName, const ThemeProperty &prop)
|
bool DSThemeGroup::updateProperty(ThemeId theme, const ThemeProperty &prop)
|
||||||
{
|
{
|
||||||
if (!m_values.contains(prop.name)) {
|
if (!m_values.contains(prop.name)) {
|
||||||
qCDebug(dsLog) << "Property update failure. Can't find property" << prop;
|
qCDebug(dsLog) << "Property update failure. Can't find property" << prop;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ThemeProperty{newName, prop.value, prop.isBinding}.isValid()) {
|
if (!prop.isValid()) {
|
||||||
qCDebug(dsLog) << "Property update failure. Invalid property" << prop << newName;
|
qCDebug(dsLog) << "Property update failure. Invalid property" << prop;
|
||||||
return;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (newName != prop.name && m_values.contains(newName)) {
|
|
||||||
qCDebug(dsLog) << "Property update failure. Property name update already exists" << newName
|
|
||||||
<< prop;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &tValues = m_values.at(prop.name);
|
auto &tValues = m_values.at(prop.name);
|
||||||
const auto itr = tValues.find(theme);
|
const auto itr = tValues.find(theme);
|
||||||
if (itr == tValues.end()) {
|
if (itr == tValues.end()) {
|
||||||
qCDebug(dsLog) << "Property update failure. No property for the theme" << theme << prop;
|
qCDebug(dsLog) << "Property update failure. No property for the theme" << theme << prop;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &entry = tValues.at(theme);
|
auto &entry = tValues.at(theme);
|
||||||
entry.value = prop.value;
|
entry.value = prop.value;
|
||||||
entry.isBinding = prop.isBinding;
|
entry.isBinding = prop.isBinding;
|
||||||
if (newName != prop.name) {
|
return true;
|
||||||
m_values[newName] = std::move(tValues);
|
|
||||||
m_values.erase(prop.name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSThemeGroup::removeProperty(const PropertyName &name)
|
void DSThemeGroup::removeProperty(const PropertyName &name)
|
||||||
@@ -135,6 +126,25 @@ void DSThemeGroup::removeProperty(const PropertyName &name)
|
|||||||
m_values.erase(name);
|
m_values.erase(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DSThemeGroup::renameProperty(const PropertyName &name, const PropertyName &newName)
|
||||||
|
{
|
||||||
|
auto itr = m_values.find(name);
|
||||||
|
if (itr == m_values.end()) {
|
||||||
|
qCDebug(dsLog) << "Renaming non-existing property" << name;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_values.contains(newName) || newName.trimmed().isEmpty()) {
|
||||||
|
qCDebug(dsLog) << "Renaming failed. Invalid new name" << name;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto node = m_values.extract(itr);
|
||||||
|
node.key() = newName;
|
||||||
|
m_values.insert(std::move(node));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
size_t DSThemeGroup::count(ThemeId theme) const
|
size_t DSThemeGroup::count(ThemeId theme) const
|
||||||
{
|
{
|
||||||
return std::accumulate(m_values.cbegin(),
|
return std::accumulate(m_values.cbegin(),
|
||||||
|
@@ -38,8 +38,9 @@ public:
|
|||||||
std::optional<ThemeProperty> propertyValue(ThemeId theme, const PropertyName &name) const;
|
std::optional<ThemeProperty> propertyValue(ThemeId theme, const PropertyName &name) const;
|
||||||
bool hasProperty(const PropertyName &name) const;
|
bool hasProperty(const PropertyName &name) const;
|
||||||
|
|
||||||
void updateProperty(ThemeId theme, PropertyName newName, const ThemeProperty &prop);
|
bool updateProperty(ThemeId theme, const ThemeProperty &prop);
|
||||||
void removeProperty(const PropertyName &name);
|
void removeProperty(const PropertyName &name);
|
||||||
|
bool renameProperty(const PropertyName &name, const PropertyName &newName);
|
||||||
|
|
||||||
size_t count(ThemeId theme) const;
|
size_t count(ThemeId theme) const;
|
||||||
size_t count() const;
|
size_t count() const;
|
||||||
|
@@ -73,6 +73,24 @@ ThemeName DSThemeManager::themeName(ThemeId id) const
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DSThemeManager::renameTheme(ThemeId id, const ThemeName &newName)
|
||||||
|
{
|
||||||
|
const ThemeName oldName = themeName(id);
|
||||||
|
if (oldName.isEmpty()) {
|
||||||
|
qCDebug(dsLog) << "Invalid theme rename. Theme does not exists. Id:" << id;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ThemeName sanitizedName = uniqueThemeName(newName);
|
||||||
|
if (sanitizedName != newName) {
|
||||||
|
qCDebug(dsLog) << "Theme rename fail. New name " << newName << " is not valid:";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_themes[id] = sanitizedName;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<ThemeId> DSThemeManager::allThemeIds() const
|
const std::vector<ThemeId> DSThemeManager::allThemeIds() const
|
||||||
{
|
{
|
||||||
std::vector<ThemeId> ids;
|
std::vector<ThemeId> ids;
|
||||||
@@ -168,23 +186,29 @@ void DSThemeManager::removeProperty(GroupType gType, const PropertyName &name)
|
|||||||
dsGroup->removeProperty(name);
|
dsGroup->removeProperty(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSThemeManager::updateProperty(ThemeId id, GroupType gType, const ThemeProperty &p)
|
bool DSThemeManager::updateProperty(ThemeId id, GroupType gType, const ThemeProperty &prop)
|
||||||
{
|
|
||||||
updateProperty(id, gType, p, p.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DSThemeManager::updateProperty(ThemeId id,
|
|
||||||
GroupType gType,
|
|
||||||
const ThemeProperty &p,
|
|
||||||
const PropertyName &newName)
|
|
||||||
{
|
{
|
||||||
if (!m_themes.contains(id))
|
if (!m_themes.contains(id))
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
DSThemeGroup *dsGroup = propertyGroup(gType);
|
DSThemeGroup *dsGroup = propertyGroup(gType);
|
||||||
QTC_ASSERT(dsGroup, return);
|
QTC_ASSERT(dsGroup, return false);
|
||||||
|
|
||||||
dsGroup->updateProperty(id, newName, p);
|
return dsGroup->updateProperty(id, prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DSThemeManager::renameProperty(GroupType gType, const PropertyName &name, const PropertyName &newName)
|
||||||
|
{
|
||||||
|
DSThemeGroup *dsGroup = propertyGroup(gType);
|
||||||
|
QTC_ASSERT(dsGroup, return false);
|
||||||
|
|
||||||
|
const auto generatedName = uniquePropertyName(newName);
|
||||||
|
if (generatedName != newName) {
|
||||||
|
qCDebug(dsLog) << "Can not rename property. Invalid property name";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dsGroup->renameProperty(name, newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSThemeManager::decorate(ModelNode rootNode, const QByteArray &nodeType, bool isMCU) const
|
void DSThemeManager::decorate(ModelNode rootNode, const QByteArray &nodeType, bool isMCU) const
|
||||||
|
@@ -36,6 +36,7 @@ public:
|
|||||||
std::optional<ThemeId> addTheme(const ThemeName &themeNameHint);
|
std::optional<ThemeId> addTheme(const ThemeName &themeNameHint);
|
||||||
std::optional<ThemeId> themeId(const ThemeName &themeName) const;
|
std::optional<ThemeId> themeId(const ThemeName &themeName) const;
|
||||||
ThemeName themeName(ThemeId id) const;
|
ThemeName themeName(ThemeId id) const;
|
||||||
|
bool renameTheme(ThemeId id, const ThemeName &newName);
|
||||||
const std::vector<ThemeId> allThemeIds() const;
|
const std::vector<ThemeId> allThemeIds() const;
|
||||||
|
|
||||||
void forAllGroups(std::function<void(GroupType, DSThemeGroup *)> callback) const;
|
void forAllGroups(std::function<void(GroupType, DSThemeGroup *)> callback) const;
|
||||||
@@ -51,8 +52,9 @@ public:
|
|||||||
GroupType gType,
|
GroupType gType,
|
||||||
const PropertyName &name) const;
|
const PropertyName &name) const;
|
||||||
void removeProperty(GroupType gType, const PropertyName &p);
|
void removeProperty(GroupType gType, const PropertyName &p);
|
||||||
void updateProperty(ThemeId id, GroupType gType, const ThemeProperty &p);
|
|
||||||
void updateProperty(ThemeId id, GroupType gType, const ThemeProperty &p, const PropertyName &newName);
|
bool updateProperty(ThemeId id, GroupType gType, const ThemeProperty &prop);
|
||||||
|
bool renameProperty(GroupType gType, const PropertyName &name, const PropertyName &newName);
|
||||||
|
|
||||||
void decorate(ModelNode rootNode, const QByteArray &nodeType = "QtObject", bool isMCU = false) const;
|
void decorate(ModelNode rootNode, const QByteArray &nodeType = "QtObject", bool isMCU = false) const;
|
||||||
void decorateThemeInterface(ModelNode rootNode) const;
|
void decorateThemeInterface(ModelNode rootNode) const;
|
||||||
|
@@ -203,7 +203,7 @@ TEST_P(DesignSystemManagerTest, update_property_name)
|
|||||||
mgr.addProperty(groupType, testProp);
|
mgr.addProperty(groupType, testProp);
|
||||||
|
|
||||||
// act
|
// act
|
||||||
mgr.updateProperty(*themeId, groupType, testProp, testPropUpdated.name);
|
mgr.renameProperty(groupType, testPropNameFoo, testPropNameBar);
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
ASSERT_THAT(mgr,
|
ASSERT_THAT(mgr,
|
||||||
@@ -220,7 +220,7 @@ TEST_P(DesignSystemManagerTest, updating_invalid_property_fails)
|
|||||||
mgr.addProperty(groupType, testProp);
|
mgr.addProperty(groupType, testProp);
|
||||||
|
|
||||||
// act
|
// act
|
||||||
mgr.updateProperty(*themeId, groupType, testProp, testPropUpdated.name);
|
mgr.updateProperty(*themeId, groupType, testPropUpdated);
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
ASSERT_THAT(mgr,
|
ASSERT_THAT(mgr,
|
||||||
|
Reference in New Issue
Block a user