mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Planner: Fix Editing of Plans in Multi-Divecomputer Dives.
Currently editing of planned dives that have been merged with actual (logged) dives only works if the 'Planned dive' divecomputer is the first divecomputer, and this divecomputer is selected when clicking 'Edit planned dive'. In other cases the profile of the first divecomputer is overlaid with the profile of the planned dive, and the first divecomputer's profile is overwritten when saving the dive plan. Fix this problem. Triggered by @SeppoTakalo's comment (https://github.com/subsurface/subsurface/issues/1913#issuecomment-2075562119): Users don't like that planned dives show up as their own entries in the dive list, so being able to merge them with the actual dive after it has been executed is a good feature - but this wasn't working well until now. Signed-off-by: Michael Keller <github@ike.ch>
This commit is contained in:
parent
a83349015a
commit
528532572f
11 changed files with 114 additions and 106 deletions
|
@ -339,28 +339,27 @@ extern "C" void selective_copy_dive(const struct dive *s, struct dive *d, struct
|
|||
}
|
||||
#undef CONDITIONAL_COPY_STRING
|
||||
|
||||
/* copies all events from all dive computers before a given time
|
||||
/* copies all events from the given dive computer before a given time
|
||||
this is used when editing a dive in the planner to preserve the events
|
||||
of the old dive */
|
||||
extern "C" void copy_events_until(const struct dive *sd, struct dive *dd, int time)
|
||||
extern "C" void copy_events_until(const struct dive *sd, struct dive *dd, int dcNr, int time)
|
||||
{
|
||||
if (!sd || !dd)
|
||||
return;
|
||||
|
||||
const struct divecomputer *s = &sd->dc;
|
||||
struct divecomputer *d = &dd->dc;
|
||||
struct divecomputer *d = get_dive_dc(dd, dcNr);
|
||||
|
||||
while (s && d) {
|
||||
const struct event *ev;
|
||||
ev = s->events;
|
||||
while (ev != NULL) {
|
||||
// Don't add events the planner knows about
|
||||
if (ev->time.seconds < time && !event_is_gaschange(ev) && !event_is_divemodechange(ev))
|
||||
add_event(d, ev->time.seconds, ev->type, ev->flags, ev->value, ev->name);
|
||||
ev = ev->next;
|
||||
}
|
||||
s = s->next;
|
||||
d = d->next;
|
||||
if (!s || !d)
|
||||
return;
|
||||
|
||||
const struct event *ev;
|
||||
ev = s->events;
|
||||
while (ev != NULL) {
|
||||
// Don't add events the planner knows about
|
||||
if (ev->time.seconds < time && !event_is_gaschange(ev) && !event_is_divemodechange(ev))
|
||||
add_event(d, ev->time.seconds, ev->type, ev->flags, ev->value, ev->name);
|
||||
ev = ev->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ extern int split_dive(const struct dive *dive, struct dive **new1, struct dive *
|
|||
extern int split_dive_at_time(const struct dive *dive, duration_t time, struct dive **new1, struct dive **new2);
|
||||
extern struct dive *merge_dives(const struct dive *a, const struct dive *b, int offset, bool prefer_downloaded, struct dive_trip **trip, struct dive_site **site);
|
||||
extern struct dive *try_to_merge(struct dive *a, struct dive *b, bool prefer_downloaded);
|
||||
extern void copy_events_until(const struct dive *sd, struct dive *dd, int time);
|
||||
extern void copy_events_until(const struct dive *sd, struct dive *dd, int dcNr, int time);
|
||||
extern void copy_used_cylinders(const struct dive *s, struct dive *d, bool used_only);
|
||||
extern bool is_cylinder_used(const struct dive *dive, int idx);
|
||||
extern bool is_cylinder_prot(const struct dive *dive, int idx);
|
||||
|
|
|
@ -111,9 +111,8 @@ static void interpolate_transition(struct deco_state *ds, struct dive *dive, dur
|
|||
}
|
||||
|
||||
/* returns the tissue tolerance at the end of this (partial) dive */
|
||||
static int tissue_at_end(struct deco_state *ds, struct dive *dive, deco_state_cache &cache)
|
||||
static int tissue_at_end(struct deco_state *ds, struct dive *dive, const struct divecomputer *dc, deco_state_cache &cache)
|
||||
{
|
||||
struct divecomputer *dc;
|
||||
struct sample *sample, *psample;
|
||||
int i;
|
||||
depth_t lastdepth = {};
|
||||
|
@ -129,7 +128,6 @@ static int tissue_at_end(struct deco_state *ds, struct dive *dive, deco_state_ca
|
|||
surface_interval = init_decompression(ds, dive, true);
|
||||
cache.cache(ds);
|
||||
}
|
||||
dc = &dive->dc;
|
||||
if (!dc->samples)
|
||||
return 0;
|
||||
psample = sample = dc->sample;
|
||||
|
@ -208,10 +206,9 @@ static void update_cylinder_pressure(struct dive *d, int old_depth, int new_dept
|
|||
|
||||
/* overwrite the data in dive
|
||||
* return false if something goes wrong */
|
||||
static void create_dive_from_plan(struct diveplan *diveplan, struct dive *dive, bool track_gas)
|
||||
static void create_dive_from_plan(struct diveplan *diveplan, struct dive *dive, struct divecomputer *dc, bool track_gas)
|
||||
{
|
||||
struct divedatapoint *dp;
|
||||
struct divecomputer *dc;
|
||||
struct sample *sample;
|
||||
struct event *ev;
|
||||
cylinder_t *cyl;
|
||||
|
@ -219,7 +216,7 @@ static void create_dive_from_plan(struct diveplan *diveplan, struct dive *dive,
|
|||
int lasttime = 0, last_manual_point = 0;
|
||||
depth_t lastdepth = {.mm = 0};
|
||||
int lastcylid;
|
||||
enum divemode_t type = dive->dc.divemode;
|
||||
enum divemode_t type = dc->divemode;
|
||||
|
||||
if (!diveplan || !diveplan->dp)
|
||||
return;
|
||||
|
@ -231,7 +228,6 @@ static void create_dive_from_plan(struct diveplan *diveplan, struct dive *dive,
|
|||
// reset the cylinders and clear out the samples and events of the
|
||||
// dive-to-be-planned so we can restart
|
||||
reset_cylinders(dive, track_gas);
|
||||
dc = &dive->dc;
|
||||
dc->when = dive->when = diveplan->when;
|
||||
dc->surface_pressure.mbar = diveplan->surface_pressure;
|
||||
dc->salinity = diveplan->salinity;
|
||||
|
@ -319,7 +315,7 @@ static void create_dive_from_plan(struct diveplan *diveplan, struct dive *dive,
|
|||
finish_sample(dc);
|
||||
dp = dp->next;
|
||||
}
|
||||
dive->dc.last_manual_time.seconds = last_manual_point;
|
||||
dc->last_manual_time.seconds = last_manual_point;
|
||||
|
||||
#if DEBUG_PLAN & 32
|
||||
save_dive(stdout, dive);
|
||||
|
@ -655,7 +651,7 @@ static void average_max_depth(struct diveplan *dive, int *avg_depth, int *max_de
|
|||
*avg_depth = *max_depth = 0;
|
||||
}
|
||||
|
||||
bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, int timestep, struct decostop *decostoptable, deco_state_cache &cache, bool is_planner, bool show_disclaimer)
|
||||
bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, int dcNr, int timestep, struct decostop *decostoptable, deco_state_cache &cache, bool is_planner, bool show_disclaimer)
|
||||
{
|
||||
|
||||
int bottom_depth;
|
||||
|
@ -690,15 +686,16 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
|
|||
int laststoptime = timestep;
|
||||
bool o2breaking = false;
|
||||
int decostopcounter = 0;
|
||||
enum divemode_t divemode = dive->dc.divemode;
|
||||
struct divecomputer *dc = get_dive_dc(dive, dcNr);
|
||||
enum divemode_t divemode = dc->divemode;
|
||||
|
||||
set_gf(diveplan->gflow, diveplan->gfhigh);
|
||||
set_vpmb_conservatism(diveplan->vpmb_conservatism);
|
||||
|
||||
if (!diveplan->surface_pressure) {
|
||||
// Lets use dive's surface pressure in planner, if have one...
|
||||
if (dive->dc.surface_pressure.mbar) { // First from DC...
|
||||
diveplan->surface_pressure = dive->dc.surface_pressure.mbar;
|
||||
if (dc->surface_pressure.mbar) { // First from DC...
|
||||
diveplan->surface_pressure = dc->surface_pressure.mbar;
|
||||
}
|
||||
else if (dive->surface_pressure.mbar) { // After from user...
|
||||
diveplan->surface_pressure = dive->surface_pressure.mbar;
|
||||
|
@ -707,10 +704,10 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
|
|||
diveplan->surface_pressure = SURFACE_PRESSURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
clear_deco(ds, dive->surface_pressure.mbar / 1000.0, true);
|
||||
ds->max_bottom_ceiling_pressure.mbar = ds->first_ceiling_pressure.mbar = 0;
|
||||
create_dive_from_plan(diveplan, dive, is_planner);
|
||||
create_dive_from_plan(diveplan, dive, dc, is_planner);
|
||||
|
||||
// Do we want deco stop array in metres or feet?
|
||||
if (prefs.units.length == units::METERS ) {
|
||||
|
@ -731,20 +728,20 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
|
|||
*(decostoplevels + 1) = M_OR_FT(3,10);
|
||||
|
||||
/* Let's start at the last 'sample', i.e. the last manually entered waypoint. */
|
||||
sample = &dive->dc.sample[dive->dc.samples - 1];
|
||||
sample = &dc->sample[dc->samples - 1];
|
||||
|
||||
/* Keep time during the ascend */
|
||||
bottom_time = clock = previous_point_time = dive->dc.sample[dive->dc.samples - 1].time.seconds;
|
||||
bottom_time = clock = previous_point_time = dc->sample[dc->samples - 1].time.seconds;
|
||||
|
||||
current_cylinder = get_cylinderid_at_time(dive, &dive->dc, sample->time);
|
||||
current_cylinder = get_cylinderid_at_time(dive, dc, sample->time);
|
||||
// Find the divemode at the end of the dive
|
||||
const struct event *ev = NULL;
|
||||
divemode = UNDEF_COMP_TYPE;
|
||||
divemode = get_current_divemode(&dive->dc, bottom_time, &ev, &divemode);
|
||||
divemode = get_current_divemode(dc, bottom_time, &ev, &divemode);
|
||||
gas = get_cylinder(dive, current_cylinder)->gasmix;
|
||||
|
||||
po2 = sample->setpoint.mbar;
|
||||
depth = dive->dc.sample[dive->dc.samples - 1].depth.mm;
|
||||
depth = dc->sample[dc->samples - 1].depth.mm;
|
||||
average_max_depth(diveplan, &avg_depth, &max_depth);
|
||||
last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time);
|
||||
|
||||
|
@ -755,7 +752,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
|
|||
*/
|
||||
transitiontime = lrint(depth / (double)prefs.ascratelast6m);
|
||||
plan_add_segment(diveplan, transitiontime, 0, current_cylinder, po2, false, divemode);
|
||||
create_dive_from_plan(diveplan, dive, is_planner);
|
||||
create_dive_from_plan(diveplan, dive, dc, is_planner);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -782,7 +779,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
|
|||
gi = static_cast<int>(gaschanges.size()) - 1;
|
||||
|
||||
/* Set tissue tolerance and initial vpmb gradient at start of ascent phase */
|
||||
diveplan->surface_interval = tissue_at_end(ds, dive, cache);
|
||||
diveplan->surface_interval = tissue_at_end(ds, dive, dc, cache);
|
||||
nuclear_regeneration(ds, clock);
|
||||
vpmb_start_gradient(ds);
|
||||
if (decoMode(true) == RECREATIONAL) {
|
||||
|
@ -830,9 +827,9 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
|
|||
}
|
||||
} while (depth > 0);
|
||||
plan_add_segment(diveplan, clock - previous_point_time, 0, current_cylinder, po2, false, divemode);
|
||||
create_dive_from_plan(diveplan, dive, is_planner);
|
||||
create_dive_from_plan(diveplan, dive, dc, is_planner);
|
||||
add_plan_to_notes(diveplan, dive, show_disclaimer, error);
|
||||
fixup_dc_duration(&dive->dc);
|
||||
fixup_dc_duration(dc);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -848,7 +845,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
|
|||
}
|
||||
|
||||
// VPM-B or Buehlmann Deco
|
||||
tissue_at_end(ds, dive, cache);
|
||||
tissue_at_end(ds, dive, dc, cache);
|
||||
if ((divemode == CCR || divemode == PSCR) && prefs.dobailout) {
|
||||
divemode = OC;
|
||||
po2 = 0;
|
||||
|
@ -1112,9 +1109,9 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
|
|||
current_cylinder = dive->cylinders.nr;
|
||||
plan_add_segment(diveplan, prefs.surface_segment, 0, current_cylinder, 0, false, OC);
|
||||
}
|
||||
create_dive_from_plan(diveplan, dive, is_planner);
|
||||
create_dive_from_plan(diveplan, dive, dc, is_planner);
|
||||
add_plan_to_notes(diveplan, dive, show_disclaimer, error);
|
||||
fixup_dc_duration(&dive->dc);
|
||||
fixup_dc_duration(dc);
|
||||
|
||||
return decodive;
|
||||
}
|
||||
|
|
|
@ -60,6 +60,6 @@ struct decostop {
|
|||
|
||||
#include <string>
|
||||
extern std::string get_planner_disclaimer_formatted();
|
||||
extern bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, int timestep, struct decostop *decostoptable, deco_state_cache &cache, bool is_planner, bool show_disclaimer);
|
||||
extern bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, int dcNr, int timestep, struct decostop *decostoptable, deco_state_cache &cache, bool is_planner, bool show_disclaimer);
|
||||
#endif
|
||||
#endif // PLANNER_H
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <QBuffer>
|
||||
#endif
|
||||
|
||||
DivePlannerWidget::DivePlannerWidget(dive &planned_dive, PlannerWidgets *parent)
|
||||
DivePlannerWidget::DivePlannerWidget(dive &planned_dive, int dcNr, PlannerWidgets *parent)
|
||||
{
|
||||
DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
|
||||
CylindersModel *cylinders = DivePlannerPointsModel::instance()->cylindersModel();
|
||||
|
@ -52,7 +52,7 @@ DivePlannerWidget::DivePlannerWidget(dive &planned_dive, PlannerWidgets *parent)
|
|||
view->setColumnHidden(CylindersModel::SENSORS, true);
|
||||
view->setItemDelegateForColumn(CylindersModel::TYPE, new TankInfoDelegate(this));
|
||||
auto tankUseDelegate = new TankUseDelegate(this);
|
||||
tankUseDelegate->setCurrentDC(get_dive_dc(&planned_dive, 0));
|
||||
tankUseDelegate->setCurrentDC(get_dive_dc(&planned_dive, dcNr));
|
||||
view->setItemDelegateForColumn(CylindersModel::USE, tankUseDelegate);
|
||||
connect(ui.cylinderTableWidget, &TableView::addButtonClicked, plannerModel, &DivePlannerPointsModel::addCylinder_clicked);
|
||||
connect(ui.tableWidget, &TableView::addButtonClicked, plannerModel, &DivePlannerPointsModel::addDefaultStop);
|
||||
|
@ -539,7 +539,8 @@ void PlannerDetails::setPlanNotes(QString plan)
|
|||
|
||||
PlannerWidgets::PlannerWidgets() :
|
||||
planned_dive(alloc_dive()),
|
||||
plannerWidget(*planned_dive, this),
|
||||
dcNr(0),
|
||||
plannerWidget(*planned_dive, dcNr, this),
|
||||
plannerSettingsWidget(this)
|
||||
{
|
||||
connect(plannerDetails.printPlan(), &QPushButton::pressed, this, &PlannerWidgets::printDecoPlan);
|
||||
|
@ -556,21 +557,27 @@ struct dive *PlannerWidgets::getDive() const
|
|||
return planned_dive.get();
|
||||
}
|
||||
|
||||
divemode_t PlannerWidgets::getRebreatherMode() const
|
||||
int PlannerWidgets::getDcNr()
|
||||
{
|
||||
return planned_dive->dc.divemode;
|
||||
return dcNr;
|
||||
}
|
||||
|
||||
void PlannerWidgets::preparePlanDive(const dive *currentDive)
|
||||
divemode_t PlannerWidgets::getRebreatherMode() const
|
||||
{
|
||||
return get_dive_dc_const(planned_dive.get(), dcNr)->divemode;
|
||||
}
|
||||
|
||||
void PlannerWidgets::preparePlanDive(const dive *currentDive, int currentDcNr)
|
||||
{
|
||||
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN);
|
||||
// create a simple starting dive, using the first gas from the just copied cylinders
|
||||
DivePlannerPointsModel::instance()->createSimpleDive(planned_dive.get());
|
||||
dcNr = 0;
|
||||
|
||||
// plan the dive in the same mode as the currently selected one
|
||||
if (currentDive) {
|
||||
plannerSettingsWidget.setDiveMode(currentDive->dc.divemode);
|
||||
plannerSettingsWidget.setBailoutVisibility(currentDive->dc.divemode);
|
||||
plannerSettingsWidget.setDiveMode(get_dive_dc_const(currentDive, currentDcNr)->divemode);
|
||||
plannerSettingsWidget.setBailoutVisibility(get_dive_dc_const(currentDive, currentDcNr)->divemode);
|
||||
if (currentDive->salinity)
|
||||
plannerWidget.setSalinity(currentDive->salinity);
|
||||
else // No salinity means salt water
|
||||
|
@ -586,15 +593,16 @@ void PlannerWidgets::planDive()
|
|||
plannerWidget.setupStartTime(timestampToDateTime(planned_dive->when)); // This will reload the profile!
|
||||
}
|
||||
|
||||
void PlannerWidgets::prepareReplanDive(const dive *d)
|
||||
void PlannerWidgets::prepareReplanDive(const dive *currentDive, int currentDcNr)
|
||||
{
|
||||
copy_dive(d, planned_dive.get());
|
||||
copy_dive(currentDive, planned_dive.get());
|
||||
dcNr = currentDcNr;
|
||||
}
|
||||
|
||||
void PlannerWidgets::replanDive(int currentDC)
|
||||
void PlannerWidgets::replanDive()
|
||||
{
|
||||
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN);
|
||||
DivePlannerPointsModel::instance()->loadFromDive(planned_dive.get(), currentDC);
|
||||
DivePlannerPointsModel::instance()->loadFromDive(planned_dive.get(), dcNr);
|
||||
|
||||
plannerWidget.setReplanButton(true);
|
||||
plannerWidget.setupStartTime(timestampToDateTime(planned_dive->when));
|
||||
|
@ -603,7 +611,7 @@ void PlannerWidgets::replanDive(int currentDC)
|
|||
if (planned_dive->salinity)
|
||||
plannerWidget.setSalinity(planned_dive->salinity);
|
||||
reset_cylinders(planned_dive.get(), true);
|
||||
DivePlannerPointsModel::instance()->cylindersModel()->updateDive(planned_dive.get(), currentDC);
|
||||
DivePlannerPointsModel::instance()->cylindersModel()->updateDive(planned_dive.get(), dcNr);
|
||||
}
|
||||
|
||||
void PlannerWidgets::printDecoPlan()
|
||||
|
|
|
@ -18,7 +18,7 @@ struct dive;
|
|||
class DivePlannerWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DivePlannerWidget(dive &planned_dive, PlannerWidgets *parent);
|
||||
explicit DivePlannerWidget(dive &planned_dive, int dcNr, PlannerWidgets *parent);
|
||||
~DivePlannerWidget();
|
||||
void setReplanButton(bool replan);
|
||||
public
|
||||
|
@ -80,17 +80,20 @@ class PlannerWidgets : public QObject {
|
|||
public:
|
||||
PlannerWidgets();
|
||||
~PlannerWidgets();
|
||||
void preparePlanDive(const dive *currentDive); // Create a new planned dive
|
||||
void preparePlanDive(const dive *currentDive, int currentDc); // Create a new planned dive
|
||||
void planDive();
|
||||
void prepareReplanDive(const dive *d); // Make a copy of the dive to be replanned
|
||||
void replanDive(int currentDC);
|
||||
void prepareReplanDive(const dive *currentDive, int currentDc); // Make a copy of the dive to be replanned
|
||||
void replanDive();
|
||||
struct dive *getDive() const;
|
||||
int getDcNr();
|
||||
divemode_t getRebreatherMode() const;
|
||||
public
|
||||
slots:
|
||||
void printDecoPlan();
|
||||
public:
|
||||
private:
|
||||
OwningDivePtr planned_dive;
|
||||
int dcNr;
|
||||
public:
|
||||
DivePlannerWidget plannerWidget;
|
||||
PlannerSettingsWidget plannerSettingsWidget;
|
||||
PlannerDetails plannerDetails;
|
||||
|
|
|
@ -665,8 +665,8 @@ void MainWindow::on_actionReplanDive_triggered()
|
|||
{
|
||||
if (!plannerStateClean() || !current_dive || !userMayChangeAppState())
|
||||
return;
|
||||
else if (!is_dc_planner(¤t_dive->dc)) {
|
||||
if (QMessageBox::warning(this, tr("Warning"), tr("Trying to replan a dive that's not a planned dive."),
|
||||
else if (!is_dc_planner(get_dive_dc(current_dive, profile->dc))) {
|
||||
if (QMessageBox::warning(this, tr("Warning"), tr("Trying to replan a dive dive profile that is not a dive plan."),
|
||||
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
|
||||
return;
|
||||
}
|
||||
|
@ -675,9 +675,9 @@ void MainWindow::on_actionReplanDive_triggered()
|
|||
setApplicationState(ApplicationState::PlanDive);
|
||||
|
||||
disableShortcuts(true);
|
||||
plannerWidgets->prepareReplanDive(current_dive);
|
||||
profile->setPlanState(plannerWidgets->getDive(), profile->dc);
|
||||
plannerWidgets->replanDive(profile->dc);
|
||||
plannerWidgets->prepareReplanDive(current_dive, profile->dc);
|
||||
profile->setPlanState(plannerWidgets->getDive(), plannerWidgets->getDcNr());
|
||||
plannerWidgets->replanDive();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionDivePlanner_triggered()
|
||||
|
@ -689,8 +689,8 @@ void MainWindow::on_actionDivePlanner_triggered()
|
|||
setApplicationState(ApplicationState::PlanDive);
|
||||
|
||||
disableShortcuts(true);
|
||||
plannerWidgets->preparePlanDive(current_dive);
|
||||
profile->setPlanState(plannerWidgets->getDive(), 0);
|
||||
plannerWidgets->preparePlanDive(current_dive, profile->dc);
|
||||
profile->setPlanState(plannerWidgets->getDive(), plannerWidgets->getDcNr());
|
||||
plannerWidgets->planDive();
|
||||
}
|
||||
|
||||
|
|
|
@ -157,11 +157,11 @@ void ProfileWidget::setEnabledToolbar(bool enabled)
|
|||
b->setEnabled(enabled);
|
||||
}
|
||||
|
||||
void ProfileWidget::setDive(const struct dive *d)
|
||||
void ProfileWidget::setDive(const struct dive *d, int dcNr)
|
||||
{
|
||||
stack->setCurrentIndex(1); // show profile
|
||||
|
||||
bool freeDiveMode = d->dc.divemode == FREEDIVE;
|
||||
bool freeDiveMode = get_dive_dc_const(d, dcNr)->divemode == FREEDIVE;
|
||||
ui.profCalcCeiling->setDisabled(freeDiveMode);
|
||||
ui.profCalcCeiling->setDisabled(freeDiveMode);
|
||||
ui.profCalcAllTissues ->setDisabled(freeDiveMode);
|
||||
|
@ -217,12 +217,12 @@ void ProfileWidget::plotDive(dive *dIn, int dcIn)
|
|||
setEnabledToolbar(d != nullptr);
|
||||
if (editedDive) {
|
||||
view->plotDive(editedDive.get(), editedDc);
|
||||
setDive(editedDive.get());
|
||||
setDive(editedDive.get(), dc);
|
||||
} else if (d) {
|
||||
view->setProfileState(d, dc);
|
||||
view->resetZoom(); // when switching dive, reset the zoomLevel
|
||||
view->plotDive(d, dc);
|
||||
setDive(d);
|
||||
setDive(d, dc);
|
||||
} else {
|
||||
view->clear();
|
||||
stack->setCurrentIndex(0);
|
||||
|
@ -274,11 +274,12 @@ void ProfileWidget::divesChanged(const QVector<dive *> &dives, DiveField field)
|
|||
plotCurrentDive();
|
||||
}
|
||||
|
||||
void ProfileWidget::setPlanState(const struct dive *d, int dc)
|
||||
void ProfileWidget::setPlanState(const struct dive *d, int dcNr)
|
||||
{
|
||||
exitEditMode();
|
||||
view->setPlanState(d, dc);
|
||||
setDive(d);
|
||||
dc = dcNr;
|
||||
view->setPlanState(d, dcNr);
|
||||
setDive(d, dcNr);
|
||||
}
|
||||
|
||||
void ProfileWidget::unsetProfHR()
|
||||
|
|
|
@ -44,7 +44,7 @@ private:
|
|||
std::vector<QAction *> toolbarActions;
|
||||
Ui::ProfileWidget ui;
|
||||
QStackedWidget *stack;
|
||||
void setDive(const struct dive *d);
|
||||
void setDive(const struct dive *d, int dcNr);
|
||||
void editDive();
|
||||
void exitEditMode();
|
||||
void rotateDC(int dir);
|
||||
|
|
|
@ -65,6 +65,7 @@ void DivePlannerPointsModel::createSimpleDive(struct dive *dIn)
|
|||
{
|
||||
// clean out the dive and give it an id and the correct dc model
|
||||
d = dIn;
|
||||
dcNr = 0;
|
||||
clear_dive(d);
|
||||
d->id = dive_getUniqID();
|
||||
d->when = QDateTime::currentMSecsSinceEpoch() / 1000L + gettimezoneoffset() + 3600;
|
||||
|
@ -117,7 +118,7 @@ void DivePlannerPointsModel::loadFromDive(dive *dIn, int dcNrIn)
|
|||
int depthsum = 0;
|
||||
int samplecount = 0;
|
||||
o2pressure_t last_sp;
|
||||
struct divecomputer *dc = &(d->dc);
|
||||
struct divecomputer *dc = get_dive_dc(d, dcNr);
|
||||
const struct event *evd = NULL;
|
||||
enum divemode_t current_divemode = UNDEF_COMP_TYPE;
|
||||
cylinders.updateDive(d, dcNr);
|
||||
|
@ -180,9 +181,9 @@ void DivePlannerPointsModel::loadFromDive(dive *dIn, int dcNrIn)
|
|||
}
|
||||
}
|
||||
// make sure we get the last point right so the duration is correct
|
||||
current_divemode = get_current_divemode(dc, d->dc.duration.seconds, &evd, ¤t_divemode);
|
||||
current_divemode = get_current_divemode(dc, dc->duration.seconds, &evd, ¤t_divemode);
|
||||
if (!hasMarkedSamples && !dc->last_manual_time.seconds)
|
||||
addStop(0, d->dc.duration.seconds,cylinderid, last_sp.mbar, true, current_divemode);
|
||||
addStop(0, dc->duration.seconds,cylinderid, last_sp.mbar, true, current_divemode);
|
||||
preserved_until = d->duration;
|
||||
|
||||
updateDiveProfile();
|
||||
|
@ -549,9 +550,8 @@ int DivePlannerPointsModel::gfLow() const
|
|||
|
||||
void DivePlannerPointsModel::setRebreatherMode(int mode)
|
||||
{
|
||||
int i;
|
||||
d->dc.divemode = (divemode_t) mode;
|
||||
for (i = 0; i < rowCount(); i++) {
|
||||
get_dive_dc(d, dcNr)->divemode = (divemode_t) mode;
|
||||
for (int i = 0; i < rowCount(); i++) {
|
||||
divepoints[i].setpoint = mode == CCR ? prefs.defaultsetpoint : 0;
|
||||
divepoints[i].divemode = (enum divemode_t) mode;
|
||||
}
|
||||
|
@ -830,7 +830,7 @@ int DivePlannerPointsModel::addStop(int milimeters, int seconds, int cylinderid_
|
|||
}
|
||||
}
|
||||
if (divemode == UNDEF_COMP_TYPE)
|
||||
divemode = d->dc.divemode;
|
||||
divemode = get_dive_dc_const(d, dcNr)->divemode;
|
||||
|
||||
// add the new stop
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
|
@ -1084,7 +1084,7 @@ void DivePlannerPointsModel::updateDiveProfile()
|
|||
struct deco_state plan_deco_state;
|
||||
|
||||
memset(&plan_deco_state, 0, sizeof(struct deco_state));
|
||||
plan(&plan_deco_state, &diveplan, d, decotimestep, stoptable, cache, isPlanner(), false);
|
||||
plan(&plan_deco_state, &diveplan, d, dcNr, decotimestep, stoptable, cache, isPlanner(), false);
|
||||
updateMaxDepth();
|
||||
|
||||
if (isPlanner() && shouldComputeVariations()) {
|
||||
|
@ -1226,7 +1226,7 @@ void DivePlannerPointsModel::computeVariations(struct diveplan *original_plan, c
|
|||
goto finish;
|
||||
if (my_instance != instanceCounter)
|
||||
goto finish;
|
||||
plan(&ds, &plan_copy, dive, 1, original, cache, true, false);
|
||||
plan(&ds, &plan_copy, dive, dcNr, 1, original, cache, true, false);
|
||||
free_dps(&plan_copy);
|
||||
save.restore(&ds, false);
|
||||
|
||||
|
@ -1235,7 +1235,7 @@ void DivePlannerPointsModel::computeVariations(struct diveplan *original_plan, c
|
|||
last_segment->next->depth.mm += delta_depth.mm;
|
||||
if (my_instance != instanceCounter)
|
||||
goto finish;
|
||||
plan(&ds, &plan_copy, dive, 1, deeper, cache, true, false);
|
||||
plan(&ds, &plan_copy, dive, dcNr, 1, deeper, cache, true, false);
|
||||
free_dps(&plan_copy);
|
||||
save.restore(&ds, false);
|
||||
|
||||
|
@ -1244,7 +1244,7 @@ void DivePlannerPointsModel::computeVariations(struct diveplan *original_plan, c
|
|||
last_segment->next->depth.mm -= delta_depth.mm;
|
||||
if (my_instance != instanceCounter)
|
||||
goto finish;
|
||||
plan(&ds, &plan_copy, dive, 1, shallower, cache, true, false);
|
||||
plan(&ds, &plan_copy, dive, dcNr, 1, shallower, cache, true, false);
|
||||
free_dps(&plan_copy);
|
||||
save.restore(&ds, false);
|
||||
|
||||
|
@ -1252,7 +1252,7 @@ void DivePlannerPointsModel::computeVariations(struct diveplan *original_plan, c
|
|||
last_segment->next->time += delta_time.seconds;
|
||||
if (my_instance != instanceCounter)
|
||||
goto finish;
|
||||
plan(&ds, &plan_copy, dive, 1, longer, cache, true, false);
|
||||
plan(&ds, &plan_copy, dive, dcNr, 1, longer, cache, true, false);
|
||||
free_dps(&plan_copy);
|
||||
save.restore(&ds, false);
|
||||
|
||||
|
@ -1260,7 +1260,7 @@ void DivePlannerPointsModel::computeVariations(struct diveplan *original_plan, c
|
|||
last_segment->next->time -= delta_time.seconds;
|
||||
if (my_instance != instanceCounter)
|
||||
goto finish;
|
||||
plan(&ds, &plan_copy, dive, 1, shorter, cache, true, false);
|
||||
plan(&ds, &plan_copy, dive, dcNr, 1, shorter, cache, true, false);
|
||||
free_dps(&plan_copy);
|
||||
save.restore(&ds, false);
|
||||
|
||||
|
@ -1296,7 +1296,7 @@ void DivePlannerPointsModel::createPlan(bool replanCopy)
|
|||
createTemporaryPlan();
|
||||
|
||||
struct decostop stoptable[60];
|
||||
plan(&ds_after_previous_dives, &diveplan, d, decotimestep, stoptable, cache, isPlanner(), true);
|
||||
plan(&ds_after_previous_dives, &diveplan, d, dcNr, decotimestep, stoptable, cache, isPlanner(), true);
|
||||
|
||||
if (shouldComputeVariations()) {
|
||||
struct diveplan *plan_copy;
|
||||
|
@ -1349,7 +1349,7 @@ void DivePlannerPointsModel::createPlan(bool replanCopy)
|
|||
Command::addDive(d, divelog.autogroup, true);
|
||||
#endif // !SUBSURFACE_TESTING
|
||||
} else {
|
||||
copy_events_until(current_dive, d, preserved_until.seconds);
|
||||
copy_events_until(current_dive, d, dcNr, preserved_until.seconds);
|
||||
if (replanCopy) {
|
||||
// we were planning an old dive and save as a new dive
|
||||
d->id = dive_getUniqID(); // Things will break horribly if we create dives with the same id.
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
static struct dive dive = { 0 };
|
||||
static struct decostop stoptable[60];
|
||||
static struct deco_state test_deco_state;
|
||||
extern bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, int timestep, struct decostop *decostoptable, deco_state_cache &cache, bool is_planner, bool show_disclaimer);
|
||||
extern bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, int dcNr, int timestep, struct decostop *decostoptable, deco_state_cache &cache, bool is_planner, bool show_disclaimer);
|
||||
void setupPrefs()
|
||||
{
|
||||
copy_prefs(&default_prefs, &prefs);
|
||||
|
@ -453,7 +453,7 @@ void TestPlan::testMetric()
|
|||
struct diveplan testPlan = {};
|
||||
setupPlan(&testPlan);
|
||||
|
||||
plan(&test_deco_state, &testPlan, &dive, 60, stoptable, cache, 1, 0);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, 1, 0);
|
||||
|
||||
#if DEBUG
|
||||
free(dive.notes);
|
||||
|
@ -494,7 +494,7 @@ void TestPlan::testImperial()
|
|||
struct diveplan testPlan = {};
|
||||
setupPlan(&testPlan);
|
||||
|
||||
plan(&test_deco_state, &testPlan, &dive, 60, stoptable, cache, 1, 0);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, 1, 0);
|
||||
|
||||
#if DEBUG
|
||||
free(dive.notes);
|
||||
|
@ -534,7 +534,7 @@ void TestPlan::testVpmbMetric45m30minTx()
|
|||
struct diveplan testPlan = {};
|
||||
setupPlanVpmb45m30mTx(&testPlan);
|
||||
|
||||
plan(&test_deco_state, &testPlan, &dive, 60, stoptable, cache, 1, 0);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, 1, 0);
|
||||
|
||||
#if DEBUG
|
||||
free(dive.notes);
|
||||
|
@ -564,7 +564,7 @@ void TestPlan::testVpmbMetric60m10minTx()
|
|||
struct diveplan testPlan = {};
|
||||
setupPlanVpmb60m10mTx(&testPlan);
|
||||
|
||||
plan(&test_deco_state, &testPlan, &dive, 60, stoptable, cache, 1, 0);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, 1, 0);
|
||||
|
||||
#if DEBUG
|
||||
free(dive.notes);
|
||||
|
@ -594,7 +594,7 @@ void TestPlan::testVpmbMetric60m30minAir()
|
|||
struct diveplan testPlan = {};
|
||||
setupPlanVpmb60m30minAir(&testPlan);
|
||||
|
||||
plan(&test_deco_state, &testPlan, &dive, 60, stoptable, cache, 1, 0);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, 1, 0);
|
||||
|
||||
#if DEBUG
|
||||
free(dive.notes);
|
||||
|
@ -624,7 +624,7 @@ void TestPlan::testVpmbMetric60m30minEan50()
|
|||
struct diveplan testPlan = {};
|
||||
setupPlanVpmb60m30minEan50(&testPlan);
|
||||
|
||||
plan(&test_deco_state, &testPlan, &dive, 60, stoptable, cache, 1, 0);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, 1, 0);
|
||||
|
||||
#if DEBUG
|
||||
free(dive.notes);
|
||||
|
@ -660,7 +660,7 @@ void TestPlan::testVpmbMetric60m30minTx()
|
|||
struct diveplan testPlan = {};
|
||||
setupPlanVpmb60m30minTx(&testPlan);
|
||||
|
||||
plan(&test_deco_state, &testPlan, &dive, 60, stoptable, cache, 1, 0);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, 1, 0);
|
||||
|
||||
#if DEBUG
|
||||
free(dive.notes);
|
||||
|
@ -696,7 +696,7 @@ void TestPlan::testVpmbMetric100m60min()
|
|||
struct diveplan testPlan = {};
|
||||
setupPlanVpmb100m60min(&testPlan);
|
||||
|
||||
plan(&test_deco_state, &testPlan, &dive, 60, stoptable, cache, 1, 0);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, 1, 0);
|
||||
|
||||
#if DEBUG
|
||||
free(dive.notes);
|
||||
|
@ -739,7 +739,7 @@ void TestPlan::testMultipleGases()
|
|||
|
||||
setupPlanSeveralGases(&testPlan);
|
||||
|
||||
plan(&test_deco_state, &testPlan, &dive, 60, stoptable, cache, 1, 0);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, 1, 0);
|
||||
|
||||
#if DEBUG
|
||||
free(dive.notes);
|
||||
|
@ -764,7 +764,7 @@ void TestPlan::testVpmbMetricMultiLevelAir()
|
|||
struct diveplan testPlan = {};
|
||||
setupPlanVpmbMultiLevelAir(&testPlan);
|
||||
|
||||
plan(&test_deco_state, &testPlan, &dive, 60, stoptable, cache, 1, 0);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, 1, 0);
|
||||
|
||||
#if DEBUG
|
||||
free(dive.notes);
|
||||
|
@ -794,7 +794,7 @@ void TestPlan::testVpmbMetric100m10min()
|
|||
struct diveplan testPlan = {};
|
||||
setupPlanVpmb100m10min(&testPlan);
|
||||
|
||||
plan(&test_deco_state, &testPlan, &dive, 60, stoptable, cache, 1, 0);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, 1, 0);
|
||||
|
||||
#if DEBUG
|
||||
free(dive.notes);
|
||||
|
@ -840,7 +840,7 @@ void TestPlan::testVpmbMetricRepeat()
|
|||
struct diveplan testPlan = {};
|
||||
setupPlanVpmb30m20min(&testPlan);
|
||||
|
||||
plan(&test_deco_state, &testPlan, &dive, 60, stoptable, cache, 1, 0);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, 1, 0);
|
||||
|
||||
#if DEBUG
|
||||
free(dive.notes);
|
||||
|
@ -861,7 +861,7 @@ void TestPlan::testVpmbMetricRepeat()
|
|||
int firstDiveRunTimeSeconds = dive.dc.duration.seconds;
|
||||
|
||||
setupPlanVpmb100mTo70m30min(&testPlan);
|
||||
plan(&test_deco_state, &testPlan, &dive, 60, stoptable, cache, 1, 0);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, 1, 0);
|
||||
|
||||
#if DEBUG
|
||||
free(dive.notes);
|
||||
|
@ -898,7 +898,7 @@ void TestPlan::testVpmbMetricRepeat()
|
|||
QVERIFY(compareDecoTime(dive.dc.duration.seconds, 127u * 60u + 20u, 127u * 60u + 20u));
|
||||
|
||||
setupPlanVpmb30m20min(&testPlan);
|
||||
plan(&test_deco_state, &testPlan, &dive, 60, stoptable, cache, 1, 0);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, 1, 0);
|
||||
|
||||
#if DEBUG
|
||||
free(dive.notes);
|
||||
|
@ -937,7 +937,7 @@ void TestPlan::testCcrBailoutGasSelection()
|
|||
struct diveplan testPlan = {};
|
||||
setupPlanCcr(&testPlan);
|
||||
|
||||
plan(&test_deco_state, &testPlan, &dive, 60, stoptable, cache, true, false);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, true, false);
|
||||
|
||||
#if DEBUG
|
||||
free(dive.notes);
|
||||
|
|
Loading…
Add table
Reference in a new issue