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 <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-03-30 13:40:00 +01:00 committed by Michael Keller
parent de313bd01a
commit 0d011231e6
16 changed files with 130 additions and 215 deletions

View file

@ -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)

View file

@ -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 };

View file

@ -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
}

View file

@ -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<GasSelectionModel>()),
diveTypeModel(std::make_unique<DiveTypeSelectionModel>()),
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

View file

@ -10,8 +10,6 @@
#include <QDateTime>
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<GasSelectionModel> gasModel;
std::unique_ptr<DiveTypeSelectionModel> diveTypeModel;
DivePlannerWidget plannerWidget;
PlannerSettingsWidget plannerSettingsWidget;
PlannerDetails plannerDetails;

View file

@ -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<QAbstractItemModel *(QWidget *)> 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<WeightModel *>(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)
{
}

View file

@ -6,8 +6,10 @@
#include <QStyledItemDelegate>
#include <QComboBox>
#include <functional>
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<QAbstractItemModel *(QWidget *)> 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<QAbstractItemModel *(QWidget *)> 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;

View file

@ -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();
}

View file

@ -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:

View file

@ -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++)

View file

@ -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;
};

View file

@ -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();
}

View file

@ -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

View file

@ -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.

View file

@ -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();
}

View file

@ -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