some first thoguhts of receiving actual data

This commit is contained in:
Blue 2024-01-16 18:12:41 -03:00
parent 74701e9431
commit 1597bd9522
Signed by: blue
GPG key ID: 9B203B252A63EE38
8 changed files with 448 additions and 41 deletions

12
API/models/CMakeLists.txt Normal file
View file

@ -0,0 +1,12 @@
# SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
# SPDX-License-Identifier: GPL-3.0-or-later
set(HEADERS
assets.h
)
set(SOURCES
assets.cpp
)
target_sources(magpie PRIVATE ${SOURCES})

138
API/models/assets.cpp Normal file
View file

@ -0,0 +1,138 @@
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#include "assets.h"
#include "../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() + 1);
records.push_back(asset);
endInsertRows();
}
void Models::Assets::addAssets (const std::deque<Asset>& 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());
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 insert to delete non existing Asset from asset model");
int row = index.row();
beginRemoveRows(QModelIndex(), row, row + 1);
records.erase(records.begin() + row);
if (state == State::syncronized) //give a second thought
state = State::initial;
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<int, QByteArray> Models::Assets::roleNames () const {
static const QHash<int, QByteArray> roleNames{
{Title, "title"}, {Icon, "icon"}, {Balance, "balance"}, {Archived, "archived"}
};
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;
}
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;
}
}
return QVariant();
}
bool Models::Assets::deserialize (const QVariantList& from, std::deque<Asset>& out) {
for (const QVariant& item : from) {
if (!item.canConvert<QVariantMap>())
return false;
const QVariantMap& ser = qast<QVariantMap>(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("archived").toUInt();
}
return true;
}
void Models::Assets::receivedAssets (const std::deque<Asset>& 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();
}

71
API/models/assets.h Normal file
View file

@ -0,0 +1,71 @@
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <deque>
#include <QString>
#include <QAbstractListModel>
#include <qqmlregistration.h>
namespace Models {
struct Asset {
unsigned int id;
QString title;
QString icon;
double balance;
bool archived;
unsigned int currency;
};
class Assets : public QAbstractListModel {
Q_OBJECT
QML_ELEMENT
public:
explicit Assets (QObject* parent = nullptr);
enum Roles {
Title = Qt::UserRole + 1,
Icon,
Balance,
Archived
};
void clear();
void addAsset(const Asset& asset);
void addAssets(const std::deque<Asset>& assets);
void deleteAsset(unsigned int id);
//Basic functionality:
int rowCount (const QModelIndex& parent = QModelIndex()) const override;
QHash<int, QByteArray> roleNames () const override;
//Fetch data dynamically:
bool canFetchMore (const QModelIndex& parent) const override;
void fetchMore (const QModelIndex& parent) override;
QVariant data (const QModelIndex& index, int role = Qt::DisplayRole) const override;
static bool deserialize(const QVariantList& from, std::deque<Asset>& out);
signals:
void requestAssets();
public slots:
void receivedAssets(const std::deque<Asset>& assets);
private:
QModelIndex getIndex(unsigned int id) const;
private:
enum class State {
initial,
requesting,
syncronized
};
State state;
std::deque<Asset> records;
};
}