diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/configuredivecomputer.cpp | 4 | ||||
-rw-r--r-- | core/configuredivecomputerthreads.cpp | 4 | ||||
-rw-r--r-- | core/datatrak.c | 2 | ||||
-rw-r--r-- | core/deco.c | 2 | ||||
-rw-r--r-- | core/dive.c | 24 | ||||
-rw-r--r-- | core/dive.h | 4 | ||||
-rw-r--r-- | core/libdivecomputer.c | 2 | ||||
-rw-r--r-- | core/liquivision.c | 2 | ||||
-rw-r--r-- | core/planner.c | 131 | ||||
-rw-r--r-- | core/pref.h | 2 | ||||
-rw-r--r-- | core/profile.c | 6 | ||||
-rw-r--r-- | core/save-html.c | 2 | ||||
-rw-r--r-- | core/subsurface-qt/SettingsObjectWrapper.cpp | 38 | ||||
-rw-r--r-- | core/subsurface-qt/SettingsObjectWrapper.h | 8 | ||||
-rw-r--r-- | core/subsurfacestartup.c | 2 | ||||
-rw-r--r-- | core/uemis-downloader.c | 40 | ||||
-rw-r--r-- | core/units.h | 2 |
17 files changed, 192 insertions, 83 deletions
diff --git a/core/configuredivecomputer.cpp b/core/configuredivecomputer.cpp index d8aefaecc..1e1f9faaf 100644 --- a/core/configuredivecomputer.cpp +++ b/core/configuredivecomputer.cpp @@ -131,8 +131,8 @@ bool ConfigureDiveComputer::saveXMLBackup(QString fileName, DeviceDetails *detai writer.writeTextElement("Dil3", dil3); writer.writeTextElement("Dil4", dil4); writer.writeTextElement("Dil5", dil5); - // - //Add set point values + + //Add setpoint values QString sp1 = QString("%1,%2") .arg(QString::number(details->sp1.sp), QString::number(details->sp1.depth)); diff --git a/core/configuredivecomputerthreads.cpp b/core/configuredivecomputerthreads.cpp index 33edbdce0..9dd83a6ea 100644 --- a/core/configuredivecomputerthreads.cpp +++ b/core/configuredivecomputerthreads.cpp @@ -501,7 +501,7 @@ static dc_status_t read_ostc3_settings(dc_device_t *device, DeviceDetails *m_dev m_deviceDetails->dil4 = dil4; m_deviceDetails->dil5 = dil5; - //Read set point Values + //Read setpoint Values setpoint sp1; setpoint sp2; setpoint sp3; @@ -700,7 +700,7 @@ static dc_status_t write_ostc3_settings(dc_device_t *device, DeviceDetails *m_de return rc; EMIT_PROGRESS(); - //write set point values + //write setpoint values unsigned char sp1Data[2] = { m_deviceDetails->sp1.sp, m_deviceDetails->sp1.depth diff --git a/core/datatrak.c b/core/datatrak.c index d46167cc8..6c9b00764 100644 --- a/core/datatrak.c +++ b/core/datatrak.c @@ -150,7 +150,7 @@ static dtrakheader read_file_header(FILE *archivo) return fileheader; } if (two_bytes_to_int(lector[0], lector[1]) != 0xA100) { - report_error(translate("gettextFromC", "Error: the file does not appear to be a DATATRAK divelog")); + report_error(translate("gettextFromC", "Error: the file does not appear to be a DATATRAK dive log")); free(lector); return fileheader; } diff --git a/core/deco.c b/core/deco.c index 66ed219ee..88585c98d 100644 --- a/core/deco.c +++ b/core/deco.c @@ -43,7 +43,7 @@ struct buehlmann_config { double gf_high; //! gradient factor high (at surface). double gf_low; //! gradient factor low (at bottom/start of deco calculation). double gf_low_position_min; //! gf_low_position below surface_min_shallow. - bool gf_low_at_maxdepth; //! if true, gf_low applies at max depth instead of at deepest ceiling. + bool gf_low_at_maxdepth; //! if true, gf_low applies at max. depth instead of at deepest ceiling. }; struct buehlmann_config buehlmann_config = { diff --git a/core/dive.c b/core/dive.c index 6c438b1a3..3fc348520 100644 --- a/core/dive.c +++ b/core/dive.c @@ -248,11 +248,15 @@ int units_to_sac(double volume) return lrint(volume * 1000); } -unsigned int units_to_depth(double depth) +depth_t units_to_depth(double depth) { - if (get_units()->length == METERS) - return lrint(depth * 1000); - return feet_to_mm(depth); + depth_t internaldepth; + if (get_units()->length == METERS) { + internaldepth.mm = lrint(depth * 1000); + } else { + internaldepth.mm = feet_to_mm(depth); + } + return internaldepth; } double get_depth_units(int mm, int *frac, const char **units) @@ -659,7 +663,7 @@ void finish_sample(struct divecomputer *dc) * new ones. * * Why? Because a dive computer may well actually track the - * max depth and mean depth at finer granularity than the + * max. depth and mean depth at finer granularity than the * samples it stores. So it's possible that the max and mean * have been reported more correctly originally. * @@ -2436,7 +2440,7 @@ static int find_sample_offset(struct divecomputer *a, struct divecomputer *b) * difference? * * So for example, we'd expect different dive computers to give different - * max depth readings. You might have them on different arms, and they + * max. depth readings. You might have them on different arms, and they * have different pressure sensors and possibly different ideas about * water salinity etc. * @@ -3584,11 +3588,11 @@ void average_max_depth(struct diveplan *dive, int *avg_depth, int *max_depth) while (dp) { if (dp->time) { /* Ignore gas indication samples */ - integral += (dp->depth + last_depth) * (dp->time - last_time) / 2; + integral += (dp->depth.mm + last_depth) * (dp->time - last_time) / 2; last_time = dp->time; - last_depth = dp->depth; - if (dp->depth > *max_depth) - *max_depth = dp->depth; + last_depth = dp->depth.mm; + if (dp->depth.mm > *max_depth) + *max_depth = dp->depth.mm; } dp = dp->next; } diff --git a/core/dive.h b/core/dive.h index 981cdc0b9..b8096d50c 100644 --- a/core/dive.h +++ b/core/dive.h @@ -131,7 +131,7 @@ extern double get_temp_units(unsigned int mk, const char **units); extern double get_weight_units(unsigned int grams, int *frac, const char **units); extern double get_vertical_speed_units(unsigned int mms, int *frac, const char **units); -extern unsigned int units_to_depth(double depth); +extern depth_t units_to_depth(double depth); extern int units_to_sac(double volume); /* Volume in mliter of a cylinder at pressure 'p' */ @@ -845,7 +845,7 @@ extern double tissue_tolerance_calc(const struct dive *dive, double pressure); /* this should be converted to use our types */ struct divedatapoint { int time; - int depth; + depth_t depth; int cylinderid; int setpoint; bool entered; diff --git a/core/libdivecomputer.c b/core/libdivecomputer.c index 799846fc2..8ffb49d43 100644 --- a/core/libdivecomputer.c +++ b/core/libdivecomputer.c @@ -709,7 +709,7 @@ static dc_status_t libdc_header_parser(dc_parser_t *parser, struct device_data_t dc_divemode_t divemode; rc = dc_parser_get_field(parser, DC_FIELD_DIVEMODE, 0, &divemode); if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { - dev_info(devdata, translate("gettextFromC", "Error obtaining divemode")); + dev_info(devdata, translate("gettextFromC", "Error obtaining dive mode")); return rc; } if (rc == DC_STATUS_SUCCESS) diff --git a/core/liquivision.c b/core/liquivision.c index e2e9ff75e..c42086403 100644 --- a/core/liquivision.c +++ b/core/liquivision.c @@ -54,7 +54,7 @@ static int handle_event_ver3(int code, const unsigned char *ps, unsigned int ps_ break; case 0x0008: // 4 byte time - // 2 byte gas set point 2 + // 2 byte gas setpoint 2 skip = 6; break; case 0x000f: diff --git a/core/planner.c b/core/planner.c index 771ea6acc..eb7352739 100644 --- a/core/planner.c +++ b/core/planner.c @@ -262,7 +262,7 @@ static void create_dive_from_plan(struct diveplan *diveplan, bool track_gas) cylinder_t *cyl; int oldpo2 = 0; int lasttime = 0; - int lastdepth = 0; + depth_t lastdepth = {.mm = 0}; int lastcylid = 0; enum dive_comp_type type = displayed_dive.dc.divemode; @@ -303,7 +303,7 @@ static void create_dive_from_plan(struct diveplan *diveplan, bool track_gas) if (dp->setpoint) type = CCR; int time = dp->time; - int depth = dp->depth; + depth_t depth = dp->depth; if (time == 0) { /* special entries that just inform the algorithm about @@ -329,7 +329,7 @@ static void create_dive_from_plan(struct diveplan *diveplan, bool track_gas) sample = prepare_sample(dc); sample[-1].setpoint.mbar = po2; sample->time.seconds = lasttime + 1; - sample->depth.mm = lastdepth; + sample->depth = lastdepth; sample->manually_entered = dp->entered; sample->sac.mliter = dp->entered ? prefs.bottomsac : prefs.decosac; if (track_gas && cyl->type.workingpressure.mbar) @@ -344,11 +344,11 @@ static void create_dive_from_plan(struct diveplan *diveplan, bool track_gas) sample[-1].setpoint.mbar = po2; sample->setpoint.mbar = po2; sample->time.seconds = lasttime = time; - sample->depth.mm = lastdepth = depth; + sample->depth = lastdepth = depth; sample->manually_entered = dp->entered; sample->sac.mliter = dp->entered ? prefs.bottomsac : prefs.decosac; if (track_gas && !sample[-1].setpoint.mbar) { /* Don't track gas usage for CCR legs of dive */ - update_cylinder_pressure(&displayed_dive, sample[-1].depth.mm, depth, time - sample[-1].time.seconds, + update_cylinder_pressure(&displayed_dive, sample[-1].depth.mm, depth.mm, time - sample[-1].time.seconds, dp->entered ? diveplan->bottomsac : diveplan->decosac, cyl, !dp->entered); if (cyl->type.workingpressure.mbar) sample->cylinderpressure.mbar = cyl->end.mbar; @@ -382,7 +382,7 @@ struct divedatapoint *create_dp(int time_incr, int depth, int cylinderid, int po dp = malloc(sizeof(struct divedatapoint)); dp->time = time_incr; - dp->depth = depth; + dp->depth.mm = depth; dp->cylinderid = cylinderid; dp->setpoint = po2; dp->entered = false; @@ -429,24 +429,24 @@ static struct gaschanges *analyze_gaslist(struct diveplan *diveplan, int *gascha bool total_time_zero = true; while (dp) { if (dp->time == 0 && total_time_zero) { - if (dp->depth <= depth) { + if (dp->depth.mm <= depth) { int i = 0; nr++; gaschanges = realloc(gaschanges, nr * sizeof(struct gaschanges)); while (i < nr - 1) { - if (dp->depth < gaschanges[i].depth) { + if (dp->depth.mm < gaschanges[i].depth) { memmove(gaschanges + i + 1, gaschanges + i, (nr - i - 1) * sizeof(struct gaschanges)); break; } i++; } - gaschanges[i].depth = dp->depth; + gaschanges[i].depth = dp->depth.mm; 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; + if (dp->depth.mm < best_depth) { + best_depth = dp->depth.mm; *asc_cylinder = dp->cylinderid; } } @@ -546,6 +546,7 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool bool gaschange_before; bool lastentered = true; struct divedatapoint *nextdp = NULL; + struct divedatapoint *lastbottomdp = NULL; plan_verbatim = prefs.verbatim_plan; plan_display_runtime = prefs.display_runtime; @@ -614,13 +615,13 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool const char *depth_unit; double depthvalue; int decimals; - bool isascent = (dp->depth < lastdepth); + bool isascent = (dp->depth.mm < lastdepth); nextdp = dp->next; if (dp->time == 0) continue; gasmix = dive->cylinder[dp->cylinderid].gasmix; - depthvalue = get_depth_units(dp->depth, &decimals, &depth_unit); + depthvalue = get_depth_units(dp->depth.mm, &decimals, &depth_unit); /* analyze the dive points ahead */ while (nextdp && nextdp->time == 0) nextdp = nextdp->next; @@ -631,14 +632,25 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool /* do we want to skip this leg as it is devoid of anything useful? */ if (!dp->entered && nextdp && - dp->depth != lastdepth && - nextdp->depth != dp->depth && + dp->depth.mm != lastdepth && + nextdp->depth.mm != dp->depth.mm && !gaschange_before && !gaschange_after) continue; - if (dp->time - lasttime < 10 && !(gaschange_after && dp->next && dp->depth != dp->next->depth)) + if (dp->time - lasttime < 10 && !(gaschange_after && dp->next && dp->depth.mm != dp->next->depth.mm)) continue; + /* Store pointer to last entered datapoint for minimum gas calculation */ + /* Do this only if depth is larger than last/2nd last deco stop at ~6m */ + int secondlastdecostop = 0; + if (prefs.units.length == METERS ) { + secondlastdecostop = decostoplevels_metric[2]; + } else { + secondlastdecostop = decostoplevels_imperial[2]; + } + if (dp->entered && !nextdp->entered && dp->depth.mm > secondlastdecostop) + lastbottomdp = dp; + len = strlen(buffer); if (plan_verbatim) { /* When displaying a verbatim plan, we output a waypoint for every gas change. @@ -647,8 +659,8 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool * to determine whether or not to print a segment much simpler than with the * non-verbatim plan. */ - if (dp->depth != lastprintdepth) { - if (plan_display_transitions || dp->entered || !dp->next || (gaschange_after && dp->next && dp->depth != nextdp->depth)) { + if (dp->depth.mm != lastprintdepth) { + if (plan_display_transitions || dp->entered || !dp->next || (gaschange_after && dp->next && dp->depth.mm != nextdp->depth.mm)) { if (dp->setpoint) snprintf(temp, sz_temp, translate("gettextFromC", "Transition to %.*f %s in %d:%02d min - runtime %d:%02u on %s (SP = %.1fbar)"), decimals, depthvalue, depth_unit, @@ -666,10 +678,10 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool len += snprintf(buffer + len, sz_buffer - len, "%s<br>", temp); } - newdepth = dp->depth; + newdepth = dp->depth.mm; lasttime = dp->time; } else { - if ((nextdp && dp->depth != nextdp->depth) || gaschange_after) { + if ((nextdp && dp->depth.mm != nextdp->depth.mm) || gaschange_after) { if (dp->setpoint) snprintf(temp, sz_temp, translate("gettextFromC", "Stay at %.*f %s for %d:%02d min - runtime %d:%02u on %s (SP = %.1fbar)"), decimals, depthvalue, depth_unit, @@ -685,7 +697,7 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool gasname(&gasmix)); len += snprintf(buffer + len, sz_buffer - len, "%s<br>", temp); - newdepth = dp->depth; + newdepth = dp->depth.mm; lasttime = dp->time; } } @@ -707,14 +719,14 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool * time has been allowed for a gas switch. */ if (plan_display_transitions || dp->entered || !dp->next || - (nextdp && dp->depth != nextdp->depth) || - (!isascent && gaschange_before && nextdp && dp->depth != nextdp->depth) || + (nextdp && dp->depth.mm != nextdp->depth.mm) || + (!isascent && gaschange_before && nextdp && dp->depth.mm != nextdp->depth.mm) || (gaschange_after && lastentered) || (gaschange_after && !isascent) || - (isascent && gaschange_after && nextdp && dp->depth != nextdp->depth )) { + (isascent && gaschange_after && nextdp && dp->depth.mm != nextdp->depth.mm )) { // Print a symbol to indicate whether segment is an ascent, descent, constant depth (user entered) or deco stop if (isascent) segmentsymbol = "➚"; // up-right arrow for ascent - else if (dp->depth > lastdepth) + else if (dp->depth.mm > lastdepth) segmentsymbol = "➘"; // down-right arrow for descent else if (dp->entered) segmentsymbol = "➙"; // right arrow for entered entered segment at constant depth @@ -737,7 +749,7 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool /* Normally a gas change is displayed on the stopping segment, so only display a gas change at the end of * an ascent segment if it is not followed by a stop */ - if ((isascent || dp->entered) && gaschange_after && dp->next && nextdp && (dp->depth != nextdp->depth || nextdp->entered)) { + if ((isascent || dp->entered) && gaschange_after && dp->next && nextdp && (dp->depth.mm != nextdp->depth.mm || nextdp->entered)) { if (dp->setpoint) { snprintf(temp, sz_temp, translate("gettextFromC", "(SP = %.1fbar)"), (double) nextdp->setpoint / 1000.0); len += snprintf(buffer + len, sz_buffer - len, "<td style='padding-left: 10px; color: red; float: left;'><b>%s %s</b></td>", gasname(&newgasmix), @@ -765,7 +777,7 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool len += snprintf(buffer + len, sz_buffer - len, "<td> </td>"); } len += snprintf(buffer + len, sz_buffer - len, "</tr>"); - newdepth = dp->depth; + newdepth = dp->depth.mm; lasttime = dp->time; } } @@ -785,7 +797,7 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool } } lastprintdepth = newdepth; - lastdepth = dp->depth; + lastdepth = dp->depth.mm; lastsetpoint = dp->setpoint; lastentered = dp->entered; } while ((dp = nextdp) != NULL); @@ -847,10 +859,13 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool snprintf(temp, sz_temp, "%s %.*f|%.*f%s/min):", translate("gettextFromC", "Gas consumption (based on SAC"), sacdecimals, bottomsacvalue, sacdecimals, decosacvalue, sacunit); len += snprintf(buffer + len, sz_buffer - len, "<div>%s<br>", temp); + + /* Print gas consumption: This loop covers all cylinders */ for (int gasidx = 0; gasidx < MAX_CYLINDERS; gasidx++) { - double volume, pressure, deco_volume, deco_pressure; - const char *unit, *pressure_unit; + double volume, pressure, deco_volume, deco_pressure, mingas_volume, mingas_pressure, mingas_depth; + const char *unit, *pressure_unit, *depth_unit; char warning[1000] = ""; + char mingas[1000] = ""; cylinder_t *cyl = &dive->cylinder[gasidx]; if (cylinder_none(cyl)) break; @@ -867,35 +882,73 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool * This only works if we have working pressure for the cylinder * 10bar is a made up number - but it seemed silly to pretend you could breathe cylinder down to 0 */ if (cyl->end.mbar < 10000) - snprintf(warning, sizeof(warning), " — <span style='color: red;'>%s </span> %s", + snprintf(warning, sizeof(warning), "<br> — <span style='color: red;'>%s </span> %s", translate("gettextFromC", "Warning:"), translate("gettextFromC", "this is more gas than available in the specified cylinder!")); else if ((float) cyl->end.mbar * cyl->type.size.mliter / 1000.0 / gas_compressibility_factor(&cyl->gasmix, cyl->end.mbar / 1000.0) < (float) cyl->deco_gas_used.mliter) - snprintf(warning, sizeof(warning), " — <span style='color: red;'>%s </span> %s", + snprintf(warning, sizeof(warning), "<br> — <span style='color: red;'>%s </span> %s", translate("gettextFromC", "Warning:"), translate("gettextFromC", "not enough reserve for gas sharing on ascent!")); - snprintf(temp, sz_temp, translate("gettextFromC", "%.0f%s/%.0f%s of %s (%.0f%s/%.0f%s in planned ascent)"), volume, unit, pressure, pressure_unit, gasname(&cyl->gasmix), deco_volume, unit, deco_pressure, pressure_unit); + /* Do and print minimum gas calculation for last bottom gas, but only for OC mode, */ + /* not for recreational mode and if no other warning was set before. */ + else + if (lastbottomdp && gasidx == lastbottomdp->cylinderid + && dive->dc.divemode == OC && decoMode() != RECREATIONAL) { + /* Calculate minimum gas volume. */ + volume_t mingasv; + mingasv.mliter = prefs.problemsolvingtime * prefs.bottomsac * prefs.sacfactor / 100.0 + * depth_to_bar(lastbottomdp->depth.mm, dive) + + cyl->deco_gas_used.mliter * prefs.sacfactor / 100.0; + /* Calculate minimum gas pressure for cyclinder. */ + pressure_t mingasp; + mingasp.mbar = isothermal_pressure(&cyl->gasmix, 1.0, + mingasv.mliter, cyl->type.size.mliter) * 1000; + /* Translate all results into correct units */ + mingas_volume = get_volume_units(mingasv.mliter, NULL, &unit); + mingas_pressure = get_pressure_units(mingasp.mbar, &pressure_unit); + mingas_depth = get_depth_units(lastbottomdp->depth.mm, NULL, &depth_unit); + /* Print it to results */ + if (cyl->start.mbar > mingasp.mbar) snprintf(mingas, sizeof(mingas), + translate("gettextFromC", "<br> — <span style='color: green;'>Minimum gas</span> (based on %.1fxSAC/+%dmin@%.0f%s): %.0f%s/%.0f%s"), + prefs.sacfactor / 100.0, prefs.problemsolvingtime, + mingas_depth, depth_unit, + mingas_volume, unit, + mingas_pressure, pressure_unit); + else snprintf(warning, sizeof(warning), "<br> — <span style='color: red;'>%s </span> %s", + translate("gettextFromC", "Warning:"), + translate("gettextFromC", "required minimum gas for ascent already exceeding start pressure of cylinder!")); + } + /* Print the gas consumption for every cylinder here to temp buffer. */ + snprintf(temp, sz_temp, translate("gettextFromC", "%.0f%s/%.0f%s of <span style='color: red;'><b>%s</b></span> (%.0f%s/%.0f%s in planned ascent)"), volume, unit, pressure, pressure_unit, gasname(&cyl->gasmix), deco_volume, unit, deco_pressure, pressure_unit); + } else { - snprintf(temp, sz_temp, translate("gettextFromC", "%.0f%s (%.0f%s during planned ascent) of %s"), volume, unit, deco_volume, unit, gasname(&cyl->gasmix)); + snprintf(temp, sz_temp, translate("gettextFromC", "%.0f%s (%.0f%s during planned ascent) of <span style='color: red;'><b>%s</b></span>"), + volume, unit, deco_volume, unit, gasname(&cyl->gasmix)); } - len += snprintf(buffer + len, sz_buffer - len, "%s%s<br>", temp, warning); + /* Gas consumption: Now finally print all strings to output */ + len += snprintf(buffer + len, sz_buffer - len, "%s%s%s<br>", temp, warning, mingas); } + + /* Print warnings for pO2 */ dp = diveplan->dp; + bool o2warning_exist = false; if (dive->dc.divemode != CCR) { while (dp) { if (dp->time != 0) { struct gas_pressures pressures; struct gasmix *gasmix = &dive->cylinder[dp->cylinderid].gasmix; - fill_pressures(&pressures, depth_to_atm(dp->depth, dive), gasmix, 0.0, dive->dc.divemode); + fill_pressures(&pressures, depth_to_atm(dp->depth.mm, dive), gasmix, 0.0, dive->dc.divemode); if (pressures.o2 > (dp->entered ? prefs.bottompo2 : prefs.decopo2) / 1000.0) { const char *depth_unit; int decimals; - double depth_value = get_depth_units(dp->depth, &decimals, &depth_unit); + double depth_value = get_depth_units(dp->depth.mm, &decimals, &depth_unit); len = strlen(buffer); + if (!o2warning_exist) len += snprintf(buffer + len, sz_buffer - len, "<br>"); + o2warning_exist = true; 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(gasmix), decimals, depth_value, depth_unit); @@ -904,8 +957,10 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool } else if (pressures.o2 < 0.16) { const char *depth_unit; int decimals; - double depth_value = get_depth_units(dp->depth, &decimals, &depth_unit); + double depth_value = get_depth_units(dp->depth.mm, &decimals, &depth_unit); len = strlen(buffer); + if (!o2warning_exist) len += snprintf(buffer + len, sz_buffer - len, "<br>"); + o2warning_exist = true; 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(gasmix), decimals, depth_value, depth_unit); diff --git a/core/pref.h b/core/pref.h index 1360fba14..9122800bb 100644 --- a/core/pref.h +++ b/core/pref.h @@ -105,6 +105,8 @@ struct preferences { int ascratestops; int ascratelast6m; int descrate; + int sacfactor; + int problemsolvingtime; int bottompo2; int decopo2; enum deco_mode display_deco_mode; diff --git a/core/profile.c b/core/profile.c index 1a50c7efd..233f67360 100644 --- a/core/profile.c +++ b/core/profile.c @@ -1350,7 +1350,7 @@ static void plot_string(struct plot_info *pi, struct plot_data *entry, struct me put_format(b, translate("gettextFromC", "Safetystop: %umin @ %.0f%s\n"), DIV_UP(entry->stoptime, 60), depthvalue, depth_unit); else - put_format(b, translate("gettextFromC", "Safetystop: unkn time @ %.0f%s\n"), + put_format(b, translate("gettextFromC", "Safetystop: unknown time @ %.0f%s\n"), depthvalue, depth_unit); } else { /* actual deco stop */ @@ -1358,7 +1358,7 @@ static void plot_string(struct plot_info *pi, struct plot_data *entry, struct me put_format(b, translate("gettextFromC", "Deco: %umin @ %.0f%s\n"), DIV_UP(entry->stoptime, 60), depthvalue, depth_unit); else - put_format(b, translate("gettextFromC", "Deco: unkn time @ %.0f%s\n"), + put_format(b, translate("gettextFromC", "Deco: unknown time @ %.0f%s\n"), depthvalue, depth_unit); } } else if (entry->in_deco) { @@ -1573,7 +1573,7 @@ void compare_samples(struct plot_data *e1, struct plot_data *e2, char *buf, int int sac = lrint(volume_used / atm * 60 / delta_time); memcpy(buf2, buf, bufsize); volume_value = get_volume_units(sac, &volume_precision, &volume_unit); - snprintf(buf, bufsize, translate("gettextFromC", "%s SAC:%.*f %s"), buf2, volume_precision, volume_value, volume_unit); + snprintf(buf, bufsize, translate("gettextFromC", "%s SAC: %.*f%s"), buf2, volume_precision, volume_value, volume_unit); } } diff --git a/core/save-html.c b/core/save-html.c index 66472fdfc..0b2d8e79a 100644 --- a/core/save-html.c +++ b/core/save-html.c @@ -528,7 +528,7 @@ void export_translation(const char *file_name) write_attribute(b, "Back_to_List", translate("gettextFromC", "Back to list"), ", "); //dive detailed view - write_attribute(b, "Dive_No", translate("gettextFromC", "Dive No."), ", "); + write_attribute(b, "Dive_No", translate("gettextFromC", "Dive #"), ", "); write_attribute(b, "Dive_profile", translate("gettextFromC", "Dive profile"), ", "); write_attribute(b, "Dive_information", translate("gettextFromC", "Dive information"), ", "); write_attribute(b, "Dive_equipment", translate("gettextFromC", "Dive equipment"), ", "); diff --git a/core/subsurface-qt/SettingsObjectWrapper.cpp b/core/subsurface-qt/SettingsObjectWrapper.cpp index dfb486065..f5d2e0f9a 100644 --- a/core/subsurface-qt/SettingsObjectWrapper.cpp +++ b/core/subsurface-qt/SettingsObjectWrapper.cpp @@ -1240,6 +1240,16 @@ int DivePlannerSettings::descrate() const return prefs.descrate; } +int DivePlannerSettings::sacfactor() const +{ + return prefs.sacfactor; +} + +int DivePlannerSettings::problemsolvingtime() const +{ + return prefs.problemsolvingtime; +} + int DivePlannerSettings::bottompo2() const { return prefs.bottompo2; @@ -1441,6 +1451,30 @@ void DivePlannerSettings::setDescrate(int value) emit descrateChanged(value); } +void DivePlannerSettings::setSacFactor(int value) +{ + if (value == prefs.sacfactor) + return; + + QSettings s; + s.beginGroup(group); + s.setValue("sacfactor", value); + prefs.sacfactor = value; + emit sacFactorChanged(value); +} + +void DivePlannerSettings::setProblemSolvingTime(int value) +{ + if (value == prefs.problemsolvingtime) + return; + + QSettings s; + s.beginGroup(group); + s.setValue("problemsolvingtime", value); + prefs.problemsolvingtime = value; + emit problemSolvingTimeChanged(value); +} + void DivePlannerSettings::setBottompo2(int value) { if (value == prefs.bottompo2) @@ -2279,6 +2313,8 @@ void SettingsObjectWrapper::load() GET_INT("ascratestops", ascratestops); GET_INT("ascratelast6m", ascratelast6m); GET_INT("descrate", descrate); + GET_INT("sacfactor", sacfactor); + GET_INT("problemsolvingtime", problemsolvingtime); GET_INT("bottompo2", bottompo2); GET_INT("decopo2", decopo2); GET_INT("bestmixend", bestmixend.mm); @@ -2331,6 +2367,8 @@ void SettingsObjectWrapper::sync() s.setValue("ascratestops", prefs.ascratestops); s.setValue("ascratelast6m", prefs.ascratelast6m); s.setValue("descrate", prefs.descrate); + s.setValue("sacfactor", prefs.sacfactor); + s.setValue("problemsolvingtime", prefs.problemsolvingtime); s.setValue("bottompo2", prefs.bottompo2); s.setValue("decopo2", prefs.decopo2); s.setValue("bestmixend", prefs.bestmixend.mm); diff --git a/core/subsurface-qt/SettingsObjectWrapper.h b/core/subsurface-qt/SettingsObjectWrapper.h index 7fdd10498..1d35dd5d5 100644 --- a/core/subsurface-qt/SettingsObjectWrapper.h +++ b/core/subsurface-qt/SettingsObjectWrapper.h @@ -402,6 +402,8 @@ class DivePlannerSettings : public QObject { Q_PROPERTY(int ascratestops READ ascratestops WRITE setAscratestops NOTIFY ascratestopsChanged) Q_PROPERTY(int ascratelast6m READ ascratelast6m WRITE setAscratelast6m NOTIFY ascratelast6mChanged) Q_PROPERTY(int descrate READ descrate WRITE setDescrate NOTIFY descrateChanged) + Q_PROPERTY(int sacfactor READ sacfactor WRITE setSacFactor NOTIFY sacFactorChanged) + Q_PROPERTY(int problemsolvingtime READ problemsolvingtime WRITE setProblemSolvingTime NOTIFY problemSolvingTimeChanged) Q_PROPERTY(int bottompo2 READ bottompo2 WRITE setBottompo2 NOTIFY bottompo2Changed) Q_PROPERTY(int decopo2 READ decopo2 WRITE setDecopo2 NOTIFY decopo2Changed) Q_PROPERTY(int bestmixend READ bestmixend WRITE setBestmixend NOTIFY bestmixendChanged) @@ -427,6 +429,8 @@ public: int ascratestops() const; int ascratelast6m() const; int descrate() const; + int sacfactor() const; + int problemsolvingtime() const; int bottompo2() const; int decopo2() const; int bestmixend() const; @@ -451,6 +455,8 @@ public slots: void setAscratestops(int value); void setAscratelast6m(int value); void setDescrate(int value); + void setSacFactor(int value); + void setProblemSolvingTime(int value); void setBottompo2(int value); void setDecopo2(int value); void setBestmixend(int value); @@ -475,6 +481,8 @@ signals: void ascratestopsChanged(int value); void ascratelast6mChanged(int value); void descrateChanged(int value); + void sacFactorChanged(int value); + void problemSolvingTimeChanged(int value); void bottompo2Changed(int value); void decopo2Changed(int value); void bestmixendChanged(int value); diff --git a/core/subsurfacestartup.c b/core/subsurfacestartup.c index 1f9518136..89ecbd2fb 100644 --- a/core/subsurfacestartup.c +++ b/core/subsurfacestartup.c @@ -50,6 +50,8 @@ struct preferences default_prefs = { .ascratestops = 6000 / 60, .ascratelast6m = 1000 / 60, .descrate = 18000 / 60, + .sacfactor = 400, + .problemsolvingtime = 4, .bottompo2 = 1400, .decopo2 = 1600, .bestmixend.mm = 30000, diff --git a/core/uemis-downloader.c b/core/uemis-downloader.c index 237a6863f..6bf2dcabf 100644 --- a/core/uemis-downloader.c +++ b/core/uemis-downloader.c @@ -492,9 +492,9 @@ static bool uemis_get_answer(const char *path, char *request, int n_param_in, answer_in_mbuf = true; str_append_with_delim(sb, ""); if (!strcmp(request, "getDivelogs")) - what = translate("gettextFromC", "divelog #"); + what = translate("gettextFromC", "dive log #"); else if (!strcmp(request, "getDivespot")) - what = translate("gettextFromC", "divespot #"); + what = translate("gettextFromC", "dive spot #"); else if (!strcmp(request, "getDive")) what = translate("gettextFromC", "details for #"); } @@ -773,17 +773,17 @@ static bool uemis_delete_dive(device_data_t *devdata, uint32_t diveid) return false; } -/* This function is called for both divelog and dive information that we get - * from the SDA (what an insane design, btw). The object_id in the divelog +/* This function is called for both dive log and dive information that we get + * from the SDA (what an insane design, btw). The object_id in the dive log * matches the logfilenr in the dive information (which has its own, often * different object_id) - we use this as the diveid. - * We create the dive when parsing the divelog and then later, when we parse + * We create the dive when parsing the dive log and then later, when we parse * the dive information we locate the already created dive via its diveid. * Most things just get parsed and converted into our internal data structures, * but the dive location API is even more crazy. We just get an id that is an * index into yet another data store that we read out later. In order to * correctly populate the location and gps data from that we need to remember - * the addresses of those fields for every dive that references the divespot. */ + * the addresses of those fields for every dive that references the dive spot. */ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, char *inbuf, char **max_divenr, int *for_dive) { char *buf = strdup(inbuf); @@ -805,7 +805,7 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, char * bp = buf + 1; tp = next_token(&bp); if (strcmp(tp, "divelog") == 0) { - /* this is a divelog */ + /* this is a dive log */ is_log = true; tp = next_token(&bp); /* is it a valid entry or nothing ? */ @@ -1129,7 +1129,7 @@ static bool get_matching_dive(int idx, char *newmax, int *uemis_mem_status, stru snprintf(log_file_no_to_find, sizeof(log_file_no_to_find), "logfilenr{int{%d", dive->dc.diveid); #if UEMIS_DEBUG & 2 - fprintf(debugfile, "Looking for dive details to go with divelog id %d\n", dive->dc.diveid); + fprintf(debugfile, "Looking for dive details to go with dive log id %d\n", dive->dc.diveid); #endif while (!found) { if (import_thread_cancelled) @@ -1142,15 +1142,15 @@ static bool get_matching_dive(int idx, char *newmax, int *uemis_mem_status, stru #endif *uemis_mem_status = get_memory(data->download_table, UEMIS_CHECK_SINGLE_DIVE); if (*uemis_mem_status == UEMIS_MEM_OK) { - /* if the memory isn's completely full we can try to read more divelog vs. dive details + /* if the memory isn's completely full we can try to read more dive log vs. dive details * UEMIS_MEM_CRITICAL means not enough space for a full round but the dive details - * and the divespots should fit into the UEMIS memory + * and the dive spots should fit into the UEMIS memory * The match we do here is to map the object_id to the logfilenr, we do this - * by iterating through the last set of loaded divelogs and then find the corresponding + * by iterating through the last set of loaded dive logs and then find the corresponding * dive with the matching logfilenr */ if (mbuf) { if (strstr(mbuf, log_file_no_to_find)) { - /* we found the logfilenr that matches our object_id from the divelog we were looking for + /* we found the logfilenr that matches our object_id from the dive log we were looking for * we mark the search successful even if the dive has been deleted. */ found = true; if (strstr(mbuf, "deleted{bool{true") == NULL) { @@ -1160,7 +1160,7 @@ static bool get_matching_dive(int idx, char *newmax, int *uemis_mem_status, stru * UEMIS unfortunately deletes dives by deleting the dive details and not the logs. */ #if UEMIS_DEBUG & 2 d_time = get_dive_date_c_string(dive->when); - fprintf(debugfile, "Matching divelog id %d from %s with dive details %d\n", dive->dc.diveid, d_time, dive_to_read); + fprintf(debugfile, "Matching dive log id %d from %s with dive details %d\n", dive->dc.diveid, d_time, dive_to_read); #endif int divespot_id = uemis_get_divespot_id_by_diveid(dive->dc.diveid); if (divespot_id >= 0) @@ -1170,7 +1170,7 @@ static bool get_matching_dive(int idx, char *newmax, int *uemis_mem_status, stru /* in this case we found a deleted file, so let's increment */ #if UEMIS_DEBUG & 2 d_time = get_dive_date_c_string(dive->when); - fprintf(debugfile, "TRY matching divelog id %d from %s with dive details %d but details are deleted\n", dive->dc.diveid, d_time, dive_to_read); + fprintf(debugfile, "TRY matching dive log id %d from %s with dive details %d but details are deleted\n", dive->dc.diveid, d_time, dive_to_read); #endif deleted_files++; max_deleted_seen = dive_to_read; @@ -1200,7 +1200,7 @@ static bool get_matching_dive(int idx, char *newmax, int *uemis_mem_status, stru break; dive_to_read++; } else { - /* At this point the memory of the UEMIS is full, let's cleanup all divelog files were + /* At this point the memory of the UEMIS is full, let's cleanup all dive log files were * we could not match the details to. */ do_delete_dives(data->download_table, idx); return false; @@ -1281,7 +1281,7 @@ const char *do_uemis_import(device_data_t *data) realmbuf = strchr(mbuf, '{'); if (success && realmbuf && uemis_mem_status != UEMIS_MEM_FULL) { #if UEMIS_DEBUG & 16 - do_dump_buffer_to_file(realmbuf, "Divelogs"); + do_dump_buffer_to_file(realmbuf, "Dive logs"); #endif /* process the buffer we have assembled */ if (!process_raw_buffer(data, deviceidnr, realmbuf, &newmax, NULL)) { @@ -1307,7 +1307,7 @@ const char *do_uemis_import(device_data_t *data) fprintf(debugfile, "d_u_i after download and parse start %d end %d newmax %s progress %4.2f\n", start, end, newmax, progress_bar_fraction); #endif /* The way this works is that I am reading the current dive from what has been loaded during the getDiveLogs call to the UEMIS. - * As the object_id of the divelog entry and the object_id of the dive details are not necessarily the same, the match needs + * As the object_id of the dive log entry and the object_id of the dive details are not necessarily the same, the match needs * to happen based on the logfilenr. * What the following part does is to optimize the mapping by using * dive_to_read = the dive details entry that need to be read using the object_id @@ -1352,9 +1352,9 @@ const char *do_uemis_import(device_data_t *data) } #endif } else { - /* some of the loading from the UEMIS failed at the divelog level - * if the memory status = full, we can't even load the divespots and/or buddies. - * The loaded block of divelogs is useless and all new loaded divelogs need to + /* some of the loading from the UEMIS failed at the dive log level + * if the memory status = full, we can't even load the dive spots and/or buddies. + * The loaded block of dive logs is useless and all new loaded dive logs need to * be deleted from the download_table. */ if (uemis_mem_status == UEMIS_MEM_FULL) diff --git a/core/units.h b/core/units.h index 30d52fbf8..f2557ed22 100644 --- a/core/units.h +++ b/core/units.h @@ -53,7 +53,7 @@ extern "C" { * Also strive to use units that can not possibly be mistaken for a * valid value in a "normal" system without conversion. If the max * depth of a dive is '20000', you probably didn't convert from mm on - * output, or if the max depth gets reported as "0.2ft" it was either + * output, or if the max. depth gets reported as "0.2ft" it was either * a really boring dive, or there was some missing input conversion, * and a 60-ft dive got recorded as 60mm. * |