Fix various issues with the dive add / edit manual dive code

- get_gas_from_events does NOT always set o2/he. It only updates them IFF
  a matching event is found; so we need to make sure we start out with a
  valid gas mix
- the way we tried to restore the edited dive in case of an edit to a
  manually added that is cancelled was completely bogus. Way too complex
  when we can simply and reliably simply store the dive and then copy it
  back

Fixes #270

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2013-11-18 11:55:56 -08:00
parent 3801b765ff
commit 8ae8c81d3d
4 changed files with 22 additions and 26 deletions

View file

@ -57,6 +57,8 @@ void set_last_stop(bool last_stop_6m)
void get_gas_from_events(struct divecomputer *dc, int time, int *o2, int *he) void get_gas_from_events(struct divecomputer *dc, int time, int *o2, int *he)
{ {
// we don't modify the values passed in if nothing is found
// so don't call with uninitialized o2/he !
struct event *event = dc->events; struct event *event = dc->events;
while (event && event->time.seconds <= time) { while (event && event->time.seconds <= time) {
if (!strcmp(event->name, "gaschange")) { if (!strcmp(event->name, "gaschange")) {

View file

@ -442,28 +442,30 @@ void DivePlannerPointsModel::loadFromDive(dive* d)
* as soon as the model is modified, it will * as soon as the model is modified, it will
* remove all samples from the current dive. * remove all samples from the current dive.
* */ * */
struct dive *backupDive = alloc_dive(); memcpy(&backupDive, current_dive, sizeof(struct dive));
backupDive->when = current_dive->when; // do we need anything else? copy_samples(current_dive, &backupDive);
copy_samples(current_dive, backupDive); copy_events(current_dive, &backupDive);
copy_cylinders(current_dive, backupDive);
copy_events(current_dive, backupDive);
backupSamples.clear();
for(int i = 0; i < d->dc.samples-1; i++){
backupSamples.push_back( d->dc.sample[i]);
}
copy_cylinders(current_dive, stagingDive); // this way the correct cylinder data is shown copy_cylinders(current_dive, stagingDive); // this way the correct cylinder data is shown
CylindersModel::instance()->setDive(stagingDive); CylindersModel::instance()->setDive(stagingDive);
int lasttime = 0; int lasttime = 0;
Q_FOREACH(const sample &s, backupSamples){ // we start with the first gas and see if it was changed
int o2 = 0, he = 0; int o2 = backupDive.cylinder[0].gasmix.o2.permille;
int he = backupDive.cylinder[0].gasmix.he.permille;
for (int i = 0; i < backupDive.dc.samples; i++) {
const sample &s = backupDive.dc.sample[i];
if (s.time.seconds == 0) if (s.time.seconds == 0)
continue; continue;
get_gas_from_events(&backupDive->dc, lasttime, &o2, &he); get_gas_from_events(&backupDive.dc, lasttime, &o2, &he);
plannerModel->addStop(s.depth.mm, s.time.seconds, o2, he, 0); plannerModel->addStop(s.depth.mm, s.time.seconds, o2, he, 0);
lasttime = s.time.seconds; lasttime = s.time.seconds;
} }
} }
void DivePlannerPointsModel::restoreBackupDive()
{
memcpy(current_dive, &backupDive, sizeof(struct dive));
}
void DivePlannerPointsModel::copyCylinders(dive *d) void DivePlannerPointsModel::copyCylinders(dive *d)
{ {
copy_cylinders(stagingDive, d); copy_cylinders(stagingDive, d);
@ -1412,18 +1414,6 @@ void DivePlannerPointsModel::createTemporaryPlan()
#endif #endif
} }
void DivePlannerPointsModel::undoEdition()
{
clear();
Q_FOREACH(const sample &s, backupSamples){
if (s.time.seconds > 0) {
int o2, he;
get_gas_from_events(&current_dive->dc, s.time.seconds, &o2, &he);
plannerModel->addStop(s.depth.mm, s.time.seconds, o2, he, 0);
}
}
}
void DivePlannerPointsModel::deleteTemporaryPlan() void DivePlannerPointsModel::deleteTemporaryPlan()
{ {
deleteTemporaryPlan(diveplan.dp); deleteTemporaryPlan(diveplan.dp);

View file

@ -61,7 +61,8 @@ public slots:
void createTemporaryPlan(); void createTemporaryPlan();
void deleteTemporaryPlan(); void deleteTemporaryPlan();
void loadFromDive(dive* d); void loadFromDive(dive* d);
void undoEdition(); void restoreBackupDive();
signals: signals:
void planCreated(); void planCreated();
void planCanceled(); void planCanceled();
@ -73,6 +74,7 @@ private:
Mode mode; Mode mode;
QVector<divedatapoint> divepoints; QVector<divedatapoint> divepoints;
struct dive *tempDive; struct dive *tempDive;
struct dive backupDive;
void deleteTemporaryPlan(struct divedatapoint *dp); void deleteTemporaryPlan(struct divedatapoint *dp);
QVector<sample> backupSamples; // For editing added dives. QVector<sample> backupSamples; // For editing added dives.
struct dive *stagingDive; struct dive *stagingDive;

View file

@ -565,7 +565,9 @@ void MainTab::rejectChanges()
// clean up // clean up
DivePlannerPointsModel::instance()->cancelPlan(); DivePlannerPointsModel::instance()->cancelPlan();
} else if (lastMode == MANUALLY_ADDED_DIVE ) { } else if (lastMode == MANUALLY_ADDED_DIVE ) {
DivePlannerPointsModel::instance()->undoEdition(); // that's BOGUS... just copy the original dive back and be done with it... // when we tried to edit a manually added dive, we destroyed
// the dive we edited, so let's just restore it from backup
DivePlannerPointsModel::instance()->restoreBackupDive();
} }
struct dive *curr = current_dive; struct dive *curr = current_dive;
ui.notes->setText(notesBackup[curr].notes ); ui.notes->setText(notesBackup[curr].notes );