From 1af00703b367b060a0be450c3577e99dd30d86a4 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Wed, 17 Apr 2024 17:31:50 +0800 Subject: [PATCH] core: use C++ structures for weightsystem info Use std::vector<> instead of fixed size array. Doesn't do any logic change, even though the back-translation logic is ominous. Signed-off-by: Berthold Stoeger --- commands/command_edit.cpp | 14 ++++---- core/dive.cpp | 2 +- core/equipment.cpp | 52 ++++++++++++----------------- core/equipment.h | 23 +++++++------ core/units.h | 4 +++ desktop-widgets/modeldelegates.cpp | 5 ++- qt-models/weightsysteminfomodel.cpp | 23 ++++--------- qt-models/weightsysteminfomodel.h | 7 ++-- 8 files changed, 58 insertions(+), 72 deletions(-) diff --git a/commands/command_edit.cpp b/commands/command_edit.cpp index 0fb4b5992..d2cd24d7c 100644 --- a/commands/command_edit.cpp +++ b/commands/command_edit.cpp @@ -1079,12 +1079,12 @@ EditWeight::EditWeight(int index, weightsystem_t wsIn, bool currentDiveOnly) : // Try to untranslate the weightsystem name new_ws = clone_weightsystem(wsIn); QString vString(new_ws.description); - for (int i = 0; i < MAX_WS_INFO && ws_info[i].name; ++i) { - if (gettextFromC::tr(ws_info[i].name) == vString) { - free_weightsystem(new_ws); - new_ws.description = copy_string(ws_info[i].name); - break; - } + auto it = std::find_if(ws_info_table.begin(), ws_info_table.end(), + [&vString](const ws_info &info) + { return gettextFromC::tr(info.name.c_str()) == vString; }); + if (it != ws_info_table.end()) { + free_weightsystem(new_ws); + new_ws.description = strdup(it->name.c_str()); } // If that doesn't change anything, do nothing @@ -1102,7 +1102,7 @@ EditWeight::~EditWeight() void EditWeight::redo() { for (size_t i = 0; i < dives.size(); ++i) { - add_weightsystem_description(&new_ws); // This updates the weightsystem info table + add_weightsystem_description(new_ws); // This updates the weightsystem info table set_weightsystem(dives[i], indices[i], new_ws); emit diveListNotifier.weightEdited(dives[i], indices[i]); invalidate_dive_cache(dives[i]); // Ensure that dive is written in git_save() diff --git a/core/dive.cpp b/core/dive.cpp index 497774e0f..45ab40156 100644 --- a/core/dive.cpp +++ b/core/dive.cpp @@ -1298,7 +1298,7 @@ extern "C" struct dive *fixup_dive(struct dive *dive) } update_cylinder_related_info(dive); for (i = 0; i < dive->weightsystems.nr; i++) { - weightsystem_t *ws = &dive->weightsystems.weightsystems[i]; + const weightsystem_t &ws = dive->weightsystems.weightsystems[i]; add_weightsystem_description(ws); } /* we should always have a uniq ID as that gets assigned during alloc_dive(), diff --git a/core/equipment.cpp b/core/equipment.cpp index 492f24eee..fffd7f5fe 100644 --- a/core/equipment.cpp +++ b/core/equipment.cpp @@ -169,36 +169,28 @@ extern "C" void add_cylinder_description(const cylinder_type_t *type) type->workingpressure.mbar / 1000); } -extern "C" void add_weightsystem_description(const weightsystem_t *weightsystem) +void add_weightsystem_description(const weightsystem_t &weightsystem) { - const char *desc; - int i; - - desc = weightsystem->description; - if (!desc) + if (empty_string(weightsystem.description)) + return; + + auto it = std::find_if(ws_info_table.begin(), ws_info_table.end(), + [&weightsystem](const ws_info &info) + { return info.name == weightsystem.description; }); + if (it != ws_info_table.end()) { + it->weight = weightsystem.weight; return; - for (i = 0; i < MAX_WS_INFO && ws_info[i].name != NULL; i++) { - if (same_string(ws_info[i].name, desc)) { - ws_info[i].grams = weightsystem->weight.grams; - return; - } - } - if (i < MAX_WS_INFO) { - // FIXME: leaked on exit - ws_info[i].name = strdup(desc); - ws_info[i].grams = weightsystem->weight.grams; } + ws_info_table.push_back(ws_info { std::string(weightsystem.description), weightsystem.weight }); } -extern "C" struct ws_info_t *get_weightsystem_description(const char *name) +weight_t get_weightsystem_weight(const std::string &name) { - for (int i = 0; i < MAX_WS_INFO && ws_info[i].name != NULL; i++) { - // Also finds translated names (TODO: should only consider non-user items). - if (same_string(ws_info[i].name, name) || - same_string(translate("gettextFromC", ws_info[i].name), name)) - return &ws_info[i]; - } - return NULL; + // Also finds translated names (TODO: should only consider non-user items). + auto it = std::find_if(ws_info_table.begin(), ws_info_table.end(), + [&name](const ws_info &info) + { return info.name == name || translate("gettextFromC", info.name.c_str()) == name; }); + return it != ws_info_table.end() ? it->weight : weight_t(); } extern "C" weightsystem_t clone_weightsystem(weightsystem_t ws) @@ -370,12 +362,12 @@ extern "C" void reset_tank_info_table(struct tank_info_table *table) * We hardcode the most common weight system types * This is a bit odd as the weight system types don't usually encode weight */ -struct ws_info_t ws_info[MAX_WS_INFO] = { - { QT_TRANSLATE_NOOP("gettextFromC", "integrated"), 0 }, - { QT_TRANSLATE_NOOP("gettextFromC", "belt"), 0 }, - { QT_TRANSLATE_NOOP("gettextFromC", "ankle"), 0 }, - { QT_TRANSLATE_NOOP("gettextFromC", "backplate"), 0 }, - { QT_TRANSLATE_NOOP("gettextFromC", "clip-on"), 0 }, +struct std::vector ws_info_table = { + { QT_TRANSLATE_NOOP("gettextFromC", "integrated"), weight_t() }, + { QT_TRANSLATE_NOOP("gettextFromC", "belt"), weight_t() }, + { QT_TRANSLATE_NOOP("gettextFromC", "ankle"), weight_t() }, + { QT_TRANSLATE_NOOP("gettextFromC", "backplate"), weight_t() }, + { QT_TRANSLATE_NOOP("gettextFromC", "clip-on"), weight_t() }, }; extern "C" void remove_cylinder(struct dive *dive, int idx) diff --git a/core/equipment.h b/core/equipment.h index 0d23b9341..1bc04c2b2 100644 --- a/core/equipment.h +++ b/core/equipment.h @@ -68,8 +68,6 @@ struct weightsystem_table { weightsystem_t *weightsystems; }; -#define MAX_WS_INFO (100) - extern enum cylinderuse cylinderuse_from_text(const char *text); extern void copy_weights(const struct weightsystem_table *s, struct weightsystem_table *d); extern void copy_cylinders(const struct cylinder_table *s, struct cylinder_table *d); @@ -84,7 +82,6 @@ extern void add_cloned_cylinder(struct cylinder_table *t, cylinder_t cyl); extern cylinder_t *get_cylinder(const struct dive *d, int idx); extern cylinder_t *get_or_create_cylinder(struct dive *d, int idx); extern void add_cylinder_description(const cylinder_type_t *); -extern void add_weightsystem_description(const weightsystem_t *); extern bool same_weightsystem(weightsystem_t w1, weightsystem_t w2); extern void remove_cylinder(struct dive *dive, int idx); extern void remove_weightsystem(struct dive *dive, int idx); @@ -130,15 +127,21 @@ extern void extract_tank_info(const struct tank_info *info, volume_t *size, pres extern bool get_tank_info_data(struct tank_info_table *table, const char *name, volume_t *size, pressure_t *pressure); extern void set_tank_info_data(struct tank_info_table *table, const char *name, volume_t size, pressure_t working_pressure); -struct ws_info_t { - const char *name; - int grams; -}; -extern struct ws_info_t ws_info[MAX_WS_INFO]; -extern struct ws_info_t *get_weightsystem_description(const char *name); - #ifdef __cplusplus } + +#include +#include +#include + +struct ws_info { + std::string name; + weight_t weight; +}; +extern std::vector ws_info_table; +extern weight_t get_weightsystem_weight(const std::string &name); // returns 0 if not found +extern void add_weightsystem_description(const weightsystem_t &); + #endif #endif // EQUIPMENT_H diff --git a/core/units.h b/core/units.h index f781ab8df..cd77ef483 100644 --- a/core/units.h +++ b/core/units.h @@ -131,7 +131,11 @@ typedef struct typedef struct { +#ifdef __cplusplus + int grams = 0; +#else int grams; +#endif } weight_t; typedef struct diff --git a/desktop-widgets/modeldelegates.cpp b/desktop-widgets/modeldelegates.cpp index d0ca3e541..9432214e5 100644 --- a/desktop-widgets/modeldelegates.cpp +++ b/desktop-widgets/modeldelegates.cpp @@ -339,10 +339,9 @@ void WSInfoDelegate::setModelData(QWidget *, QAbstractItemModel *, const QModelI { WeightModel *mymodel = qobject_cast(currCombo.model); QString weightName = currCombo.activeText; - ws_info_t *info = get_weightsystem_description(qPrintable(weightName)); - int grams = info ? info->grams : 0; + weight_t weight = get_weightsystem_weight(qPrintable(weightName)); - mymodel->setTempWS(currCombo.currRow, weightsystem_t{ { grams }, copy_qstring(weightName), false }); + mymodel->setTempWS(currCombo.currRow, weightsystem_t{ weight, copy_qstring(weightName), false }); } static QAbstractItemModel *createWSInfoModel(QWidget *parent) diff --git a/qt-models/weightsysteminfomodel.cpp b/qt-models/weightsysteminfomodel.cpp index d784dca82..765741a14 100644 --- a/qt-models/weightsysteminfomodel.cpp +++ b/qt-models/weightsysteminfomodel.cpp @@ -1,17 +1,15 @@ // SPDX-License-Identifier: GPL-2.0 #include "qt-models/weightsysteminfomodel.h" -#include "core/subsurface-qt/divelistnotifier.h" -#include "core/dive.h" +#include "core/equipment.h" #include "core/metrics.h" #include "core/gettextfromc.h" QVariant WSInfoModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() >= rows) + if (index.row() < 0 || index.row() >= static_cast(ws_info_table.size())) return QVariant(); - struct ws_info_t *info = &ws_info[index.row()]; + const ws_info &info = ws_info_table[index.row()]; - int gr = info->grams; switch (role) { case Qt::FontRole: return defaultModelFont(); @@ -19,9 +17,10 @@ QVariant WSInfoModel::data(const QModelIndex &index, int role) const case Qt::EditRole: switch (index.column()) { case GR: - return gr; + return info.weight.grams; case DESCRIPTION: - return gettextFromC::tr(info->name); + // TODO: don't translate user supplied names + return gettextFromC::tr(info.name.c_str()); } break; } @@ -30,13 +29,5 @@ QVariant WSInfoModel::data(const QModelIndex &index, int role) const int WSInfoModel::rowCount(const QModelIndex&) const { - return rows; -} - -WSInfoModel::WSInfoModel(QObject *parent) : CleanerTableModel(parent) -{ - setHeaderDataStrings(QStringList() << tr("Description") << tr("kg")); - rows = 0; - for (struct ws_info_t *info = ws_info; info->name && info < ws_info + MAX_WS_INFO; info++, rows++) - ; + return static_cast(ws_info_table.size()); } diff --git a/qt-models/weightsysteminfomodel.h b/qt-models/weightsysteminfomodel.h index 04ebdbca4..c515be587 100644 --- a/qt-models/weightsysteminfomodel.h +++ b/qt-models/weightsysteminfomodel.h @@ -12,13 +12,10 @@ public: DESCRIPTION, GR }; - WSInfoModel(QObject *parent); + using CleanerTableModel::CleanerTableModel; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant data(const QModelIndex &index, int role) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; - -private: - int rows; }; #endif