From 0d011231e6810c4c002e6ea5d14fa15b137e6293 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Sat, 30 Mar 2024 13:40:00 +0100 Subject: [PATCH] desktop: unglobalize ComboBox-models The combo-boxes (cylinder type, weightsystem, etc.) were controlled by global models. Keeping these models up-to-date was very combersome and buggy. Create a new model everytime a combobox is opened. Ultimately it might even be better to create a copy of the strings and switch to simple QStringListModel. Set data in the core directly and don't do this via the models. The result is much simpler and easier to handle. Signed-off-by: Berthold Stoeger --- commands/command_edit.cpp | 19 +----- core/equipment.c | 52 ++++++++++++++- core/equipment.h | 4 ++ desktop-widgets/diveplanner.cpp | 15 +---- desktop-widgets/diveplanner.h | 5 -- desktop-widgets/modeldelegates.cpp | 64 +++++++++++-------- desktop-widgets/modeldelegates.h | 11 ++-- .../preferences/preferences_equipment.cpp | 9 +-- qt-models/cylindermodel.cpp | 20 ++---- qt-models/models.cpp | 7 +- qt-models/models.h | 4 +- qt-models/tankinfomodel.cpp | 52 +-------------- qt-models/tankinfomodel.h | 9 +-- qt-models/weightmodel.cpp | 4 +- qt-models/weightsysteminfomodel.cpp | 61 ++---------------- qt-models/weightsysteminfomodel.h | 9 +-- 16 files changed, 130 insertions(+), 215 deletions(-) diff --git a/commands/command_edit.cpp b/commands/command_edit.cpp index c98cbfa99..cd767c660 100644 --- a/commands/command_edit.cpp +++ b/commands/command_edit.cpp @@ -1090,11 +1090,6 @@ EditWeight::EditWeight(int index, weightsystem_t wsIn, bool currentDiveOnly) : dives.clear(); return; } - - WSInfoModel *wsim = WSInfoModel::instance(); - QModelIndexList matches = wsim->match(wsim->index(0, 0), Qt::DisplayRole, gettextFromC::tr(new_ws.description)); - if (!matches.isEmpty()) - wsim->setData(wsim->index(matches.first().row(), WSInfoModel::GR), new_ws.weight.grams); } EditWeight::~EditWeight() @@ -1105,6 +1100,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 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() @@ -1302,16 +1298,6 @@ EditCylinder::EditCylinder(int index, cylinder_t cylIn, EditCylinderType typeIn, } } - // Update the tank info model - TankInfoModel *tim = TankInfoModel::instance(); - QModelIndexList matches = tim->match(tim->index(0, 0), Qt::DisplayRole, gettextFromC::tr(cylIn.type.description)); - if (!matches.isEmpty()) { - if (cylIn.type.size.mliter != cyl[0].type.size.mliter) - tim->setData(tim->index(matches.first().row(), TankInfoModel::ML), cylIn.type.size.mliter); - if (cylIn.type.workingpressure.mbar != cyl[0].type.workingpressure.mbar) - tim->setData(tim->index(matches.first().row(), TankInfoModel::BAR), cylIn.type.workingpressure.mbar / 1000.0); - } - // The base class copied the cylinders for us, let's edit them for (int i = 0; i < (int)indexes.size(); ++i) { switch (type) { @@ -1338,6 +1324,8 @@ EditCylinder::EditCylinder(int index, cylinder_t cylIn, EditCylinderType typeIn, void EditCylinder::redo() { for (size_t i = 0; i < dives.size(); ++i) { + set_tank_info_size(&tank_info_table, cyl[i].type.description, cyl[i].type.size); + set_tank_info_workingpressure(&tank_info_table, cyl[i].type.description, cyl[i].type.workingpressure); std::swap(*get_cylinder(dives[i], indexes[i]), cyl[i]); update_cylinder_related_info(dives[i]); emit diveListNotifier.cylinderEdited(dives[i], indexes[i]); @@ -1358,7 +1346,6 @@ EditSensors::EditSensors(int toCylinderIn, int fromCylinderIn, int dcNr) return; setText(Command::Base::tr("Edit sensors")); - } void EditSensors::mapSensors(int toCyl, int fromCyl) diff --git a/core/equipment.c b/core/equipment.c index cdc818fce..c4cd1e767 100644 --- a/core/equipment.c +++ b/core/equipment.c @@ -108,6 +108,45 @@ void add_tank_info_imperial(struct tank_info_table *table, const char *name, int add_to_tank_info_table(table, table->nr, info); } +extern struct tank_info *get_tank_info(struct tank_info_table *table, const char *name) +{ + for (int i = 0; i < table->nr; ++i) { + if (same_string(table->infos[i].name, name)) + return &table->infos[i]; + } + return NULL; +} + +extern void set_tank_info_size(struct tank_info_table *table, const char *name, volume_t size) +{ + struct tank_info *info = get_tank_info(table, name); + if (info) { + // Try to be smart about metric vs. imperial + if (info->cuft == 0 && info->psi == 0) + info->ml = size.mliter; + else + info->cuft = lrint(ml_to_cuft(size.mliter)); + } else { + // By default add metric...? + add_tank_info_metric(table, name, size.mliter, 0); + } +} + +extern void set_tank_info_workingpressure(struct tank_info_table *table, const char *name, pressure_t working_pressure) +{ + struct tank_info *info = get_tank_info(table, name); + if (info) { + // Try to be smart about metric vs. imperial + if (info->cuft == 0 && info->psi == 0) + info->bar = working_pressure.mbar / 1000; + else + info->psi = lrint(mbar_to_PSI(working_pressure.mbar)); + } else { + // By default add metric...? + add_tank_info_metric(table, name, 0, working_pressure.mbar / 1000); + } +} + /* placeholders for a few functions that we need to redesign for the Qt UI */ void add_cylinder_description(const cylinder_type_t *type) { @@ -131,7 +170,7 @@ void add_weightsystem_description(const weightsystem_t *weightsystem) if (!desc) return; for (i = 0; i < MAX_WS_INFO && ws_info[i].name != NULL; i++) { - if (strcmp(ws_info[i].name, desc) == 0) { + if (same_string(ws_info[i].name, desc)) { ws_info[i].grams = weightsystem->weight.grams; return; } @@ -143,6 +182,17 @@ void add_weightsystem_description(const weightsystem_t *weightsystem) } } +struct ws_info_t *get_weightsystem_description(const char *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; +} + weightsystem_t clone_weightsystem(weightsystem_t ws) { weightsystem_t res = { ws.weight, copy_string(ws.description), ws.auto_filled }; diff --git a/core/equipment.h b/core/equipment.h index d46d37168..43de4dcf4 100644 --- a/core/equipment.h +++ b/core/equipment.h @@ -125,12 +125,16 @@ extern void reset_tank_info_table(struct tank_info_table *table); extern void clear_tank_info_table(struct tank_info_table *table); extern void add_tank_info_metric(struct tank_info_table *table, const char *name, int ml, int bar); extern void add_tank_info_imperial(struct tank_info_table *table, const char *name, int cuft, int psi); +extern void set_tank_info_size(struct tank_info_table *table, const char *name, volume_t size); +extern void set_tank_info_workingpressure(struct tank_info_table *table, const char *name, pressure_t working_pressure); +extern struct tank_info *get_tank_info(struct tank_info_table *table, const char *name); 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 } diff --git a/desktop-widgets/diveplanner.cpp b/desktop-widgets/diveplanner.cpp index 2431b09bb..cd0c19a3a 100644 --- a/desktop-widgets/diveplanner.cpp +++ b/desktop-widgets/diveplanner.cpp @@ -32,8 +32,8 @@ DivePlannerWidget::DivePlannerWidget(dive &planned_dive, PlannerWidgets *parent) ui.tableWidget->setTitle(tr("Dive planner points")); ui.tableWidget->setModel(plannerModel); connect(ui.tableWidget, &TableView::itemClicked, plannerModel, &DivePlannerPointsModel::remove); - ui.tableWidget->view()->setItemDelegateForColumn(DivePlannerPointsModel::GAS, new AirTypesDelegate(parent->gasModel.get(), this)); - ui.tableWidget->view()->setItemDelegateForColumn(DivePlannerPointsModel::DIVEMODE, new DiveTypesDelegate(parent->diveTypeModel.get(), this)); + ui.tableWidget->view()->setItemDelegateForColumn(DivePlannerPointsModel::GAS, new AirTypesDelegate(planned_dive, this)); + ui.tableWidget->view()->setItemDelegateForColumn(DivePlannerPointsModel::DIVEMODE, new DiveTypesDelegate(this)); ui.cylinderTableWidget->setTitle(tr("Available gases")); ui.cylinderTableWidget->setBtnToolTip(tr("Add cylinder")); ui.cylinderTableWidget->setModel(cylinders); @@ -56,9 +56,6 @@ DivePlannerWidget::DivePlannerWidget(dive &planned_dive, PlannerWidgets *parent) view->setItemDelegateForColumn(CylindersModel::USE, tankUseDelegate); connect(ui.cylinderTableWidget, &TableView::addButtonClicked, plannerModel, &DivePlannerPointsModel::addCylinder_clicked); connect(ui.tableWidget, &TableView::addButtonClicked, plannerModel, &DivePlannerPointsModel::addDefaultStop); - connect(cylinders, &CylindersModel::dataChanged, parent, &PlannerWidgets::repopulateGasModel); - connect(cylinders, &CylindersModel::rowsInserted, parent, &PlannerWidgets::repopulateGasModel); - connect(cylinders, &CylindersModel::rowsRemoved, parent, &PlannerWidgets::repopulateGasModel); connect(cylinders, &CylindersModel::dataChanged, plannerModel, &DivePlannerPointsModel::emitDataChanged); connect(cylinders, &CylindersModel::dataChanged, plannerModel, &DivePlannerPointsModel::cylinderModelEdited); connect(cylinders, &CylindersModel::rowsInserted, plannerModel, &DivePlannerPointsModel::cylinderModelEdited); @@ -542,8 +539,6 @@ void PlannerDetails::setPlanNotes(QString plan) PlannerWidgets::PlannerWidgets() : planned_dive(alloc_dive()), - gasModel(std::make_unique()), - diveTypeModel(std::make_unique()), plannerWidget(*planned_dive, this), plannerSettingsWidget(this) { @@ -587,7 +582,6 @@ void PlannerWidgets::planDive() { DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN); - repopulateGasModel(); plannerWidget.setReplanButton(false); plannerWidget.setupStartTime(timestampToDateTime(planned_dive->when)); // This will reload the profile! } @@ -612,11 +606,6 @@ void PlannerWidgets::replanDive(int currentDC) DivePlannerPointsModel::instance()->cylindersModel()->updateDive(planned_dive.get(), currentDC); } -void PlannerWidgets::repopulateGasModel() -{ - gasModel->repopulate(planned_dive.get()); -} - void PlannerWidgets::printDecoPlan() { #ifndef NO_PRINTING diff --git a/desktop-widgets/diveplanner.h b/desktop-widgets/diveplanner.h index 5fef8efcc..e4c68f80c 100644 --- a/desktop-widgets/diveplanner.h +++ b/desktop-widgets/diveplanner.h @@ -10,8 +10,6 @@ #include class DivePlannerPointsModel; -class GasSelectionModel; -class DiveTypeSelectionModel; class PlannerWidgets; struct dive; @@ -92,10 +90,7 @@ public slots: void printDecoPlan(); public: - void repopulateGasModel(); OwningDivePtr planned_dive; - std::unique_ptr gasModel; - std::unique_ptr diveTypeModel; DivePlannerWidget plannerWidget; PlannerSettingsWidget plannerSettingsWidget; PlannerDetails plannerDetails; diff --git a/desktop-widgets/modeldelegates.cpp b/desktop-widgets/modeldelegates.cpp index 30936425e..e432448dc 100644 --- a/desktop-widgets/modeldelegates.cpp +++ b/desktop-widgets/modeldelegates.cpp @@ -84,9 +84,11 @@ const QSize &StarWidgetsDelegate::starSize() const return minStarSize; } -ComboBoxDelegate::ComboBoxDelegate(QAbstractItemModel *model, QObject *parent, bool allowEdit) : QStyledItemDelegate(parent), model(model) +ComboBoxDelegate::ComboBoxDelegate(std::function create_model_func, + QObject *parent, bool allowEdit) : QStyledItemDelegate(parent), + create_model_func(std::move(create_model_func)), + editable(allowEdit) { - editable = allowEdit; connect(this, &ComboBoxDelegate::closeEditor, this, &ComboBoxDelegate::editorClosed); } @@ -105,7 +107,7 @@ void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) QWidget *ComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const { QComboBox *comboDelegate = new QComboBox(parent); - comboDelegate->setModel(model); + comboDelegate->setModel(create_model_func(comboDelegate)); comboDelegate->setEditable(true); comboDelegate->completer()->setCaseSensitivity(Qt::CaseInsensitive); comboDelegate->completer()->setCompletionMode(QCompleter::PopupCompletion); @@ -207,34 +209,34 @@ void ComboBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionV editor->setGeometry(defaultRect); } -void TankInfoDelegate::setModelData(QWidget *, QAbstractItemModel *, const QModelIndex &) const +void TankInfoDelegate::setModelData(QWidget *, QAbstractItemModel *model, const QModelIndex &index) const { QAbstractItemModel *mymodel = currCombo.model; - TankInfoModel *tanks = TankInfoModel::instance(); QString cylinderName = currCombo.activeText.trimmed(); if (cylinderName.isEmpty()) { mymodel->setData(IDX(CylindersModel::TYPE), cylinderName, CylindersModel::TEMP_ROLE); return; } - QModelIndexList matches = tanks->match(tanks->index(0, 0), Qt::DisplayRole, cylinderName, 1, Qt::MatchFixedString | Qt::MatchWrap); - int row; - if (matches.isEmpty()) { - tanks->insertRows(tanks->rowCount(), 1); - tanks->setData(tanks->index(tanks->rowCount() - 1, 0), currCombo.activeText); - row = tanks->rowCount() - 1; - } else { - row = matches.first().row(); - cylinderName = matches.first().data().toString(); + int tankSize = 0; + int tankPressure = 0; + tank_info *info = get_tank_info(&tank_info_table, qPrintable(cylinderName)); + if (info) { + // OMG, the units here are a mess. + tankSize = info->ml != 0 ? info->ml : lrint(cuft_to_l(info->cuft) * 1000.0); + tankPressure = info->bar != 0 ? info->bar * 1000 : psi_to_mbar(info->psi); } - int tankSize = tanks->data(tanks->index(row, TankInfoModel::ML)).toInt(); - int tankPressure = tanks->data(tanks->index(row, TankInfoModel::BAR)).toInt(); mymodel->setData(IDX(CylindersModel::TYPE), cylinderName, CylindersModel::TEMP_ROLE); mymodel->setData(IDX(CylindersModel::WORKINGPRESS), tankPressure, CylindersModel::TEMP_ROLE); mymodel->setData(IDX(CylindersModel::SIZE), tankSize, CylindersModel::TEMP_ROLE); } -TankInfoDelegate::TankInfoDelegate(QObject *parent) : ComboBoxDelegate(TankInfoModel::instance(), parent, true) +static QAbstractItemModel *createTankInfoModel(QWidget *parent) +{ + return new TankInfoModel(parent); +} + +TankInfoDelegate::TankInfoDelegate(QObject *parent) : ComboBoxDelegate(&createTankInfoModel, parent, true) { } @@ -340,20 +342,19 @@ void WSInfoDelegate::editorClosed(QWidget *, QAbstractItemDelegate::EndEditHint void WSInfoDelegate::setModelData(QWidget *, QAbstractItemModel *, const QModelIndex &) const { WeightModel *mymodel = qobject_cast(currCombo.model); - WSInfoModel *wsim = WSInfoModel::instance(); QString weightName = currCombo.activeText; - QModelIndexList matches = wsim->match(wsim->index(0, 0), Qt::DisplayRole, weightName, 1, Qt::MatchFixedString | Qt::MatchWrap); - int grams = 0; - if (!matches.isEmpty()) { - int row = matches.first().row(); - weightName = matches.first().data().toString(); - grams = wsim->data(wsim->index(row, WSInfoModel::GR)).toInt(); - } + ws_info_t *info = get_weightsystem_description(qPrintable(weightName)); + int grams = info ? info->grams : 0; mymodel->setTempWS(currCombo.currRow, weightsystem_t{ { grams }, copy_qstring(weightName), false }); } -WSInfoDelegate::WSInfoDelegate(QObject *parent) : ComboBoxDelegate(WSInfoModel::instance(), parent, true) +static QAbstractItemModel *createWSInfoModel(QWidget *parent) +{ + return new WSInfoModel(parent); +} + +WSInfoDelegate::WSInfoDelegate(QObject *parent) : ComboBoxDelegate(&createWSInfoModel, parent, true) { } @@ -369,7 +370,9 @@ void AirTypesDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, model->setData(index, QVariant(combo->currentIndex())); } -AirTypesDelegate::AirTypesDelegate(QAbstractItemModel *model, QObject *parent) : ComboBoxDelegate(model, parent, false) +AirTypesDelegate::AirTypesDelegate(const dive &d, QObject *parent) : + ComboBoxDelegate([d] (QWidget *parent) { return new GasSelectionModel(d, parent); }, + parent, false) { } @@ -385,7 +388,12 @@ void DiveTypesDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, model->setData(index, QVariant(combo->currentIndex())); } -DiveTypesDelegate::DiveTypesDelegate(QAbstractItemModel *model, QObject *parent) : ComboBoxDelegate(model, parent, false) +static QAbstractItemModel *createDiveTypeSelectionModel(QWidget *parent) +{ + return new DiveTypeSelectionModel(parent); +} + +DiveTypesDelegate::DiveTypesDelegate(QObject *parent) : ComboBoxDelegate(&createDiveTypeSelectionModel, parent, false) { } diff --git a/desktop-widgets/modeldelegates.h b/desktop-widgets/modeldelegates.h index 4f3e12804..9d3a392b0 100644 --- a/desktop-widgets/modeldelegates.h +++ b/desktop-widgets/modeldelegates.h @@ -6,8 +6,10 @@ #include #include +#include class QPainter; +struct dive; struct divecomputer; class DiveListDelegate : public QStyledItemDelegate { @@ -32,7 +34,8 @@ private: class ComboBoxDelegate : public QStyledItemDelegate { Q_OBJECT public: - explicit ComboBoxDelegate(QAbstractItemModel *model, QObject *parent = 0, bool allowEdit = true); + // First parameter: function that creates a model and makes it a child of the passed-in widget. + explicit ComboBoxDelegate(std::function create_model_func, QObject *parent = 0, bool allowEdit = true); private slots: void testActivationString(const QString &currString); @@ -43,13 +46,13 @@ protected slots: virtual void editorClosed(QWidget *widget, QAbstractItemDelegate::EndEditHint hint) = 0; private: + std::function create_model_func; bool editable; QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void setEditorData(QWidget *editor, const QModelIndex &index) const override; void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; bool eventFilter(QObject *object, QEvent *event) override; protected: - QAbstractItemModel *model; mutable struct CurrSelected { QComboBox *comboEditor; int currRow; @@ -103,7 +106,7 @@ private: class AirTypesDelegate : public ComboBoxDelegate { Q_OBJECT public: - explicit AirTypesDelegate(QAbstractItemModel *model, QObject *parent = 0); + explicit AirTypesDelegate(const dive &d, QObject *parent = 0); private: void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; void editorClosed(QWidget *widget, QAbstractItemDelegate::EndEditHint hint) override; @@ -112,7 +115,7 @@ private: class DiveTypesDelegate : public ComboBoxDelegate { Q_OBJECT public: - explicit DiveTypesDelegate(QAbstractItemModel *model, QObject *parent = 0); + explicit DiveTypesDelegate(QObject *parent = 0); private: void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; void editorClosed(QWidget *widget, QAbstractItemDelegate::EndEditHint hint) override; diff --git a/desktop-widgets/preferences/preferences_equipment.cpp b/desktop-widgets/preferences/preferences_equipment.cpp index 2cd674993..1e8c1e1e8 100644 --- a/desktop-widgets/preferences/preferences_equipment.cpp +++ b/desktop-widgets/preferences/preferences_equipment.cpp @@ -42,11 +42,8 @@ void PreferencesEquipment::syncSettings() equipment->set_default_cylinder(ui->default_cylinder->currentText()); // In case the user changed the tank info settings, - // reset the tank_info_table and inform the TankInfoModel of - // the changed table. It is somewhat questionable to do this here. - // Moreover, it is a bit crude, as this will be called for *any* - // preferences change. Perhaps, the model should listen to the - // precise changed signal of the preferences system? + // reset the tank_info_table. It is somewhat questionable + // to do this here. Moreover, it is a bit crude, as this + // will be called for *any* preferences change. reset_tank_info_table(&tank_info_table); - TankInfoModel::instance()->update(); } diff --git a/qt-models/cylindermodel.cpp b/qt-models/cylindermodel.cpp index f20846f66..6868e2bea 100644 --- a/qt-models/cylindermodel.cpp +++ b/qt-models/cylindermodel.cpp @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include "cylindermodel.h" -#include "tankinfomodel.h" #include "models.h" #include "commands/command.h" #include "core/qthelper.h" @@ -381,23 +380,12 @@ bool CylindersModel::setData(const QModelIndex &index, const QVariant &value, in cyl.type.description = newType.c_str(); type = Command::EditCylinderType::TYPE; break; - case SIZE: { - TankInfoModel *tanks = TankInfoModel::instance(); - QModelIndexList matches = tanks->match(tanks->index(0, 0), Qt::DisplayRole, cyl.type.description); - - cyl.type.size = string_to_volume(qPrintable(vString), cyl.type.workingpressure); - if (!matches.isEmpty()) - tanks->setData(tanks->index(matches.first().row(), TankInfoModel::ML), cyl.type.size.mliter); - } + case SIZE: + cyl.type.size = string_to_volume(qPrintable(vString), cyl.type.workingpressure); type = Command::EditCylinderType::TYPE; break; - case WORKINGPRESS: { - TankInfoModel *tanks = TankInfoModel::instance(); - QModelIndexList matches = tanks->match(tanks->index(0, 0), Qt::DisplayRole, cyl.type.description); - cyl.type.workingpressure = string_to_pressure(qPrintable(vString)); - if (!matches.isEmpty()) - tanks->setData(tanks->index(matches.first().row(), TankInfoModel::BAR), cyl.type.workingpressure.mbar / 1000.0); - } + case WORKINGPRESS: + cyl.type.workingpressure = string_to_pressure(qPrintable(vString)); type = Command::EditCylinderType::TYPE; break; case START: diff --git a/qt-models/models.cpp b/qt-models/models.cpp index cc0482d1e..a1f227eb1 100644 --- a/qt-models/models.cpp +++ b/qt-models/models.cpp @@ -18,9 +18,10 @@ Qt::ItemFlags GasSelectionModel::flags(const QModelIndex&) const return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } -void GasSelectionModel::repopulate(const dive *d) +GasSelectionModel::GasSelectionModel(const dive &d, QObject *parent) + : QStringListModel(parent) { - setStringList(get_dive_gas_list(d)); + setStringList(get_dive_gas_list(&d)); } QVariant GasSelectionModel::data(const QModelIndex &index, int role) const @@ -37,7 +38,7 @@ Qt::ItemFlags DiveTypeSelectionModel::flags(const QModelIndex&) const return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } -DiveTypeSelectionModel::DiveTypeSelectionModel() +DiveTypeSelectionModel::DiveTypeSelectionModel(QObject *parent) : QStringListModel(parent) { QStringList modes; for (int i = 0; i < FREEDIVE; i++) diff --git a/qt-models/models.h b/qt-models/models.h index d102fc3b5..3db13a5b1 100644 --- a/qt-models/models.h +++ b/qt-models/models.h @@ -24,15 +24,15 @@ struct dive; class GasSelectionModel : public QStringListModel { Q_OBJECT public: + GasSelectionModel(const dive &d, QObject *parent); Qt::ItemFlags flags(const QModelIndex &index) const; QVariant data(const QModelIndex &index, int role) const override; - void repopulate(const dive *d); }; class DiveTypeSelectionModel : public QStringListModel { Q_OBJECT public: - DiveTypeSelectionModel(); + DiveTypeSelectionModel(QObject *parent); Qt::ItemFlags flags(const QModelIndex &index) const; QVariant data(const QModelIndex &index, int role) const override; }; diff --git a/qt-models/tankinfomodel.cpp b/qt-models/tankinfomodel.cpp index 0a9379ec9..6dca11cef 100644 --- a/qt-models/tankinfomodel.cpp +++ b/qt-models/tankinfomodel.cpp @@ -5,48 +5,9 @@ #include "core/gettextfromc.h" #include "core/metrics.h" -TankInfoModel *TankInfoModel::instance() -{ - static TankInfoModel self; - return &self; -} - -bool TankInfoModel::insertRows(int, int count, const QModelIndex &parent) -{ - beginInsertRows(parent, rowCount(), rowCount() + count - 1); - for (int i = 0; i < count; ++i) - add_tank_info_metric(&tank_info_table, "", 0, 0); - endInsertRows(); - return true; -} - -bool TankInfoModel::setData(const QModelIndex &index, const QVariant &value, int) -{ - //WARN Seems wrong, we need to check for role == Qt::EditRole - - if (index.row() < 0 || index.row() >= tank_info_table.nr ) - return false; - - struct tank_info &info = tank_info_table.infos[index.row()]; - switch (index.column()) { - case DESCRIPTION: - free((void *)info.name); - info.name = strdup(value.toByteArray().data()); - break; - case ML: - info.ml = value.toInt(); - break; - case BAR: - info.bar = value.toInt(); - break; - } - emit dataChanged(index, index); - return true; -} - QVariant TankInfoModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() < 0 || index.row() >= tank_info_table.nr) + if (index.row() < 0 || index.row() >= tank_info_table.nr) return QVariant(); if (role == Qt::FontRole) return defaultModelFont(); @@ -75,16 +36,7 @@ int TankInfoModel::rowCount(const QModelIndex&) const return tank_info_table.nr; } -TankInfoModel::TankInfoModel() +TankInfoModel::TankInfoModel(QObject *parent) : CleanerTableModel(parent) { setHeaderDataStrings(QStringList() << tr("Description") << tr("ml") << tr("bar")); - connect(&diveListNotifier, &DiveListNotifier::dataReset, this, &TankInfoModel::update); - connect(&diveListNotifier, &DiveListNotifier::settingsChanged, this, &TankInfoModel::update); - update(); -} - -void TankInfoModel::update() -{ - beginResetModel(); - endResetModel(); } diff --git a/qt-models/tankinfomodel.h b/qt-models/tankinfomodel.h index 2fad322ea..76e2bd709 100644 --- a/qt-models/tankinfomodel.h +++ b/qt-models/tankinfomodel.h @@ -9,22 +9,15 @@ class TankInfoModel : public CleanerTableModel { Q_OBJECT public: - static TankInfoModel *instance(); - enum Column { DESCRIPTION, ML, BAR }; - TankInfoModel(); + TankInfoModel(QObject *parent); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; - bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; -public -slots: - void update(); }; #endif diff --git a/qt-models/weightmodel.cpp b/qt-models/weightmodel.cpp index 7e89f30bf..296a2c8e6 100644 --- a/qt-models/weightmodel.cpp +++ b/qt-models/weightmodel.cpp @@ -78,8 +78,10 @@ QVariant WeightModel::data(const QModelIndex &index, int role) const // Ownership of passed in weight system will be taken. Caller must not use it any longer. void WeightModel::setTempWS(int row, weightsystem_t ws) { - if (!d || row < 0 || row >= d->weightsystems.nr) // Sanity check: row must exist + if (!d || row < 0 || row >= d->weightsystems.nr) { // Sanity check: row must exist + free_weightsystem(ws); return; + } clearTempWS(); // Shouldn't be necessary, just in case: Reset old temporary row. diff --git a/qt-models/weightsysteminfomodel.cpp b/qt-models/weightsysteminfomodel.cpp index 9c28d5f64..d784dca82 100644 --- a/qt-models/weightsysteminfomodel.cpp +++ b/qt-models/weightsysteminfomodel.cpp @@ -5,66 +5,27 @@ #include "core/metrics.h" #include "core/gettextfromc.h" -WSInfoModel *WSInfoModel::instance() -{ - static WSInfoModel self; - return &self; -} - -bool WSInfoModel::insertRows(int, int count, const QModelIndex &parent) -{ - beginInsertRows(parent, rowCount(), rowCount()); - rows += count; - endInsertRows(); - return true; -} - -bool WSInfoModel::setData(const QModelIndex &index, const QVariant &value, int) -{ - //WARN: check for Qt::EditRole - struct ws_info_t *info = &ws_info[index.row()]; - switch (index.column()) { - case DESCRIPTION: - info->name = strdup(value.toByteArray().data()); - break; - case GR: - info->grams = value.toInt(); - break; - } - emit dataChanged(index, index); - return true; -} - -void WSInfoModel::clear() -{ -} - QVariant WSInfoModel::data(const QModelIndex &index, int role) const { - QVariant ret; - if (!index.isValid()) { - return ret; - } + if (!index.isValid() || index.row() >= rows) + return QVariant(); struct ws_info_t *info = &ws_info[index.row()]; int gr = info->grams; switch (role) { case Qt::FontRole: - ret = defaultModelFont(); - break; + return defaultModelFont(); case Qt::DisplayRole: case Qt::EditRole: switch (index.column()) { case GR: - ret = gr; - break; + return gr; case DESCRIPTION: - ret = gettextFromC::tr(info->name); - break; + return gettextFromC::tr(info->name); } break; } - return ret; + return QVariant(); } int WSInfoModel::rowCount(const QModelIndex&) const @@ -72,18 +33,10 @@ int WSInfoModel::rowCount(const QModelIndex&) const return rows; } -WSInfoModel::WSInfoModel() +WSInfoModel::WSInfoModel(QObject *parent) : CleanerTableModel(parent) { setHeaderDataStrings(QStringList() << tr("Description") << tr("kg")); - connect(&diveListNotifier, &DiveListNotifier::dataReset, this, &WSInfoModel::update); - update(); -} - -void WSInfoModel::update() -{ - beginResetModel(); rows = 0; for (struct ws_info_t *info = ws_info; info->name && info < ws_info + MAX_WS_INFO; info++, rows++) ; - endResetModel(); } diff --git a/qt-models/weightsysteminfomodel.h b/qt-models/weightsysteminfomodel.h index 6e572f337..04ebdbca4 100644 --- a/qt-models/weightsysteminfomodel.h +++ b/qt-models/weightsysteminfomodel.h @@ -8,24 +8,17 @@ class WSInfoModel : public CleanerTableModel { Q_OBJECT public: - static WSInfoModel *instance(); - enum Column { DESCRIPTION, GR }; - WSInfoModel(); + WSInfoModel(QObject *parent); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; - bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - void clear(); - void update(); private: int rows; - QString biggerEntry; }; #endif