mirror of
https://github.com/subsurface/subsurface.git
synced 2025-01-19 06:15:26 +00:00
Mobile: don't format trip heading for all dives
QML's ListView uses the "section" property to test if items belong to the same section. Apparently, this must be a string and therefore we can't pass e.g. a dive-trip object. Therefore a specially formatted string was passed in, which was guaranteed to be unique (contained the dive-trip pointer value) and the fully formatted trip-title and short-date. The disadvantage of that approach is that the formatting is performed for every dive and not every trip. Perhaps not a problem now, but it makes it for example necessary to cache the number of filtered dives. To be more flexible, pass in only the pointer value formatted as hexadecimal string and provide a function to convert that string back to a trip-pointer (in the form of a QVariant, so that it can be passed to QML). Moreover provide two functions for formatting the title and the short-date. The three new functions are members of DiveListSortModel. This might not be the perfect place, but it is easy to reach from the DiveListView. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
a863386cd4
commit
68414531ad
5 changed files with 67 additions and 51 deletions
|
@ -324,40 +324,9 @@ QList<CylinderObjectHelper*> DiveObjectHelper::cylinderObjects() const
|
|||
return m_cyls;
|
||||
}
|
||||
|
||||
// combine the pointer address with the trip title so that
|
||||
// we detect multiple, destinct trips with the same title
|
||||
// the trip title is designed to be
|
||||
// location (# dives)
|
||||
// or, if there is no location name
|
||||
// date range (# dives)
|
||||
// where the date range is given as "month year" or "month-month year" or "month year - month year"
|
||||
QString DiveObjectHelper::tripMeta() const
|
||||
QString DiveObjectHelper::tripId() const
|
||||
{
|
||||
QString ret = EMPTY_DIVE_STRING;
|
||||
struct dive_trip *dt = m_dive->divetrip;
|
||||
if (dt) {
|
||||
QString numDives = tr("(%n dive(s))", "", dt->showndives);
|
||||
QString title(dt->location);
|
||||
QDateTime firstTime = QDateTime::fromMSecsSinceEpoch(1000*trip_date(dt), Qt::UTC);
|
||||
QString firstMonth = firstTime.toString("MMM");
|
||||
QString tripDate = QStringLiteral("%1@%2").arg(firstMonth,firstTime.toString("yy"));
|
||||
|
||||
if (title.isEmpty()) {
|
||||
// so use the date range
|
||||
QString firstYear = firstTime.toString("yyyy");
|
||||
QDateTime lastTime = QDateTime::fromMSecsSinceEpoch(1000*dt->dives.dives[0]->when, Qt::UTC);
|
||||
QString lastMonth = lastTime.toString("MMM");
|
||||
QString lastYear = lastTime.toString("yyyy");
|
||||
if (lastMonth == firstMonth && lastYear == firstYear)
|
||||
title = firstMonth + " " + firstYear;
|
||||
else if (lastMonth != firstMonth && lastYear == firstYear)
|
||||
title = firstMonth + "-" + lastMonth + " " + firstYear;
|
||||
else
|
||||
title = firstMonth + " " + firstYear + " - " + lastMonth + " " + lastYear;
|
||||
}
|
||||
ret = QString::number((quint64)m_dive->divetrip, 16) + QLatin1Literal("++") + tripDate + QLatin1Literal("::") + QStringLiteral("%1 %2").arg(title, numDives);
|
||||
}
|
||||
return ret;
|
||||
return m_dive->divetrip ? QString::number((quint64)m_dive->divetrip, 16) : QString();
|
||||
}
|
||||
|
||||
int DiveObjectHelper::tripNrDives() const
|
||||
|
|
|
@ -39,7 +39,7 @@ class DiveObjectHelper : public QObject {
|
|||
Q_PROPERTY(QStringList cylinderList READ cylinderList CONSTANT)
|
||||
Q_PROPERTY(QStringList cylinders READ cylinders CONSTANT)
|
||||
Q_PROPERTY(QList<CylinderObjectHelper*> cylinderObjects READ cylinderObjects CONSTANT)
|
||||
Q_PROPERTY(QString tripMeta READ tripMeta CONSTANT)
|
||||
Q_PROPERTY(QString tripId READ tripId CONSTANT)
|
||||
Q_PROPERTY(int tripNrDives READ tripNrDives CONSTANT)
|
||||
Q_PROPERTY(int maxcns READ maxcns CONSTANT)
|
||||
Q_PROPERTY(int otu READ otu CONSTANT)
|
||||
|
@ -85,7 +85,7 @@ public:
|
|||
QStringList cylinders() const;
|
||||
QString cylinder(int idx) const;
|
||||
QList<CylinderObjectHelper*> cylinderObjects() const;
|
||||
QString tripMeta() const;
|
||||
QString tripId() const;
|
||||
int tripNrDives() const;
|
||||
int maxcns() const;
|
||||
int otu() const;
|
||||
|
|
|
@ -58,7 +58,7 @@ Kirigami.ScrollablePage {
|
|||
states: [
|
||||
State {
|
||||
name: "isHidden";
|
||||
when: dive.tripMeta !== activeTrip && ! diveOutsideTrip
|
||||
when: dive.tripId !== activeTrip && ! diveOutsideTrip
|
||||
PropertyChanges {
|
||||
target: innerListItem
|
||||
height: 0
|
||||
|
@ -67,7 +67,7 @@ Kirigami.ScrollablePage {
|
|||
},
|
||||
State {
|
||||
name: "isVisible";
|
||||
when: dive.tripMeta === activeTrip || diveOutsideTrip
|
||||
when: dive.tripId === activeTrip || diveOutsideTrip
|
||||
PropertyChanges {
|
||||
target: innerListItem
|
||||
height: diveListEntry.height + Kirigami.Units.smallSpacing
|
||||
|
@ -130,7 +130,7 @@ Kirigami.ScrollablePage {
|
|||
Item {
|
||||
Rectangle {
|
||||
id: leftBarDive
|
||||
width: dive.tripMeta == "" ? 0 : Kirigami.Units.smallSpacing
|
||||
width: dive.tripId == "" ? 0 : Kirigami.Units.smallSpacing
|
||||
height: diveListEntry.height * 0.8
|
||||
color: subsurfaceTheme.lightPrimaryColor
|
||||
anchors {
|
||||
|
@ -348,7 +348,10 @@ Kirigami.ScrollablePage {
|
|||
leftMargin: Kirigami.Units.smallSpacing
|
||||
}
|
||||
Controls.Label {
|
||||
text: { section.replace(/.*\+\+/, "").replace(/::.*/, "").replace("@", "\n'") }
|
||||
text: {
|
||||
var trip = diveListView.model.tripIdToObject(section);
|
||||
diveListView.model.tripShortDate(trip);
|
||||
}
|
||||
color: subsurfaceTheme.primaryTextColor
|
||||
font.pointSize: subsurfaceTheme.smallPointSize
|
||||
lineHeightMode: Text.FixedHeight
|
||||
|
@ -372,17 +375,8 @@ Kirigami.ScrollablePage {
|
|||
Controls.Label {
|
||||
id: sectionText
|
||||
text: {
|
||||
// if the tripMeta (which we get as "section") ends in ::-- we know
|
||||
// that there's no trip -- otherwise strip the meta information before
|
||||
// the :: and show the trip location
|
||||
var shownText
|
||||
var endsWithDoubleDash = /::--$/;
|
||||
if (endsWithDoubleDash.test(section) || section === "--") {
|
||||
shownText = ""
|
||||
} else {
|
||||
shownText = section.replace(/.*::/, "")
|
||||
}
|
||||
shownText
|
||||
var trip = diveListView.model.tripIdToObject(section);
|
||||
diveListView.model.tripTitle(trip);
|
||||
}
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
visible: text !== ""
|
||||
|
@ -526,7 +520,7 @@ Kirigami.ScrollablePage {
|
|||
maximumFlickVelocity: parent.height * 5
|
||||
bottomMargin: Kirigami.Units.iconSizes.medium + Kirigami.Units.gridUnit
|
||||
cacheBuffer: 40 // this will increase memory use, but should help with scrolling
|
||||
section.property: "dive.tripMeta"
|
||||
section.property: "dive.tripId"
|
||||
section.criteria: ViewSection.FullString
|
||||
section.delegate: tripHeading
|
||||
section.labelPositioning: ViewSection.CurrentLabelAtStart | ViewSection.InlineLabels
|
||||
|
|
|
@ -112,6 +112,56 @@ void DiveListSortModel::updateDivesShownInTrips()
|
|||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
QVariant DiveListSortModel::tripIdToObject(const QString &s)
|
||||
{
|
||||
if (s.isEmpty())
|
||||
return QVariant();
|
||||
return QVariant::fromValue((dive_trip *)s.toULongLong(nullptr, 16));
|
||||
}
|
||||
|
||||
// the trip title is designed to be location (# dives)
|
||||
// or, if there is no location name date range (# dives)
|
||||
// where the date range is given as "month year" or "month-month year" or "month year - month year"
|
||||
QString DiveListSortModel::tripTitle(const QVariant &tripIn)
|
||||
{
|
||||
dive_trip *dt = tripIn.value<dive_trip *>();
|
||||
if (!dt)
|
||||
return QString();
|
||||
QString numDives = tr("(%n dive(s))", "", dt->showndives);
|
||||
QString title(dt->location);
|
||||
|
||||
if (title.isEmpty()) {
|
||||
// so use the date range
|
||||
QDateTime firstTime = QDateTime::fromMSecsSinceEpoch(1000*trip_date(dt), Qt::UTC);
|
||||
QString firstMonth = firstTime.toString("MMM");
|
||||
QString firstYear = firstTime.toString("yyyy");
|
||||
QDateTime lastTime = QDateTime::fromMSecsSinceEpoch(1000*dt->dives.dives[0]->when, Qt::UTC);
|
||||
QString lastMonth = lastTime.toString("MMM");
|
||||
QString lastYear = lastTime.toString("yyyy");
|
||||
if (lastMonth == firstMonth && lastYear == firstYear)
|
||||
title = firstMonth + " " + firstYear;
|
||||
else if (lastMonth != firstMonth && lastYear == firstYear)
|
||||
title = firstMonth + "-" + lastMonth + " " + firstYear;
|
||||
else
|
||||
title = firstMonth + " " + firstYear + " - " + lastMonth + " " + lastYear;
|
||||
}
|
||||
return QStringLiteral("%1 %2").arg(title, numDives);
|
||||
}
|
||||
|
||||
QString DiveListSortModel::tripShortDate(const QVariant &tripIn)
|
||||
{
|
||||
dive_trip *dt = tripIn.value<dive_trip *>();
|
||||
if (!dt)
|
||||
return QString();
|
||||
QDateTime firstTime = QDateTime::fromMSecsSinceEpoch(1000*trip_date(dt), Qt::UTC);
|
||||
QString firstMonth = firstTime.toString("MMM");
|
||||
return QStringLiteral("%1\n'%2").arg(firstMonth,firstTime.toString("yy"));
|
||||
}
|
||||
|
||||
DiveListModel *DiveListModel::m_instance = NULL;
|
||||
|
||||
DiveListModel::DiveListModel(QObject *parent) : QAbstractListModel(parent)
|
||||
|
|
|
@ -15,6 +15,9 @@ public:
|
|||
void setSourceModel(QAbstractItemModel *sourceModel);
|
||||
Q_INVOKABLE void addAllDives();
|
||||
Q_INVOKABLE void clear();
|
||||
Q_INVOKABLE QVariant tripIdToObject(const QString &s);
|
||||
Q_INVOKABLE QString tripTitle(const QVariant &trip);
|
||||
Q_INVOKABLE QString tripShortDate(const QVariant &trip);
|
||||
public slots:
|
||||
int getDiveId(int idx);
|
||||
int getIdxForId(int id);
|
||||
|
|
Loading…
Add table
Reference in a new issue