diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2019-09-14 19:43:40 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2019-09-21 16:12:23 -0700 |
commit | ce751bd6963d13c23f554da4e5fc66ee0d74eb1f (patch) | |
tree | dc327f225b49048cf605c4c7c51dc443be738a7d | |
parent | 067a481b781b09d4f672733550eba987981ea8b6 (diff) | |
download | subsurface-ce751bd6963d13c23f554da4e5fc66ee0d74eb1f.tar.gz |
Mobile: pass trip-ids through QML, not formatted pointers
The section heading in the QtQuick ListView has to be a string.
Therefore, we passed a pointer formatted using hexadecimal notation.
Later, that was converted back without being checked.
A very scary proposition, so let's pass unique integer trip-id instead.
This means that on converting back we have to scan the trip table,
but that is a very minor cost comsidering to the gained robustness.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r-- | qt-models/divelistmodel.cpp | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/qt-models/divelistmodel.cpp b/qt-models/divelistmodel.cpp index 64661a3f8..4b0058b43 100644 --- a/qt-models/divelistmodel.cpp +++ b/qt-models/divelistmodel.cpp @@ -76,15 +76,21 @@ void DiveListSortModel::reload() mySourceModel->reload(); } -// In QML, section headings can only be strings. To identify dives that -// belong to the same trip, a string containing the trip-pointer in hexadecimal -// encoding is passed in. To format the trip heading, the string is then -// converted back with this function. +// In QtQuick ListView, section headings can only be strings. To identify dives +// that belong to the same trip, a string containing the trip-id is passed in. +// To format the trip heading, the string is then converted back with this function. QVariant DiveListSortModel::tripIdToObject(const QString &s) { if (s.isEmpty()) return QVariant(); - return QVariant::fromValue((dive_trip *)s.toULongLong(nullptr, 16)); + int id = s.toInt(); + dive_trip **trip = std::find_if(&trip_table.trips[0], &trip_table.trips[trip_table.nr], + [id] (const dive_trip *t) { return t->id == id; }); + if (trip == &trip_table.trips[trip_table.nr]) { + fprintf(stderr, "Warning: unknown trip id passed through QML: %d\n", id); + return QVariant(); + } + return QVariant::fromValue(*trip); } // the trip title is designed to be location (# dives) @@ -211,7 +217,10 @@ QVariant DiveListModel::data(const QModelIndex &index, int role) const switch(role) { case DiveRole: return QVariant::fromValue(DiveObjectHelper(d)); case DiveDateRole: return (qlonglong)d->when; - case TripIdRole: return d->divetrip ? QString::number((quint64)d->divetrip, 16) : QString(); + // We have to return a QString as trip-id, because that will be used as section + // variable in the QtQuick list view. That has to be a string because it will try + // to do locale-aware sorting. And amazingly this can't be changed. + case TripIdRole: return d->divetrip ? QString::number(d->divetrip->id) : QString(); case TripNrDivesRole: return d->divetrip ? d->divetrip->dives.nr : 0; case DateTimeRole: { QDateTime localTime = QDateTime::fromMSecsSinceEpoch(1000 * d->when, Qt::UTC); |