//SPDX-FileCopyrightText: 2023 Yury Gubich //SPDX-License-Identifier: GPL-3.0-or-later #include "assets.h" #include "utils/helpers.h" const QHash Models::Assets::roles({ {Title, "title"}, {Icon, "icon"}, {Balance, "balance"}, {Archived, "archived"}, {Color, "color"}, {Currency, "currency"}, {CurrencyID, "currencyID"}, {ID, "assetID"} }); Models::Assets::Assets (Currencies& currencies, QObject* parent): QAbstractListModel(parent), records(), state(State::initial), currencies(currencies) {} void Models::Assets::clear () { beginResetModel(); records.clear(); endResetModel(); } void Models::Assets::add (const Asset& asset) { int index = getIndexByID(asset.id); if (index != -1) 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::add (const std::deque& assets) { if (assets.empty()) return; for (const Asset& asset : assets) if (getIndexByID(asset.id) != -1) 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::remove (Asset::ID id) { int index = getIndexByID(id); if (index == -1) throw std::runtime_error("An attempt to delete non existing Asset from asset model"); beginRemoveRows(QModelIndex(), index, index); records.erase(records.begin() + index); endRemoveRows(); } void Models::Assets::change (const Asset& asset) { int index = getIndexByID(asset.id); if (index == -1) throw std::runtime_error("An attempt to change non existing Asset in asset model"); records[index] = asset; emit dataChanged(createIndex(index, 0, &records[index]), createIndex(index, 0, &records[index])); } void Models::Assets::change (const std::deque& assets) { for (const Asset& asset : assets) change(asset); } Models::Asset Models::Assets::get (Asset::ID id) const { int index = getIndexByID(id); if (index == -1) throw std::runtime_error("An attempt to access non existing Asset from asset model"); return records[index]; } 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 { return roles; } 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 Currency: return currencies.getCode(records[row].currency); case CurrencyID: return records[row].currency; 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(); asset.currency = ser.value("currency").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(); } int Models::Assets::getIndexByID (Asset::ID id) const { for (std::size_t i = 0; i < records.size(); ++i) { if (records[i].id == id) return i; } return -1; } QVariantMap Models::Assets::getAssetByIndex (int index) const { QVariantMap result; if (index < 0 || index >= records.size()) return result; QModelIndex idx = createIndex(index, 0, &records[index]); for (int role = Roles::Title; role <= Roles::ID; ++role) result[roles[role]] = data(idx, role); return result; } QVariantMap Models::Assets::getAssetByID (Asset::ID id) const { return getAssetByIndex(getIndexByID(id)); }