cylinders: add cylinder before hidden cylinders

When adding a cylinder, it was added at the end of the list.
This would make hidden cylinders visible as the new rule is
to only hide unused cylinders at the end of the list.

Therefore, add the cylinder after the last used cylinder,
i.e. before the first hidden cylinder.

This means that the position where the cylinder is added has
to be hidden in the undo command.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2021-11-21 11:39:02 +01:00 committed by Dirk Hohndel
parent a40b40ae7a
commit 1af67512a1
5 changed files with 42 additions and 34 deletions

View file

@ -1052,6 +1052,7 @@ AddCylinder::AddCylinder(bool currentDiveOnly) :
else else
setText(Command::Base::tr("Add cylinder (%n dive(s))", "", dives.size())); setText(Command::Base::tr("Add cylinder (%n dive(s))", "", dives.size()));
cyl = create_new_cylinder(dives[0]); cyl = create_new_cylinder(dives[0]);
indexes.reserve(dives.size());
} }
AddCylinder::~AddCylinder() AddCylinder::~AddCylinder()
@ -1066,22 +1067,23 @@ bool AddCylinder::workToBeDone()
void AddCylinder::undo() void AddCylinder::undo()
{ {
for (dive *d: dives) { for (size_t i = 0; i < dives.size(); ++i) {
if (d->cylinders.nr <= 0) remove_cylinder(dives[i], indexes[i]);
continue; update_cylinder_related_info(dives[i]);
remove_cylinder(d, d->cylinders.nr - 1); emit diveListNotifier.cylinderRemoved(dives[i], indexes[i]);
update_cylinder_related_info(d); invalidate_dive_cache(dives[i]); // Ensure that dive is written in git_save()
emit diveListNotifier.cylinderRemoved(d, d->cylinders.nr);
invalidate_dive_cache(d); // Ensure that dive is written in git_save()
} }
} }
void AddCylinder::redo() void AddCylinder::redo()
{ {
indexes.clear();
for (dive *d: dives) { for (dive *d: dives) {
add_cloned_cylinder(&d->cylinders, cyl); int index = first_hidden_cylinder(d);
indexes.push_back(index);
add_cylinder(&d->cylinders, index, clone_cylinder(cyl));
update_cylinder_related_info(d); update_cylinder_related_info(d);
emit diveListNotifier.cylinderAdded(d, d->cylinders.nr - 1); emit diveListNotifier.cylinderAdded(d, index);
invalidate_dive_cache(d); // Ensure that dive is written in git_save() invalidate_dive_cache(d); // Ensure that dive is written in git_save()
} }
} }

View file

@ -386,6 +386,7 @@ public:
~AddCylinder(); ~AddCylinder();
private: private:
cylinder_t cyl; cylinder_t cyl;
std::vector<int> indexes; // An index for each dive in the dives vector.
void undo() override; void undo() override;
void redo() override; void redo() override;
bool workToBeDone() override; bool workToBeDone() override;

View file

@ -464,6 +464,34 @@ cylinder_t create_new_cylinder(const struct dive *d)
return cyl; return cyl;
} }
static bool show_cylinder(const struct dive *d, int i)
{
if (is_cylinder_used(d, i))
return true;
const cylinder_t *cyl = &d->cylinders.cylinders[i];
if (cyl->start.mbar || cyl->sample_start.mbar ||
cyl->end.mbar || cyl->sample_end.mbar)
return true;
if (cyl->manually_added)
return true;
/*
* The cylinder has some data, but none of it is very interesting,
* it has no pressures and no gas switches. Do we want to show it?
*/
return false;
}
/* The unused cylinders at the end of the cylinder list are hidden. */
int first_hidden_cylinder(const struct dive *d)
{
int res = d->cylinders.nr;
while (res > 0 && !show_cylinder(d, res - 1))
--res;
return res;
}
#ifdef DEBUG_CYL #ifdef DEBUG_CYL
void dump_cylinders(struct dive *dive, bool verbose) void dump_cylinders(struct dive *dive, bool verbose)
{ {

View file

@ -94,6 +94,7 @@ extern int gas_volume(const cylinder_t *cyl, pressure_t p); /* Volume in mliter
extern int find_best_gasmix_match(struct gasmix mix, const struct cylinder_table *cylinders); extern int find_best_gasmix_match(struct gasmix mix, const struct cylinder_table *cylinders);
extern void fill_default_cylinder(const struct dive *dive, cylinder_t *cyl); /* dive is needed to fill out MOD, which depends on salinity. */ extern void fill_default_cylinder(const struct dive *dive, cylinder_t *cyl); /* dive is needed to fill out MOD, which depends on salinity. */
extern cylinder_t create_new_cylinder(const struct dive *dive); /* dive is needed to fill out MOD, which depends on salinity. */ extern cylinder_t create_new_cylinder(const struct dive *dive); /* dive is needed to fill out MOD, which depends on salinity. */
extern int first_hidden_cylinder(const struct dive *d);
#ifdef DEBUG_CYL #ifdef DEBUG_CYL
extern void dump_cylinders(struct dive *dive, bool verbose); extern void dump_cylinders(struct dive *dive, bool verbose);
#endif #endif

View file

@ -131,27 +131,6 @@ static QVariant percent_string(fraction_t fraction)
return QString("%L1%").arg(permille / 10.0, 0, 'f', 1); return QString("%L1%").arg(permille / 10.0, 0, 'f', 1);
} }
bool CylindersModel::cylinderUsed(int i) const
{
if (i < 0 || i >= d->cylinders.nr)
return false;
if (is_cylinder_used(d, i))
return true;
cylinder_t *cyl = get_cylinder(d, i);
if (cyl->start.mbar || cyl->sample_start.mbar ||
cyl->end.mbar || cyl->sample_end.mbar)
return true;
if (cyl->manually_added)
return true;
/*
* The cylinder has some data, but none of it is very interesting,
* it has no pressures and no gas switches. Do we want to show it?
*/
return false;
}
// Calculate the number of displayed cylinders: If hideUnused // Calculate the number of displayed cylinders: If hideUnused
// is set, we don't show unused cylinders at the end of the list. // is set, we don't show unused cylinders at the end of the list.
int CylindersModel::calcNumRows() const int CylindersModel::calcNumRows() const
@ -160,10 +139,7 @@ int CylindersModel::calcNumRows() const
return 0; return 0;
if (!hideUnused || prefs.display_unused_tanks) if (!hideUnused || prefs.display_unused_tanks)
return d->cylinders.nr; return d->cylinders.nr;
int res = d->cylinders.nr; return first_hidden_cylinder(d);
while (res > 0 && !cylinderUsed(res - 1))
--res;
return res;
} }
QVariant CylindersModel::data(const QModelIndex &index, int role) const QVariant CylindersModel::data(const QModelIndex &index, int role) const