Used gas in dive planner points: Support for multiple cyl with same gas

In the planner if one adds two or more cylinders with the same gasmix
(e.g. back gas and bottom stage 18/45) the drop down and data in the
used gas column of the planner points table will be filled with a more
verbose string mentioning also the cyl number and the cyl type
description.
Makes it easier in such a case to select the right cylinder.

Introduces also a helper function which tells you if there is another
cylinder with the same gasmix as the provided cylinder.
This also has an option if it should consider unused cylinders or not.

Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
This commit is contained in:
Stefan Fuchs 2017-10-08 05:14:57 +02:00 committed by Robert C. Helling
parent 8fd1c72f04
commit c29456f0bb
4 changed files with 39 additions and 32 deletions

View file

@ -1858,7 +1858,7 @@ static int sort_event(struct event *a, struct event *b)
static int same_gas(struct event *a, struct event *b) static int same_gas(struct event *a, struct event *b)
{ {
if (a->type == b->type && a->flags == b->flags && a->value == b->value && !strcmp(a->name, b->name) && if (a->type == b->type && a->flags == b->flags && a->value == b->value && !strcmp(a->name, b->name) &&
a->gas.mix.o2.permille == b->gas.mix.o2.permille && a->gas.mix.he.permille == b->gas.mix.he.permille) { same_gasmix(&a->gas.mix, &b->gas.mix)) {
return true; return true;
} }
return false; return false;
@ -2078,6 +2078,19 @@ int same_gasmix(struct gasmix *a, struct gasmix *b)
return a->o2.permille == b->o2.permille && a->he.permille == b->he.permille; return a->o2.permille == b->o2.permille && a->he.permille == b->he.permille;
} }
int same_gasmix_cylinder(cylinder_t *cyl, int cylid, struct dive *dive, bool check_unused)
{
struct gasmix *mygas = &cyl->gasmix;
for (int i = 0; i < MAX_CYLINDERS; i++) {
if (i == cylid || cylinder_none(&dive->cylinder[i]))
continue;
struct gasmix *gas2 = &dive->cylinder[i].gasmix;
if (gasmix_distance(mygas, gas2) == 0 && (is_cylinder_used(dive, i) || check_unused))
return i;
}
return -1;
}
static int pdiff(pressure_t a, pressure_t b) static int pdiff(pressure_t a, pressure_t b)
{ {
return a.mbar && b.mbar && a.mbar != b.mbar; return a.mbar && b.mbar && a.mbar != b.mbar;

View file

@ -368,6 +368,7 @@ static inline bool dive_cache_is_valid(const struct dive *dive)
extern int get_cylinder_idx_by_use(struct dive *dive, enum cylinderuse cylinder_use_type); extern int get_cylinder_idx_by_use(struct dive *dive, enum cylinderuse cylinder_use_type);
extern void dc_cylinder_renumber(struct dive *dive, struct divecomputer *dc, int mapping[]); extern void dc_cylinder_renumber(struct dive *dive, struct divecomputer *dc, int mapping[]);
extern int same_gasmix_cylinder(cylinder_t *cyl, int cylid, struct dive *dive, bool check_unused);
/* when selectively copying dive information, which parts should be copied? */ /* when selectively copying dive information, which parts should be copied? */
struct dive_components { struct dive_components {

View file

@ -139,7 +139,6 @@ QVariant CylindersModel::data(const QModelIndex &index, int role) const
int mapping[MAX_CYLINDERS]; int mapping[MAX_CYLINDERS];
int same_gas = -1; int same_gas = -1;
cylinder_t *cyl = &displayed_dive.cylinder[index.row()]; cylinder_t *cyl = &displayed_dive.cylinder[index.row()];
struct gasmix *mygas = &cyl->gasmix;
switch (role) { switch (role) {
case Qt::BackgroundRole: { case Qt::BackgroundRole: {
@ -233,15 +232,8 @@ QVariant CylindersModel::data(const QModelIndex &index, int role) const
case Qt::DecorationRole: case Qt::DecorationRole:
case Qt::SizeHintRole: case Qt::SizeHintRole:
if (index.column() == REMOVE) { if (index.column() == REMOVE) {
same_gas = -1; same_gas = same_gasmix_cylinder(cyl, index.row(), &displayed_dive, false);
for (int i = 0; i < MAX_CYLINDERS; i++) {
mapping[i] = i;
if (i == index.row() || cylinder_none(&displayed_dive.cylinder[i]))
continue;
struct gasmix *gas2 = &displayed_dive.cylinder[i].gasmix;
if (gasmix_distance(mygas, gas2) == 0 && is_cylinder_used(&displayed_dive, i))
same_gas = i;
}
if ((in_planner() || same_gas == -1) && if ((in_planner() || same_gas == -1) &&
((DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING && ((DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING &&
DivePlannerPointsModel::instance()->tankInUse(index.row())) || DivePlannerPointsModel::instance()->tankInUse(index.row())) ||
@ -256,15 +248,8 @@ QVariant CylindersModel::data(const QModelIndex &index, int role) const
case Qt::ToolTipRole: case Qt::ToolTipRole:
switch (index.column()) { switch (index.column()) {
case REMOVE: case REMOVE:
same_gas = -1; same_gas = same_gasmix_cylinder(cyl, index.row(), &displayed_dive, false);
for (int i = 0; i < MAX_CYLINDERS; i++) {
mapping[i] = i;
if (i == index.row() || cylinder_none(&displayed_dive.cylinder[i]))
continue;
struct gasmix *gas2 = &displayed_dive.cylinder[i].gasmix;
if (gasmix_distance(mygas, gas2) == 0 && is_cylinder_used(&displayed_dive, i))
same_gas = i;
}
if ((in_planner() || same_gas == -1) && if ((in_planner() || same_gas == -1) &&
((DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING && ((DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING &&
DivePlannerPointsModel::instance()->tankInUse(index.row())) || DivePlannerPointsModel::instance()->tankInUse(index.row())) ||
@ -558,17 +543,9 @@ void CylindersModel::remove(const QModelIndex &index)
if (index.column() != REMOVE) { if (index.column() != REMOVE) {
return; return;
} }
int same_gas = -1;
cylinder_t *cyl = &displayed_dive.cylinder[index.row()]; cylinder_t *cyl = &displayed_dive.cylinder[index.row()];
struct gasmix *mygas = &cyl->gasmix; int same_gas = same_gasmix_cylinder(cyl, index.row(), &displayed_dive, false);
for (int i = 0; i < MAX_CYLINDERS; i++) {
mapping[i] = i;
if (i == index.row() || cylinder_none(&displayed_dive.cylinder[i]))
continue;
struct gasmix *gas2 = &displayed_dive.cylinder[i].gasmix;
if (gasmix_distance(mygas, gas2) == 0 && is_cylinder_used(&displayed_dive, i))
same_gas = i;
}
if ((in_planner() || same_gas == -1) && if ((in_planner() || same_gas == -1) &&
((DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING && ((DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING &&
DivePlannerPointsModel::instance()->tankInUse(index.row())) || DivePlannerPointsModel::instance()->tankInUse(index.row())) ||
@ -604,6 +581,7 @@ void CylindersModel::remove(const QModelIndex &index)
dc_cylinder_renumber(&displayed_dive, dc, mapping); dc_cylinder_renumber(&displayed_dive, dc, mapping);
dc = dc->next; dc = dc->next;
} }
dataChanged(index, index);
} }
void CylindersModel::updateDecoDepths(pressure_t olddecopo2) void CylindersModel::updateDecoDepths(pressure_t olddecopo2)

View file

@ -181,7 +181,14 @@ QStringList &DivePlannerPointsModel::getGasList()
cylinder_t *cyl = &displayed_dive.cylinder[i]; cylinder_t *cyl = &displayed_dive.cylinder[i];
if (cylinder_nodata(cyl)) if (cylinder_nodata(cyl))
break; break;
list.push_back(get_gas_string(cyl->gasmix)); /* 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(tr("cyl.")).arg(i + 1) +
cyl->type.description + ")");
} }
return list; return list;
} }
@ -258,7 +265,15 @@ QVariant DivePlannerPointsModel::data(const QModelIndex &index, int role) const
else else
return p.time / 60; return p.time / 60;
case GAS: case GAS:
return get_gas_string(displayed_dive.cylinder[p.cylinderid].gasmix); /* Check if we have the same gasmix two or more times
* If yes return more verbose string */
int same_gas = same_gasmix_cylinder(&displayed_dive.cylinder[p.cylinderid], p.cylinderid, &displayed_dive, true);
if (same_gas == -1)
return get_gas_string(displayed_dive.cylinder[p.cylinderid].gasmix);
else
return get_gas_string(displayed_dive.cylinder[p.cylinderid].gasmix) +
QString(" (%1 %2 ").arg(tr("cyl.")).arg(p.cylinderid + 1) +
displayed_dive.cylinder[p.cylinderid].type.description + ")";
} }
} else if (role == Qt::DecorationRole) { } else if (role == Qt::DecorationRole) {
switch (index.column()) { switch (index.column()) {