diff options
author | Rick Walsh <rickmwalsh@gmail.com> | 2016-07-06 22:40:28 +1000 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2016-07-09 12:07:25 -0700 |
commit | b1ed04a7f462d88b28b1abab881a0e1a8acc212a (patch) | |
tree | 3281beb6fb2789d790330e14a07266ec8df4c5c9 | |
parent | 066f79223cf49cda5f762b3b9413774b8417cb9f (diff) | |
download | subsurface-b1ed04a7f462d88b28b1abab881a0e1a8acc212a.tar.gz |
Have divedatapoint store cylinder id instead of gasmix
Determining the correct cylinder index from a known gas mix can be
complicated, but it is trivial to look up the gasmix from the cylinder_t
structure.
It makes sense to remember which cylinder is being used. This simplifies
handling changing a cylinder's gas mix, either directly by the user, or
indirectly in the planner. It also permits tracking of multiple cylinders of
the same mix, e.g. independent twins / sidemount.
Signed-off-by: Rick Walsh <rickmwalsh@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r-- | core/dive.h | 6 | ||||
-rw-r--r-- | core/planner.c | 92 | ||||
-rw-r--r-- | core/planner.h | 1 | ||||
-rw-r--r-- | core/qthelper.cpp | 5 | ||||
-rw-r--r-- | core/qthelper.h | 2 | ||||
-rw-r--r-- | desktop-widgets/diveplanner.cpp | 5 | ||||
-rw-r--r-- | desktop-widgets/modeldelegates.cpp | 2 | ||||
-rw-r--r-- | profile-widget/profilewidget2.cpp | 2 | ||||
-rw-r--r-- | qt-models/cylindermodel.cpp | 6 | ||||
-rw-r--r-- | qt-models/diveplannermodel.cpp | 113 | ||||
-rw-r--r-- | qt-models/diveplannermodel.h | 6 |
11 files changed, 98 insertions, 142 deletions
diff --git a/core/dive.h b/core/dive.h index 5988990b5..9c612048d 100644 --- a/core/dive.h +++ b/core/dive.h @@ -821,7 +821,7 @@ extern double tissue_tolerance_calc(const struct dive *dive, double pressure); struct divedatapoint { int time; int depth; - struct gasmix gasmix; + int cylinderid; int setpoint; bool entered; struct divedatapoint *next; @@ -838,8 +838,8 @@ struct diveplan { struct divedatapoint *dp; }; -struct divedatapoint *plan_add_segment(struct diveplan *diveplan, int duration, int depth, struct gasmix gasmix, int po2, bool entered); -struct divedatapoint *create_dp(int time_incr, int depth, struct gasmix gasmix, int po2); +struct divedatapoint *plan_add_segment(struct diveplan *diveplan, int duration, int depth, int cylinderid, int po2, bool entered); +struct divedatapoint *create_dp(int time_incr, int depth, int cylinderid, int po2); #if DEBUG_PLAN void dump_plan(struct diveplan *diveplan); #endif diff --git a/core/planner.c b/core/planner.c index e67033dd8..8ce1e29bd 100644 --- a/core/planner.c +++ b/core/planner.c @@ -92,6 +92,20 @@ void get_gas_at_time(struct dive *dive, struct divecomputer *dc, duration_t time } } +/* get the cylinder index at a certain time during the dive */ +int get_cylinderid_at_time(struct dive *dive, struct divecomputer *dc, duration_t time) +{ + // we start with the first cylinder unless an event tells us otherwise + int cylinder_idx = 0; + struct event *event = dc->events; + while (event && event->time.seconds <= time.seconds) { + if (!strcmp(event->name, "gaschange")) + cylinder_idx = get_cylinder_index(dive, event); + event = event->next; + } + return cylinder_idx; +} + int get_gasidx(struct dive *dive, struct gasmix *mix) { return find_best_gasmix_match(mix, dive->cylinder, 0); @@ -255,12 +269,12 @@ static void create_dive_from_plan(struct diveplan *diveplan, bool track_gas) struct divedatapoint *dp; struct divecomputer *dc; struct sample *sample; - struct gasmix oldgasmix; struct event *ev; cylinder_t *cyl; int oldpo2 = 0; int lasttime = 0; int lastdepth = 0; + int lastcylid = 0; enum dive_comp_type type = displayed_dive.dc.divemode; if (!diveplan || !diveplan->dp) @@ -284,8 +298,7 @@ static void create_dive_from_plan(struct diveplan *diveplan, bool track_gas) free(ev); } dp = diveplan->dp; - cyl = &displayed_dive.cylinder[0]; - oldgasmix = cyl->gasmix; + cyl = &displayed_dive.cylinder[lastcylid]; sample = prepare_sample(dc); sample->setpoint.mbar = dp->setpoint; sample->sac.mliter = prefs.bottomsac; @@ -295,7 +308,6 @@ static void create_dive_from_plan(struct diveplan *diveplan, bool track_gas) sample->manually_entered = true; finish_sample(dc); while (dp) { - struct gasmix gasmix = dp->gasmix; int po2 = dp->setpoint; if (dp->setpoint) type = CCR; @@ -305,8 +317,6 @@ static void create_dive_from_plan(struct diveplan *diveplan, bool track_gas) if (time == 0) { /* special entries that just inform the algorithm about * additional gases that are available */ - if (verify_gas_exists(gasmix) < 0) - goto gas_error_exit; dp = dp->next; continue; } @@ -321,13 +331,10 @@ static void create_dive_from_plan(struct diveplan *diveplan, bool track_gas) } /* Make sure we have the new gas, and create a gas change event */ - if (gasmix_distance(&gasmix, &oldgasmix) > 0) { - int idx; - if ((idx = verify_gas_exists(gasmix)) < 0) - goto gas_error_exit; + if (dp->cylinderid != lastcylid) { /* need to insert a first sample for the new gas */ - add_gas_switch_event(&displayed_dive, dc, lasttime + 1, idx); - cyl = &displayed_dive.cylinder[idx]; + add_gas_switch_event(&displayed_dive, dc, lasttime + 1, dp->cylinderid); + cyl = &displayed_dive.cylinder[dp->cylinderid]; sample = prepare_sample(dc); sample[-1].setpoint.mbar = po2; sample->time.seconds = lasttime + 1; @@ -337,7 +344,7 @@ static void create_dive_from_plan(struct diveplan *diveplan, bool track_gas) if (track_gas && cyl->type.workingpressure.mbar) sample->cylinderpressure.mbar = cyl->sample_end.mbar; finish_sample(dc); - oldgasmix = gasmix; + lastcylid = dp->cylinderid; } /* Create sample */ sample = prepare_sample(dc); @@ -382,14 +389,14 @@ void free_dps(struct diveplan *diveplan) diveplan->dp = NULL; } -struct divedatapoint *create_dp(int time_incr, int depth, struct gasmix gasmix, int po2) +struct divedatapoint *create_dp(int time_incr, int depth, int cylinderid, int po2) { struct divedatapoint *dp; dp = malloc(sizeof(struct divedatapoint)); dp->time = time_incr; dp->depth = depth; - dp->gasmix = gasmix; + dp->cylinderid = cylinderid; dp->setpoint = po2; dp->entered = false; dp->next = NULL; @@ -412,9 +419,9 @@ void add_to_end_of_diveplan(struct diveplan *diveplan, struct divedatapoint *dp) dp->time += lasttime; } -struct divedatapoint *plan_add_segment(struct diveplan *diveplan, int duration, int depth, struct gasmix gasmix, int po2, bool entered) +struct divedatapoint *plan_add_segment(struct diveplan *diveplan, int duration, int depth, int cylinderid, int po2, bool entered) { - struct divedatapoint *dp = create_dp(duration, depth, gasmix, po2); + struct divedatapoint *dp = create_dp(duration, depth, cylinderid, po2); dp->entered = entered; add_to_end_of_diveplan(diveplan, dp); return (dp); @@ -428,14 +435,12 @@ struct gaschanges { static struct gaschanges *analyze_gaslist(struct diveplan *diveplan, int *gaschangenr, int depth, int *asc_cylinder) { - struct gasmix gas; int nr = 0; struct gaschanges *gaschanges = NULL; struct divedatapoint *dp = diveplan->dp; int best_depth = displayed_dive.cylinder[*asc_cylinder].depth.mm; while (dp) { if (dp->time == 0) { - gas = dp->gasmix; if (dp->depth <= depth) { int i = 0; nr++; @@ -448,13 +453,13 @@ static struct gaschanges *analyze_gaslist(struct diveplan *diveplan, int *gascha i++; } gaschanges[i].depth = dp->depth; - gaschanges[i].gasidx = get_gasidx(&displayed_dive, &gas); + gaschanges[i].gasidx = dp->cylinderid; assert(gaschanges[i].gasidx != -1); } else { /* is there a better mix to start deco? */ if (dp->depth < best_depth) { best_depth = dp->depth; - *asc_cylinder = get_gasidx(&displayed_dive, &gas); + *asc_cylinder = dp->cylinderid; } } } @@ -614,13 +619,13 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool nextdp = dp->next; if (dp->time == 0) continue; - gasmix = dp->gasmix; + gasmix = dive->cylinder[dp->cylinderid].gasmix; depthvalue = get_depth_units(dp->depth, &decimals, &depth_unit); /* analyze the dive points ahead */ while (nextdp && nextdp->time == 0) nextdp = nextdp->next; if (nextdp) - newgasmix = nextdp->gasmix; + newgasmix = dive->cylinder[nextdp->cylinderid].gasmix; gaschange_after = (nextdp && (gasmix_distance(&gasmix, &newgasmix) || dp->setpoint != nextdp->setpoint)); gaschange_before = (gasmix_distance(&lastprintgasmix, &gasmix) || lastprintsetpoint != dp->setpoint); /* do we want to skip this leg as it is devoid of anything useful? */ @@ -837,7 +842,8 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool while (dp) { if (dp->time != 0) { struct gas_pressures pressures; - fill_pressures(&pressures, depth_to_atm(dp->depth, dive), &dp->gasmix, 0.0, dive->dc.divemode); + struct gasmix *gasmix = &dive->cylinder[dp->cylinderid].gasmix; + fill_pressures(&pressures, depth_to_atm(dp->depth, dive), gasmix, 0.0, dive->dc.divemode); if (pressures.o2 > (dp->entered ? prefs.bottompo2 : prefs.decopo2) / 1000.0) { const char *depth_unit; @@ -846,7 +852,7 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool len = strlen(buffer); snprintf(temp, sz_temp, translate("gettextFromC", "high pO₂ value %.2f at %d:%02u with gas %s at depth %.*f %s"), - pressures.o2, FRACTION(dp->time, 60), gasname(&dp->gasmix), decimals, depth_value, depth_unit); + pressures.o2, FRACTION(dp->time, 60), gasname(gasmix), decimals, depth_value, depth_unit); len += snprintf(buffer + len, sz_buffer - len, "<span style='color: red;'>%s </span> %s<br>", translate("gettextFromC", "Warning:"), temp); } else if (pressures.o2 < 0.16) { @@ -856,7 +862,7 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool len = strlen(buffer); snprintf(temp, sz_temp, translate("gettextFromC", "low pO₂ value %.2f at %d:%02u with gas %s at depth %.*f %s"), - pressures.o2, FRACTION(dp->time, 60), gasname(&dp->gasmix), decimals, depth_value, depth_unit); + pressures.o2, FRACTION(dp->time, 60), gasname(gasmix), decimals, depth_value, depth_unit); len += snprintf(buffer + len, sz_buffer - len, "<span style='color: red;'>%s </span> %s<br>", translate("gettextFromC", "Warning:"), temp); @@ -1025,13 +1031,10 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool /* Let's start at the last 'sample', i.e. the last manually entered waypoint. */ sample = &displayed_dive.dc.sample[displayed_dive.dc.samples - 1]; - get_gas_at_time(&displayed_dive, &displayed_dive.dc, sample->time, &gas); + current_cylinder = get_cylinderid_at_time(&displayed_dive, &displayed_dive.dc, sample->time); + gas = displayed_dive.cylinder[current_cylinder].gasmix; po2 = sample->setpoint.mbar; - if ((current_cylinder = get_gasidx(&displayed_dive, &gas)) == -1) { - report_error(translate("gettextFromC", "Can't find gas %s"), gasname(&gas)); - current_cylinder = 0; - } depth = displayed_dive.dc.sample[displayed_dive.dc.samples - 1].depth.mm; average_max_depth(diveplan, &avg_depth, &max_depth); last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time); @@ -1039,7 +1042,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool /* if all we wanted was the dive just get us back to the surface */ if (!is_planner) { transitiontime = depth / 75; /* this still needs to be made configurable */ - plan_add_segment(diveplan, transitiontime, 0, gas, po2, false); + plan_add_segment(diveplan, transitiontime, 0, current_cylinder, po2, false); create_dive_from_plan(diveplan, is_planner); return(false); } @@ -1047,6 +1050,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool #if DEBUG_PLAN & 4 printf("gas %s\n", gasname(&gas)); printf("depth %5.2lfm \n", depth / 1000.0); + printf("current_cylinder %i\n", current_cylinder); #endif best_first_ascend_cylinder = current_cylinder; @@ -1097,13 +1101,13 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool // so we don't really have to compute the deco state. update_cylinder_pressure(&displayed_dive, depth, depth, -DECOTIMESTEP, prefs.bottomsac, &displayed_dive.cylinder[current_cylinder], false); clock -= DECOTIMESTEP; - plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, true); + plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, true); previous_point_time = clock; do { /* Ascend to surface */ int deltad = ascent_velocity(depth, avg_depth, bottom_time) * TIMESTEP; if (ascent_velocity(depth, avg_depth, bottom_time) != last_ascend_rate) { - plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false); + plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, false); previous_point_time = clock; last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time); } @@ -1113,15 +1117,15 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool clock += TIMESTEP; depth -= deltad; if (depth <= 5000 && depth >= (5000 - deltad) && safety_stop) { - plan_add_segment(diveplan, clock - previous_point_time, 5000, gas, po2, false); + plan_add_segment(diveplan, clock - previous_point_time, 5000, current_cylinder, po2, false); previous_point_time = clock; clock += 180; - plan_add_segment(diveplan, clock - previous_point_time, 5000, gas, po2, false); + plan_add_segment(diveplan, clock - previous_point_time, 5000, current_cylinder, po2, false); previous_point_time = clock; safety_stop = false; } } while (depth > 0); - plan_add_segment(diveplan, clock - previous_point_time, 0, gas, po2, false); + plan_add_segment(diveplan, clock - previous_point_time, 0, current_cylinder, po2, false); create_dive_from_plan(diveplan, is_planner); add_plan_to_notes(diveplan, &displayed_dive, show_disclaimer, error); fixup_dc_duration(&displayed_dive.dc); @@ -1192,7 +1196,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool int deltad = ascent_velocity(depth, avg_depth, bottom_time) * TIMESTEP; if (ascent_velocity(depth, avg_depth, bottom_time) != last_ascend_rate) { if (is_final_plan) - plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false); + plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, false); previous_point_time = clock; stopping = false; last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time); @@ -1214,7 +1218,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool /* We have reached a gas change. * Record this in the dive plan */ if (is_final_plan) - plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false); + plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, false); previous_point_time = clock; stopping = true; @@ -1264,7 +1268,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool /* The last segment was an ascend segment. * Add a waypoint for start of this deco stop */ if (is_final_plan) - plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false); + plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, false); previous_point_time = clock; stopping = true; } @@ -1312,7 +1316,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool breaktime = 0; breakcylinder = current_cylinder; if (is_final_plan) - plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false); + plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, false); previous_point_time = clock; current_cylinder = 0; gas = displayed_dive.cylinder[current_cylinder].gasmix; @@ -1323,7 +1327,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool if (breaktime >= 6 * 60) { o2time = 0; if (is_final_plan) - plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false); + plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, false); previous_point_time = clock; current_cylinder = breakcylinder; gas = displayed_dive.cylinder[current_cylinder].gasmix; @@ -1336,7 +1340,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool if (stopping) { /* Next we will ascend again. Add a waypoint if we have spend deco time */ if (is_final_plan) - plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false); + plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, false); previous_point_time = clock; stopping = false; } @@ -1345,7 +1349,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool deco_time = clock - bottom_time; } while (!is_final_plan); - plan_add_segment(diveplan, clock - previous_point_time, 0, gas, po2, false); + plan_add_segment(diveplan, clock - previous_point_time, 0, current_cylinder, po2, false); create_dive_from_plan(diveplan, is_planner); add_plan_to_notes(diveplan, &displayed_dive, show_disclaimer, error); fixup_dc_duration(&displayed_dive.dc); diff --git a/core/planner.h b/core/planner.h index a675989e0..3298d7ddb 100644 --- a/core/planner.h +++ b/core/planner.h @@ -17,6 +17,7 @@ extern void set_display_runtime(bool display); extern void set_display_duration(bool display); extern void set_display_transitions(bool display); extern void get_gas_at_time(struct dive *dive, struct divecomputer *dc, duration_t time, struct gasmix *gas); +extern int get_cylinderid_at_time(struct dive *dive, struct divecomputer *dc, duration_t time); extern int get_gasidx(struct dive *dive, struct gasmix *mix); extern bool diveplan_empty(struct diveplan *diveplan); diff --git a/core/qthelper.cpp b/core/qthelper.cpp index d6a6c2579..01351376d 100644 --- a/core/qthelper.cpp +++ b/core/qthelper.cpp @@ -1215,9 +1215,10 @@ QString get_gas_string(struct gasmix gas) return result; } -QString get_divepoint_gas_string(const divedatapoint &p) +QString get_divepoint_gas_string(struct dive *d, const divedatapoint &p) { - return get_gas_string(p.gasmix); + int idx = p.cylinderid; + return get_gas_string(d->cylinder[idx].gasmix); } weight_t string_to_weight(const char *str) diff --git a/core/qthelper.h b/core/qthelper.h index 3a5ef60e4..95bdf4dbd 100644 --- a/core/qthelper.h +++ b/core/qthelper.h @@ -18,7 +18,7 @@ bool gpsHasChanged(struct dive *dive, struct dive *master, const QString &gps_te extern "C" const char *printGPSCoords(int lat, int lon); QList<int> getDivesInTrip(dive_trip_t *trip); QString get_gas_string(struct gasmix gas); -QString get_divepoint_gas_string(const divedatapoint& dp); +QString get_divepoint_gas_string(struct dive *d, const divedatapoint& dp); void read_hashes(); void write_hashes(); void updateHash(struct picture *picture); diff --git a/desktop-widgets/diveplanner.cpp b/desktop-widgets/diveplanner.cpp index 0455573e4..4e462cca0 100644 --- a/desktop-widgets/diveplanner.cpp +++ b/desktop-widgets/diveplanner.cpp @@ -49,6 +49,7 @@ void DiveHandler::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) for (int i = 0; i < rowCount; i++) { QAction *action = new QAction(&m); action->setText(model->data(model->index(i, 0), Qt::DisplayRole).toString()); + action->setData(i); connect(action, SIGNAL(triggered(bool)), this, SLOT(changeGas())); m.addAction(action); } @@ -72,7 +73,7 @@ void DiveHandler::changeGas() { QAction *action = qobject_cast<QAction *>(sender()); QModelIndex index = plannerModel->index(parentIndex(), DivePlannerPointsModel::GAS); - plannerModel->gaschange(index.sibling(index.row() + 1, index.column()), action->text()); + plannerModel->gaschange(index.sibling(index.row() + 1, index.column()), action->data().toInt()); } void DiveHandler::mouseMoveEvent(QGraphicsSceneMouseEvent *event) @@ -126,6 +127,8 @@ DivePlannerWidget::DivePlannerWidget(QWidget *parent, Qt::WindowFlags f) : QWidg connect(CylindersModel::instance(), SIGNAL(rowsRemoved(QModelIndex, int, int)), GasSelectionModel::instance(), SLOT(repopulate())); connect(CylindersModel::instance(), SIGNAL(dataChanged(QModelIndex, QModelIndex)), + plannerModel, SLOT(emitDataChanged())); + connect(CylindersModel::instance(), SIGNAL(dataChanged(QModelIndex, QModelIndex)), plannerModel, SIGNAL(cylinderModelEdited())); connect(CylindersModel::instance(), SIGNAL(rowsInserted(QModelIndex, int, int)), plannerModel, SIGNAL(cylinderModelEdited())); diff --git a/desktop-widgets/modeldelegates.cpp b/desktop-widgets/modeldelegates.cpp index a80137e80..01e8f4d17 100644 --- a/desktop-widgets/modeldelegates.cpp +++ b/desktop-widgets/modeldelegates.cpp @@ -403,7 +403,7 @@ void AirTypesDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, if (!index.isValid()) return; QComboBox *combo = qobject_cast<QComboBox *>(editor); - model->setData(index, QVariant(combo->currentText())); + model->setData(index, QVariant(combo->currentIndex())); } AirTypesDelegate::AirTypesDelegate(QObject *parent) : ComboBoxDelegate(GasSelectionModel::instance(), parent) diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp index 5aa0c53a5..aae8fdd3b 100644 --- a/profile-widget/profilewidget2.cpp +++ b/profile-widget/profilewidget2.cpp @@ -1739,7 +1739,7 @@ void ProfileWidget2::repositionDiveHandlers() QLineF line(p1, p2); QPointF pos = line.pointAt(0.5); gases[i]->setPos(pos); - gases[i]->setText(get_divepoint_gas_string(datapoint)); + gases[i]->setText(get_gas_string(displayed_dive.cylinder[datapoint.cylinderid].gasmix)); gases[i]->setVisible(datapoint.entered && (i == 0 || gases[i]->text() != gases[i-1]->text())); } diff --git a/qt-models/cylindermodel.cpp b/qt-models/cylindermodel.cpp index 20b72077d..6ea27f167 100644 --- a/qt-models/cylindermodel.cpp +++ b/qt-models/cylindermodel.cpp @@ -296,8 +296,6 @@ bool CylindersModel::setData(const QModelIndex &index, const QVariant &value, in } break; } - if (addDiveMode) - DivePlannerPointsModel::instance()->tanksUpdated(); dataChanged(index, index); return true; } @@ -391,8 +389,8 @@ void CylindersModel::remove(const QModelIndex &index) } if (same_gas == -1 && ((DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING && - DivePlannerPointsModel::instance()->tankInUse(cyl->gasmix)) || - (DivePlannerPointsModel::instance()->currentMode() == DivePlannerPointsModel::NOTHING && + DivePlannerPointsModel::instance()->tankInUse(index.row())) || + (DivePlannerPointsModel::instance()->currentMode() == DivePlannerPointsModel::NOTHING && is_cylinder_used(&displayed_dive, index.row())))) { emit warningMessage(TITLE_OR_TEXT( tr("Cylinder cannot be removed"), diff --git a/qt-models/diveplannermodel.cpp b/qt-models/diveplannermodel.cpp index 16a2e40eb..f44d94c17 100644 --- a/qt-models/diveplannermodel.cpp +++ b/qt-models/diveplannermodel.cpp @@ -25,24 +25,21 @@ void DivePlannerPointsModel::removeSelectedPoints(const QVector<int> &rows) void DivePlannerPointsModel::createSimpleDive() { - struct gasmix gas = {}; - // initialize the start time in the plan diveplan.when = displayed_dive.when; - if (isPlanner()) - // let's use the gas from the first cylinder - gas = displayed_dive.cylinder[0].gasmix; + // Use gas from the first cylinder + int cylinderid = 0; // If we're in drop_stone_mode, don't add a first point. // It will be added implicit. if (!prefs.drop_stone_mode) - addStop(M_OR_FT(15, 45), 1 * 60, &gas, 0, true); + addStop(M_OR_FT(15, 45), 1 * 60, cylinderid, 0, true); - addStop(M_OR_FT(15, 45), 20 * 60, &gas, 0, true); + addStop(M_OR_FT(15, 45), 20 * 60, 0, 0, true); if (!isPlanner()) { - addStop(M_OR_FT(5, 15), 42 * 60, &gas, 0, true); - addStop(M_OR_FT(5, 15), 45 * 60, &gas, 0, true); + addStop(M_OR_FT(5, 15), 42 * 60, 0, cylinderid, true); + addStop(M_OR_FT(5, 15), 45 * 60, 0, cylinderid, true); } } @@ -99,8 +96,8 @@ void DivePlannerPointsModel::loadFromDive(dive *d) j++; } if (samplecount) { - get_gas_at_time(d, &d->dc, lasttime, &gas); - addStop(depthsum / samplecount, newtime.seconds, &gas, 0, true); + int cylinderid = get_cylinderid_at_time(d, &d->dc, lasttime); + addStop(depthsum / samplecount, newtime.seconds, cylinderid, 0, true); lasttime = newtime; depthsum = 0; samplecount = 0; @@ -222,7 +219,7 @@ QVariant DivePlannerPointsModel::data(const QModelIndex &index, int role) const else return p.time / 60; case GAS: - return get_divepoint_gas_string(p); + return get_gas_string(displayed_dive.cylinder[p.cylinderid].gasmix); } } else if (role == Qt::DecorationRole) { switch (index.column()) { @@ -282,9 +279,8 @@ bool DivePlannerPointsModel::setData(const QModelIndex &index, const QVariant &v p.setpoint = po2; } break; case GAS: - QByteArray gasv = value.toByteArray(); - if (validate_gas(gasv.data(), &gas)) - p.gasmix = gas; + if (value.toInt() >= 0 && value.toInt() < MAX_CYLINDERS) + p.cylinderid = value.toInt(); break; } editStop(index.row(), p); @@ -292,15 +288,11 @@ bool DivePlannerPointsModel::setData(const QModelIndex &index, const QVariant &v return QAbstractItemModel::setData(index, value, role); } -void DivePlannerPointsModel::gaschange(const QModelIndex &index, QString newgas) +void DivePlannerPointsModel::gaschange(const QModelIndex &index, int newcylinderid) { - int i = index.row(); - gasmix oldgas = divepoints[i].gasmix; - gasmix gas = {}; - if (!validate_gas(newgas.toUtf8().data(), &gas)) - return; - while (i < rowCount() && gasmix_distance(&oldgas, &divepoints[i].gasmix) == 0) - divepoints[i++].gasmix = gas; + int i = index.row(), oldcylinderid = divepoints[i].cylinderid; + while (i < rowCount() && oldcylinderid == divepoints[i].cylinderid) + divepoints[i++].cylinderid = newcylinderid; emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, COLUMNS - 1)); } @@ -589,13 +581,12 @@ int DivePlannerPointsModel::lastEnteredPoint() return -1; } -int DivePlannerPointsModel::addStop(int milimeters, int seconds, gasmix *gas_in, int ccpoint, bool entered) +int DivePlannerPointsModel::addStop(int milimeters, int seconds, int cylinderid_in, int ccpoint, bool entered) { - struct gasmix air = {}; - struct gasmix gas = {}; + int cylinderid; bool usePrevious = false; - if (gas_in) - gas = *gas_in; + if (cylinderid_in) + cylinderid = cylinderid_in; else usePrevious = true; if (recalcQ()) @@ -607,19 +598,14 @@ int DivePlannerPointsModel::addStop(int milimeters, int seconds, gasmix *gas_in, const divedatapoint t = divepoints.at(lastEnteredPoint()); milimeters = t.depth; seconds = t.time + 600; // 10 minutes. - gas = t.gasmix; + cylinderid = t.cylinderid; ccpoint = t.setpoint; } else if (seconds == 0 && milimeters == 0 && row == 0) { milimeters = M_OR_FT(5, 15); // 5m / 15ft seconds = 600; // 10 min - //Default to the first defined gas, if we got one. - cylinder_t *cyl = &displayed_dive.cylinder[0]; - if (cyl) - gas = cyl->gasmix; + // Default to the first cylinder + cylinderid = 0; } - if (!usePrevious) - if (!addGas(gas)) - qDebug("addGas failed"); // FIXME add error propagation // check if there's already a new stop before this one: for (int i = 0; i < row; i++) { @@ -640,13 +626,9 @@ int DivePlannerPointsModel::addStop(int milimeters, int seconds, gasmix *gas_in, // the segment is determined by the waypoint at the end. if (usePrevious) { if (row < divepoints.count()) { - gas = divepoints.at(row).gasmix; + cylinderid = divepoints.at(row).cylinderid; } else if (row > 0) { - gas = divepoints.at(row - 1).gasmix; - } else { - if (!addGas(air)) - qDebug("addGas failed"); // FIXME add error propagation - + cylinderid = divepoints.at(row - 1).cylinderid; } } @@ -655,7 +637,7 @@ int DivePlannerPointsModel::addStop(int milimeters, int seconds, gasmix *gas_in, divedatapoint point; point.depth = milimeters; point.time = seconds; - point.gasmix = gas; + point.cylinderid = cylinderid; point.setpoint = ccpoint; point.entered = entered; point.next = NULL; @@ -772,7 +754,7 @@ void DivePlannerPointsModel::rememberTanks() oldGases = collectGases(&displayed_dive); } -bool DivePlannerPointsModel::tankInUse(struct gasmix gasmix) +bool DivePlannerPointsModel::tankInUse(int cylinderid) { for (int j = 0; j < rowCount(); j++) { divedatapoint &p = divepoints[j]; @@ -780,45 +762,12 @@ bool DivePlannerPointsModel::tankInUse(struct gasmix gasmix) continue; if (!p.entered) // removing deco gases is ok continue; - if (gasmix_distance(&p.gasmix, &gasmix) < 100) + if (p.cylinderid == cylinderid) // tank is in use return true; } return false; } -void DivePlannerPointsModel::tanksUpdated() -{ - // we don't know exactly what changed - what we care about is - // "did a gas change on us". So we look through the diveplan to - // see if there is a gas that is now missing and if there is, we - // replace it with the matching new gas. - QVector<QPair<int, int> > gases = collectGases(&displayed_dive); - if (gases.count() == oldGases.count()) { - // either nothing relevant changed, or exactly ONE gasmix changed - for (int i = 0; i < gases.count(); i++) { - if (gases.at(i) != oldGases.at(i)) { - if (oldGases.count(oldGases.at(i)) > 1) { - // we had this gas more than once, so don't - // change segments that used this gas as it still exists - break; - } - for (int j = 0; j < rowCount(); j++) { - divedatapoint &p = divepoints[j]; - struct gasmix gas; - gas.o2.permille = oldGases.at(i).first; - gas.he.permille = oldGases.at(i).second; - if (gasmix_distance(&gas, &p.gasmix) < 100) { - p.gasmix.o2.permille = gases.at(i).first; - p.gasmix.he.permille = gases.at(i).second; - } - } - break; - } - } - } - emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, COLUMNS - 1)); -} - void DivePlannerPointsModel::clear() { bool oldRecalc = setRecalc(false); @@ -843,12 +792,12 @@ void DivePlannerPointsModel::createTemporaryPlan() int deltaT = lastIndex != -1 ? p.time - at(lastIndex).time : p.time; lastIndex = i; if (i == 0 && prefs.drop_stone_mode) { - /* Okay, we add a fist segment where we go down to depth */ - plan_add_segment(&diveplan, p.depth / prefs.descrate, p.depth, p.gasmix, p.setpoint, true); + /* Okay, we add a first segment where we go down to depth */ + plan_add_segment(&diveplan, p.depth / prefs.descrate, p.depth, p.cylinderid, p.setpoint, true); deltaT -= p.depth / prefs.descrate; } if (p.entered) - plan_add_segment(&diveplan, deltaT, p.depth, p.gasmix, p.setpoint, true); + plan_add_segment(&diveplan, deltaT, p.depth, p.cylinderid, p.setpoint, true); } // what does the cache do??? @@ -857,7 +806,7 @@ void DivePlannerPointsModel::createTemporaryPlan() for (int i = 0; i < MAX_CYLINDERS; i++) { cylinder_t *cyl = &displayed_dive.cylinder[i]; if (cyl->depth.mm) { - dp = create_dp(0, cyl->depth.mm, cyl->gasmix, 0); + dp = create_dp(0, cyl->depth.mm, i, 0); if (diveplan.dp) { dp->next = diveplan.dp; diveplan.dp = dp; diff --git a/qt-models/diveplannermodel.h b/qt-models/diveplannermodel.h index 0770aa077..da84119ce 100644 --- a/qt-models/diveplannermodel.h +++ b/qt-models/diveplannermodel.h @@ -30,7 +30,7 @@ public: virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); virtual Qt::ItemFlags flags(const QModelIndex &index) const; - void gaschange(const QModelIndex &index, QString newgas); + void gaschange(const QModelIndex &index, int newcylinderid); void removeSelectedPoints(const QVector<int> &rows); void setPlanMode(Mode mode); bool isPlanner(); @@ -42,7 +42,7 @@ public: bool recalcQ(); void tanksUpdated(); void rememberTanks(); - bool tankInUse(struct gasmix gasmix); + bool tankInUse(int cylinderid); void setupCylinders(); /** * @return the row number. @@ -59,7 +59,7 @@ public: public slots: - int addStop(int millimeters = 0, int seconds = 0, struct gasmix *gas = 0, int ccpoint = 0, bool entered = true); + int addStop(int millimeters = 0, int seconds = 0, int cylinderid_in = 0, int ccpoint = 0, bool entered = true); void addCylinder_clicked(); void setGFHigh(const int gfhigh); void triggerGFHigh(); |