//SPDX-FileCopyrightText: 2023 Yury Gubich //SPDX-License-Identifier: GPL-3.0-or-later #include "currencies.h" #include "utils/helpers.h" const QHash Models::Currencies::roles({ {Id, "id"}, {Code, "code"}, {Title, "title"}, {Type, "type"}, {Value, "value"}, {Description, "description"}, {Icon, "icon"} }); Models::Currencies::Currencies (QObject* parent): QAbstractListModel(parent), order(), index(), map() {} void Models::Currencies::clear () { beginResetModel(); order.clear(); index.clear(); map.clear(); endResetModel(); } void Models::Currencies::add (const Currency& currency) { if (map.count(currency.id)) throw std::runtime_error("An attempt to insert a duplicating currency to a currency model"); beginInsertRows(QModelIndex(), index.size(), index.size()); Order::iterator itr = order.insert(order.end(), currency); index.push_back(itr); map.emplace(currency.id, itr); endInsertRows(); } void Models::Currencies::add (const std::deque& currencies) { if (currencies.empty()) return; for (const Currency& currency : currencies) if (map.count(currency.id)) throw std::runtime_error("An attempt to insert a duplicating currency to a currency model (bulk)"); beginInsertRows(QModelIndex(), index.size(), index.size() + currencies.size() - 1); for (const Currency& currency : currencies) { Order::iterator itr = order.insert(order.end(), currency); index.push_back(itr); map.emplace(currency.id, itr); } endInsertRows(); } void Models::Currencies::remove (Currency::ID id) { Map::iterator mItr = map.find(id); if (mItr == map.end()) throw std::runtime_error("An attempt to delete non existing currency from currency model"); Order::iterator itr = mItr->second; Index::iterator iItr = std::find(index.begin(), index.end(), itr); int row = std::distance(index.begin(), iItr); beginRemoveRows(QModelIndex(), row, row); map.erase(mItr); index.erase(iItr); order.erase(itr); endRemoveRows(); } int Models::Currencies::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 index.size(); } QHash Models::Currencies::roleNames () const { return roles; } QVariant Models::Currencies::data (const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); int row = index.row(); if (row >= 0 && row < Currencies::index.size()) { const Order::iterator& itr = Currencies::index[row]; switch (role) { case Qt::DisplayRole: case Title: return itr->title; case Icon: return itr->icon; case Description: return itr->description; case Code: return itr->code; case Type: return itr->type; case Id: return itr->id; case Value: return itr->value; } } return QVariant(); } bool Models::Currencies::deserialize (const QVariantList& from, std::deque& out) { for (const QVariant& item : from) { if (!item.canConvert()) return false; const QVariantMap& ser = qast(item); Currency& currency = out.emplace_back(); currency.title = ser.value("title").toString(); currency.icon = ser.value("icon", "").toString(); currency.description = ser.value("archived", "").toString(); currency.id = ser.value("id").toUInt(); currency.code = ser.value("code").toString(); currency.value = ser.value("value").toDouble(); currency.type = ser.value("type", 1).toUInt(); } return true; }