magpie/models/currencies.cpp

133 lines
4.0 KiB
C++

//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#include "currencies.h"
#include "utils/helpers.h"
const QHash<int, QByteArray> 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<Currency>& 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<int, QByteArray> 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<Currency>& out) {
for (const QVariant& item : from) {
if (!item.canConvert<QVariantMap>())
return false;
const QVariantMap& ser = qast<QVariantMap>(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;
}