fuzbal/event_list.cpp

142 lines
3.1 KiB
C++
Raw Normal View History

#include "event_list.h"
#include <QJsonArray>
#include <QJSValue>
Qt::ItemFlags EventList::flags(const QModelIndex&) const
{
return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren;
}
QHash<int, QByteArray> EventList::roleNames() const
{
static const QHash<int, QByteArray> roles{
{Role::Time, "time"},
{Role::Tag, "tag"},
{Role::Values, "values"},
};
return roles;
}
int EventList::rowCount(const QModelIndex&) const
{
return events.size();
}
QVariant EventList::data(const QModelIndex& index, int role) const
{
const auto& event = events[index.row()];
switch (role) {
case Role::Time:
return event.time;
case Role::Tag:
return event.tag;
case Role::Values:
return event.values;
default:
return {};
}
}
bool EventList::setData(const QModelIndex& index, const QVariant& value, int role)
{
auto& event = events[index.row()];
switch (role) {
case Role::Time:
event.time = value.toLongLong();
break;
case Role::Tag:
event.tag = value.toString();
break;
case Role::Values:
event.values = value.value<QJSValue>().toVariant().toMap();
break;
default:
return false;
}
emit dataChanged(index, index, {role});
return true;
}
int EventList::insert(const int time)
{
int row = time == -1 ? rowCount() : find(time);
beginInsertRows(QModelIndex{}, row, row);
events.insert(row, {time});
endInsertRows();
return row;
}
bool EventList::removeRows(int row, int count, const QModelIndex&)
{
beginRemoveRows({}, row, row + count - 1);
while (row < events.size() && count-- > 0)
events.removeAt(row);
endRemoveRows();
return count == -1;
}
void EventList::load(const QJsonObject& json)
{
const auto& jsonTags = json["tags"].toArray();
if (!jsonTags.isEmpty()) {
tags = {};
tagsOrder.clear();
for (int i = 0; i < jsonTags.size(); i++) {
const auto name = jsonTags[i]["tag"].toString();
tags[name] = jsonTags[i].toObject();
tagsOrder.append(name);
}
emit tagsChanged();
}
const auto& jsonEvents = json["events"].toArray();
if (!jsonEvents.isEmpty()) {
beginResetModel();
events.clear();
for (int i = 0; i < jsonEvents.size(); i++) {
auto event = jsonEvents[i].toObject().toVariantMap();
events.append({
event["time"].toLongLong(),
event["tag"].toString(),
event[event.contains("values") ? "values" : "fields"].toMap(),
});
}
endResetModel();
}
}
QJsonObject EventList::save() const
{
QJsonArray jsonEvents;
for (const auto& event : events) {
jsonEvents.append(QJsonObject{
{"time", event.time},
{"tag", event.tag},
{"values", QJsonObject::fromVariantMap(event.values)}
});
}
QJsonArray jsonTags;
for (int i = 0; i < tagsOrder.size(); i++)
jsonTags.append(tags[tagsOrder[i]].toObject());
return {{"tags", jsonTags}, {"events", jsonEvents}};
}
// Return the index of the last event not later than given time.
// Assumes events are sorted by time.
int EventList::find(long long time) const
{
int low = 0;
int high = events.size() - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (events[mid].time <= time)
low = mid + 1;
else
high = mid - 1;
}
return low;
}