diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2019-08-13 07:28:24 +0200 |
---|---|---|
committer | bstoeger <32835590+bstoeger@users.noreply.github.com> | 2019-09-14 13:20:59 +0200 |
commit | be763452adc110cfcc011322d989698d897dd6ed (patch) | |
tree | b4185f9d99a237621caa262a44340a9300396e7b | |
parent | a79c45e4010a18f8ffe0742ab844743eeeebab9e (diff) | |
download | subsurface-be763452adc110cfcc011322d989698d897dd6ed.tar.gz |
DiveObjectHelper: Turn DiveObjectHelper into Q_GADGET based object
DiveObjectHelper is a tiny wrapper around dive * to allow access
to dive data from QML and grantlee. It doesn't have to be a
full-fledged QObject with support for signals, etc. Therefore,
turn it into a Q_GADGET based object. This allows us passing the
object around as object, not as pointer to DiveObjectHelper.
This makes memory-management distinctly easier.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r-- | core/subsurface-qt/DiveObjectHelper.cpp | 7 | ||||
-rw-r--r-- | core/subsurface-qt/DiveObjectHelper.h | 7 | ||||
-rw-r--r-- | desktop-widgets/templatelayout.cpp | 14 | ||||
-rw-r--r-- | desktop-widgets/templatelayout.h | 79 | ||||
-rw-r--r-- | qt-models/divelistmodel.cpp | 14 |
5 files changed, 101 insertions, 20 deletions
diff --git a/core/subsurface-qt/DiveObjectHelper.cpp b/core/subsurface-qt/DiveObjectHelper.cpp index e4945f007..c19c03eb4 100644 --- a/core/subsurface-qt/DiveObjectHelper.cpp +++ b/core/subsurface-qt/DiveObjectHelper.cpp @@ -55,6 +55,13 @@ static QString getPressures(struct dive *dive, int i, enum returnPressureSelecto return fmt; } +// Qt's metatype system insists on generating a default constructed object, +// even if that makes no sense. Usage of this object *will* crash. +DiveObjectHelper::DiveObjectHelper() : + m_dive(nullptr) +{ +} + DiveObjectHelper::DiveObjectHelper(struct dive *d) : m_dive(d) { diff --git a/core/subsurface-qt/DiveObjectHelper.h b/core/subsurface-qt/DiveObjectHelper.h index 397bc4d36..7071c1580 100644 --- a/core/subsurface-qt/DiveObjectHelper.h +++ b/core/subsurface-qt/DiveObjectHelper.h @@ -9,8 +9,8 @@ #include <QVector> #include <QVariant> -class DiveObjectHelper : public QObject { - Q_OBJECT +class DiveObjectHelper { + Q_GADGET Q_PROPERTY(int number READ number CONSTANT) Q_PROPERTY(int id READ id CONSTANT) Q_PROPERTY(int rating READ rating CONSTANT) @@ -48,6 +48,7 @@ class DiveObjectHelper : public QObject { Q_PROPERTY(QStringList endPressure READ endPressure CONSTANT) Q_PROPERTY(QStringList firstGas READ firstGas CONSTANT) public: + DiveObjectHelper(); // This is only to be used by Qt's metatype system! DiveObjectHelper(struct dive *dive); int number() const; int id() const; @@ -92,6 +93,6 @@ public: private: struct dive *m_dive; }; - Q_DECLARE_METATYPE(DiveObjectHelper *) + Q_DECLARE_METATYPE(DiveObjectHelper) #endif diff --git a/desktop-widgets/templatelayout.cpp b/desktop-widgets/templatelayout.cpp index 99deeef97..bdcdfbbe9 100644 --- a/desktop-widgets/templatelayout.cpp +++ b/desktop-widgets/templatelayout.cpp @@ -134,19 +134,13 @@ QString TemplateLayout::generate() Grantlee::registerMetaType<template_options>(); Grantlee::registerMetaType<print_options>(); Grantlee::registerMetaType<CylinderObjectHelper>(); // TODO: Remove when grantlee supports Q_GADGET + Grantlee::registerMetaType<DiveObjectHelper>(); // TODO: Remove when grantlee supports Q_GADGET - // Note: Currently, this should not be transformed into a QVector<> or std::vector<>, - // as diveList contains pointers to elements in this list. But vectors might relocate - // and thus invalidate the pointers! std::list<> is used here, because the new elements - // can be directly constructed in the list with the emplace_back() call. - // Ultimately, the memory management should be fixed. - std::list<DiveObjectHelper> diveObjectList; QVariantList diveList; struct dive *dive; if (in_planner()) { - diveObjectList.emplace_back(&displayed_dive); - diveList.append(QVariant::fromValue(&diveObjectList.back())); + diveList.append(QVariant::fromValue(DiveObjectHelper(&displayed_dive))); emit progressUpdated(100.0); } else { int i; @@ -154,8 +148,7 @@ QString TemplateLayout::generate() //TODO check for exporting selected dives only if (!dive->selected && printOptions->print_selected) continue; - diveObjectList.emplace_back(dive); - diveList.append(QVariant::fromValue(&diveObjectList.back())); + diveList.append(QVariant::fromValue(DiveObjectHelper(dive))); progress++; emit progressUpdated(lrint(progress * 100.0 / totalWork)); } @@ -198,6 +191,7 @@ QString TemplateLayout::generateStatistics() Grantlee::registerMetaType<template_options>(); Grantlee::registerMetaType<print_options>(); Grantlee::registerMetaType<CylinderObjectHelper>(); // TODO: Remove when grantlee supports Q_GADGET + Grantlee::registerMetaType<DiveObjectHelper>(); // TODO: Remove when grantlee supports Q_GADGET QVariantList years; diff --git a/desktop-widgets/templatelayout.h b/desktop-widgets/templatelayout.h index 10c5e96cc..aea44b2b8 100644 --- a/desktop-widgets/templatelayout.h +++ b/desktop-widgets/templatelayout.h @@ -139,4 +139,83 @@ if (property == "description") { return object.gasMix; } GRANTLEE_END_LOOKUP + +// TODO: This is currently needed because our grantlee version +// doesn't support Q_GADGET based classes. A patch to fix this +// exists. Remove in due course. +GRANTLEE_BEGIN_LOOKUP(DiveObjectHelper) +if (property == "number") { + return object.number(); +} else if (property == "id") { + return object.id(); +} else if (property == "rating") { + return object.rating(); +} else if (property == "visibility") { + return object.visibility(); +} else if (property == "date") { + return object.date(); +} else if (property == "time") { + return object.time(); +} else if (property == "timestamp") { + return QVariant::fromValue(object.timestamp()); +} else if (property == "location") { + return object.location(); +} else if (property == "gps") { + return object.gps(); +} else if (property == "gps_decimal") { + return object.gps_decimal(); +} else if (property == "dive_site") { + return object.dive_site(); +} else if (property == "duration") { + return object.duration(); +} else if (property == "noDive") { + return object.noDive(); +} else if (property == "depth") { + return object.depth(); +} else if (property == "divemaster") { + return object.divemaster(); +} else if (property == "buddy") { + return object.buddy(); +} else if (property == "airTemp") { + return object.airTemp(); +} else if (property == "waterTemp") { + return object.waterTemp(); +} else if (property == "notes") { + return object.notes(); +} else if (property == "tags") { + return object.tags(); +} else if (property == "gas") { + return object.gas(); +} else if (property == "sac") { + return object.sac(); +} else if (property == "weightList") { + return object.weightList(); +} else if (property == "weights") { + return object.weights(); +} else if (property == "singleWeight") { + return object.singleWeight(); +} else if (property == "suit") { + return object.suit(); +} else if (property == "cylinderList") { + return object.cylinderList(); +} else if (property == "cylinders") { + return object.cylinders(); +} else if (property == "cylinderObjects") { + return QVariant::fromValue(object.cylinderObjects()); +} else if (property == "maxcns") { + return object.maxcns(); +} else if (property == "otu") { + return object.otu(); +} else if (property == "sumWeight") { + return object.sumWeight(); +} else if (property == "getCylinder") { + return object.getCylinder(); +} else if (property == "startPressure") { + return object.startPressure(); +} else if (property == "endPressure") { + return object.endPressure(); +} else if (property == "firstGas") { + return object.firstGas(); +} +GRANTLEE_END_LOOKUP #endif diff --git a/qt-models/divelistmodel.cpp b/qt-models/divelistmodel.cpp index 9c67ced8d..028bd3600 100644 --- a/qt-models/divelistmodel.cpp +++ b/qt-models/divelistmodel.cpp @@ -64,8 +64,8 @@ int DiveListSortModel::getIdxForId(int id) { for (int i = 0; i < rowCount(); i++) { QVariant v = data(index(i, 0), DiveListModel::DiveRole); - DiveObjectHelper *d = v.value<DiveObjectHelper *>(); - if (d->id() == id) + DiveObjectHelper d = v.value<DiveObjectHelper>(); + if (d.id() == id) return i; } return -1; @@ -239,13 +239,13 @@ QVariant DiveListModel::data(const QModelIndex &index, int role) const if(index.row() < 0 || index.row() >= m_dives.count()) return QVariant(); - DiveObjectHelper *curr_dive = m_dives[index.row()]; - const dive *d = curr_dive->getDive(); + DiveObjectHelper &curr_dive = *m_dives[index.row()]; + const dive *d = curr_dive.getDive(); if (!d) return QVariant(); switch(role) { - case DiveRole: return QVariant::fromValue<QObject*>(curr_dive); - case DiveDateRole: return (qlonglong)curr_dive->timestamp(); + case DiveRole: return QVariant::fromValue<DiveObjectHelper>(curr_dive); + case DiveDateRole: return (qlonglong)d->when; case TripIdRole: return d->divetrip ? QString::number((quint64)d->divetrip, 16) : QString(); case TripNrDivesRole: return d->divetrip ? d->divetrip->dives.nr : 0; case DateTimeRole: { @@ -305,7 +305,7 @@ DiveListModel *DiveListModel::instance() return m_instance; } -DiveObjectHelper* DiveListModel::at(int i) +DiveObjectHelper *DiveListModel::at(int i) { return m_dives.at(i); } |