aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2019-08-13 07:28:24 +0200
committerGravatar bstoeger <32835590+bstoeger@users.noreply.github.com>2019-09-14 13:20:59 +0200
commitbe763452adc110cfcc011322d989698d897dd6ed (patch)
treeb4185f9d99a237621caa262a44340a9300396e7b
parenta79c45e4010a18f8ffe0742ab844743eeeebab9e (diff)
downloadsubsurface-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.cpp7
-rw-r--r--core/subsurface-qt/DiveObjectHelper.h7
-rw-r--r--desktop-widgets/templatelayout.cpp14
-rw-r--r--desktop-widgets/templatelayout.h79
-rw-r--r--qt-models/divelistmodel.cpp14
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);
}