profile: update profile in edit mode on undo

When the user undos/redos the profile should update even
when in edit mode. This is a bit more complicated than
anticipated:

1) We should not do the update when emitting an undo command
from the profile. But we *should* update if it is an undo
command from the maintab (change depth/time).

2) The divepointsplannermodel has to be reset. Side note:
the code is truly abysmal as it sends numerous changed-signals.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2022-03-02 20:50:50 +01:00
parent 5aa67c134b
commit 4c46a11ed1
3 changed files with 41 additions and 5 deletions

View file

@ -51,7 +51,7 @@ void EmptyView::resizeEvent(QResizeEvent *)
update();
}
ProfileWidget::ProfileWidget() : originalDive(nullptr)
ProfileWidget::ProfileWidget() : originalDive(nullptr), placingCommand(false)
{
ui.setupUi(this);
@ -117,6 +117,7 @@ ProfileWidget::ProfileWidget() : originalDive(nullptr)
connect(ui.profPn2, &QAction::triggered, pp_gas, &qPrefPartialPressureGas::set_pn2);
connect(ui.profPO2, &QAction::triggered, pp_gas, &qPrefPartialPressureGas::set_po2);
connect(&diveListNotifier, &DiveListNotifier::divesChanged, this, &ProfileWidget::divesChanged);
connect(&diveListNotifier, &DiveListNotifier::settingsChanged, view.get(), &ProfileWidget2::settingsChanged);
connect(view.get(), &ProfileWidget2::editCurrentDive, this, &ProfileWidget::editDive);
connect(view.get(), &ProfileWidget2::stopAdded, this, &ProfileWidget::stopAdded);
@ -201,6 +202,27 @@ void ProfileWidget::plotCurrentDive()
}
}
void ProfileWidget::divesChanged(const QVector<dive *> &dives, DiveField field)
{
// If the current dive is not in list of changed dives, do nothing.
// Only if duration or depth changed, the profile needs to be replotted.
// Also, if we are currently placing a command, don't do anything.
// Note that we cannot use Command::placingCommand(), because placing
// a depth or time change on the maintab requires an update.
if (!current_dive || !dives.contains(current_dive) || !(field.duration || field.depth) || placingCommand)
return;
// If were editing the current dive and not currently
// placing command, we have to update the edited dive.
if (editedDive) {
copy_dive(current_dive, editedDive.get());
// TODO: Holy moly that function sends too many signals. Fix it!
DivePlannerPointsModel::instance()->loadFromDive(editedDive.get());
}
plotCurrentDive();
}
void ProfileWidget::setPlanState(const struct dive *d, int dc)
{
exitEditMode();
@ -256,11 +278,24 @@ static void calcDepth(dive &d, int dcNr)
fixup_dive(&d);
}
// Silly RAII-variable setter class: reset variable when going out of scope.
template <typename T>
struct Setter {
T &var, old;
Setter(T &var, T value) : var(var), old(var) {
var = value;
}
~Setter() {
var = old;
}
};
void ProfileWidget::stopAdded()
{
if (!editedDive)
return;
calcDepth(*editedDive, editedDc);
Setter s(placingCommand, true);
Command::editProfile(editedDive.get(), Command::EditProfileType::ADD, 0);
}
@ -269,6 +304,7 @@ void ProfileWidget::stopRemoved(int count)
if (!editedDive)
return;
calcDepth(*editedDive, editedDc);
Setter s(placingCommand, true);
Command::editProfile(editedDive.get(), Command::EditProfileType::REMOVE, count);
}
@ -277,5 +313,6 @@ void ProfileWidget::stopMoved(int count)
if (!editedDive)
return;
calcDepth(*editedDive, editedDc);
Setter s(placingCommand, true);
Command::editProfile(editedDive.get(), Command::EditProfileType::MOVE, count);
}

View file

@ -5,6 +5,7 @@
#define PROFILEWIDGET_H
#include "ui_profilewidget.h"
#include "core/subsurface-qt/divelistnotifier.h"
#include <vector>
#include <memory>
@ -27,6 +28,7 @@ public:
void setEnabledToolbar(bool enabled);
private
slots:
void divesChanged(const QVector<dive *> &dives, DiveField field);
void unsetProfHR();
void unsetProfTissues();
void stopAdded();
@ -48,6 +50,7 @@ private:
std::unique_ptr<dive, DiveDeleter> editedDive;
int editedDc;
dive *originalDive;
bool placingCommand;
};
#endif // PROFILEWIDGET_H

View file

@ -213,10 +213,6 @@ void MainTab::divesChanged(const QVector<dive *> &dives, DiveField field)
ui.buddy->setText(current_dive->buddy);
if (field.diveguide)
ui.diveguide->setText(current_dive->diveguide);
// If duration or depth changed, the profile needs to be replotted
if (field.duration || field.depth)
MainWindow::instance()->refreshProfile();
}
void MainTab::diveSiteEdited(dive_site *ds, int)