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