//SPDX-FileCopyrightText: 2023 Yury Gubich //SPDX-License-Identifier: GPL-3.0-or-later #include "assets.h" #include "utils/helpers.h" Models::Assets::Assets (QObject* parent): QAbstractListModel(parent), records(), state(State::initial) {} void Models::Assets::clear () { beginResetModel(); records.clear(); endResetModel(); } void Models::Assets::addAsset (const Asset& asset) { QModelIndex index = getIndex(asset.id); if (index.isValid()) throw std::runtime_error("An attempt to insert a duplicating Asset to an asset model"); beginInsertRows(QModelIndex(), records.size(), records.size()); records.push_back(asset); endInsertRows(); } void Models::Assets::addAssets (const std::deque& assets) { if (assets.empty()) return; for (const Asset& asset : assets) if (getIndex(asset.id).isValid()) throw std::runtime_error("An attempt to insert a duplicating Asset to an asset model (bulk)"); beginInsertRows(QModelIndex(), records.size(), records.size() + assets.size() - 1); for (const Asset& asset : assets) records.push_back(asset); endInsertRows(); } void Models::Assets::deleteAsset (unsigned int id) { QModelIndex index = getIndex(id); if (!index.isValid()) throw std::runtime_error("An attempt to delete non existing Asset from asset model"); int row = index.row(); beginRemoveRows(QModelIndex(), row, row); records.erase(records.begin() + row); endRemoveRows(); } int Models::Assets::rowCount (const QModelIndex& parent) const { //For list models only the root node (an invalid parent) should return the //list's size. For all other (valid) parents, rowCount() should return 0 so //that it does not become a tree model. if (parent.isValid()) return 0; return records.size(); } QHash Models::Assets::roleNames () const { static const QHash roleNames({ {Title, "title"}, {Icon, "icon"}, {Balance, "balance"}, {Archived, "archived"}, {Color, "color"}, {Id, "assetId"} }); return roleNames; } bool Models::Assets::canFetchMore (const QModelIndex& parent) const { return state == State::initial; } void Models::Assets::fetchMore (const QModelIndex& parent) { if (state != State::initial) return; state = State::requesting; emit requestAssets(); } QVariant Models::Assets::data (const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); int row = index.row(); if (row >= 0 && row < records.size()) { switch (role) { case Qt::DisplayRole: case Title: return records[row].title; case Icon: return records[row].icon; case Balance: return records[row].balance; case Archived: return records[row].archived; case Color: return records[row].color; case Id: return records[row].id; } } return QVariant(); } bool Models::Assets::deserialize (const QVariantList& from, std::deque& out) { for (const QVariant& item : from) { if (!item.canConvert()) return false; const QVariantMap& ser = qast(item); Asset& asset = out.emplace_back(); asset.title = ser.value("title").toString(); asset.icon = ser.value("icon").toString(); asset.archived = ser.value("archived").toBool(); asset.id = ser.value("id").toUInt(); uint32_t color = ser.value("color").toUInt(); asset.color = QColor::fromRgba(color); } return true; } void Models::Assets::receivedAssets (const std::deque& assets) { beginResetModel(); records = assets; state = State::syncronized; endResetModel(); } QModelIndex Models::Assets::getIndex (unsigned int id) const { for (std::size_t i = 0; i < records.size(); ++i) { if (records[i].id == id) return createIndex(i, 0, &records[i]); } return QModelIndex(); }