Commit 2603551c authored by Volker Krause's avatar Volker Krause
Browse files

Move sorting to PassManager and add grouping by expirey status

parent bf5b1b03
Pipeline #185690 passed with stage
in 1 minute and 23 seconds
......@@ -39,8 +39,8 @@ private Q_SLOTS:
QCOMPARE(mgr.rowCount(), 0);
// test import
QVERIFY(mgr.import(JsonLdDocument::fromJsonSingular(QJsonDocument::fromJson(Test::readFile(QStringLiteral(SOURCE_DIR "/data/bahncard.json"))).object()), QStringLiteral("1")));
QVERIFY(mgr.import(JsonLdDocument::fromJsonSingular(QJsonDocument::fromJson(Test::readFile(QStringLiteral(SOURCE_DIR "/data/9euroticket.json"))).object()), QStringLiteral("2")));
QVERIFY(mgr.import(JsonLdDocument::fromJsonSingular(QJsonDocument::fromJson(Test::readFile(QStringLiteral(SOURCE_DIR "/data/bahncard.json"))).object())));
QVERIFY(mgr.import(JsonLdDocument::fromJsonSingular(QJsonDocument::fromJson(Test::readFile(QStringLiteral(SOURCE_DIR "/data/9euroticket.json"))).object())));
QCOMPARE(mgr.rowCount(), 2);
// retrieval
......@@ -54,6 +54,7 @@ private Q_SLOTS:
QVERIFY(!idx.data(PassManager::PassDataRole).toByteArray().isEmpty());
QCOMPARE(idx.data(PassManager::NameRole).toString(), QLatin1String("BahnCard 25 (2. Kl.) (BC25)"));
QCOMPARE(idx.data(PassManager::ValidUntilRole).toDateTime(), QDateTime({2122, 3, 24}, {23, 59, 59}));
QVERIFY(!idx.data(PassManager::SectionRole).toString().isEmpty());
QVERIFY(!mgr.pass(passId).isNull());
idx = mgr.index(1, 0);
......@@ -66,6 +67,7 @@ private Q_SLOTS:
QVERIFY(!idx.data(PassManager::PassDataRole).toByteArray().isEmpty());
QCOMPARE(idx.data(PassManager::NameRole).toString(), QLatin1String("9-Euro-Ticket"));
QCOMPARE(idx.data(PassManager::ValidUntilRole).toDateTime(), QDateTime({2022, 5, 31}, {23, 59, 59}));
QVERIFY(!idx.data(PassManager::SectionRole).toString().isEmpty());
QVERIFY(!mgr.pass(passId2).isNull());
mgr.remove(passId2);
QCOMPARE(mgr.rowCount(), 1);
......
......@@ -69,17 +69,14 @@ Kirigami.ScrollablePage {
}
}
KSortFilterProxyModel {
id: passSortModel
sourceModel: PassManager
sortRole: "name"
sortOrder: Qt.AscendingOrder
}
ListView {
id: passListView
model: passSortModel
model: PassManager
delegate: chooser
section.delegate: Kirigami.ListSectionHeader {
text: section
}
section.property: "section"
Kirigami.PlaceholderMessage {
anchors.centerIn: parent
......
......@@ -12,6 +12,8 @@
#include <KItinerary/ProgramMembership>
#include <KItinerary/Ticket>
#include <KLocalizedString>
#include <QDirIterator>
#include <QJsonDocument>
#include <QJsonObject>
......@@ -45,14 +47,26 @@ QDateTime PassManager::Entry::validUntil() const
return {};
}
bool PassManager::Entry::operator<(const PassManager::Entry &other) const
bool PassManager::PassComparator::operator()(const PassManager::Entry &lhs, const PassManager::Entry &rhs) const
{
return id < other.id;
}
// valid before invalid, then sorted by name
const auto lhsExpired = lhs.validUntil().isValid() && lhs.validUntil() < m_baseTime;
const auto rhsExpired = rhs.validUntil().isValid() && rhs.validUntil() < m_baseTime;
if (lhsExpired == rhsExpired) {
const auto nameCmp = lhs.name().localeAwareCompare(rhs.name());
if (nameCmp == 0) {
return lhs.id < rhs.id;
}
return nameCmp < 0;
}
return !lhsExpired;
}
PassManager::PassManager(QObject *parent)
: QAbstractListModel(parent)
, m_baseTime(QDateTime::currentDateTime())
{
load();
}
......@@ -85,7 +99,7 @@ bool PassManager::import(const QVariant &pass, const QString &id)
f.write(QJsonDocument(JsonLdDocument::toJson(entry.data)).toJson());
f.close();
const auto it = std::lower_bound(m_entries.begin(), m_entries.end(), entry);
const auto it = std::lower_bound(m_entries.begin(), m_entries.end(), entry, PassComparator(m_baseTime));
if (it != m_entries.end() && (*it).id == entry.id) {
(*it).data = entry.data;
const auto idx = index(std::distance(m_entries.begin(), it), 0);
......@@ -183,6 +197,11 @@ QVariant PassManager::data(const QModelIndex &index, int role) const
return entry.name();
case ValidUntilRole:
return entry.validUntil();
case SectionRole:
if (const auto dt = entry.validUntil(); dt.isValid() && dt < m_baseTime) {
return i18nc("no longer valid tickets", "Expired");
}
return i18nc("not yet expired tickets", "Valid");
}
return {};
......@@ -196,6 +215,7 @@ QHash<int, QByteArray> PassManager::roleNames() const
r.insert(PassTypeRole, "type");
r.insert(NameRole, "name");
r.insert(ValidUntilRole, "validUntil");
r.insert(SectionRole, "section");
return r;
}
......@@ -212,7 +232,7 @@ void PassManager::load()
}
m_entries.push_back(std::move(entry));
}
std::sort(m_entries.begin(), m_entries.end());
std::sort(m_entries.begin(), m_entries.end(), PassComparator(m_baseTime));
}
QByteArray PassManager::rawData(const Entry &entry) const
......
......@@ -7,6 +7,7 @@
#define PASSMANAGER_H
#include <QAbstractListModel>
#include <QDateTime>
/** Holds time-less pass or program membership elements.
* Not to be confused with PkPassManager, which handles storage
......@@ -26,6 +27,7 @@ public:
PassDataRole,
NameRole,
ValidUntilRole,
SectionRole,
};
enum PassType {
......@@ -64,15 +66,21 @@ private:
QString name() const;
QDateTime validUntil() const;
};
bool operator<(const Entry &other) const;
struct PassComparator {
PassComparator(const QDateTime &baseTime) : m_baseTime(baseTime) {}
bool operator()(const PassManager::Entry &lhs, const PassManager::Entry &rhs) const;
QDateTime m_baseTime;
};
std::vector<Entry> m_entries;
void load();
QByteArray rawData(const Entry &entry) const;
static QString basePath();
std::vector<Entry> m_entries;
QDateTime m_baseTime;
};
#endif // PASSMANAGER_H
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment