Undo: implement undo of depth and duration editing

This was a bit different from the other editing commands:
1) Only the current dive is edited not all selected dives.
   Therefore, create a function that turns the current dive
   into a one-element list.
2) The profile has to be replot. Here, likewise, create a
   function to do that.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2019-02-10 17:37:06 +01:00 committed by Dirk Hohndel
parent 02d572226d
commit c82f4487f9
7 changed files with 113 additions and 30 deletions

View file

@ -14,6 +14,8 @@
// Use "enum class" to not polute the global name space.
enum class DiveField {
DATETIME,
DEPTH,
DURATION,
AIR_TEMP,
WATER_TEMP,
DIVESITE,

View file

@ -165,6 +165,16 @@ void editWaterTemp(const QVector<dive *> dives, int newValue, int oldValue)
execute(new EditWaterTemp(dives, newValue, oldValue));
}
void editDepth(const QVector<dive *> dives, int newValue, int oldValue)
{
execute(new EditDepth(dives, newValue, oldValue));
}
void editDuration(const QVector<dive *> dives, int newValue, int oldValue)
{
execute(new EditDuration(dives, newValue, oldValue));
}
void editDiveSite(const QVector<dive *> dives, struct dive_site *newValue, struct dive_site *oldValue)
{
execute(new EditDiveSite(dives, newValue, oldValue));

View file

@ -59,6 +59,8 @@ void editRating(const QVector<dive *> dives, int newValue, int oldValue);
void editVisibility(const QVector<dive *> dives, int newValue, int oldValue);
void editAirTemp(const QVector<dive *> dives, int newValue, int oldValue);
void editWaterTemp(const QVector<dive *> dives, int newValue, int oldValue);
void editDepth(const QVector<dive *> dives, int newValue, int oldValue);
void editDuration(const QVector<dive *> dives, int newValue, int oldValue);
void editDiveSite(const QVector<dive *> dives, struct dive_site *newValue, struct dive_site *oldValue);
void editDiveSiteNew(const QVector<dive *> dives, const QString &newName, struct dive_site *oldValue);
void editTags(const QVector<dive *> &dives, const QStringList &newList, struct dive *d);

View file

@ -215,6 +215,54 @@ DiveField EditWaterTemp::fieldId() const
return DiveField::WATER_TEMP;
}
// ***** Duration *****
void EditDuration::set(struct dive *d, int value) const
{
d->dc.duration.seconds = value;
d->duration = d->dc.duration;
d->dc.meandepth.mm = 0;
d->dc.samples = 0;
}
int EditDuration::data(struct dive *d) const
{
return d->duration.seconds;
}
QString EditDuration::fieldName() const
{
return tr("duration");
}
DiveField EditDuration::fieldId() const
{
return DiveField::DURATION;
}
// ***** Depth *****
void EditDepth::set(struct dive *d, int value) const
{
d->dc.maxdepth.mm = value;
d->maxdepth = d->dc.maxdepth;
d->dc.meandepth.mm = 0;
d->dc.samples = 0;
}
int EditDepth::data(struct dive *d) const
{
return d->maxdepth.mm;
}
QString EditDepth::fieldName() const
{
return tr("depth");
}
DiveField EditDepth::fieldId() const
{
return DiveField::DEPTH;
}
// ***** DiveSite *****
void EditDiveSite::set(struct dive *d, struct dive_site *dive_site) const
{

View file

@ -102,6 +102,24 @@ public:
DiveField fieldId() const override;
};
class EditDuration : public EditBase<int> {
public:
using EditBase<int>::EditBase; // Use constructor of base class.
void set(struct dive *d, int value) const override;
int data(struct dive *d) const override;
QString fieldName() const override;
DiveField fieldId() const override;
};
class EditDepth : public EditBase<int> {
public:
using EditBase<int>::EditBase; // Use constructor of base class.
void set(struct dive *d, int value) const override;
int data(struct dive *d) const override;
QString fieldName() const override;
DiveField fieldId() const override;
};
class EditDiveSite : public EditBase<struct dive_site *> {
public:
using EditBase<struct dive_site *>::EditBase; // Use constructor of base class.

View file

@ -333,6 +333,13 @@ void MainTab::enableEdition(EditMode newEditMode)
}
}
static void profileFromDive(struct dive *d)
{
DivePlannerPointsModel::instance()->loadFromDive(d);
MainWindow::instance()->graphics->setReplot(true);
MainWindow::instance()->graphics->plotDive(current_dive, true);
}
// This function gets called if a field gets updated by an undo command.
// Refresh the corresponding UI field.
void MainTab::divesEdited(const QVector<dive *> &, DiveField field)
@ -342,6 +349,14 @@ void MainTab::divesEdited(const QVector<dive *> &, DiveField field)
return;
switch(field) {
case DiveField::DURATION:
ui.duration->setText(render_seconds_to_string(current_dive->duration.seconds));
profileFromDive(current_dive);
break;
case DiveField::DEPTH:
ui.depth->setText(get_depth_string(current_dive->maxdepth, true));
profileFromDive(current_dive);
break;
case DiveField::AIR_TEMP:
ui.airtemp->setText(get_temperature_string(current_dive->airtemp, true));
break;
@ -724,6 +739,13 @@ static QVector<dive *> getSelectedDivesCurrentLast()
return res;
}
// When editing depth and duration, we only edit a single dive. Therefore, return the current dive as a list
static QVector<dive *> getCurrentAsList()
{
return current_dive ? QVector<dive *> { current_dive }
: QVector<dive *> { };
}
void MainTab::acceptChanges()
{
int i, addedId = -1;
@ -1009,41 +1031,22 @@ void MainTab::on_divemaster_editingFinished()
Command::editDiveMaster(getSelectedDivesCurrentLast(), stringToList(ui.divemaster->toPlainText()), current_dive);
}
void MainTab::on_duration_textChanged(const QString &text)
void MainTab::on_duration_editingFinished()
{
if (editMode == IGNORE || acceptingEdit == true)
if (editMode == IGNORE || acceptingEdit == true || !current_dive)
return;
// parse this
MainWindow::instance()->graphics->setReplot(false);
if (!isEditing())
enableEdition();
displayed_dive.dc.duration.seconds = parseDurationToSeconds(text);
displayed_dive.duration = displayed_dive.dc.duration;
displayed_dive.dc.meandepth.mm = 0;
displayed_dive.dc.samples = 0;
DivePlannerPointsModel::instance()->loadFromDive(&displayed_dive);
markChangedWidget(ui.duration);
MainWindow::instance()->graphics->setReplot(true);
MainWindow::instance()->graphics->plotDive();
// Duration editing is special: we only edit the current dive.
Command::editDuration(getCurrentAsList(), parseDurationToSeconds(ui.duration->text()), displayed_dive.dc.duration.seconds);
}
void MainTab::on_depth_textChanged(const QString &text)
void MainTab::on_depth_editingFinished()
{
if (editMode == IGNORE || acceptingEdit == true)
if (editMode == IGNORE || acceptingEdit == true || !current_dive)
return;
// don't replot until we set things up the way we want them
MainWindow::instance()->graphics->setReplot(false);
if (!isEditing())
enableEdition();
displayed_dive.dc.maxdepth.mm = parseLengthToMm(text);
displayed_dive.maxdepth = displayed_dive.dc.maxdepth;
displayed_dive.dc.meandepth.mm = 0;
displayed_dive.dc.samples = 0;
DivePlannerPointsModel::instance()->loadFromDive(&displayed_dive);
markChangedWidget(ui.depth);
MainWindow::instance()->graphics->setReplot(true);
MainWindow::instance()->graphics->plotDive();
// Depth editing is special: we only edit the current dive.
Command::editDepth(getCurrentAsList(), parseLengthToMm(ui.depth->text()), current_dive->dc.maxdepth.mm);
}
void MainTab::on_airtemp_editingFinished()

View file

@ -81,8 +81,8 @@ slots:
void on_notes_textChanged();
void on_notes_editingFinished();
void on_airtemp_editingFinished();
void on_duration_textChanged(const QString &text);
void on_depth_textChanged(const QString &text);
void on_duration_editingFinished();
void on_depth_editingFinished();
void divetype_Changed(int);
void on_watertemp_editingFinished();
void on_dateEdit_dateChanged(const QDate &date);