KPublicTransport

locationhistorymodel.cpp
1/*
2 SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "locationhistorymodel.h"
8#include "logging.h"
9
10#include <QDirIterator>
11#include <QJsonDocument>
12#include <QJsonObject>
13#include <QStandardPaths>
14
15using namespace KPublicTransport;
16
17static QString basePath()
18{
19#ifdef Q_OS_ANDROID
20 constexpr auto dataLoc = QStandardPaths::AppDataLocation;
21#else
22 constexpr auto dataLoc = QStandardPaths::GenericDataLocation;
23#endif
24 return QStandardPaths::writableLocation(dataLoc) + QLatin1String("/org.kde.kpublictransport/location-history/");
25}
26
27LocationHistoryModel::LocationHistoryModel(QObject *parent)
28 : QAbstractListModel(parent)
29{
30 rescan();
31}
32
33LocationHistoryModel::~LocationHistoryModel() = default;
34
35int LocationHistoryModel::rowCount(const QModelIndex &parent) const
36{
37 if (parent.isValid()) {
38 return 0;
39 }
40 return m_locations.size();
41}
42
43QVariant LocationHistoryModel::data(const QModelIndex &index, int role) const
44{
45 if (!checkIndex(index)) {
46 return {};
47 }
48
49 switch (role) {
50 case LocationRole: return m_locations[index.row()].loc;
51 case LocationNameRole: return m_locations[index.row()].loc.name();
52 case LastUsedRole: return m_locations[index.row()].lastUse;
53 case UseCountRole: return m_locations[index.row()].useCount;
54 }
55
56 return {};
57}
58
59QHash<int, QByteArray> LocationHistoryModel::roleNames() const
60{
62 r.insert(LocationRole, "location");
63 r.insert(LocationNameRole, "locationName");
64 r.insert(LastUsedRole, "lastUsed");
65 r.insert(UseCountRole, "useCount");
66 return r;
67}
68
69bool LocationHistoryModel::removeRow(int row, const QModelIndex& parent)
70{
72}
73
74bool LocationHistoryModel::removeRows(int row, int count, const QModelIndex &parent)
75{
76 if (parent.isValid()) {
77 return false;
78 }
79
80 const auto path = basePath();
81 beginRemoveRows({}, row, row + count - 1);
82 for (int i = row; i < row + count; ++i) {
83 QFile::remove(path + m_locations[i].id);
84 }
85 m_locations.erase(m_locations.begin() + row, m_locations.begin() + row + count);
87 return true;
88}
89
91{
92 for (auto it = m_locations.begin(); it != m_locations.end(); ++it) {
93 if (Location::isSame((*it).loc, loc)) {
94 (*it).loc = Location::merge((*it).loc, loc);
95 (*it).lastUse = QDateTime::currentDateTime();
96 (*it).useCount++;
97 store(*it);
98 const auto idx = index(std::distance(m_locations.begin(), it));
99 Q_EMIT dataChanged(idx, idx);
100 return;
101 }
102 }
103
104 Data data;
106 data.loc = loc;
107 data.lastUse = QDateTime::currentDateTime();
108 data.useCount = 1;
109 store(data);
110
111 beginInsertRows({}, m_locations.size(), m_locations.size());
112 m_locations.push_back(std::move(data));
114}
115
117{
119 const auto path = basePath();
120 for (const auto &data : m_locations) {
121 QFile::remove(path + data.id);
122 }
123 m_locations.clear();
125}
126
127void LocationHistoryModel::rescan()
128{
130 for(QDirIterator it(basePath(), QDir::Files); it.hasNext();) {
131 QFile f(it.next());
132 if (!f.open(QFile::ReadOnly)) {
133 qCWarning(Log) << "Unable to read history entry:" << f.fileName() << f.errorString();
134 continue;
135 }
136
137 const auto doc = QJsonDocument::fromJson(f.readAll());
138 const auto obj = doc.object();
139 Data data;
140 data.id = it.fileInfo().baseName();
141 data.loc = Location::fromJson(obj.value(QLatin1String("location")).toObject());
142 data.lastUse = QDateTime::fromString(obj.value(QLatin1String("lastUse")).toString(), Qt::ISODate);
143 data.useCount = obj.value(QLatin1String("useCount")).toInt();
144 m_locations.push_back(std::move(data));
145 }
147}
148
149void LocationHistoryModel::store(const LocationHistoryModel::Data &data) const
150{
151 const auto path = basePath();
152 QDir().mkpath(path);
153
154 QFile f(path + data.id);
155 if (!f.open(QFile::WriteOnly)) {
156 qCWarning(Log) << "Unable to write history entry:" << f.fileName() << f.errorString();
157 return;
158 }
159
160 QJsonObject obj;
161 obj.insert(QLatin1String("location"), Location::toJson(data.loc));
162 obj.insert(QLatin1String("lastUse"), data.lastUse.toString(Qt::ISODate));
163 obj.insert(QLatin1String("useCount"), data.useCount);
164 f.write(QJsonDocument(obj).toJson(QJsonDocument::Compact));
165}
void clear()
Delete the entire history content.
void addLocation(const KPublicTransport::Location &loc)
Add a location to the history.
static Location fromJson(const QJsonObject &obj)
Deserialize a Location object from JSON.
Definition location.cpp:497
static QJsonObject toJson(const Location &loc)
Serializes one Location object to JSON.
Definition location.cpp:456
static Location merge(const Location &lhs, const Location &rhs)
Merge two departure instances.
Definition location.cpp:380
static bool isSame(const Location &lhs, const Location &rhs)
Checks if to instances refer to the same location (which does not necessarily mean they are exactly e...
Definition location.cpp:274
QString path(const QString &relativePath)
Query operations and data types for accessing realtime public transport information from online servi...
KEDUVOCDOCUMENT_EXPORT void rescan()
void beginInsertRows(const QModelIndex &parent, int first, int last)
void beginRemoveRows(const QModelIndex &parent, int first, int last)
bool checkIndex(const QModelIndex &index, CheckIndexOptions options) const const
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles)
bool removeRow(int row, const QModelIndex &parent)
virtual QHash< int, QByteArray > roleNames() const const
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
QDateTime currentDateTime()
QDateTime fromString(QStringView string, QStringView format, QCalendar cal)
QString toString(QStringView format, QCalendar cal) const const
bool mkpath(const QString &dirPath) const const
bool hasNext() const const
bool remove()
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
iterator insert(QLatin1StringView key, const QJsonValue &value)
int row() const const
Q_EMITQ_EMIT
QObject * parent() const const
QString writableLocation(StandardLocation type)
QUuid createUuid()
QString toString(StringFormat mode) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jul 26 2024 11:59:21 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.