FluentUI/src/FluTreeModel.cpp

275 lines
8.2 KiB
C++
Raw Normal View History

2023-09-15 19:11:55 +08:00
#include "FluTreeModel.h"
#include <QMetaEnum>
2024-04-11 14:51:43 +08:00
#include <utility>
2023-09-15 19:11:55 +08:00
2024-04-11 14:51:43 +08:00
FluTreeNode::FluTreeNode(QObject *parent) : QObject{parent} {
2023-09-17 20:36:33 +08:00
}
2024-04-11 14:51:43 +08:00
FluTreeModel::FluTreeModel(QObject *parent) : QAbstractItemModel{parent} {
_dataSourceSize = 0;
2023-09-15 19:11:55 +08:00
}
2024-04-11 14:51:43 +08:00
QModelIndex FluTreeModel::parent(const QModelIndex &child) const {
return {};
2023-09-19 23:41:56 +08:00
}
2024-04-11 14:51:43 +08:00
QModelIndex FluTreeModel::index(int row, int column, const QModelIndex &parent) const {
2023-09-19 23:41:56 +08:00
if (!hasIndex(row, column, parent) || parent.isValid())
2024-04-11 14:51:43 +08:00
return {};
2023-09-19 23:41:56 +08:00
return createIndex(row, column, _rows.at(row));
}
2023-09-15 19:11:55 +08:00
int FluTreeModel::rowCount(const QModelIndex &parent) const {
return _rows.count();
2024-04-11 14:51:43 +08:00
}
2023-09-15 19:11:55 +08:00
int FluTreeModel::columnCount(const QModelIndex &parent) const {
2024-04-09 20:53:52 +08:00
return this->_columnSource.size();
2024-04-11 14:51:43 +08:00
}
2023-09-15 19:11:55 +08:00
QVariant FluTreeModel::data(const QModelIndex &index, int role) const {
switch (role) {
2024-04-11 14:51:43 +08:00
case TreeModelRoles::RowModel:
return QVariant::fromValue(_rows.at(index.row()));
case TreeModelRoles::ColumnModel:
return QVariant::fromValue(_columnSource.at(index.column()));
default:
break;
2023-09-15 19:11:55 +08:00
}
2024-04-11 14:51:43 +08:00
return {};
}
2023-09-15 19:11:55 +08:00
QHash<int, QByteArray> FluTreeModel::roleNames() const {
2024-04-09 20:53:52 +08:00
return {
2024-04-11 14:51:43 +08:00
{TreeModelRoles::RowModel, "rowModel"},
{TreeModelRoles::ColumnModel, "columnModel"}
2024-04-09 20:53:52 +08:00
};
2024-04-11 14:51:43 +08:00
}
2023-09-15 19:11:55 +08:00
2024-04-11 14:51:43 +08:00
void FluTreeModel::setData(QList<FluTreeNode *> data) {
2023-09-15 19:11:55 +08:00
beginResetModel();
2024-04-11 14:51:43 +08:00
_rows = std::move(data);
2023-09-15 19:11:55 +08:00
endResetModel();
}
2024-04-11 14:51:43 +08:00
void FluTreeModel::removeRows(int row, int count) {
if (row < 0 || row + count > _rows.size() || count == 0)
2023-09-15 19:11:55 +08:00
return;
2024-04-11 14:51:43 +08:00
beginRemoveRows(QModelIndex(), row, row + count - 1);
QList<FluTreeNode *> firstPart = _rows.mid(0, row);
QList<FluTreeNode *> secondPart = _rows.mid(row + count);
2023-09-21 18:29:09 +08:00
_rows.clear();
_rows.append(firstPart);
_rows.append(secondPart);
2023-09-18 00:12:39 +08:00
endRemoveRows();
2023-09-15 19:11:55 +08:00
}
2024-04-11 14:51:43 +08:00
void FluTreeModel::insertRows(int row, const QList<FluTreeNode *> &data) {
if (row < 0 || row > _rows.size() || data.empty())
return;
2023-09-18 00:12:39 +08:00
beginInsertRows(QModelIndex(), row, row + data.size() - 1);
2024-04-11 14:51:43 +08:00
QList<FluTreeNode *> firstPart = _rows.mid(0, row);
QList<FluTreeNode *> secondPart = _rows.mid(row);
2023-09-21 18:29:09 +08:00
_rows.clear();
_rows.append(firstPart);
_rows.append(data);
_rows.append(secondPart);
2023-09-18 00:12:39 +08:00
endInsertRows();
2023-09-15 19:11:55 +08:00
}
2024-04-11 14:51:43 +08:00
QObject *FluTreeModel::getRow(int row) {
2023-09-15 19:11:55 +08:00
return _rows.at(row);
}
2023-09-17 20:36:33 +08:00
2024-04-11 14:51:43 +08:00
void FluTreeModel::setRow(int row, QVariantMap data) {
_rows.at(row)->_data = std::move(data);
Q_EMIT dataChanged(index(row, 0), index(row, columnCount() - 1));
2024-04-09 20:53:52 +08:00
}
2024-04-11 14:51:43 +08:00
void FluTreeModel::checkRow(int row, bool checked) {
2023-09-22 17:35:02 +08:00
auto itemData = _rows.at(row);
2024-04-11 14:51:43 +08:00
if (itemData->hasChildren()) {
QList<FluTreeNode *> stack = itemData->_children;
2023-09-22 17:35:02 +08:00
std::reverse(stack.begin(), stack.end());
while (stack.count() > 0) {
2024-04-11 14:51:43 +08:00
auto item = stack.at(stack.count() - 1);
2023-09-22 17:35:02 +08:00
stack.pop_back();
2024-04-11 14:51:43 +08:00
if (!item->hasChildren()) {
2024-03-31 21:52:06 +08:00
item->_checked = checked;
2023-09-22 17:35:02 +08:00
}
2024-04-11 14:51:43 +08:00
QList<FluTreeNode *> children = item->_children;
if (!children.isEmpty()) {
2023-09-22 17:35:02 +08:00
std::reverse(children.begin(), children.end());
2024-04-11 14:51:43 +08:00
foreach (auto c, children) {
stack.append(c);
}
2023-09-22 17:35:02 +08:00
}
}
2024-04-11 14:51:43 +08:00
} else {
if (itemData->_checked == checked) {
2023-09-22 17:35:02 +08:00
return;
}
2024-03-31 21:52:06 +08:00
itemData->_checked = checked;
2023-09-22 17:35:02 +08:00
}
2024-04-11 14:51:43 +08:00
Q_EMIT dataChanged(index(0, 0), index(rowCount() - 1, 0));
QList<FluTreeNode *> data;
foreach (auto item, _dataSource) {
if (!item->hasChildren()) {
if (item->_checked) {
data.append(item);
}
2023-09-22 17:35:02 +08:00
}
}
selectionModel(data);
}
2024-04-11 14:51:43 +08:00
void FluTreeModel::setDataSource(QList<QMap<QString, QVariant>> data) {
2023-09-17 20:36:33 +08:00
_dataSource.clear();
2024-04-11 14:51:43 +08:00
if (_root) {
2023-09-17 20:36:33 +08:00
delete _root;
_root = nullptr;
}
2024-04-03 11:19:35 +08:00
_root = new FluTreeNode(this);
2023-09-17 20:36:33 +08:00
std::reverse(data.begin(), data.end());
while (data.count() > 0) {
2024-04-11 14:51:43 +08:00
auto item = data.at(data.count() - 1);
2023-09-17 20:36:33 +08:00
data.pop_back();
2024-04-11 14:51:43 +08:00
auto *node = new FluTreeNode(this);
2023-09-17 20:36:33 +08:00
node->_depth = item.value("__depth").toInt();
2024-04-11 14:51:43 +08:00
node->_parent = item.value("__parent").value<FluTreeNode *>();
2024-04-09 20:53:52 +08:00
node->_data = item;
2023-09-17 20:36:33 +08:00
node->_isExpanded = true;
2024-04-11 14:51:43 +08:00
if (node->_parent) {
2023-09-17 20:36:33 +08:00
node->_parent->_children.append(node);
2024-04-11 14:51:43 +08:00
} else {
2023-09-17 20:36:33 +08:00
node->_parent = _root;
_root->_children.append(node);
}
_dataSource.append(node);
if (item.contains("children")) {
QList<QVariant> children = item.value("children").toList();
2024-04-11 14:51:43 +08:00
if (!children.isEmpty()) {
2023-09-17 20:36:33 +08:00
std::reverse(children.begin(), children.end());
2024-04-11 14:51:43 +08:00
for (int i = 0; i <= children.count() - 1; ++i) {
2023-09-21 18:29:09 +08:00
auto child = children.at(i).toMap();
2024-04-11 14:51:43 +08:00
child.insert("__depth", item.value("__depth").toInt(nullptr) + 1);
child.insert("__parent", QVariant::fromValue(node));
2023-09-17 20:36:33 +08:00
data.append(child);
}
}
}
}
beginResetModel();
_rows = _dataSource;
endResetModel();
dataSourceSize(_dataSource.size());
}
2024-04-11 14:51:43 +08:00
void FluTreeModel::collapse(int row) {
if (!_rows.at(row)->_isExpanded) {
2023-09-17 20:36:33 +08:00
return;
}
_rows.at(row)->_isExpanded = false;
2024-04-11 14:51:43 +08:00
Q_EMIT dataChanged(index(row, 0), index(row, 0));
2023-09-17 20:36:33 +08:00
auto modelData = _rows.at(row);
int removeCount = 0;
2024-04-11 14:51:43 +08:00
for (int i = row + 1; i < _rows.count(); i++) {
2023-09-17 20:36:33 +08:00
auto obj = _rows[i];
2024-04-11 14:51:43 +08:00
if (obj->_depth <= modelData->_depth) {
2023-09-17 20:36:33 +08:00
break;
}
removeCount = removeCount + 1;
}
2024-04-11 14:51:43 +08:00
removeRows(row + 1, removeCount);
2023-09-17 20:36:33 +08:00
}
2024-04-11 14:51:43 +08:00
void FluTreeModel::expand(int row) {
if (_rows.at(row)->_isExpanded) {
2023-09-17 20:36:33 +08:00
return;
}
_rows.at(row)->_isExpanded = true;
2024-04-11 14:51:43 +08:00
Q_EMIT dataChanged(index(row, 0), index(row, 0));
2023-09-17 20:36:33 +08:00
auto modelData = _rows.at(row);
2024-04-11 14:51:43 +08:00
QList<FluTreeNode *> insertData;
QList<FluTreeNode *> stack = modelData->_children;
2023-09-17 20:36:33 +08:00
std::reverse(stack.begin(), stack.end());
while (stack.count() > 0) {
2024-04-11 14:51:43 +08:00
auto item = stack.at(stack.count() - 1);
2023-09-17 20:36:33 +08:00
stack.pop_back();
2024-04-11 14:51:43 +08:00
if (item->isShown()) {
2023-09-17 20:36:33 +08:00
insertData.append(item);
}
2024-04-11 14:51:43 +08:00
QList<FluTreeNode *> children = item->_children;
if (!children.isEmpty()) {
2023-09-17 20:36:33 +08:00
std::reverse(children.begin(), children.end());
2024-04-11 14:51:43 +08:00
foreach (auto c, children) {
stack.append(c);
}
2023-09-17 20:36:33 +08:00
}
}
2024-04-11 14:51:43 +08:00
insertRows(row + 1, insertData);
2023-09-17 20:36:33 +08:00
}
2024-04-11 14:51:43 +08:00
bool FluTreeModel::hitHasChildrenExpanded(int row) {
2023-09-22 00:11:58 +08:00
auto itemData = _rows.at(row);
2024-04-11 14:51:43 +08:00
if (itemData->hasChildren() && itemData->_isExpanded) {
2023-09-22 00:11:58 +08:00
return true;
}
2023-09-19 00:31:49 +08:00
return false;
}
2024-04-11 14:51:43 +08:00
void FluTreeModel::refreshNode(int row) {
Q_EMIT dataChanged(index(row, 0), index(row, 0));
}
2023-09-18 18:10:27 +08:00
2024-04-11 14:51:43 +08:00
FluTreeNode *FluTreeModel::getNode(int row) {
2023-09-18 18:10:27 +08:00
return _rows.at(row);
}
2023-09-19 00:31:49 +08:00
2024-04-11 14:51:43 +08:00
void FluTreeModel::allExpand() {
2023-09-19 00:31:49 +08:00
beginResetModel();
2024-04-11 14:51:43 +08:00
QList<FluTreeNode *> data;
QList<FluTreeNode *> stack = _root->_children;
2023-09-19 00:31:49 +08:00
std::reverse(stack.begin(), stack.end());
while (stack.count() > 0) {
2024-04-11 14:51:43 +08:00
auto item = stack.at(stack.count() - 1);
2023-09-19 00:31:49 +08:00
stack.pop_back();
2024-04-11 14:51:43 +08:00
if (item->hasChildren()) {
2023-09-19 00:31:49 +08:00
item->_isExpanded = true;
}
data.append(item);
2024-04-11 14:51:43 +08:00
QList<FluTreeNode *> children = item->_children;
if (!children.isEmpty()) {
2023-09-19 00:31:49 +08:00
std::reverse(children.begin(), children.end());
2024-04-11 14:51:43 +08:00
foreach (auto c, children) {
stack.append(c);
}
2023-09-19 00:31:49 +08:00
}
}
_rows = data;
endResetModel();
}
2024-04-11 14:51:43 +08:00
void FluTreeModel::allCollapse() {
2023-09-19 00:31:49 +08:00
beginResetModel();
2024-04-11 14:51:43 +08:00
QList<FluTreeNode *> stack = _root->_children;
2023-09-19 00:31:49 +08:00
std::reverse(stack.begin(), stack.end());
while (stack.count() > 0) {
2024-04-11 14:51:43 +08:00
auto item = stack.at(stack.count() - 1);
2023-09-19 00:31:49 +08:00
stack.pop_back();
2024-04-11 14:51:43 +08:00
if (item->hasChildren()) {
2023-09-19 00:31:49 +08:00
item->_isExpanded = false;
}
2024-04-11 14:51:43 +08:00
QList<FluTreeNode *> children = item->_children;
if (!children.isEmpty()) {
2023-09-19 00:31:49 +08:00
std::reverse(children.begin(), children.end());
2024-04-11 14:51:43 +08:00
foreach (auto c, children) {
stack.append(c);
}
2023-09-19 00:31:49 +08:00
}
}
_rows = _root->_children;
endResetModel();
}