From 1af67512a1b313a4a9f53c95cce479d3d42e2f44 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Sun, 21 Nov 2021 11:39:02 +0100 Subject: [PATCH] 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 --- commands/command_edit.cpp | 20 +++++++++++--------- commands/command_edit.h | 1 + core/equipment.c | 28 ++++++++++++++++++++++++++++ core/equipment.h | 1 + qt-models/cylindermodel.cpp | 26 +------------------------- 5 files changed, 42 insertions(+), 34 deletions(-) diff --git a/commands/command_edit.cpp b/commands/command_edit.cpp index cf2d0e5d3..0617e0e8b 100644 --- a/commands/command_edit.cpp +++ b/commands/command_edit.cpp @@ -1052,6 +1052,7 @@ AddCylinder::AddCylinder(bool currentDiveOnly) : else setText(Command::Base::tr("Add cylinder (%n dive(s))", "", dives.size())); cyl = create_new_cylinder(dives[0]); + indexes.reserve(dives.size()); } AddCylinder::~AddCylinder() @@ -1066,22 +1067,23 @@ bool AddCylinder::workToBeDone() void AddCylinder::undo() { - for (dive *d: dives) { - if (d->cylinders.nr <= 0) - continue; - remove_cylinder(d, d->cylinders.nr - 1); - update_cylinder_related_info(d); - emit diveListNotifier.cylinderRemoved(d, d->cylinders.nr); - invalidate_dive_cache(d); // Ensure that dive is written in git_save() + for (size_t i = 0; i < dives.size(); ++i) { + remove_cylinder(dives[i], indexes[i]); + update_cylinder_related_info(dives[i]); + emit diveListNotifier.cylinderRemoved(dives[i], indexes[i]); + invalidate_dive_cache(dives[i]); // Ensure that dive is written in git_save() } } void AddCylinder::redo() { + indexes.clear(); 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); - 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() } } diff --git a/commands/command_edit.h b/commands/command_edit.h index 257461c59..78c596b6c 100644 --- a/commands/command_edit.h +++ b/commands/command_edit.h @@ -386,6 +386,7 @@ public: ~AddCylinder(); private: cylinder_t cyl; + std::vector indexes; // An index for each dive in the dives vector. void undo() override; void redo() override; bool workToBeDone() override; diff --git a/core/equipment.c b/core/equipment.c index 0fd7644b7..685306981 100644 --- a/core/equipment.c +++ b/core/equipment.c @@ -464,6 +464,34 @@ cylinder_t create_new_cylinder(const struct dive *d) 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 void dump_cylinders(struct dive *dive, bool verbose) { diff --git a/core/equipment.h b/core/equipment.h index 8f7cee74a..c82963631 100644 --- a/core/equipment.h +++ b/core/equipment.h @@ -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 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 int first_hidden_cylinder(const struct dive *d); #ifdef DEBUG_CYL extern void dump_cylinders(struct dive *dive, bool verbose); #endif diff --git a/qt-models/cylindermodel.cpp b/qt-models/cylindermodel.cpp index 325f53add..fa0dac1b9 100644 --- a/qt-models/cylindermodel.cpp +++ b/qt-models/cylindermodel.cpp @@ -131,27 +131,6 @@ static QVariant percent_string(fraction_t fraction) 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 // is set, we don't show unused cylinders at the end of the list. int CylindersModel::calcNumRows() const @@ -160,10 +139,7 @@ int CylindersModel::calcNumRows() const return 0; if (!hideUnused || prefs.display_unused_tanks) return d->cylinders.nr; - int res = d->cylinders.nr; - while (res > 0 && !cylinderUsed(res - 1)) - --res; - return res; + return first_hidden_cylinder(d); } QVariant CylindersModel::data(const QModelIndex &index, int role) const