From 235146a95f5d79c54cf3b68b490c1cb0fb146b5f Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Sat, 9 Jan 2021 21:18:37 +0100 Subject: [PATCH] profile: pass dive to DiveHandler The DiveHandler shows a context menu where a cylinder can be chosen. This indirectly accesses the global displayed_dive variable. Remove this in a step to make the profile reentrant. The code was quite ominous: instead of simply generating the list of cylinders, a global model was reset and then accessed with Qt's cumbersome model/view API. All this trampling over global state can be removed by simply making the function that generates the list globally accessible. Signed-off-by: Berthold Stoeger --- core/qthelper.cpp | 17 +++++++++++++++++ core/qthelper.h | 1 + profile-widget/divehandler.cpp | 13 ++++++------- profile-widget/divehandler.h | 5 ++++- profile-widget/profilewidget2.cpp | 2 +- qt-models/models.cpp | 19 +------------------ 6 files changed, 30 insertions(+), 27 deletions(-) diff --git a/core/qthelper.cpp b/core/qthelper.cpp index ed2aeb924..fe06a7c00 100644 --- a/core/qthelper.cpp +++ b/core/qthelper.cpp @@ -1274,6 +1274,23 @@ QString get_gas_string(struct gasmix gas) return result; } +QStringList get_dive_gas_list(const struct dive *d) +{ + QStringList list; + for (int i = 0; i < d->cylinders.nr; i++) { + const cylinder_t *cyl = get_cylinder(d, i); + /* Check if we have the same gasmix two or more times + * If yes return more verbose string */ + int same_gas = same_gasmix_cylinder(cyl, i, d, true); + if (same_gas == -1) + list.push_back(get_gas_string(cyl->gasmix)); + else + list.push_back(get_gas_string(cyl->gasmix) + QString(" (%1 %2 ").arg(gettextFromC::tr("cyl.")).arg(i + 1) + + cyl->type.description + ")"); + } + return list; +} + QString get_taglist_string(struct tag_entry *tag_list) { char *buffer = taglist_get_tagstring(tag_list); diff --git a/core/qthelper.h b/core/qthelper.h index d78f65357..b380d2c8c 100644 --- a/core/qthelper.h +++ b/core/qthelper.h @@ -27,6 +27,7 @@ QString weight_string(int weight_in_grams); QString distance_string(int distanceInMeters); bool gpsHasChanged(struct dive *dive, struct dive *master, const QString &gps_text, bool *parsed_out = 0); QString get_gas_string(struct gasmix gas); +QStringList get_dive_gas_list(const struct dive *d); QString get_taglist_string(struct tag_entry *tag_list); QStringList stringToList(const QString &s); void read_hashes(); diff --git a/profile-widget/divehandler.cpp b/profile-widget/divehandler.cpp index ab56feb6f..4a5088964 100644 --- a/profile-widget/divehandler.cpp +++ b/profile-widget/divehandler.cpp @@ -1,15 +1,16 @@ // SPDX-License-Identifier: GPL-2.0 #include "divehandler.h" #include "profilewidget2.h" +#include "core/dive.h" #include "core/gettextfromc.h" +#include "core/qthelper.h" #include "qt-models/diveplannermodel.h" -#include "qt-models/models.h" #include #include #include -DiveHandler::DiveHandler() : QGraphicsEllipseItem() +DiveHandler::DiveHandler(const struct dive *d) : dive(d) { setRect(-5, -5, 10, 10); setFlags(ItemIgnoresTransformations | ItemIsSelectable | ItemIsMovable | ItemSendsGeometryChanges); @@ -32,12 +33,10 @@ void DiveHandler::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance(); QModelIndex index = plannerModel->index(parentIndex(), DivePlannerPointsModel::GAS); if (index.sibling(index.row() + 1, index.column()).isValid()) { - GasSelectionModel *model = GasSelectionModel::instance(); - model->repopulate(); - int rowCount = model->rowCount(); - for (int i = 0; i < rowCount; i++) { + QStringList gases = get_dive_gas_list(dive); + for (int i = 0; i < gases.size(); i++) { QAction *action = new QAction(&m); - action->setText(model->data(model->index(i, 0), Qt::DisplayRole).toString()); + action->setText(gases[i]); action->setData(i); connect(action, &QAction::triggered, this, &DiveHandler::changeGas); m.addAction(action); diff --git a/profile-widget/divehandler.h b/profile-widget/divehandler.h index ecd0248c8..2bf3527ac 100644 --- a/profile-widget/divehandler.h +++ b/profile-widget/divehandler.h @@ -5,10 +5,12 @@ #include #include +struct dive; + class DiveHandler : public QObject, public QGraphicsEllipseItem { Q_OBJECT public: - DiveHandler(); + DiveHandler(const struct dive *d); protected: void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); @@ -26,6 +28,7 @@ slots: void selfRemove(); void changeGas(); private: + const struct dive *dive; QElapsedTimer t; }; diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp index 90638649d..a20504be2 100644 --- a/profile-widget/profilewidget2.cpp +++ b/profile-widget/profilewidget2.cpp @@ -1695,7 +1695,7 @@ void ProfileWidget2::disconnectTemporaryConnections() #ifndef SUBSURFACE_MOBILE void ProfileWidget2::pointInserted(const QModelIndex&, int, int) { - DiveHandler *item = new DiveHandler(); + DiveHandler *item = new DiveHandler(&displayed_dive); scene()->addItem(item); handles << item; diff --git a/qt-models/models.cpp b/qt-models/models.cpp index 70f95abc1..dfc917993 100644 --- a/qt-models/models.cpp +++ b/qt-models/models.cpp @@ -24,26 +24,9 @@ GasSelectionModel *GasSelectionModel::instance() return &self; } -static QStringList getGasList() -{ - QStringList list; - for (int i = 0; i < displayed_dive.cylinders.nr; i++) { - const cylinder_t *cyl = get_cylinder(&displayed_dive, i); - /* Check if we have the same gasmix two or more times - * If yes return more verbose string */ - int same_gas = same_gasmix_cylinder(cyl, i, &displayed_dive, true); - if (same_gas == -1) - list.push_back(get_gas_string(cyl->gasmix)); - else - list.push_back(get_gas_string(cyl->gasmix) + QString(" (%1 %2 ").arg(GasSelectionModel::tr("cyl.")).arg(i + 1) + - cyl->type.description + ")"); - } - return list; -} - void GasSelectionModel::repopulate() { - setStringList(getGasList()); + setStringList(get_dive_gas_list(&displayed_dive)); } QVariant GasSelectionModel::data(const QModelIndex &index, int role) const