1 /****************************************************************************
2 **
3 ** Copyright (C) 2021 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25
26 #include "itemlibrarycategoriesmodel.h"
27 #include "itemlibrarycategory.h"
28 #include "itemlibrarymodel.h"
29
30 #include <utils/algorithm.h>
31 #include <utils/qtcassert.h>
32
33 #include <QDebug>
34 #include <QVariant>
35 #include <QMetaProperty>
36 #include <QMetaObject>
37
38 namespace QmlDesigner {
39
ItemLibraryCategoriesModel(QObject * parent)40 ItemLibraryCategoriesModel::ItemLibraryCategoriesModel(QObject *parent) :
41 QAbstractListModel(parent)
42 {
43 addRoleNames();
44 }
45
~ItemLibraryCategoriesModel()46 ItemLibraryCategoriesModel::~ItemLibraryCategoriesModel()
47 {
48 }
49
rowCount(const QModelIndex &) const50 int ItemLibraryCategoriesModel::rowCount(const QModelIndex &) const
51 {
52 return m_categoryList.count();
53 }
54
data(const QModelIndex & index,int role) const55 QVariant ItemLibraryCategoriesModel::data(const QModelIndex &index, int role) const
56 {
57 if (!index.isValid() || index.row() >= m_categoryList.count()) {
58 qWarning() << Q_FUNC_INFO << "invalid index requested";
59 return {};
60 }
61
62 if (m_roleNames.contains(role)) {
63 QVariant value = m_categoryList.at(index.row())->property(m_roleNames.value(role));
64
65 if (auto model = qobject_cast<ItemLibraryItemsModel *>(value.value<QObject *>()))
66 return QVariant::fromValue(model);
67
68 return value;
69 }
70
71 qWarning() << Q_FUNC_INFO << "invalid role requested";
72
73 return {};
74 }
75
setData(const QModelIndex & index,const QVariant & value,int role)76 bool ItemLibraryCategoriesModel::setData(const QModelIndex &index, const QVariant &value, int role)
77 {
78 // currently only categoryExpanded and categoryVisible properties is updatable
79 if (index.isValid() && m_roleNames.contains(role)) {
80 QVariant currValue = m_categoryList.at(index.row())->property(m_roleNames.value(role));
81
82 if (currValue != value) {
83 m_categoryList[index.row()]->setProperty(m_roleNames.value(role), value);
84 if (m_roleNames.value(role) == "categoryExpanded") {
85 ItemLibraryModel::saveExpandedState(value.toBool(),
86 m_categoryList[index.row()]->categoryName());
87 } else if (m_roleNames.value(role) == "categoryVisible") {
88 const ItemLibraryCategory *category = m_categoryList[index.row()];
89 ItemLibraryModel::saveCategoryVisibleState(value.toBool(), category->categoryName(),
90 category->ownerImport()->importName());
91 }
92 emit dataChanged(index, index, {role});
93 return true;
94 }
95 }
96 return false;
97 }
98
roleNames() const99 QHash<int, QByteArray> ItemLibraryCategoriesModel::roleNames() const
100 {
101 return m_roleNames;
102 }
103
expandCategories(bool expand)104 void ItemLibraryCategoriesModel::expandCategories(bool expand)
105 {
106 int i = 0;
107 for (const auto &category : std::as_const(m_categoryList)) {
108 if (category->categoryExpanded() != expand) {
109 category->setExpanded(expand);
110 ItemLibraryModel::saveExpandedState(expand, category->categoryName());
111 emit dataChanged(index(i), index(i), {m_roleNames.key("categoryExpanded")});
112 }
113 ++i;
114 }
115 }
116
addCategory(ItemLibraryCategory * category)117 void ItemLibraryCategoriesModel::addCategory(ItemLibraryCategory *category)
118 {
119 m_categoryList.append(category);
120
121 category->setVisible(true);
122 }
123
categorySections() const124 const QList<QPointer<ItemLibraryCategory>> &ItemLibraryCategoriesModel::categorySections() const
125 {
126 return m_categoryList;
127 }
128
sortCategorySections()129 void ItemLibraryCategoriesModel::sortCategorySections()
130 {
131 auto categorySort = [](ItemLibraryCategory *first, ItemLibraryCategory *second) {
132 return QString::localeAwareCompare(first->sortingName(), second->sortingName()) < 0;
133 };
134
135 std::sort(m_categoryList.begin(), m_categoryList.end(), categorySort);
136
137 for (const auto &category : qAsConst(m_categoryList))
138 category->sortItems();
139 }
140
resetModel()141 void ItemLibraryCategoriesModel::resetModel()
142 {
143 beginResetModel();
144 endResetModel();
145 }
146
showAllCategories(bool show)147 void ItemLibraryCategoriesModel::showAllCategories(bool show)
148 {
149 for (const auto &category : std::as_const(m_categoryList)) {
150 if (category->isCategoryVisible() != show) {
151 category->setCategoryVisible(show);
152 ItemLibraryModel::saveCategoryVisibleState(show, category->categoryName(),
153 category->ownerImport()->importName());
154 }
155 }
156 emit dataChanged(index(0), index(m_categoryList.size() - 1), {m_roleNames.key("categoryVisible")});
157 }
158
addRoleNames()159 void ItemLibraryCategoriesModel::addRoleNames()
160 {
161 int role = 0;
162 const QMetaObject meta = ItemLibraryCategory::staticMetaObject;
163 for (int i = meta.propertyOffset(); i < meta.propertyCount(); ++i)
164 m_roleNames.insert(role++, meta.property(i).name());
165 }
166
167 } // namespace QmlDesigner
168