diff options
Diffstat (limited to 'core')
71 files changed, 1647 insertions, 1903 deletions
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 9babe1931..310ba6659 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -103,13 +103,16 @@ set(SUBSURFACE_CORE_LIB_SRCS # classes to manage struct preferences for QWidget and QML settings/qPref.cpp - settings/qPrefAnimations.cpp settings/qPrefCloudStorage.cpp settings/qPrefDisplay.cpp settings/qPrefDiveComputer.cpp settings/qPrefDivePlanner.cpp settings/qPrefFacebook.cpp + settings/qPrefGeneral.cpp + settings/qPrefGeocoding.cpp + settings/qPrefLanguage.cpp settings/qPrefLocationService.cpp + settings/qPrefPartialPressureGas.cpp settings/qPrefPrivate.cpp settings/qPrefProxy.cpp settings/qPrefTechnicalDetails.cpp @@ -119,7 +122,6 @@ set(SUBSURFACE_CORE_LIB_SRCS #Subsurface Qt have the Subsurface structs QObjectified for easy access via QML. subsurface-qt/DiveObjectHelper.cpp subsurface-qt/CylinderObjectHelper.cpp - subsurface-qt/SettingsObjectWrapper.cpp ${SERIAL_FTDI} ${PLATFORM_SRC} diff --git a/core/datatrak.h b/core/datatrak.h index 7aea1741f..05534fcee 100644 --- a/core/datatrak.h +++ b/core/datatrak.h @@ -41,8 +41,6 @@ static const struct models_table_t g_models[] = { {0xEE, 0x44, "Uwatec Unknown model", DC_FAMILY_UWATEC_ALADIN}, }; -extern struct sample *add_sample(struct sample *sample, int time, struct divecomputer *dc); - #define JUMP(_ptr, _n) if ((long) (_ptr += _n) > maxbuf) goto bail #define CHECK(_ptr, _n) if ((long) _ptr + _n > maxbuf) goto bail #define read_bytes(_n) \ diff --git a/core/deco.c b/core/deco.c index e8bafd426..f072a2a17 100644 --- a/core/deco.c +++ b/core/deco.c @@ -479,7 +479,7 @@ void calc_crushing_pressure(struct deco_state *ds, double pressure) } /* add period_in_seconds at the given pressure and gas to the deco calculation */ -void add_segment(struct deco_state *ds, double pressure, const struct gasmix *gasmix, int period_in_seconds, int ccpo2, enum divemode_t divemode, int sac) +void add_segment(struct deco_state *ds, double pressure, struct gasmix gasmix, int period_in_seconds, int ccpo2, enum divemode_t divemode, int sac) { UNUSED(sac); int ci; @@ -581,7 +581,7 @@ void restore_deco_state(struct deco_state *data, struct deco_state *target, bool } -int deco_allowed_depth(double tissues_tolerance, double surface_pressure, struct dive *dive, bool smooth) +int deco_allowed_depth(double tissues_tolerance, double surface_pressure, const struct dive *dive, bool smooth) { int depth; double pressure_delta; diff --git a/core/deco.h b/core/deco.h index 075e7758c..717aa94cf 100644 --- a/core/deco.h +++ b/core/deco.h @@ -8,7 +8,7 @@ extern "C" { extern double buehlmann_N2_t_halflife[]; -extern int deco_allowed_depth(double tissues_tolerance, double surface_pressure, struct dive *dive, bool smooth); +extern int deco_allowed_depth(double tissues_tolerance, double surface_pressure, const struct dive *dive, bool smooth); double get_gf(struct deco_state *ds, double ambpressure_bar, const struct dive *dive); diff --git a/core/dive.c b/core/dive.c index 482ba585b..044c969ee 100644 --- a/core/dive.c +++ b/core/dive.c @@ -99,13 +99,13 @@ void add_sample_pressure(struct sample *sample, int sensor, int mbar) * This function returns a negative number for "no legacy mode", * or a non-negative number that indicates the o2 sensor index. */ -int legacy_format_o2pressures(struct dive *dive, struct divecomputer *dc) +int legacy_format_o2pressures(const struct dive *dive, const struct divecomputer *dc) { int i, o2sensor; o2sensor = (dc->divemode == CCR) ? get_cylinder_idx_by_use(dive, OXYGEN) : -1; for (i = 0; i < dc->samples; i++) { - struct sample *s = dc->sample + i; + const struct sample *s = dc->sample + i; int seen_pressure = 0, idx; for (idx = 0; idx < MAX_SENSORS; idx++) { @@ -130,7 +130,7 @@ int legacy_format_o2pressures(struct dive *dive, struct divecomputer *dc) return o2sensor < 0 ? 256 : o2sensor; } -int event_is_gaschange(struct event *ev) +int event_is_gaschange(const struct event *ev) { return ev->type == SAMPLE_EVENT_GASCHANGE || ev->type == SAMPLE_EVENT_GASCHANGE2; @@ -184,7 +184,7 @@ struct event *add_event(struct divecomputer *dc, unsigned int time, int type, in return ev; } -static int same_event(struct event *a, struct event *b) +static int same_event(const struct event *a, const struct event *b) { if (a->time.seconds != b->time.seconds) return 0; @@ -255,9 +255,9 @@ void add_extra_data(struct divecomputer *dc, const char *key, const char *value) * saving the dive mode for each event. When the events occur AFTER 'time' seconds, the last stored divemode * is returned. This function is self-tracking, relying on setting the event pointer 'evp' so that, in each iteration * that calls this function, the search does not have to begin at the first event of the dive */ -enum divemode_t get_current_divemode(struct divecomputer *dc, int time, struct event **evp, enum divemode_t *divemode) +enum divemode_t get_current_divemode(const struct divecomputer *dc, int time, const struct event **evp, enum divemode_t *divemode) { - struct event *ev = *evp; + const struct event *ev = *evp; if (*divemode == UNDEF_COMP_TYPE) { *divemode = dc->divemode; ev = dc ? get_next_event(dc->events, "modechange") : NULL; @@ -270,17 +270,16 @@ enum divemode_t get_current_divemode(struct divecomputer *dc, int time, struct e return *divemode; } -/* this returns a pointer to static variable - so use it right away after calling */ -struct gasmix *get_gasmix_from_event(struct dive *dive, struct event *ev) +struct gasmix get_gasmix_from_event(const struct dive *dive, const struct event *ev) { - static struct gasmix dummy; + struct gasmix dummy = { 0 }; if (ev && event_is_gaschange(ev)) { int index = ev->gas.index; if (index >= 0 && index < MAX_CYLINDERS) - return &dive->cylinder[index].gasmix; - return &ev->gas.mix; + return dive->cylinder[index].gasmix; + return ev->gas.mix; } - return &dummy; + return dummy; } int get_pressure_units(int mb, const char **units) @@ -481,7 +480,7 @@ static void free_pic(struct picture *picture); /* this is very different from the copy_divecomputer later in this file; * this function actually makes full copies of the content */ -static void copy_dc(struct divecomputer *sdc, struct divecomputer *ddc) +static void copy_dc(const struct divecomputer *sdc, struct divecomputer *ddc) { *ddc = *sdc; ddc->model = copy_string(sdc->model); @@ -557,7 +556,7 @@ void clear_dive(struct dive *d) /* make a true copy that is independent of the source dive; * all data structures are duplicated, so the copy can be modified without * any impact on the source */ -void copy_dive(struct dive *s, struct dive *d) +void copy_dive(const struct dive *s, struct dive *d) { clear_dive(d); /* simply copy things over, but then make actual copies of the @@ -598,7 +597,7 @@ struct dive *clone_dive(struct dive *s) d->_component = copy_string(s->_component) // copy elements, depending on bits in what that are set -void selective_copy_dive(struct dive *s, struct dive *d, struct dive_components what, bool clear) +void selective_copy_dive(const struct dive *s, struct dive *d, struct dive_components what, bool clear) { if (clear) clear_dive(d); @@ -642,9 +641,10 @@ struct event *clone_event(const struct event *src_ev) } /* copies all events in this dive computer */ -void copy_events(struct divecomputer *s, struct divecomputer *d) +void copy_events(const struct divecomputer *s, struct divecomputer *d) { - struct event *ev, **pev; + const struct event *ev; + struct event **pev; if (!s || !d) return; ev = s->events; @@ -658,24 +658,24 @@ void copy_events(struct divecomputer *s, struct divecomputer *d) *pev = NULL; } -int nr_cylinders(struct dive *dive) +int nr_cylinders(const struct dive *dive) { int nr; for (nr = MAX_CYLINDERS; nr; --nr) { - cylinder_t *cylinder = dive->cylinder + nr - 1; + const cylinder_t *cylinder = dive->cylinder + nr - 1; if (!cylinder_nodata(cylinder)) break; } return nr; } -int nr_weightsystems(struct dive *dive) +int nr_weightsystems(const struct dive *dive) { int nr; for (nr = MAX_WEIGHTSYSTEMS; nr; --nr) { - weightsystem_t *ws = dive->weightsystem + nr - 1; + const weightsystem_t *ws = dive->weightsystem + nr - 1; if (!weightsystem_none(ws)) break; } @@ -683,7 +683,7 @@ int nr_weightsystems(struct dive *dive) } /* copy the equipment data part of the cylinders */ -void copy_cylinders(struct dive *s, struct dive *d, bool used_only) +void copy_cylinders(const struct dive *s, struct dive *d, bool used_only) { int i,j; cylinder_t t[MAX_CYLINDERS]; @@ -729,7 +729,7 @@ int cylinderuse_from_text(const char *text) return -1; } -void copy_samples(struct divecomputer *s, struct divecomputer *d) +void copy_samples(const struct divecomputer *s, struct divecomputer *d) { /* instead of carefully copying them one by one and calling add_sample * over and over again, let's just copy the whole blob */ @@ -876,13 +876,13 @@ void fixup_dc_duration(struct divecomputer *dc) /* Which cylinders had gas used? */ #define SOME_GAS 5000 -static unsigned int get_cylinder_used(struct dive *dive) +static unsigned int get_cylinder_used(const struct dive *dive) { int i; unsigned int mask = 0; for (i = 0; i < MAX_CYLINDERS; i++) { - cylinder_t *cyl = dive->cylinder + i; + const cylinder_t *cyl = dive->cylinder + i; int start_mbar, end_mbar; if (cylinder_nodata(cyl)) @@ -899,10 +899,10 @@ static unsigned int get_cylinder_used(struct dive *dive) } /* Which cylinders do we know usage about? */ -static unsigned int get_cylinder_known(struct dive *dive, struct divecomputer *dc) +static unsigned int get_cylinder_known(const struct dive *dive, const struct divecomputer *dc) { unsigned int mask = 0; - struct event *ev; + const struct event *ev; /* We know about using the O2 cylinder in a CCR dive */ if (dc->divemode == CCR) { @@ -926,7 +926,7 @@ static unsigned int get_cylinder_known(struct dive *dive, struct divecomputer *d return mask; } -void per_cylinder_mean_depth(struct dive *dive, struct divecomputer *dc, int *mean, int *duration) +void per_cylinder_mean_depth(const struct dive *dive, struct divecomputer *dc, int *mean, int *duration) { int i; int depthtime[MAX_CYLINDERS] = { 0, }; @@ -974,7 +974,7 @@ void per_cylinder_mean_depth(struct dive *dive, struct divecomputer *dc, int *me } if (!dc->samples) fake_dc(dc); - struct event *ev = get_next_event(dc->events, "gaschange"); + const struct event *ev = get_next_event(dc->events, "gaschange"); for (i = 0; i < dc->samples; i++) { struct sample *sample = dc->sample + i; uint32_t time = sample->time.seconds; @@ -1019,10 +1019,10 @@ static void update_min_max_temperatures(struct dive *dive, temperature_t tempera } } -int gas_volume(cylinder_t *cyl, pressure_t p) +int gas_volume(const cylinder_t *cyl, pressure_t p) { double bar = p.mbar / 1000.0; - double z_factor = gas_compressibility_factor(&cyl->gasmix, bar); + double z_factor = gas_compressibility_factor(cyl->gasmix, bar); return lrint(cyl->type.size.mliter * bar_to_atm(bar) / z_factor); } @@ -1040,10 +1040,10 @@ static int same_rounded_pressure(pressure_t a, pressure_t b) * tell us what the first gas is with a gas change event in the first sample. * Sneakily we'll use a return value of 0 (or FALSE) when there is no explicit * first cylinder - in which case cylinder 0 is indeed the first cylinder */ -int explicit_first_cylinder(struct dive *dive, struct divecomputer *dc) +int explicit_first_cylinder(const struct dive *dive, const struct divecomputer *dc) { if (dc) { - struct event *ev = get_next_event(dc->events, "gaschange"); + const struct event *ev = get_next_event(dc->events, "gaschange"); if (ev && ((dc->sample && ev->time.seconds == dc->sample[0].time.seconds) || ev->time.seconds <= 1)) return get_cylinder_index(dive, ev); else if (dc->divemode == CCR) @@ -1055,7 +1055,7 @@ int explicit_first_cylinder(struct dive *dive, struct divecomputer *dc) /* this gets called when the dive mode has changed (so OC vs. CC) * there are two places we might have setpoints... events or in the samples */ -void update_setpoint_events(struct dive *dive, struct divecomputer *dc) +void update_setpoint_events(const struct dive *dive, struct divecomputer *dc) { struct event *ev; int new_setpoint = 0; @@ -1072,9 +1072,9 @@ void update_setpoint_events(struct dive *dive, struct divecomputer *dc) // by mistake when it's actually CCR is _bad_ // So we make sure, this comes from a Predator or Petrel and we only remove // pO2 values we would have computed anyway. - struct event *ev = get_next_event(dc->events, "gaschange"); - struct gasmix *gasmix = get_gasmix_from_event(dive, ev); - struct event *next = get_next_event(ev, "gaschange"); + const struct event *ev = get_next_event(dc->events, "gaschange"); + struct gasmix gasmix = get_gasmix_from_event(dive, ev); + const struct event *next = get_next_event(ev, "gaschange"); for (int i = 0; i < dc->samples; i++) { struct gas_pressures pressures; @@ -1092,7 +1092,7 @@ void update_setpoint_events(struct dive *dive, struct divecomputer *dc) // an "SP change" event at t=0 is currently our marker for OC vs CCR // this will need to change to a saner setup, but for now we can just // check if such an event is there and adjust it, or add that event - ev = get_next_event(dc->events, "SP change"); + ev = get_next_event_mutable(dc->events, "SP change"); if (ev && ev->time.seconds == 0) { ev->value = new_setpoint; } else { @@ -1113,7 +1113,7 @@ void sanitize_gasmix(struct gasmix *mix) if (!o2) return; /* 20.8% to 21% O2 is just air */ - if (gasmix_is_air(mix)) { + if (gasmix_is_air(*mix)) { mix->o2.permille = 0; return; } @@ -1232,7 +1232,7 @@ static void sanitize_cylinder_info(struct dive *dive) * Output: i) The icd_data stucture is filled with the delta_N2 and delta_He numbers (as permille). * ii) Function returns a boolean indicating an exceeding of the rule-of-fifths. False = no icd problem. */ -bool isobaric_counterdiffusion(struct gasmix *oldgasmix, struct gasmix *newgasmix, struct icd_data *results) +bool isobaric_counterdiffusion(struct gasmix oldgasmix, struct gasmix newgasmix, struct icd_data *results) { if (!prefs.show_icd) return false; @@ -1242,7 +1242,7 @@ bool isobaric_counterdiffusion(struct gasmix *oldgasmix, struct gasmix *newgasmi } /* some events should never be thrown away */ -static bool is_potentially_redundant(struct event *event) +static bool is_potentially_redundant(const struct event *event) { if (!strcmp(event->name, "gaschange")) return false; @@ -1331,7 +1331,7 @@ static void fixup_duration(struct dive *dive) * What do the dive computers say the water temperature is? * (not in the samples, but as dc property for dcs that support that) */ -unsigned int dc_watertemp(struct divecomputer *dc) +unsigned int dc_watertemp(const struct divecomputer *dc) { int sum = 0, nr = 0; @@ -1355,7 +1355,7 @@ static void fixup_watertemp(struct dive *dive) /* * What do the dive computers say the air temperature is? */ -unsigned int dc_airtemp(struct divecomputer *dc) +unsigned int dc_airtemp(const struct divecomputer *dc) { int sum = 0, nr = 0; @@ -1609,7 +1609,7 @@ static void fixup_dive_pressures(struct dive *dive, struct divecomputer *dc) simplify_dc_pressures(dc); } -int find_best_gasmix_match(struct gasmix *mix, cylinder_t array[], unsigned int used) +int find_best_gasmix_match(struct gasmix mix, const cylinder_t array[], unsigned int used) { int i; int best = -1, score = INT_MAX; @@ -1623,7 +1623,7 @@ int find_best_gasmix_match(struct gasmix *mix, cylinder_t array[], unsigned int match = array + i; if (cylinder_nodata(match)) continue; - distance = gasmix_distance(mix, &match->gasmix); + distance = gasmix_distance(mix, match->gasmix); if (distance >= score) continue; best = i; @@ -1641,14 +1641,14 @@ static bool validate_gaschange(struct dive *dive, struct event *event) int o2, he, value; /* We'll get rid of the per-event gasmix, but for now sanitize it */ - if (gasmix_is_air(&event->gas.mix)) + if (gasmix_is_air(event->gas.mix)) event->gas.mix.o2.permille = 0; /* Do we already have a cylinder index for this gasmix? */ if (event->gas.index >= 0) return true; - index = find_best_gasmix_match(&event->gas.mix, dive->cylinder, 0); + index = find_best_gasmix_match(event->gas.mix, dive->cylinder, 0); if (index < 0) return false; @@ -1657,8 +1657,8 @@ static bool validate_gaschange(struct dive *dive, struct event *event) event->gas.mix = dive->cylinder[index].gasmix; /* Convert to odd libdivecomputer format */ - o2 = get_o2(&event->gas.mix); - he = get_he(&event->gas.mix); + o2 = get_o2(event->gas.mix); + he = get_he(event->gas.mix); o2 = (o2 + 5) / 10; he = (he + 5) / 10; @@ -1804,7 +1804,7 @@ struct dive *fixup_dive(struct dive *dive) #define MERGE_TXT(res, a, b, n, sep) res->n = merge_text(a->n, b->n, sep) #define MERGE_NONZERO(res, a, b, n) res->n = a->n ? a->n : b->n -struct sample *add_sample(struct sample *sample, int time, struct divecomputer *dc) +struct sample *add_sample(const struct sample *sample, int time, struct divecomputer *dc) { struct sample *p = prepare_sample(dc); @@ -1969,7 +1969,7 @@ static char *merge_text(const char *a, const char *b, const char *sep) if (a->field != b->field) \ return a->field < b->field ? -1 : 1 -static int sort_event(struct event *a, struct event *b) +static int sort_event(const struct event *a, const struct event *b) { SORT(a, b, time.seconds); SORT(a, b, type); @@ -1978,10 +1978,10 @@ static int sort_event(struct event *a, struct event *b) return strcmp(a->name, b->name); } -static int same_gas(struct event *a, struct event *b) +static int same_gas(const struct event *a, const struct event *b) { if (a->type == b->type && a->flags == b->flags && a->value == b->value && !strcmp(a->name, b->name) && - same_gasmix(&a->gas.mix, &b->gas.mix)) { + same_gasmix(a->gas.mix, b->gas.mix)) { return true; } return false; @@ -2056,7 +2056,7 @@ static void merge_events(struct divecomputer *res, struct divecomputer *src1, st } } -static void merge_weightsystem_info(weightsystem_t *res, weightsystem_t *a, weightsystem_t *b) +static void merge_weightsystem_info(weightsystem_t *res, const weightsystem_t *a, const weightsystem_t *b) { if (!a->weight.grams) a = b; @@ -2069,7 +2069,7 @@ static void merge_weightsystem_info(weightsystem_t *res, weightsystem_t *a, weig * A negative number returned indicates that a match could not be found. * Call parameters: dive = the dive being processed * cylinder_use_type = an enum, one of {oxygen, diluent, bailout} */ -extern int get_cylinder_idx_by_use(struct dive *dive, enum cylinderuse cylinder_use_type) +extern int get_cylinder_idx_by_use(const struct dive *dive, enum cylinderuse cylinder_use_type) { int cylinder_index; for (cylinder_index = 0; cylinder_index < MAX_CYLINDERS; cylinder_index++) { @@ -2079,7 +2079,7 @@ extern int get_cylinder_idx_by_use(struct dive *dive, enum cylinderuse cylinder_ return -1; // negative number means cylinder_use_type not found in list of cylinders } -int gasmix_distance(const struct gasmix *a, const struct gasmix *b) +int gasmix_distance(struct gasmix a, struct gasmix b) { int a_o2 = get_o2(a), b_o2 = get_o2(b); int a_he = get_he(a), b_he = get_he(b); @@ -2100,7 +2100,7 @@ int gasmix_distance(const struct gasmix *a, const struct gasmix *b) * divemode = the dive mode pertaining to this point in the dive profile. * This function called by: calculate_gas_information_new() in profile.c; add_segment() in deco.c. */ -extern void fill_pressures(struct gas_pressures *pressures, const double amb_pressure, const struct gasmix *mix, double po2, enum divemode_t divemode) +extern void fill_pressures(struct gas_pressures *pressures, const double amb_pressure, struct gasmix mix, double po2, enum divemode_t divemode) { if ((divemode != OC) && po2) { // This is a rebreather dive where pressures->o2 is defined if (po2 >= amb_pressure) { @@ -2138,7 +2138,7 @@ extern void fill_pressures(struct gas_pressures *pressures, const double amb_pre /* Force an initial gaschange event to the (old) gas #0 */ static void add_initial_gaschange(struct dive *dive, struct divecomputer *dc) { - struct event *ev = get_next_event(dc->events, "gaschange"); + const struct event *ev = get_next_event(dc->events, "gaschange"); if (ev && ev->time.seconds < 30) return; @@ -2205,20 +2205,20 @@ void cylinder_renumber(struct dive *dive, int mapping[]) dc_cylinder_renumber(dive, dc, mapping); } -int same_gasmix(struct gasmix *a, struct gasmix *b) +int same_gasmix(struct gasmix a, struct gasmix b) { if (gasmix_is_air(a) && gasmix_is_air(b)) return 1; - return a->o2.permille == b->o2.permille && a->he.permille == b->he.permille; + return a.o2.permille == b.o2.permille && a.he.permille == b.he.permille; } int same_gasmix_cylinder(cylinder_t *cyl, int cylid, struct dive *dive, bool check_unused) { - struct gasmix *mygas = &cyl->gasmix; + struct gasmix mygas = cyl->gasmix; for (int i = 0; i < MAX_CYLINDERS; i++) { if (i == cylid || cylinder_none(&dive->cylinder[i])) continue; - struct gasmix *gas2 = &dive->cylinder[i].gasmix; + struct gasmix gas2 = dive->cylinder[i].gasmix; if (gasmix_distance(mygas, gas2) == 0 && (is_cylinder_used(dive, i) || check_unused)) return i; } @@ -2230,7 +2230,7 @@ static int pdiff(pressure_t a, pressure_t b) return a.mbar && b.mbar && a.mbar != b.mbar; } -static int different_manual_pressures(cylinder_t *a, cylinder_t *b) +static int different_manual_pressures(const cylinder_t *a, const cylinder_t *b) { return pdiff(a->start, b->start) || pdiff(a->end, b->end); } @@ -2244,17 +2244,17 @@ static int different_manual_pressures(cylinder_t *a, cylinder_t *b) * same cylinder use (ie OC/Diluent/Oxygen), and if pressures * have been added manually they need to match. */ -static int match_cylinder(cylinder_t *cyl, struct dive *dive, unsigned int available) +static int match_cylinder(const cylinder_t *cyl, const struct dive *dive, unsigned int available) { int i; for (i = 0; i < MAX_CYLINDERS; i++) { - cylinder_t *target; + const cylinder_t *target; if (!(available & (1u << i))) continue; target = dive->cylinder + i; - if (!same_gasmix(&cyl->gasmix, &target->gasmix)) + if (!same_gasmix(cyl->gasmix, target->gasmix)) continue; if (cyl->cylinder_use != target->cylinder_use) continue; @@ -2425,7 +2425,7 @@ static void merge_temperatures(struct dive *res, struct dive *a, struct dive *b) * The 'next' dive is not involved in the dive merging, but is the dive * that will be the next dive after the merged dive. */ -static void pick_trip(struct dive *res, struct dive *pick) +static void pick_trip(struct dive *res, const struct dive *pick) { tripflag_t tripflag = pick->tripflag; dive_trip_t *trip = pick->divetrip; @@ -2690,7 +2690,7 @@ static int similar(unsigned long a, unsigned long b, unsigned long expected) * positive for "same dive" and negative for "definitely * not the same dive" */ -int match_one_dc(struct divecomputer *a, struct divecomputer *b) +int match_one_dc(const struct divecomputer *a, const struct divecomputer *b) { /* Not same model? Don't know if matching.. */ if (!a->model || !b->model) @@ -2722,10 +2722,10 @@ int match_one_dc(struct divecomputer *a, struct divecomputer *b) * 0 for "don't know" * 1 for "is definitely the same dive" */ -static int match_dc_dive(struct divecomputer *a, struct divecomputer *b) +static int match_dc_dive(const struct divecomputer *a, const struct divecomputer *b) { do { - struct divecomputer *tmp = b; + const struct divecomputer *tmp = b; do { int match = match_one_dc(a, tmp); if (match) @@ -2737,7 +2737,7 @@ static int match_dc_dive(struct divecomputer *a, struct divecomputer *b) return 0; } -static bool new_without_trip(struct dive *a) +static bool new_without_trip(const struct dive *a) { return a->downloaded && !a->divetrip; } @@ -2771,7 +2771,7 @@ static bool new_without_trip(struct dive *a) * dives together manually. But this tries to handle the sane * cases. */ -static int likely_same_dive(struct dive *a, struct dive *b) +static int likely_same_dive(const struct dive *a, const struct dive *b) { int match, fuzz = 20 * 60; @@ -2875,7 +2875,7 @@ static int same_sample(struct sample *a, struct sample *b) static int same_dc(struct divecomputer *a, struct divecomputer *b) { int i; - struct event *eva, *evb; + const struct event *eva, *evb; i = match_one_dc(a, b); if (i) @@ -2899,7 +2899,7 @@ static int same_dc(struct divecomputer *a, struct divecomputer *b) return eva == evb; } -static int might_be_same_device(struct divecomputer *a, struct divecomputer *b) +static int might_be_same_device(const struct divecomputer *a, const struct divecomputer *b) { /* No dive computer model? That matches anything */ if (!a->model || !b->model) @@ -2958,7 +2958,7 @@ static struct divecomputer *find_matching_computer(struct divecomputer *match, s } -static void copy_dive_computer(struct divecomputer *res, struct divecomputer *a) +static void copy_dive_computer(struct divecomputer *res, const struct divecomputer *a) { *res = *a; res->model = copy_string(a->model); @@ -3859,7 +3859,7 @@ static bool new_picture_for_dive(struct dive *d, const char *filename) // only add pictures that have timestamps between 30 minutes before the dive and // 30 minutes after the dive ends #define D30MIN (30 * 60) -bool dive_check_picture_time(struct dive *d, int shift_time, timestamp_t timestamp) +bool dive_check_picture_time(const struct dive *d, int shift_time, timestamp_t timestamp) { offset_t offset; if (timestamp) { @@ -4026,7 +4026,7 @@ void delete_current_divecomputer(void) /* helper function to make it easier to work with our structures * we don't interpolate here, just use the value from the last sample up to that time */ -int get_depth_at_time(struct divecomputer *dc, unsigned int time) +int get_depth_at_time(const struct divecomputer *dc, unsigned int time) { int depth = 0; if (dc && dc->sample) @@ -4039,7 +4039,7 @@ int get_depth_at_time(struct divecomputer *dc, unsigned int time) } //Calculate O2 in best mix -fraction_t best_o2(depth_t depth, struct dive *dive) +fraction_t best_o2(depth_t depth, const struct dive *dive) { fraction_t fo2; @@ -4051,7 +4051,7 @@ fraction_t best_o2(depth_t depth, struct dive *dive) } //Calculate He in best mix. O2 is considered narcopic -fraction_t best_he(depth_t depth, struct dive *dive) +fraction_t best_he(depth_t depth, const struct dive *dive) { fraction_t fhe; int pnarcotic, ambient; @@ -4063,10 +4063,10 @@ fraction_t best_he(depth_t depth, struct dive *dive) return fhe; } -bool gasmix_is_air(const struct gasmix *gasmix) +bool gasmix_is_air(struct gasmix gasmix) { - int o2 = gasmix->o2.permille; - int he = gasmix->he.permille; + int o2 = gasmix.o2.permille; + int he = gasmix.he.permille; return (he == 0) && (o2 == 0 || ((o2 >= O2_IN_AIR - 1) && (o2 <= O2_IN_AIR + 1))); } @@ -4108,17 +4108,17 @@ int calculate_depth_to_mbar(int depth, pressure_t surface_pressure, int salinity return mbar; } -int depth_to_mbar(int depth, struct dive *dive) +int depth_to_mbar(int depth, const struct dive *dive) { return calculate_depth_to_mbar(depth, dive->surface_pressure, dive->salinity); } -double depth_to_bar(int depth, struct dive *dive) +double depth_to_bar(int depth, const struct dive *dive) { return depth_to_mbar(depth, dive) / 1000.0; } -double depth_to_atm(int depth, struct dive *dive) +double depth_to_atm(int depth, const struct dive *dive) { return mbar_to_atm(depth_to_mbar(depth, dive)); } @@ -4127,7 +4127,7 @@ double depth_to_atm(int depth, struct dive *dive) * (that's the one that some dive computers like the Uemis Zurich * provide - for the other models that do this libdivecomputer has to * take care of this, but the Uemis we support natively */ -int rel_mbar_to_depth(int mbar, struct dive *dive) +int rel_mbar_to_depth(int mbar, const struct dive *dive) { int cm; double specific_weight = 1.03 * 0.981; @@ -4138,7 +4138,7 @@ int rel_mbar_to_depth(int mbar, struct dive *dive) return cm * 10; } -int mbar_to_depth(int mbar, struct dive *dive) +int mbar_to_depth(int mbar, const struct dive *dive) { pressure_t surface_pressure; if (dive->surface_pressure.mbar) @@ -4149,7 +4149,7 @@ int mbar_to_depth(int mbar, struct dive *dive) } /* MOD rounded to multiples of roundto mm */ -depth_t gas_mod(struct gasmix *mix, pressure_t po2_limit, struct dive *dive, int roundto) +depth_t gas_mod(struct gasmix mix, pressure_t po2_limit, const struct dive *dive, int roundto) { depth_t rounded_depth; @@ -4159,7 +4159,7 @@ depth_t gas_mod(struct gasmix *mix, pressure_t po2_limit, struct dive *dive, int } /* Maximum narcotic depth rounded to multiples of roundto mm */ -depth_t gas_mnd(struct gasmix *mix, depth_t end, struct dive *dive, int roundto) +depth_t gas_mnd(struct gasmix mix, depth_t end, const struct dive *dive, int roundto) { depth_t rounded_depth; pressure_t ppo2n2; @@ -4184,14 +4184,14 @@ struct dive *get_dive_from_table(int nr, struct dive_table *dt) return dt->dives[nr]; } -struct dive_site *get_dive_site_for_dive(struct dive *dive) +struct dive_site *get_dive_site_for_dive(const struct dive *dive) { if (dive) return get_dive_site_by_uuid(dive->dive_site_uuid); return NULL; } -const char *get_dive_country(struct dive *dive) +const char *get_dive_country(const struct dive *dive) { struct dive_site *ds = get_dive_site_by_uuid(dive->dive_site_uuid); if (ds) { @@ -4210,10 +4210,10 @@ const char *get_dive_location(const struct dive *dive) return NULL; } -unsigned int number_of_computers(struct dive *dive) +unsigned int number_of_computers(const struct dive *dive) { unsigned int total_number = 0; - struct divecomputer *dc = &dive->dc; + const struct divecomputer *dc = &dive->dc; if (!dive) return 1; @@ -4276,31 +4276,44 @@ int get_idx_by_uniq_id(int id) return i; } -bool dive_site_has_gps_location(struct dive_site *ds) +bool dive_site_has_gps_location(const struct dive_site *ds) { return ds && (ds->latitude.udeg || ds->longitude.udeg); } -int dive_has_gps_location(struct dive *dive) +int dive_has_gps_location(const struct dive *dive) { if (!dive) return false; return dive_site_has_gps_location(get_dive_site_by_uuid(dive->dive_site_uuid)); } -struct gasmix *get_gasmix(struct dive *dive, struct divecomputer *dc, int time, struct event **evp, struct gasmix *gasmix) +struct gasmix get_gasmix(const struct dive *dive, const struct divecomputer *dc, int time, const struct event **evp, struct gasmix gasmix) { - struct event *ev = *evp; + const struct event *ev = *evp; + struct gasmix res; - if (!gasmix) { + if (!ev) { + /* on first invocation, get initial gas mix and first event (if any) */ int cyl = explicit_first_cylinder(dive, dc); - gasmix = &dive->cylinder[cyl].gasmix; + res = dive->cylinder[cyl].gasmix; ev = dc ? get_next_event(dc->events, "gaschange") : NULL; + } else { + res = gasmix; } + while (ev && ev->time.seconds < time) { - gasmix = get_gasmix_from_event(dive, ev); + res = get_gasmix_from_event(dive, ev); ev = get_next_event(ev->next, "gaschange"); } *evp = ev; - return gasmix; + return res; +} + +/* get the gas at a certain time during the dive */ +struct gasmix get_gasmix_at_time(const struct dive *d, const struct divecomputer *dc, duration_t time) +{ + const struct event *ev = NULL; + struct gasmix gasmix = { 0 }; + return get_gasmix(d, dc, time.seconds, &ev, gasmix); } diff --git a/core/dive.h b/core/dive.h index 01ec1fd3d..4c24dad74 100644 --- a/core/dive.h +++ b/core/dive.h @@ -71,7 +71,7 @@ struct icd_data { // This structure provides communication between function isob int dHe; // The change in fraction (permille) of helium during the change }; -extern bool isobaric_counterdiffusion(struct gasmix *oldgasmix, struct gasmix *newgasmix, struct icd_data *results); +extern bool isobaric_counterdiffusion(struct gasmix oldgasmix, struct gasmix newgasmix, struct icd_data *results); /* * Events are currently based straight on what libdivecomputer gives us. @@ -100,7 +100,7 @@ struct event { char name[]; }; -extern int event_is_gaschange(struct event *ev); +extern int event_is_gaschange(const struct event *ev); extern int get_pressure_units(int mb, const char **units); extern double get_depth_units(int mm, int *frac, const char **units); @@ -113,33 +113,33 @@ extern depth_t units_to_depth(double depth); extern int units_to_sac(double volume); /* Volume in mliter of a cylinder at pressure 'p' */ -extern int gas_volume(cylinder_t *cyl, pressure_t p); -extern double gas_compressibility_factor(struct gasmix *gas, double bar); -extern double isothermal_pressure(struct gasmix *gas, double p1, int volume1, int volume2); -extern double gas_density(struct gasmix *gas, int pressure); -extern int same_gasmix(struct gasmix *a, struct gasmix *b); +extern int gas_volume(const cylinder_t *cyl, pressure_t p); +extern double gas_compressibility_factor(struct gasmix gas, double bar); +extern double isothermal_pressure(struct gasmix gas, double p1, int volume1, int volume2); +extern double gas_density(struct gasmix gas, int pressure); +extern int same_gasmix(struct gasmix a, struct gasmix b); -static inline int get_o2(const struct gasmix *mix) +static inline int get_o2(struct gasmix mix) { - return mix->o2.permille ?: O2_IN_AIR; + return mix.o2.permille ?: O2_IN_AIR; } -static inline int get_he(const struct gasmix *mix) +static inline int get_he(struct gasmix mix) { - return mix->he.permille; + return mix.he.permille; } struct gas_pressures { double o2, n2, he; }; -extern void fill_pressures(struct gas_pressures *pressures, const double amb_pressure, const struct gasmix *mix, double po2, enum divemode_t dctype); +extern void fill_pressures(struct gas_pressures *pressures, const double amb_pressure, struct gasmix mix, double po2, enum divemode_t dctype); extern void sanitize_gasmix(struct gasmix *mix); -extern int gasmix_distance(const struct gasmix *a, const struct gasmix *b); -extern int find_best_gasmix_match(struct gasmix *mix, cylinder_t array[], unsigned int used); +extern int gasmix_distance(struct gasmix a, struct gasmix b); +extern int find_best_gasmix_match(struct gasmix mix, const cylinder_t array[], unsigned int used); -extern bool gasmix_is_air(const struct gasmix *gasmix); +extern bool gasmix_is_air(struct gasmix gasmix); /* Linear interpolation between 'a' and 'b', when we are 'part'way into the 'whole' distance from a to b */ static inline int interpolate(int a, int b, int part, int whole) @@ -152,8 +152,8 @@ static inline int interpolate(int a, int b, int part, int whole) return (a+b)/2; } -void get_gas_string(const struct gasmix *gasmix, char *text, int len); -const char *gasname(const struct gasmix *gasmix); +void get_gas_string(struct gasmix gasmix, char *text, int len); +const char *gasname(struct gasmix gasmix); #define MAX_SENSORS 2 struct sample // BASE TYPE BYTES UNITS RANGE DESCRIPTION @@ -334,7 +334,7 @@ struct dive { extern void invalidate_dive_cache(struct dive *dive); extern bool dive_cache_is_valid(const struct dive *dive); -extern int get_cylinder_idx_by_use(struct dive *dive, enum cylinderuse cylinder_use_type); +extern int get_cylinder_idx_by_use(const struct dive *dive, enum cylinderuse cylinder_use_type); extern void cylinder_renumber(struct dive *dive, int mapping[]); extern int same_gasmix_cylinder(cylinder_t *cyl, int cylid, struct dive *dive, bool check_unused); @@ -352,9 +352,9 @@ struct dive_components { unsigned int weights : 1; }; -extern enum divemode_t get_current_divemode(struct divecomputer *dc, int time, struct event **evp, enum divemode_t *divemode); -extern struct event *get_next_divemodechange(struct event **evd, bool update_pointer); -extern enum divemode_t get_divemode_at_time(struct divecomputer *dc, int dtime, struct event **ev_dmc); +extern enum divemode_t get_current_divemode(const struct divecomputer *dc, int time, const struct event **evp, enum divemode_t *divemode); +extern struct event *get_next_divemodechange(const struct event **evd, bool update_pointer); +extern enum divemode_t get_divemode_at_time(const struct divecomputer *dc, int dtime, const struct event **ev_dmc); /* picture list and methods related to dive picture handling */ struct picture { @@ -373,7 +373,7 @@ struct picture { for (struct picture *picture = (_divestruct).picture_list; picture; picture = picture->next) extern struct picture *alloc_picture(); -extern bool dive_check_picture_time(struct dive *d, int shift_time, timestamp_t timestamp); +extern bool dive_check_picture_time(const struct dive *d, int shift_time, timestamp_t timestamp); extern void dive_create_picture(struct dive *d, const char *filename, int shift_time, bool match_all); extern void dive_add_picture(struct dive *d, struct picture *newpic); extern bool dive_remove_picture(struct dive *d, const char *filename); @@ -382,22 +382,22 @@ extern bool picture_check_valid(const char *filename, int shift_time); extern void dive_set_geodata_from_picture(struct dive *d, struct picture *pic); extern void picture_free(struct picture *picture); -extern bool has_gaschange_event(struct dive *dive, struct divecomputer *dc, int idx); -extern int explicit_first_cylinder(struct dive *dive, struct divecomputer *dc); -extern int get_depth_at_time(struct divecomputer *dc, unsigned int time); +extern bool has_gaschange_event(const struct dive *dive, const struct divecomputer *dc, int idx); +extern int explicit_first_cylinder(const struct dive *dive, const struct divecomputer *dc); +extern int get_depth_at_time(const struct divecomputer *dc, unsigned int time); -extern fraction_t best_o2(depth_t depth, struct dive *dive); -extern fraction_t best_he(depth_t depth, struct dive *dive); +extern fraction_t best_o2(depth_t depth, const struct dive *dive); +extern fraction_t best_he(depth_t depth, const struct dive *dive); extern int get_surface_pressure_in_mbar(const struct dive *dive, bool non_null); extern int calculate_depth_to_mbar(int depth, pressure_t surface_pressure, int salinity); -extern int depth_to_mbar(int depth, struct dive *dive); -extern double depth_to_bar(int depth, struct dive *dive); -extern double depth_to_atm(int depth, struct dive *dive); -extern int rel_mbar_to_depth(int mbar, struct dive *dive); -extern int mbar_to_depth(int mbar, struct dive *dive); -extern depth_t gas_mod(struct gasmix *mix, pressure_t po2_limit, struct dive *dive, int roundto); -extern depth_t gas_mnd(struct gasmix *mix, depth_t end, struct dive *dive, int roundto); +extern int depth_to_mbar(int depth, const struct dive *dive); +extern double depth_to_bar(int depth, const struct dive *dive); +extern double depth_to_atm(int depth, const struct dive *dive); +extern int rel_mbar_to_depth(int mbar, const struct dive *dive); +extern int mbar_to_depth(int mbar, const struct dive *dive); +extern depth_t gas_mod(struct gasmix mix, pressure_t po2_limit, const struct dive *dive, int roundto); +extern depth_t gas_mnd(struct gasmix mix, depth_t end, const struct dive *dive, int roundto); #define SURFACE_THRESHOLD 750 /* somewhat arbitrary: only below 75cm is it really diving */ @@ -442,10 +442,10 @@ extern unsigned int dc_number; extern struct dive *get_dive(int nr); extern struct dive *get_dive_from_table(int nr, struct dive_table *dt); -extern struct dive_site *get_dive_site_for_dive(struct dive *dive); -extern const char *get_dive_country(struct dive *dive); +extern struct dive_site *get_dive_site_for_dive(const struct dive *dive); +extern const char *get_dive_country(const struct dive *dive); extern const char *get_dive_location(const struct dive *dive); -extern unsigned int number_of_computers(struct dive *dive); +extern unsigned int number_of_computers(const struct dive *dive); extern struct divecomputer *get_dive_dc(struct dive *dive, int nr); extern timestamp_t dive_endtime(const struct dive *dive); @@ -475,8 +475,8 @@ extern "C" { extern struct dive *get_dive_by_uniq_id(int id); extern int get_idx_by_uniq_id(int id); -extern bool dive_site_has_gps_location(struct dive_site *ds); -extern int dive_has_gps_location(struct dive *dive); +extern bool dive_site_has_gps_location(const struct dive_site *ds); +extern int dive_has_gps_location(const struct dive *dive); extern int report_error(const char *fmt, ...); extern void set_error_cb(void(*cb)(char *)); // Callback takes ownership of passed string @@ -487,7 +487,7 @@ extern bool time_during_dive_with_offset(struct dive *dive, timestamp_t when, ti struct dive *find_dive_n_near(timestamp_t when, int n, timestamp_t offset); /* Check if two dive computer entries are the exact same dive (-1=no/0=maybe/1=yes) */ -extern int match_one_dc(struct divecomputer *a, struct divecomputer *b); +extern int match_one_dc(const struct divecomputer *a, const struct divecomputer *b); extern void parse_xml_init(void); extern int parse_xml_buffer(const char *url, const char *buf, int size, struct dive_table *table, const char **params); @@ -499,9 +499,9 @@ extern int parse_dm5_buffer(sqlite3 *handle, const char *url, const char *buf, i extern int parse_shearwater_buffer(sqlite3 *handle, const char *url, const char *buf, int size, struct dive_table *table); extern int parse_cobalt_buffer(sqlite3 *handle, const char *url, const char *buf, int size, struct dive_table *table); extern int parse_divinglog_buffer(sqlite3 *handle, const char *url, const char *buf, int size, struct dive_table *table); -extern int parse_dlf_buffer(unsigned char *buffer, size_t size); +extern int parse_dlf_buffer(unsigned char *buffer, size_t size, struct dive_table *table); -extern int parse_file(const char *filename); +extern int parse_file(const char *filename, struct dive_table *table); extern int parse_csv_file(const char *filename, char **params, int pnr, const char *csvtemplate); extern int parse_seabear_log(const char *filename); extern int parse_txt_file(const char *filename, const char *csv); @@ -547,8 +547,8 @@ extern struct dive *alloc_dive(void); extern void record_dive_to_table(struct dive *dive, struct dive_table *table); extern void record_dive(struct dive *dive); extern void clear_dive(struct dive *dive); -extern void copy_dive(struct dive *s, struct dive *d); -extern void selective_copy_dive(struct dive *s, struct dive *d, struct dive_components what, bool clear); +extern void copy_dive(const struct dive *s, struct dive *d); +extern void selective_copy_dive(const struct dive *s, struct dive *d, struct dive_components what, bool clear); extern struct dive *clone_dive(struct dive *s); extern void clear_table(struct dive_table *table); @@ -557,37 +557,38 @@ extern void alloc_samples(struct divecomputer *dc, int num); extern void free_samples(struct divecomputer *dc); extern struct sample *prepare_sample(struct divecomputer *dc); extern void finish_sample(struct divecomputer *dc); +extern struct sample *add_sample(const struct sample *sample, int time, struct divecomputer *dc); extern void add_sample_pressure(struct sample *sample, int sensor, int mbar); -extern int legacy_format_o2pressures(struct dive *dive, struct divecomputer *dc); +extern int legacy_format_o2pressures(const struct dive *dive, const struct divecomputer *dc); extern void sort_table(struct dive_table *table); extern struct dive *fixup_dive(struct dive *dive); extern void fixup_dc_duration(struct divecomputer *dc); extern int dive_getUniqID(); -extern unsigned int dc_airtemp(struct divecomputer *dc); -extern unsigned int dc_watertemp(struct divecomputer *dc); +extern unsigned int dc_airtemp(const struct divecomputer *dc); +extern unsigned int dc_watertemp(const struct divecomputer *dc); extern int split_dive(struct dive *); extern void split_dive_at_time(struct dive *dive, duration_t time); extern struct dive *merge_dives(struct dive *a, struct dive *b, int offset, bool prefer_downloaded); extern struct dive *try_to_merge(struct dive *a, struct dive *b, bool prefer_downloaded); extern struct event *clone_event(const struct event *src_ev); -extern void copy_events(struct divecomputer *s, struct divecomputer *d); +extern void copy_events(const struct divecomputer *s, struct divecomputer *d); extern void free_events(struct event *ev); -extern void copy_cylinders(struct dive *s, struct dive *d, bool used_only); -extern void copy_samples(struct divecomputer *s, struct divecomputer *d); -extern bool is_cylinder_used(struct dive *dive, int idx); -extern bool is_cylinder_prot(struct dive *dive, int idx); +extern void copy_cylinders(const struct dive *s, struct dive *d, bool used_only); +extern void copy_samples(const struct divecomputer *s, struct divecomputer *d); +extern bool is_cylinder_used(const struct dive *dive, int idx); +extern bool is_cylinder_prot(const struct dive *dive, int idx); extern void fill_default_cylinder(cylinder_t *cyl); extern void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int time, int idx); extern struct event *add_event(struct divecomputer *dc, unsigned int time, int type, int flags, int value, const char *name); extern void remove_event(struct event *event); -extern void update_event_name(struct dive *d, struct event* event, const char *name); +extern void update_event_name(struct dive *d, struct event *event, const char *name); extern void add_extra_data(struct divecomputer *dc, const char *key, const char *value); -extern void per_cylinder_mean_depth(struct dive *dive, struct divecomputer *dc, int *mean, int *duration); -extern int get_cylinder_index(struct dive *dive, struct event *ev); -extern struct gasmix *get_gasmix_from_event(struct dive *, struct event *ev); -extern int nr_cylinders(struct dive *dive); -extern int nr_weightsystems(struct dive *dive); +extern void per_cylinder_mean_depth(const struct dive *dive, struct divecomputer *dc, int *mean, int *duration); +extern int get_cylinder_index(const struct dive *dive, const struct event *ev); +extern struct gasmix get_gasmix_from_event(const struct dive *, const struct event *ev); +extern int nr_cylinders(const struct dive *dive); +extern int nr_weightsystems(const struct dive *dive); /* UI related protopypes */ @@ -606,7 +607,7 @@ extern void clear_events(void); extern void set_dc_nickname(struct dive *dive); extern void set_autogroup(bool value); -extern int total_weight(struct dive *); +extern int total_weight(const struct dive *); #ifdef __cplusplus } @@ -663,7 +664,7 @@ struct deco_state { bool icd_warning; }; -extern void add_segment(struct deco_state *ds, double pressure, const struct gasmix *gasmix, int period_in_seconds, int setpoint, enum divemode_t divemode, int sac); +extern void add_segment(struct deco_state *ds, double pressure, struct gasmix gasmix, int period_in_seconds, int setpoint, enum divemode_t divemode, int sac); extern void clear_deco(struct deco_state *ds, double surface_pressure); extern void dump_tissues(struct deco_state *ds); extern void set_gf(short gflow, short gfhigh); @@ -716,9 +717,18 @@ extern void vpmb_start_gradient(struct deco_state *ds); extern void clear_vpmb_state(struct deco_state *ds); extern void printdecotable(struct decostop *table); -extern struct event *get_next_event(struct event *event, const char *name); +/* Since C doesn't have parameter-based overloading, two versions of get_next_event. */ +extern const struct event *get_next_event(const struct event *event, const char *name); +extern struct event *get_next_event_mutable(struct event *event, const char *name); -extern struct gasmix *get_gasmix(struct dive *dive, struct divecomputer *dc, int time, struct event **evp, struct gasmix *gasmix); +/* Get gasmixes at increasing timestamps. + * In "evp", pass a pointer to a "struct event *" which is NULL-initialized on first invocation. + * On subsequent calls, pass the same "evp" and the "gasmix" from previous calls. + */ +extern struct gasmix get_gasmix(const struct dive *dive, const struct divecomputer *dc, int time, const struct event **evp, struct gasmix gasmix); + +/* Get gasmix at a given time */ +extern struct gasmix get_gasmix_at_time(const struct dive *dive, const struct divecomputer *dc, duration_t time); /* these structs holds the information that * describes the cylinders / weight systems. @@ -740,9 +750,8 @@ struct ws_info_t { extern struct ws_info_t ws_info[MAX_WS_INFO]; extern bool cylinder_nodata(const cylinder_t *cyl); -extern bool cylinder_none(void *_data); -extern bool weightsystem_none(void *_data); -extern bool no_weightsystems(weightsystem_t *ws); +extern bool cylinder_none(const cylinder_t *cyl); +extern bool weightsystem_none(const weightsystem_t *ws); extern void remove_cylinder(struct dive *dive, int idx); extern void remove_weightsystem(struct dive *dive, int idx); extern void reset_cylinders(struct dive *dive, bool track_gas); @@ -755,7 +764,7 @@ extern void set_informational_units(const char *units); extern void set_git_prefs(const char *prefs); extern char *get_dive_date_c_string(timestamp_t when); -extern void update_setpoint_events(struct dive *dive, struct divecomputer *dc); +extern void update_setpoint_events(const struct dive *dive, struct divecomputer *dc); #ifdef __cplusplus } diff --git a/core/divecomputer.cpp b/core/divecomputer.cpp index 978074e62..5e177e541 100644 --- a/core/divecomputer.cpp +++ b/core/divecomputer.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "divecomputer.h" #include "dive.h" -#include "subsurface-qt/SettingsObjectWrapper.h" +#include "core/settings/qPrefDiveComputer.h" #include "subsurface-string.h" DiveComputerList dcList; @@ -123,14 +123,12 @@ extern "C" void call_for_each_dc (void *f, void (*callback)(void *, const char * extern "C" int is_default_dive_computer(const char *vendor, const char *product) { - auto dc = SettingsObjectWrapper::instance()->dive_computer_settings; - return dc->vendor() == vendor && dc->product() == product; + return qPrefDiveComputer::vendor() == vendor && qPrefDiveComputer::product() == product; } extern "C" int is_default_dive_computer_device(const char *name) { - auto dc = SettingsObjectWrapper::instance()->dive_computer_settings; - return dc->device() == name; + return qPrefDiveComputer::device() == name; } extern "C" void set_dc_nickname(struct dive *dive) diff --git a/core/divelist.c b/core/divelist.c index b81e89d25..f643d14f6 100644 --- a/core/divelist.c +++ b/core/divelist.c @@ -7,8 +7,9 @@ * unsigned int amount_selected; * void dump_selection(void) * void get_dive_gas(struct dive *dive, int *o2_p, int *he_p, int *o2low_p) - * int total_weight(struct dive *dive) - * int get_divenr(struct dive *dive) + * int total_weight(const struct dive *dive) + * int get_divenr(const struct dive *dive) + * int get_divesite_idx(const struct dive_site *ds) * int init_decompression(struct dive *dive) * void update_cylinder_related_info(struct dive *dive) * void dump_trip_list(void) @@ -26,6 +27,7 @@ * int unsaved_changes() * void remove_autogen_trips() * void sort_table(struct dive_table *table) + * bool is_trip_before_after(const struct dive *dive, bool before) */ #include <unistd.h> #include <stdio.h> @@ -94,8 +96,8 @@ void get_dive_gas(struct dive *dive, int *o2_p, int *he_p, int *o2max_p) for (i = 0; i < MAX_CYLINDERS; i++) { cylinder_t *cyl = dive->cylinder + i; - int o2 = get_o2(&cyl->gasmix); - int he = get_he(&cyl->gasmix); + int o2 = get_o2(cyl->gasmix); + int he = get_he(cyl->gasmix); if (!is_cylinder_used(dive, i)) continue; @@ -122,7 +124,7 @@ void get_dive_gas(struct dive *dive, int *o2_p, int *he_p, int *o2max_p) *o2max_p = maxo2; } -int total_weight(struct dive *dive) +int total_weight(const struct dive *dive) { int i, total_grams = 0; @@ -132,19 +134,18 @@ int total_weight(struct dive *dive) return total_grams; } -static int active_o2(struct dive *dive, struct divecomputer *dc, duration_t time) +static int active_o2(const struct dive *dive, const struct divecomputer *dc, duration_t time) { - struct gasmix gas; - get_gas_at_time(dive, dc, time, &gas); - return get_o2(&gas); + struct gasmix gas = get_gasmix_at_time(dive, dc, time); + return get_o2(gas); } /* calculate OTU for a dive - this only takes the first divecomputer into account */ -static int calculate_otu(struct dive *dive) +static int calculate_otu(const struct dive *dive) { int i; double otu = 0.0; - struct divecomputer *dc = &dive->dc; + const struct divecomputer *dc = &dive->dc; for (i = 1; i < dc->samples; i++) { int t; @@ -180,11 +181,11 @@ int const cns_table[][3] = { }; /* Calculate the CNS for a single dive */ -double calculate_cns_dive(struct dive *dive) +static double calculate_cns_dive(const struct dive *dive) { int n; size_t j; - struct divecomputer *dc = &dive->dc; + const struct divecomputer *dc = &dive->dc; double cns = 0.0; /* Caclulate the CNS for each sample in this dive and sum them */ @@ -346,14 +347,14 @@ static int calculate_cns(struct dive *dive) /* * Return air usage (in liters). */ -static double calculate_airuse(struct dive *dive) +static double calculate_airuse(const struct dive *dive) { int airuse = 0; int i; for (i = 0; i < MAX_CYLINDERS; i++) { pressure_t start, end; - cylinder_t *cyl = dive->cylinder + i; + const cylinder_t *cyl = dive->cylinder + i; start = cyl->start.mbar ? cyl->start : cyl->sample_start; end = cyl->end.mbar ? cyl->end : cyl->sample_end; @@ -374,9 +375,9 @@ static double calculate_airuse(struct dive *dive) } /* this only uses the first divecomputer to calculate the SAC rate */ -static int calculate_sac(struct dive *dive) +static int calculate_sac(const struct dive *dive) { - struct divecomputer *dc = &dive->dc; + const struct divecomputer *dc = &dive->dc; double airuse, pressure, sac; int duration, meandepth; @@ -404,9 +405,9 @@ static int calculate_sac(struct dive *dive) static void add_dive_to_deco(struct deco_state *ds, struct dive *dive) { struct divecomputer *dc = &dive->dc; - struct gasmix *gasmix = NULL; + struct gasmix gasmix = { 0 }; int i; - struct event *ev = NULL, *evd = NULL; + const struct event *ev = NULL, *evd = NULL; enum divemode_t current_divemode = UNDEF_COMP_TYPE; if (!dc) @@ -428,10 +429,10 @@ static void add_dive_to_deco(struct deco_state *ds, struct dive *dive) } } -int get_divenr(struct dive *dive) +int get_divenr(const struct dive *dive) { int i; - struct dive *d; + const struct dive *d; // tempting as it may be, don't die when called with dive=NULL if (dive) for_each_dive(i, d) { @@ -441,10 +442,10 @@ int get_divenr(struct dive *dive) return -1; } -int get_divesite_idx(struct dive_site *ds) +int get_divesite_idx(const struct dive_site *ds) { int i; - struct dive_site *d; + const struct dive_site *d; // tempting as it may be, don't die when called with dive=NULL if (ds) for_each_dive_site(i, d) { @@ -577,7 +578,7 @@ int init_decompression(struct deco_state *ds, struct dive *dive) #endif return surface_time; } - add_segment(ds, surface_pressure, &air, surface_time, 0, dive->dc.divemode, prefs.decosac); + add_segment(ds, surface_pressure, air, surface_time, 0, dive->dc.divemode, prefs.decosac); #if DECO_CALC_DEBUG & 2 printf("Tissues after surface intervall of %d:%02u:\n", FRACTION(surface_time, 60)); dump_tissues(ds); @@ -615,7 +616,7 @@ int init_decompression(struct deco_state *ds, struct dive *dive) #endif return surface_time; } - add_segment(ds, surface_pressure, &air, surface_time, 0, dive->dc.divemode, prefs.decosac); + add_segment(ds, surface_pressure, air, surface_time, 0, dive->dc.divemode, prefs.decosac); #if DECO_CALC_DEBUG & 2 printf("Tissues after surface intervall of %d:%02u:\n", FRACTION(surface_time, 60)); dump_tissues(ds); @@ -776,7 +777,7 @@ void find_new_trip_start_time(dive_trip_t *trip) } /* check if we have a trip right before / after this dive */ -bool is_trip_before_after(struct dive *dive, bool before) +bool is_trip_before_after(const struct dive *dive, bool before) { int idx = get_idx_by_uniq_id(dive->id); if (before) { diff --git a/core/divelist.h b/core/divelist.h index d014b4df1..5467f10ae 100644 --- a/core/divelist.h +++ b/core/divelist.h @@ -23,8 +23,8 @@ extern char *get_dive_gas_string(struct dive *dive); struct dive **grow_dive_table(struct dive_table *table); extern void get_dive_gas(struct dive *dive, int *o2_p, int *he_p, int *o2low_p); -extern int get_divenr(struct dive *dive); -extern int get_divesite_idx(struct dive_site *ds); +extern int get_divenr(const struct dive *dive); +extern int get_divesite_idx(const struct dive_site *ds); extern void remove_dive_from_trip(struct dive *dive, short was_autogen); extern dive_trip_t *create_and_hookup_trip_from_dive(struct dive *dive); extern void autogroup_dives(void); @@ -39,7 +39,7 @@ extern void combine_trips(struct dive_trip *trip_a, struct dive_trip *trip_b); extern void find_new_trip_start_time(dive_trip_t *trip); extern struct dive *first_selected_dive(); extern struct dive *last_selected_dive(); -extern bool is_trip_before_after(struct dive *dive, bool before); +extern bool is_trip_before_after(const struct dive *dive, bool before); extern void set_dive_nr_for_current_dive(); int get_min_datafile_version(); diff --git a/core/divelogexportlogic.cpp b/core/divelogexportlogic.cpp index 82c8b452f..cb700e79a 100644 --- a/core/divelogexportlogic.cpp +++ b/core/divelogexportlogic.cpp @@ -148,8 +148,10 @@ void exportHtmlInitLogic(const QString &filename, struct htmlExportSetting &hes) export_HTML(qPrintable(json_dive_data), qPrintable(photosDirectory), hes.selectedOnly, hes.listOnly); QString searchPath = getSubsurfaceDataPath("theme"); - if (searchPath.isEmpty()) + if (searchPath.isEmpty()) { + report_error(qPrintable(gettextFromC::tr("Cannot find a folder called 'theme' in the standard locations"))); return; + } searchPath += QDir::separator(); diff --git a/core/downloadfromdcthread.cpp b/core/downloadfromdcthread.cpp index a05dffb8d..da8c09f54 100644 --- a/core/downloadfromdcthread.cpp +++ b/core/downloadfromdcthread.cpp @@ -1,7 +1,7 @@ #include "downloadfromdcthread.h" #include "core/libdivecomputer.h" #include "core/qthelper.h" -#include "core/subsurface-qt/SettingsObjectWrapper.h" +#include "core/settings/qPrefDiveComputer.h" #include <QDebug> #include <QRegularExpression> #if defined(Q_OS_ANDROID) @@ -57,11 +57,10 @@ void DownloadThread::run() } else { qDebug() << "Finishing download thread:" << downloadTable.nr << "dives downloaded"; } - auto dcs = SettingsObjectWrapper::instance()->dive_computer_settings; - dcs->set_vendor(internalData->vendor); - dcs->set_product(internalData->product); - dcs->set_device(internalData->devname); - dcs->set_device_name(m_data->devBluetoothName()); + qPrefDiveComputer::set_vendor(internalData->vendor); + qPrefDiveComputer::set_product(internalData->product); + qPrefDiveComputer::set_device(internalData->devname); + qPrefDiveComputer::set_device_name(m_data->devBluetoothName()); } static void fill_supported_mobile_list() @@ -252,13 +251,12 @@ QStringList DCDeviceData::getProductListFromVendor(const QString &vendor) int DCDeviceData::getMatchingAddress(const QString &vendor, const QString &product) { - auto dcs = SettingsObjectWrapper::instance()->dive_computer_settings; - if (dcs->vendor() == vendor && - dcs->product() == product) { + if (qPrefDiveComputer::vendor() == vendor && + qPrefDiveComputer::product() == product) { // we are trying to show the last dive computer selected for (int i = 0; i < connectionListModel.rowCount(); i++) { QString address = connectionListModel.address(i); - if (address.contains(dcs->device())) + if (address.contains(qPrefDiveComputer::device())) return i; } } @@ -415,11 +413,10 @@ device_data_t *DCDeviceData::internalData() int DCDeviceData::getDetectedVendorIndex() { - auto dcs = SettingsObjectWrapper::instance()->dive_computer_settings; - if (!dcs->vendor().isEmpty()) { + if (!qPrefDiveComputer::vendor().isEmpty()) { // use the last one for (int i = 0; i < vendorList.length(); i++) { - if (vendorList[i] == dcs->vendor()) + if (vendorList[i] == qPrefDiveComputer::vendor()) return i; } } @@ -436,12 +433,11 @@ int DCDeviceData::getDetectedVendorIndex() int DCDeviceData::getDetectedProductIndex(const QString ¤tVendorText) { - auto dcs = SettingsObjectWrapper::instance()->dive_computer_settings; - if (!dcs->vendor().isEmpty()) { - if (dcs->vendor() == currentVendorText) { + if (!qPrefDiveComputer::vendor().isEmpty()) { + if (qPrefDiveComputer::vendor() == currentVendorText) { // we are trying to show the last dive computer selected for (int i = 0; i < productList[currentVendorText].length(); i++) { - if (productList[currentVendorText][i] == dcs->product()) + if (productList[currentVendorText][i] == qPrefDiveComputer::product()) return i; } } diff --git a/core/equipment.c b/core/equipment.c index 53e4c273f..39bf97af9 100644 --- a/core/equipment.c +++ b/core/equipment.c @@ -69,19 +69,18 @@ bool cylinder_nodata(const cylinder_t *cyl) !cyl->deco_gas_used.mliter; } -static bool cylinder_nosamples(cylinder_t *cyl) +static bool cylinder_nosamples(const cylinder_t *cyl) { return !cyl->sample_start.mbar && !cyl->sample_end.mbar; } -bool cylinder_none(void *_data) +bool cylinder_none(const cylinder_t *cyl) { - cylinder_t *cyl = _data; return cylinder_nodata(cyl) && cylinder_nosamples(cyl); } -void get_gas_string(const struct gasmix *gasmix, char *text, int len) +void get_gas_string(struct gasmix gasmix, char *text, int len) { if (gasmix_is_air(gasmix)) snprintf(text, len, "%s", translate("gettextFromC", "air")); @@ -94,27 +93,18 @@ void get_gas_string(const struct gasmix *gasmix, char *text, int len) } /* Returns a static char buffer - only good for immediate use by printf etc */ -const char *gasname(const struct gasmix *gasmix) +const char *gasname(struct gasmix gasmix) { static char gas[64]; get_gas_string(gasmix, gas, sizeof(gas)); return gas; } -bool weightsystem_none(void *_data) +bool weightsystem_none(const weightsystem_t *ws) { - weightsystem_t *ws = _data; return !ws->weight.grams && !ws->description; } -bool no_weightsystems(weightsystem_t *ws) -{ - for (int i = 0; i < MAX_WEIGHTSYSTEMS; i++) - if (!weightsystem_none(ws + i)) - return false; - return true; -} - /* * We hardcode the most common standard cylinders, * we should pick up any other names from the dive @@ -216,7 +206,7 @@ void reset_cylinders(struct dive *dive, bool track_gas) if (cylinder_none(cyl)) continue; if (cyl->depth.mm == 0) /* if the gas doesn't give a mod, calculate based on prefs */ - cyl->depth = gas_mod(&cyl->gasmix, decopo2, dive, M_OR_FT(3,10)); + cyl->depth = gas_mod(cyl->gasmix, decopo2, dive, M_OR_FT(3,10)); if (track_gas) cyl->start.mbar = cyl->end.mbar = cyl->type.workingpressure.mbar; cyl->gas_used.mliter = 0; diff --git a/core/file.c b/core/file.c index 5c12c0a5d..abef20a7d 100644 --- a/core/file.c +++ b/core/file.c @@ -75,7 +75,7 @@ out: } -static void zip_read(struct zip_file *file, const char *filename) +static void zip_read(struct zip_file *file, const char *filename, struct dive_table *table) { int size = 1024, n, read = 0; char *mem = malloc(size); @@ -86,11 +86,11 @@ static void zip_read(struct zip_file *file, const char *filename) mem = realloc(mem, size); } mem[read] = 0; - (void) parse_xml_buffer(filename, mem, read, &dive_table, NULL); + (void) parse_xml_buffer(filename, mem, read, table, NULL); free(mem); } -int try_to_open_zip(const char *filename) +int try_to_open_zip(const char *filename, struct dive_table *table) { int success = 0; /* Grr. libzip needs to re-open the file, it can't take a buffer */ @@ -105,7 +105,7 @@ int try_to_open_zip(const char *filename) /* skip parsing the divelogs.de pictures */ if (strstr(zip_get_name(zip, index, 0), "pictures/")) continue; - zip_read(file, filename); + zip_read(file, filename, table); zip_fclose(file); success++; } @@ -126,7 +126,7 @@ static int db_test_func(void *param, int columns, char **data, char **column) } -static int try_to_open_db(const char *filename, struct memblock *mem) +static int try_to_open_db(const char *filename, struct memblock *mem, struct dive_table *table) { sqlite3 *handle; char dm4_test[] = "select count(*) from sqlite_master where type='table' and name='Dive' and sql like '%ProfileBlob%'"; @@ -146,7 +146,7 @@ static int try_to_open_db(const char *filename, struct memblock *mem) /* Testing if DB schema resembles Suunto DM5 database format */ retval = sqlite3_exec(handle, dm5_test, &db_test_func, 0, NULL); if (!retval) { - retval = parse_dm5_buffer(handle, filename, mem->buffer, mem->size, &dive_table); + retval = parse_dm5_buffer(handle, filename, mem->buffer, mem->size, table); sqlite3_close(handle); return retval; } @@ -154,7 +154,7 @@ static int try_to_open_db(const char *filename, struct memblock *mem) /* Testing if DB schema resembles Suunto DM4 database format */ retval = sqlite3_exec(handle, dm4_test, &db_test_func, 0, NULL); if (!retval) { - retval = parse_dm4_buffer(handle, filename, mem->buffer, mem->size, &dive_table); + retval = parse_dm4_buffer(handle, filename, mem->buffer, mem->size, table); sqlite3_close(handle); return retval; } @@ -162,7 +162,7 @@ static int try_to_open_db(const char *filename, struct memblock *mem) /* Testing if DB schema resembles Shearwater database format */ retval = sqlite3_exec(handle, shearwater_test, &db_test_func, 0, NULL); if (!retval) { - retval = parse_shearwater_buffer(handle, filename, mem->buffer, mem->size, &dive_table); + retval = parse_shearwater_buffer(handle, filename, mem->buffer, mem->size, table); sqlite3_close(handle); return retval; } @@ -170,7 +170,7 @@ static int try_to_open_db(const char *filename, struct memblock *mem) /* Testing if DB schema resembles Atomic Cobalt database format */ retval = sqlite3_exec(handle, cobalt_test, &db_test_func, 0, NULL); if (!retval) { - retval = parse_cobalt_buffer(handle, filename, mem->buffer, mem->size, &dive_table); + retval = parse_cobalt_buffer(handle, filename, mem->buffer, mem->size, table); sqlite3_close(handle); return retval; } @@ -178,7 +178,7 @@ static int try_to_open_db(const char *filename, struct memblock *mem) /* Testing if DB schema resembles Divinglog database format */ retval = sqlite3_exec(handle, divinglog_test, &db_test_func, 0, NULL); if (!retval) { - retval = parse_divinglog_buffer(handle, filename, mem->buffer, mem->size, &dive_table); + retval = parse_divinglog_buffer(handle, filename, mem->buffer, mem->size, table); sqlite3_close(handle); return retval; } @@ -204,7 +204,7 @@ static int try_to_open_db(const char *filename, struct memblock *mem) * * Followed by the data values (all comma-separated, all one long line). */ -static int open_by_filename(const char *filename, const char *fmt, struct memblock *mem) +static int open_by_filename(const char *filename, const char *fmt, struct memblock *mem, struct dive_table *table) { // hack to be able to provide a comment for the translated string static char *csv_warning = QT_TRANSLATE_NOOP3("gettextFromC", @@ -213,7 +213,7 @@ static int open_by_filename(const char *filename, const char *fmt, struct memblo /* Suunto Dive Manager files: SDE, ZIP; divelogs.de files: DLD */ if (!strcasecmp(fmt, "SDE") || !strcasecmp(fmt, "ZIP") || !strcasecmp(fmt, "DLD")) - return try_to_open_zip(filename); + return try_to_open_zip(filename, table); /* CSV files */ if (!strcasecmp(fmt, "CSV")) @@ -234,17 +234,17 @@ static int open_by_filename(const char *filename, const char *fmt, struct memblo return 0; } -static int parse_file_buffer(const char *filename, struct memblock *mem) +static int parse_file_buffer(const char *filename, struct memblock *mem, struct dive_table *table) { int ret; char *fmt = strrchr(filename, '.'); - if (fmt && (ret = open_by_filename(filename, fmt + 1, mem)) != 0) + if (fmt && (ret = open_by_filename(filename, fmt + 1, mem, table)) != 0) return ret; if (!mem->size || !mem->buffer) return report_error("Out of memory parsing file %s\n", filename); - return parse_xml_buffer(filename, mem->buffer, mem->size, &dive_table, NULL); + return parse_xml_buffer(filename, mem->buffer, mem->size, table, NULL); } int check_git_sha(const char *filename, struct git_repository **git_p, const char **branch_p) @@ -281,7 +281,7 @@ int check_git_sha(const char *filename, struct git_repository **git_p, const cha return 1; } -int parse_file(const char *filename) +int parse_file(const char *filename, struct dive_table *table) { struct git_repository *git; const char *branch = NULL; @@ -327,7 +327,7 @@ int parse_file(const char *filename) fmt = strrchr(filename, '.'); if (fmt && (!strcasecmp(fmt + 1, "DB") || !strcasecmp(fmt + 1, "BAK") || !strcasecmp(fmt + 1, "SQL"))) { - if (!try_to_open_db(filename, &mem)) { + if (!try_to_open_db(filename, &mem, table)) { free(mem.buffer); return 0; } @@ -335,27 +335,26 @@ int parse_file(const char *filename) /* Divesoft Freedom */ if (fmt && (!strcasecmp(fmt + 1, "DLF"))) { - if (!parse_dlf_buffer(mem.buffer, mem.size)) { - free(mem.buffer); - return 0; - } - return -1; + ret = parse_dlf_buffer(mem.buffer, mem.size, table); + free(mem.buffer); + return ret; } /* DataTrak/Wlog */ if (fmt && !strcasecmp(fmt + 1, "LOG")) { - ret = datatrak_import(&mem, &dive_table); + ret = datatrak_import(&mem, table); free(mem.buffer); return ret; } /* OSTCtools */ if (fmt && (!strcasecmp(fmt + 1, "DIVE"))) { - ostctools_import(filename, &dive_table); + free(mem.buffer); + ostctools_import(filename, table); return 0; } - ret = parse_file_buffer(filename, &mem); + ret = parse_file_buffer(filename, &mem, table); free(mem.buffer); return ret; } diff --git a/core/file.h b/core/file.h index 9653fbb96..7dbd07b48 100644 --- a/core/file.h +++ b/core/file.h @@ -16,7 +16,7 @@ extern void ostctools_import(const char *file, struct dive_table *table); extern "C" { #endif extern int readfile(const char *filename, struct memblock *mem); -extern int try_to_open_zip(const char *filename); +extern int try_to_open_zip(const char *filename, struct dive_table *table); #ifdef __cplusplus } #endif diff --git a/core/gas-model.c b/core/gas-model.c index 49c677967..7fb9ce111 100644 --- a/core/gas-model.c +++ b/core/gas-model.c @@ -26,7 +26,7 @@ * NOTE! Helium coefficients are a linear mix operation between the * 323K and one for 273K isotherms, to make everything be at 300K. */ -double gas_compressibility_factor(struct gasmix *gas, double bar) +double gas_compressibility_factor(struct gasmix gas, double bar) { static const double o2_coefficients[3] = { -7.18092073703e-04, @@ -69,15 +69,15 @@ double gas_compressibility_factor(struct gasmix *gas, double bar) /* Compute the new pressure when compressing (expanding) volome v1 at pressure p1 bar to volume v2 * taking into account the compressebility (to first order) */ -double isothermal_pressure(struct gasmix *gas, double p1, int volume1, int volume2) +double isothermal_pressure(struct gasmix gas, double p1, int volume1, int volume2) { double p_ideal = p1 * volume1 / volume2 / gas_compressibility_factor(gas, p1); return p_ideal * gas_compressibility_factor(gas, p_ideal); } -inline double gas_density(struct gasmix *gas, int pressure) { - int density = gas->he.permille * HE_DENSITY + gas->o2.permille * O2_DENSITY + (1000 - gas->he.permille - gas->o2.permille) * N2_DENSITY; +inline double gas_density(struct gasmix gas, int pressure) { + int density = gas.he.permille * HE_DENSITY + gas.o2.permille * O2_DENSITY + (1000 - gas.he.permille - gas.o2.permille) * N2_DENSITY; return density * (double) pressure / gas_compressibility_factor(gas, pressure / 1000.0) / SURFACE_PRESSURE / 1000000.0; } diff --git a/core/gaspressures.c b/core/gaspressures.c index 626d617bf..1b191369b 100644 --- a/core/gaspressures.c +++ b/core/gaspressures.c @@ -350,7 +350,7 @@ void populate_pressure_information(struct dive *dive, struct divecomputer *dc, s cylinder_t *cylinder = dive->cylinder + sensor; pr_track_t *track = NULL; pr_track_t *current = NULL; - struct event *ev, *b_ev; + const struct event *ev, *b_ev; int missing_pr = 0, dense = 1; enum divemode_t dmode = dc->divemode; const double gasfactor[5] = {1.0, 0.0, prefs.pscr_ratio/1000.0, 1.0, 1.0 }; diff --git a/core/import-divinglog.c b/core/import-divinglog.c index 4e205d661..3e2f396ba 100644 --- a/core/import-divinglog.c +++ b/core/import-divinglog.c @@ -137,7 +137,7 @@ extern int divinglog_profile(void *handle, int columns, char **data, char **colu cur_sample->pressure[0].mbar = pressure * 100; cur_sample->rbt.seconds = rbt; if (oldcyl != tank) { - struct gasmix *mix = &cur_dive->cylinder[tank].gasmix; + struct gasmix mix = cur_dive->cylinder[tank].gasmix; int o2 = get_o2(mix); int he = get_he(mix); diff --git a/core/parse-xml.c b/core/parse-xml.c index ae779e1f8..1f31d69d7 100644 --- a/core/parse-xml.c +++ b/core/parse-xml.c @@ -652,7 +652,7 @@ void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int second if (idx < 0 || idx >= MAX_CYLINDERS) return; /* The gas switch event format is insane for historical reasons */ - struct gasmix *mix = &dive->cylinder[idx].gasmix; + struct gasmix mix = dive->cylinder[idx].gasmix; int o2 = get_o2(mix); int he = get_he(mix); struct event *ev; @@ -665,7 +665,7 @@ void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int second ev = add_event(dc, seconds, he ? SAMPLE_EVENT_GASCHANGE2 : SAMPLE_EVENT_GASCHANGE, 0, value, "gaschange"); if (ev) { ev->gas.index = idx; - ev->gas.mix = *mix; + ev->gas.mix = mix; } } @@ -1654,7 +1654,7 @@ static timestamp_t parse_dlf_timestamp(unsigned char *buffer) return offset + 946684800; } -int parse_dlf_buffer(unsigned char *buffer, size_t size) +int parse_dlf_buffer(unsigned char *buffer, size_t size, struct dive_table *table) { unsigned char *ptr = buffer; unsigned char event; @@ -1663,7 +1663,7 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size) int i; char serial[6]; - target_table = &dive_table; + target_table = table; // Check for the correct file magic if (ptr[0] != 'D' || ptr[1] != 'i' || ptr[2] != 'v' || ptr[3] != 'E') diff --git a/core/parse.h b/core/parse.h index affffcfb0..2a666ec4d 100644 --- a/core/parse.h +++ b/core/parse.h @@ -59,8 +59,6 @@ extern int diveid; int trimspace(char *buffer); void clear_table(struct dive_table *table); -void record_dive_to_table(struct dive *dive, struct dive_table *table); -void record_dive(struct dive *dive); void start_match(const char *type, const char *name, char *buffer); void nonmatch(const char *type, const char *name, char *buffer); typedef void (*matchfn_t)(char *buffer, void *); diff --git a/core/planner.c b/core/planner.c index eefa94143..1077fb313 100644 --- a/core/planner.c +++ b/core/planner.c @@ -81,22 +81,6 @@ bool diveplan_empty(struct diveplan *diveplan) return true; } -/* get the gas at a certain time during the dive */ -void get_gas_at_time(struct dive *dive, struct divecomputer *dc, duration_t time, struct gasmix *gas) -{ - // we always start with the first gas, so that's our gas - // unless an event tells us otherwise - struct event *event = dc->events; - *gas = dive->cylinder[0].gasmix; - while (event && event->time.seconds <= time.seconds) { - if (!strcmp(event->name, "gaschange")) { - int cylinder_idx = get_cylinder_index(dive, event); - *gas = dive->cylinder[cylinder_idx].gasmix; - } - event = event->next; - } -} - /* 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) { @@ -111,12 +95,12 @@ int get_cylinderid_at_time(struct dive *dive, struct divecomputer *dc, duration_ return cylinder_idx; } -int get_gasidx(struct dive *dive, struct gasmix *mix) +int get_gasidx(struct dive *dive, struct gasmix mix) { return find_best_gasmix_match(mix, dive->cylinder, 0); } -void interpolate_transition(struct deco_state *ds, struct dive *dive, duration_t t0, duration_t t1, depth_t d0, depth_t d1, const struct gasmix *gasmix, o2pressure_t po2, enum divemode_t divemode) +void interpolate_transition(struct deco_state *ds, struct dive *dive, duration_t t0, duration_t t1, depth_t d0, depth_t d1, struct gasmix gasmix, o2pressure_t po2, enum divemode_t divemode) { int32_t j; @@ -152,7 +136,7 @@ int tissue_at_end(struct deco_state *ds, struct dive *dive, struct deco_state ** return 0; psample = sample = dc->sample; - struct event *evdm = NULL; + const struct event *evdm = NULL; enum divemode_t divemode = UNDEF_COMP_TYPE; for (i = 0; i < dc->samples; i++, sample++) { @@ -164,7 +148,7 @@ int tissue_at_end(struct deco_state *ds, struct dive *dive, struct deco_state ** setpoint = sample[0].setpoint; t1 = sample->time; - get_gas_at_time(dive, dc, t0, &gas); + gas = get_gasmix_at_time(dive, dc, t0); if (i > 0) lastdepth = psample->depth; @@ -192,7 +176,7 @@ int tissue_at_end(struct deco_state *ds, struct dive *dive, struct deco_state ** } divemode = get_current_divemode(&dive->dc, t0.seconds + 1, &evdm, &divemode); - interpolate_transition(ds, dive, t0, t1, lastdepth, sample->depth, &gas, setpoint, divemode); + interpolate_transition(ds, dive, t0, t1, lastdepth, sample->depth, gas, setpoint, divemode); psample = sample; t0 = t1; } @@ -227,7 +211,7 @@ void fill_default_cylinder(cylinder_t *cyl) cyl->type.size.mliter = lrint(cuft_to_l(ti->cuft) * 1000 / bar_to_atm(psi_to_bar(ti->psi))); } // MOD of air - cyl->depth = gas_mod(&cyl->gasmix, pO2, &displayed_dive, 1); + cyl->depth = gas_mod(cyl->gasmix, pO2, &displayed_dive, 1); } /* calculate the new end pressure of the cylinder, based on its current end pressure and the @@ -250,7 +234,7 @@ static void update_cylinder_pressure(struct dive *d, int old_depth, int new_dept if (in_deco) cyl->deco_gas_used.mliter += gas_used.mliter; if (cyl->type.size.mliter) { - delta_p.mbar = lrint(gas_used.mliter * 1000.0 / cyl->type.size.mliter * gas_compressibility_factor(&cyl->gasmix, cyl->end.mbar / 1000.0)); + delta_p.mbar = lrint(gas_used.mliter * 1000.0 / cyl->type.size.mliter * gas_compressibility_factor(cyl->gasmix, cyl->end.mbar / 1000.0)); cyl->end.mbar -= delta_p.mbar; } } @@ -566,7 +550,7 @@ void track_ascent_gas(int depth, cylinder_t *cylinder, int avg_depth, int bottom } // Determine whether ascending to the next stop will break the ceiling. Return true if the ascent is ok, false if it isn't. -bool trial_ascent(struct deco_state *ds, int wait_time, int trial_depth, int stoplevel, int avg_depth, int bottom_time, struct gasmix *gasmix, int po2, double surface_pressure, struct dive *dive, enum divemode_t divemode) +bool trial_ascent(struct deco_state *ds, int wait_time, int trial_depth, int stoplevel, int avg_depth, int bottom_time, struct gasmix gasmix, int po2, double surface_pressure, struct dive *dive, enum divemode_t divemode) { bool clear_to_ascend = true; @@ -631,7 +615,7 @@ bool enough_gas(int current_cylinder) * So we always test at the upper bundary, not in the middle! */ -int wait_until(struct deco_state *ds, struct dive *dive, int clock, int min, int leap, int stepsize, int depth, int target_depth, int avg_depth, int bottom_time, struct gasmix *gasmix, int po2, double surface_pressure, enum divemode_t divemode) +int wait_until(struct deco_state *ds, struct dive *dive, int clock, int min, int leap, int stepsize, int depth, int target_depth, int avg_depth, int bottom_time, struct gasmix gasmix, int po2, double surface_pressure, enum divemode_t divemode) { // When a deco stop exceeds two days, there is something wrong... if (min >= 48 * 3600) @@ -732,7 +716,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i current_cylinder = get_cylinderid_at_time(dive, &dive->dc, sample->time); // FIXME: This needs a function to find the divemode at the end of the dive like in - struct event *ev = NULL; + const struct event *ev = NULL; divemode = UNDEF_COMP_TYPE; divemode = get_current_divemode(&dive->dc, bottom_time, &ev, &divemode); gas = dive->cylinder[current_cylinder].gasmix; @@ -790,11 +774,11 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i // How long can we stay at the current depth and still directly ascent to the surface? do { add_segment(ds, depth_to_bar(depth, dive), - &dive->cylinder[current_cylinder].gasmix, + dive->cylinder[current_cylinder].gasmix, timestep, po2, divemode, prefs.bottomsac); update_cylinder_pressure(dive, depth, depth, timestep, prefs.bottomsac, &dive->cylinder[current_cylinder], false, divemode); clock += timestep; - } while (trial_ascent(ds, 0, depth, 0, avg_depth, bottom_time, &dive->cylinder[current_cylinder].gasmix, + } while (trial_ascent(ds, 0, depth, 0, avg_depth, bottom_time, dive->cylinder[current_cylinder].gasmix, po2, diveplan->surface_pressure / 1000.0, dive, divemode) && enough_gas(current_cylinder) && clock < 6 * 3600); @@ -885,12 +869,12 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time); /* Always prefer the best_first_ascend_cylinder if it has the right gasmix. * Otherwise take first cylinder from list with rightgasmix */ - if (same_gasmix(&gas, &dive->cylinder[best_first_ascend_cylinder].gasmix)) + if (same_gasmix(gas, dive->cylinder[best_first_ascend_cylinder].gasmix)) current_cylinder = best_first_ascend_cylinder; else - current_cylinder = get_gasidx(dive, &gas); + current_cylinder = get_gasidx(dive, gas); if (current_cylinder == -1) { - report_error(translate("gettextFromC", "Can't find gas %s"), gasname(&gas)); + report_error(translate("gettextFromC", "Can't find gas %s"), gasname(gas)); current_cylinder = 0; } reset_regression(); @@ -910,7 +894,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i deltad = depth - stoplevels[stopidx]; add_segment(ds, depth_to_bar(depth, dive), - &dive->cylinder[current_cylinder].gasmix, + dive->cylinder[current_cylinder].gasmix, TIMESTEP, po2, divemode, prefs.decosac); last_segment_min_switch = false; clock += TIMESTEP; @@ -939,7 +923,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i if (current_cylinder != gaschanges[gi].gasidx) { if (!prefs.switch_at_req_stop || !trial_ascent(ds, 0, depth, stoplevels[stopidx - 1], avg_depth, bottom_time, - &dive->cylinder[current_cylinder].gasmix, po2, diveplan->surface_pressure / 1000.0, dive, divemode) || get_o2(&dive->cylinder[current_cylinder].gasmix) < 160) { + dive->cylinder[current_cylinder].gasmix, po2, diveplan->surface_pressure / 1000.0, dive, divemode) || get_o2(dive->cylinder[current_cylinder].gasmix) < 160) { current_cylinder = gaschanges[gi].gasidx; gas = dive->cylinder[current_cylinder].gasmix; #if DEBUG_PLAN & 16 @@ -947,9 +931,9 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i (get_o2(&gas) + 5) / 10, (get_he(&gas) + 5) / 10, gaschanges[gi].depth / 1000.0); #endif /* Stop for the minimum duration to switch gas unless we switch to o2 */ - if (!last_segment_min_switch && get_o2(&dive->cylinder[current_cylinder].gasmix) != 1000) { + if (!last_segment_min_switch && get_o2(dive->cylinder[current_cylinder].gasmix) != 1000) { add_segment(ds, depth_to_bar(depth, dive), - &dive->cylinder[current_cylinder].gasmix, + dive->cylinder[current_cylinder].gasmix, prefs.min_switch_duration, po2, divemode, prefs.decosac); clock += prefs.min_switch_duration; last_segment_min_switch = true; @@ -969,7 +953,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i while (1) { /* Check if ascending to next stop is clear, go back and wait if we hit the ceiling on the way */ if (trial_ascent(ds, 0, depth, stoplevels[stopidx], avg_depth, bottom_time, - &dive->cylinder[current_cylinder].gasmix, po2, diveplan->surface_pressure / 1000.0, dive, divemode)) { + dive->cylinder[current_cylinder].gasmix, po2, diveplan->surface_pressure / 1000.0, dive, divemode)) { decostoptable[decostopcounter].depth = depth; decostoptable[decostopcounter].time = 0; decostopcounter++; @@ -1001,9 +985,9 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i (get_o2(&gas) + 5) / 10, (get_he(&gas) + 5) / 10, gaschanges[gi + 1].depth / 1000.0); #endif /* Stop for the minimum duration to switch gas unless we switch to o2 */ - if (!last_segment_min_switch && get_o2(&dive->cylinder[current_cylinder].gasmix) != 1000) { + if (!last_segment_min_switch && get_o2(dive->cylinder[current_cylinder].gasmix) != 1000) { add_segment(ds, depth_to_bar(depth, dive), - &dive->cylinder[current_cylinder].gasmix, + dive->cylinder[current_cylinder].gasmix, prefs.min_switch_duration, po2, divemode, prefs.decosac); clock += prefs.min_switch_duration; last_segment_min_switch = true; @@ -1012,7 +996,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i } int new_clock = wait_until(ds, dive, clock, clock, laststoptime * 2 + 1, timestep, depth, stoplevels[stopidx], avg_depth, - bottom_time, &dive->cylinder[current_cylinder].gasmix, po2, diveplan->surface_pressure / 1000.0, divemode); + bottom_time, dive->cylinder[current_cylinder].gasmix, po2, diveplan->surface_pressure / 1000.0, divemode); laststoptime = new_clock - clock; /* Finish infinite deco */ if (laststoptime >= 48 * 3600 && depth >= 6000) { @@ -1027,12 +1011,12 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i * backgas. This could be customized if there were demand. */ if (break_cylinder == -1) { - if (get_o2(&dive->cylinder[best_first_ascend_cylinder].gasmix) <= 320) + if (get_o2(dive->cylinder[best_first_ascend_cylinder].gasmix) <= 320) break_cylinder = best_first_ascend_cylinder; else break_cylinder = 0; } - if (get_o2(&dive->cylinder[current_cylinder].gasmix) == 1000) { + if (get_o2(dive->cylinder[current_cylinder].gasmix) == 1000) { if (laststoptime >= 12 * 60) { laststoptime = 12 * 60; new_clock = clock + laststoptime; @@ -1059,7 +1043,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i } } } - add_segment(ds, depth_to_bar(depth, dive), &dive->cylinder[stop_cylinder].gasmix, + add_segment(ds, depth_to_bar(depth, dive), dive->cylinder[stop_cylinder].gasmix, laststoptime, po2, divemode, prefs.decosac); last_segment_min_switch = false; decostoptable[decostopcounter].depth = depth; diff --git a/core/planner.h b/core/planner.h index 741f83c02..fb5338c8f 100644 --- a/core/planner.h +++ b/core/planner.h @@ -17,9 +17,8 @@ extern void set_verbatim(bool verbatim); 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 int get_gasidx(struct dive *dive, struct gasmix mix); extern bool diveplan_empty(struct diveplan *diveplan); extern void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_disclaimer, int error); diff --git a/core/plannernotes.c b/core/plannernotes.c index c7d443324..133f9a591 100644 --- a/core/plannernotes.c +++ b/core/plannernotes.c @@ -42,7 +42,7 @@ static int diveplan_duration(struct diveplan *diveplan) * 5) Pointers to gas mixes in the gas change: gas-from and gas-to. * Returns: The size of the output buffer that has been used after the new results have been added. */ -static void add_icd_entry(struct membuffer *b, struct icd_data *icdvalues, bool printheader, int time_seconds, int ambientpressure_mbar, struct gasmix *gas_from, struct gasmix *gas_to) +static void add_icd_entry(struct membuffer *b, struct icd_data *icdvalues, bool printheader, int time_seconds, int ambientpressure_mbar, struct gasmix gas_from, struct gasmix gas_to) { if (printheader) { // Create a table description and a table header if no icd data have been written yet. put_format(b, "<div>%s:", translate("gettextFromC","Isobaric counterdiffusion information")); @@ -179,8 +179,8 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d nextdp = nextdp->next; if (nextdp) newgasmix = dive->cylinder[nextdp->cylinderid].gasmix; - gaschange_after = (nextdp && (gasmix_distance(&gasmix, &newgasmix))); - gaschange_before = (gasmix_distance(&lastprintgasmix, &gasmix)); + gaschange_after = (nextdp && (gasmix_distance(gasmix, newgasmix))); + gaschange_before = (gasmix_distance(lastprintgasmix, gasmix)); rebreatherchange_after = (nextdp && (dp->setpoint != nextdp->setpoint || dp->divemode != nextdp->divemode)); rebreatherchange_before = lastprintsetpoint != dp->setpoint || lastdivemode != dp->divemode; /* do we want to skip this leg as it is devoid of anything useful? */ @@ -215,7 +215,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d decimals, depthvalue, depth_unit, FRACTION(dp->time - lasttime, 60), FRACTION(dp->time, 60), - gasname(&gasmix), + gasname(gasmix), (double) dp->setpoint / 1000.0); } else { put_format_loc(&buf, translate("gettextFromC", "%s to %.*f %s in %d:%02d min - runtime %d:%02u on %s"), @@ -223,7 +223,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d decimals, depthvalue, depth_unit, FRACTION(dp->time - lasttime, 60), FRACTION(dp->time, 60), - gasname(&gasmix)); + gasname(gasmix)); } put_string(&buf, "<br>"); @@ -237,14 +237,14 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d decimals, depthvalue, depth_unit, FRACTION(dp->time - lasttime, 60), FRACTION(dp->time, 60), - gasname(&gasmix), + gasname(gasmix), (double) dp->setpoint / 1000.0); } else { put_format_loc(&buf, translate("gettextFromC", "Stay at %.*f %s for %d:%02d min - runtime %d:%02u on %s %s"), decimals, depthvalue, depth_unit, FRACTION(dp->time - lasttime, 60), FRACTION(dp->time, 60), - gasname(&gasmix), + gasname(gasmix), translate("gettextFromC", divemode_text_ui[dp->divemode])); } put_string(&buf, "<br>"); @@ -308,16 +308,16 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d if (dp->setpoint) { asprintf_loc(&temp, translate("gettextFromC", "(SP = %.1fbar CCR)"), dp->setpoint / 1000.0); put_format(&buf, "<td style='padding-left: 10px; color: red; float: left;'><b>%s %s</b></td>", - gasname(&newgasmix), temp); + gasname(newgasmix), temp); free(temp); } else { put_format(&buf, "<td style='padding-left: 10px; color: red; float: left;'><b>%s %s</b></td>", - gasname(&newgasmix), lastdivemode == UNDEF_COMP_TYPE || lastdivemode == dp->divemode ? "" : translate("gettextFromC", divemode_text_ui[dp->divemode])); - if (isascent && (get_he(&lastprintgasmix) > 0)) { // For a trimix gas change on ascent, save ICD info if previous cylinder had helium - if (isobaric_counterdiffusion(&lastprintgasmix, &newgasmix, &icdvalues)) // Do icd calulations + gasname(newgasmix), lastdivemode == UNDEF_COMP_TYPE || lastdivemode == dp->divemode ? "" : translate("gettextFromC", divemode_text_ui[dp->divemode])); + if (isascent && (get_he(lastprintgasmix) > 0)) { // For a trimix gas change on ascent, save ICD info if previous cylinder had helium + if (isobaric_counterdiffusion(lastprintgasmix, newgasmix, &icdvalues)) // Do icd calulations icdwarning = true; if (icdvalues.dN2 > 0) { // If the gas change involved helium as well as an increase in nitrogen.. - add_icd_entry(&icdbuf, &icdvalues, icdtableheader, dp->time, depth_to_mbar(dp->depth.mm, dive), &lastprintgasmix, &newgasmix); // .. then print calculations to buffer. + add_icd_entry(&icdbuf, &icdvalues, icdtableheader, dp->time, depth_to_mbar(dp->depth.mm, dive), lastprintgasmix, newgasmix); // .. then print calculations to buffer. icdtableheader = false; } } @@ -330,16 +330,16 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d // If a new gas has been used for this segment, now is the time to show it if (dp->setpoint) { asprintf_loc(&temp, translate("gettextFromC", "(SP = %.1fbar CCR)"), (double) dp->setpoint / 1000.0); - put_format(&buf, "<td style='padding-left: 10px; color: red; float: left;'><b>%s %s</b></td>", gasname(&gasmix), temp); + put_format(&buf, "<td style='padding-left: 10px; color: red; float: left;'><b>%s %s</b></td>", gasname(gasmix), temp); free(temp); } else { - put_format(&buf, "<td style='padding-left: 10px; color: red; float: left;'><b>%s %s</b></td>", gasname(&gasmix), + put_format(&buf, "<td style='padding-left: 10px; color: red; float: left;'><b>%s %s</b></td>", gasname(gasmix), lastdivemode == UNDEF_COMP_TYPE || lastdivemode == dp->divemode ? "" : translate("gettextFromC", divemode_text_ui[dp->divemode])); - if (get_he(&lastprintgasmix) > 0) { // For a trimix gas change, save ICD info if previous cylinder had helium - if (isobaric_counterdiffusion(&lastprintgasmix, &gasmix, &icdvalues)) // Do icd calculations + if (get_he(lastprintgasmix) > 0) { // For a trimix gas change, save ICD info if previous cylinder had helium + if (isobaric_counterdiffusion(lastprintgasmix, gasmix, &icdvalues)) // Do icd calculations icdwarning = true; if (icdvalues.dN2 > 0) { // If the gas change involved helium as well as an increase in nitrogen.. - add_icd_entry(&icdbuf, &icdvalues, icdtableheader, lasttime, depth_to_mbar(dp->depth.mm, dive), &lastprintgasmix, &gasmix); // .. then print data to buffer. + add_icd_entry(&icdbuf, &icdvalues, icdtableheader, lasttime, depth_to_mbar(dp->depth.mm, dive), lastprintgasmix, gasmix); // .. then print data to buffer. icdtableheader = false; } } @@ -362,14 +362,14 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d if (plan_verbatim) { if (lastsetpoint >= 0) { if (nextdp && nextdp->setpoint) { - put_format_loc(&buf, translate("gettextFromC", "Switch gas to %s (SP = %.1fbar)"), gasname(&newgasmix), (double) nextdp->setpoint / 1000.0); + put_format_loc(&buf, translate("gettextFromC", "Switch gas to %s (SP = %.1fbar)"), gasname(newgasmix), (double) nextdp->setpoint / 1000.0); } else { - put_format(&buf, translate("gettextFromC", "Switch gas to %s"), gasname(&newgasmix)); - if ((isascent) && (get_he(&lastprintgasmix) > 0)) { // For a trimix gas change on ascent: - if (isobaric_counterdiffusion(&lastprintgasmix, &newgasmix, &icdvalues)) // Do icd calculations + put_format(&buf, translate("gettextFromC", "Switch gas to %s"), gasname(newgasmix)); + if ((isascent) && (get_he(lastprintgasmix) > 0)) { // For a trimix gas change on ascent: + if (isobaric_counterdiffusion(lastprintgasmix, newgasmix, &icdvalues)) // Do icd calculations icdwarning = true; if (icdvalues.dN2 > 0) { // If the gas change involved helium as well as an increase in nitrogen.. - add_icd_entry(&icdbuf, &icdvalues, icdtableheader, dp->time, depth_to_mbar(dp->depth.mm, dive), &lastprintgasmix, &newgasmix); // ... then print data to buffer. + add_icd_entry(&icdbuf, &icdvalues, icdtableheader, dp->time, depth_to_mbar(dp->depth.mm, dive), lastprintgasmix, newgasmix); // ... then print data to buffer. icdtableheader = false; } } @@ -451,8 +451,8 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d volume = get_volume_units(cyl->gas_used.mliter, NULL, &unit); deco_volume = get_volume_units(cyl->deco_gas_used.mliter, NULL, &unit); if (cyl->type.size.mliter) { - int remaining_gas = lrint((double)cyl->end.mbar * cyl->type.size.mliter / 1000.0 / gas_compressibility_factor(&cyl->gasmix, cyl->end.mbar / 1000.0)); - double deco_pressure_mbar = isothermal_pressure(&cyl->gasmix, 1.0, remaining_gas + cyl->deco_gas_used.mliter, + int remaining_gas = lrint((double)cyl->end.mbar * cyl->type.size.mliter / 1000.0 / gas_compressibility_factor(cyl->gasmix, cyl->end.mbar / 1000.0)); + double deco_pressure_mbar = isothermal_pressure(cyl->gasmix, 1.0, remaining_gas + cyl->deco_gas_used.mliter, cyl->type.size.mliter) * 1000 - cyl->end.mbar; deco_pressure = get_pressure_units(lrint(deco_pressure_mbar), &pressure_unit); pressure = get_pressure_units(cyl->start.mbar - cyl->end.mbar, &pressure_unit); @@ -464,7 +464,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d translate("gettextFromC", "Warning:"), translate("gettextFromC", "this is more gas than available in the specified cylinder!")); else - if (cyl->end.mbar / 1000.0 * cyl->type.size.mliter / gas_compressibility_factor(&cyl->gasmix, cyl->end.mbar / 1000.0) + if (cyl->end.mbar / 1000.0 * cyl->type.size.mliter / gas_compressibility_factor(cyl->gasmix, cyl->end.mbar / 1000.0) < cyl->deco_gas_used.mliter) snprintf(warning, sizeof(warning), "<br> — <span style='color: red;'>%s </span> %s", translate("gettextFromC", "Warning:"), @@ -481,7 +481,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d * depth_to_bar(lastbottomdp->depth.mm, dive) + prefs.sacfactor / 100.0 * cyl->deco_gas_used.mliter); /* Calculate minimum gas pressure for cyclinder. */ - lastbottomdp->minimum_gas.mbar = lrint(isothermal_pressure(&cyl->gasmix, 1.0, + lastbottomdp->minimum_gas.mbar = lrint(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); @@ -513,18 +513,18 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d /* Print the gas consumption for every cylinder here to temp buffer. */ if (lrint(volume) > 0) { asprintf_loc(&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); + volume, unit, pressure, pressure_unit, gasname(cyl->gasmix), deco_volume, unit, deco_pressure, pressure_unit); } else { asprintf_loc(&temp, translate("gettextFromC", "%.0f%s/%.0f%s of <span style='color: red;'><b>%s</b></span>"), - volume, unit, pressure, pressure_unit, gasname(&cyl->gasmix)); + volume, unit, pressure, pressure_unit, gasname(cyl->gasmix)); } } else { if (lrint(volume) > 0) { asprintf_loc(&temp, translate("gettextFromC", "%.0f%s of <span style='color: red;'><b>%s</b></span> (%.0f%s during planned ascent)"), - volume, unit, gasname(&cyl->gasmix), deco_volume, unit); + volume, unit, gasname(cyl->gasmix), deco_volume, unit); } else { asprintf_loc(&temp, translate("gettextFromC", "%.0f%s of <span style='color: red;'><b>%s</b></span>"), - volume, unit, gasname(&cyl->gasmix)); + volume, unit, gasname(cyl->gasmix)); } } /* Gas consumption: Now finally print all strings to output */ @@ -551,18 +551,18 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d bool o2warning_exist = false; enum divemode_t current_divemode; double amb; - struct event *evd = NULL; + const struct event *evd = NULL; current_divemode = UNDEF_COMP_TYPE; if (dive->dc.divemode != CCR) { while (dp) { if (dp->time != 0) { struct gas_pressures pressures; - struct gasmix *gasmix = &dive->cylinder[dp->cylinderid].gasmix; + struct gasmix gasmix = dive->cylinder[dp->cylinderid].gasmix; current_divemode = get_current_divemode(&dive->dc, dp->time, &evd, ¤t_divemode); amb = depth_to_atm(dp->depth.mm, dive); - fill_pressures(&pressures, amb, gasmix, (current_divemode == OC) ? 0.0 : amb * gasmix->o2.permille / 1000.0, current_divemode); + fill_pressures(&pressures, amb, gasmix, (current_divemode == OC) ? 0.0 : amb * gasmix.o2.permille / 1000.0, current_divemode); if (pressures.o2 > (dp->entered ? prefs.bottompo2 : prefs.decopo2) / 1000.0) { const char *depth_unit; diff --git a/core/pref.h b/core/pref.h index f317a795c..895006f7e 100644 --- a/core/pref.h +++ b/core/pref.h @@ -44,11 +44,18 @@ enum deco_mode { VPMB }; +enum def_file_behavior { + UNDEFINED_DEFAULT_FILE, + LOCAL_DEFAULT_FILE, + NO_DEFAULT_FILE, + CLOUD_DEFAULT_FILE +}; + typedef struct { bool dont_check_for_updates; bool dont_check_exists; const char *last_version_used; - const char *next_check; + int next_check; } update_manager_prefs_t; typedef struct { @@ -102,7 +109,6 @@ struct preferences { const char *divelist_font; double font_size; bool show_developer; - const char *theme; // ********** Facebook ********** facebook_prefs_t facebook; @@ -115,7 +121,7 @@ struct preferences { int defaultsetpoint; // default setpoint in mbar const char *default_cylinder; const char *default_filename; - short default_file_behavior; + enum def_file_behavior default_file_behavior; int o2consumption; // ml per min int pscr_ratio; // dump ratio times 1000 bool use_default_file; @@ -209,13 +215,6 @@ struct preferences { update_manager_prefs_t update_manager; }; -enum def_file_behavior { - UNDEFINED_DEFAULT_FILE, - LOCAL_DEFAULT_FILE, - NO_DEFAULT_FILE, - CLOUD_DEFAULT_FILE -}; - extern struct preferences prefs, default_prefs, git_prefs; extern const char *system_divelist_default_font; diff --git a/core/prefs-macros.h b/core/prefs-macros.h deleted file mode 100644 index ca5b1c7d9..000000000 --- a/core/prefs-macros.h +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#ifndef PREFSMACROS_H -#define PREFSMACROS_H - -#include "core/qthelper.h" -#include "subsurface-string.h" - -#define SB(V, B) s.setValue(V, (int)(B->isChecked() ? 1 : 0)) - -#define GET_UNIT(name, field, f, t) \ - { \ - v = s.value(QString(name)); \ - if (v.isValid()) \ - prefs.units.field = (v.toInt() == (t)) ? (t) : (f); \ - else \ - prefs.units.field = default_prefs.units.field; \ - } - -#define GET_UNIT3(name, field, f, l, type) \ - { \ - v = s.value(QString(name)); \ - if (v.isValid() && v.toInt() >= (f) && v.toInt() <= (l)) \ - prefs.units.field = (type)v.toInt(); \ - else \ - prefs.units.field = default_prefs.units.field; \ - } - -#define GET_UNIT_BOOL(name, field) \ - { \ - v = s.value(QString(name)); \ - if (v.isValid()) \ - prefs.units.field = v.toBool(); \ - else \ - prefs.units.field = default_prefs.units.field; \ - } - -#define GET_BOOL(name, field) \ - { \ - v = s.value(QString(name)); \ - if (v.isValid()) \ - prefs.field = v.toBool(); \ - else \ - prefs.field = default_prefs.field; \ - } - -#define GET_DOUBLE(name, field) \ - { \ - v = s.value(QString(name)); \ - if (v.isValid()) \ - prefs.field = v.toDouble(); \ - else \ - prefs.field = default_prefs.field; \ - } - -#define GET_INT(name, field) \ - { \ - v = s.value(QString(name)); \ - if (v.isValid()) \ - prefs.field = v.toInt(); \ - else \ - prefs.field = default_prefs.field; \ - } - -#define GET_ENUM(name, type, field) \ - { \ - v = s.value(QString(name)); \ - if (v.isValid()) \ - prefs.field = (enum type)v.toInt(); \ - else \ - prefs.field = default_prefs.field; \ - } - -#define GET_INT_DEF(name, field, defval) \ - { \ - v = s.value(QString(name)); \ - if (v.isValid()) \ - prefs.field = v.toInt(); \ - else \ - prefs.field = defval; \ - } - -#define GET_TXT(name, field) \ - { \ - v = s.value(QString(name)); \ - if (v.isValid()) \ - prefs.field = copy_qstring(v.toString()); \ - else \ - prefs.field = copy_string(default_prefs.field); \ - } - -#define SAVE_OR_REMOVE_SPECIAL(_setting, _default, _compare, _value) \ - { \ - if (_compare != _default) \ - s.setValue(_setting, _value); \ - else \ - s.remove(_setting); \ - } - -#define SAVE_OR_REMOVE(_setting, _default, _value) \ - { \ - if (_value != _default) \ - s.setValue(_setting, _value); \ - else \ - s.remove(_setting); \ - } - -#endif // PREFSMACROS_H - diff --git a/core/profile.c b/core/profile.c index 113f62845..47fc97723 100644 --- a/core/profile.c +++ b/core/profile.c @@ -316,10 +316,10 @@ struct plot_info *analyze_plot_info(struct plot_info *pi) * Some dive computers give cylinder indexes, some * give just the gas mix. */ -int get_cylinder_index(struct dive *dive, struct event *ev) +int get_cylinder_index(const struct dive *dive, const struct event *ev) { int best; - struct gasmix *mix; + struct gasmix mix; if (ev->gas.index >= 0) return ev->gas.index; @@ -337,7 +337,7 @@ int get_cylinder_index(struct dive *dive, struct event *ev) return best < 0 ? 0 : best; } -struct event *get_next_event(struct event *event, const char *name) +struct event *get_next_event_mutable(struct event *event, const char *name) { if (!name || !*name) return NULL; @@ -349,6 +349,11 @@ struct event *get_next_event(struct event *event, const char *name) return event; } +const struct event *get_next_event(const struct event *event, const char *name) +{ + return get_next_event_mutable((struct event *)event, name); +} + static int count_events(struct divecomputer *dc) { int result = 0; @@ -372,13 +377,13 @@ static int set_setpoint(struct plot_info *pi, int i, int setpoint, int end) return i; } -static void check_setpoint_events(struct dive *dive, struct divecomputer *dc, struct plot_info *pi) +static void check_setpoint_events(const struct dive *dive, struct divecomputer *dc, struct plot_info *pi) { UNUSED(dive); int i = 0; pressure_t setpoint; setpoint.mbar = 0; - struct event *ev = get_next_event(dc->events, "SP change"); + const struct event *ev = get_next_event(dc->events, "SP change"); if (!ev) return; @@ -760,14 +765,14 @@ static void fill_sac(struct dive *dive, struct plot_info *pi, int idx, unsigned /* * Create a bitmap of cylinders that match our current gasmix */ -static unsigned int matching_gases(struct dive *dive, struct gasmix *gasmix) +static unsigned int matching_gases(struct dive *dive, struct gasmix gasmix) { int i; unsigned int gases = 0; for (i = 0; i < MAX_CYLINDERS; i++) { cylinder_t *cyl = dive->cylinder + i; - if (same_gasmix(gasmix, &cyl->gasmix)) + if (same_gasmix(gasmix, cyl->gasmix)) gases |= 1 << i; } return gases; @@ -775,14 +780,14 @@ static unsigned int matching_gases(struct dive *dive, struct gasmix *gasmix) static void calculate_sac(struct dive *dive, struct divecomputer *dc, struct plot_info *pi) { - struct gasmix *gasmix = NULL; - struct event *ev = NULL; + struct gasmix gasmix = { 0 }; + const struct event *ev = NULL; unsigned int gases = 0; for (int i = 0; i < pi->nr; i++) { struct plot_data *entry = pi->entry + i; - struct gasmix *newmix = get_gasmix(dive, dc, entry->sec, &ev, gasmix); - if (newmix != gasmix) { + struct gasmix newmix = get_gasmix(dive, dc, entry->sec, &ev, gasmix); + if (!same_gasmix(newmix, gasmix)) { gasmix = newmix; gases = matching_gases(dive, newmix); } @@ -791,7 +796,7 @@ static void calculate_sac(struct dive *dive, struct divecomputer *dc, struct plo } } -static void populate_secondary_sensor_data(struct divecomputer *dc, struct plot_info *pi) +static void populate_secondary_sensor_data(const struct divecomputer *dc, struct plot_info *pi) { UNUSED(dc); UNUSED(pi); @@ -818,14 +823,14 @@ static void add_plot_pressure(struct plot_info *pi, int time, int cyl, pressure_ SENSOR_PRESSURE(entry, cyl) = p.mbar; } -static void setup_gas_sensor_pressure(struct dive *dive, struct divecomputer *dc, struct plot_info *pi) +static void setup_gas_sensor_pressure(const struct dive *dive, const struct divecomputer *dc, struct plot_info *pi) { int prev, i; - struct event *ev; + const struct event *ev; int seen[MAX_CYLINDERS] = { 0, }; unsigned int first[MAX_CYLINDERS] = { 0, }; unsigned int last[MAX_CYLINDERS] = { 0, }; - struct divecomputer *secondary; + const struct divecomputer *secondary; prev = explicit_first_cylinder(dive, dc); seen[prev] = 1; @@ -854,7 +859,7 @@ static void setup_gas_sensor_pressure(struct dive *dive, struct divecomputer *dc // Fill in "seen[]" array - mark cylinders we're not interested // in as negative. for (i = 0; i < MAX_CYLINDERS; i++) { - cylinder_t *cyl = dive->cylinder + i; + const cylinder_t *cyl = dive->cylinder + i; int start = cyl->start.mbar; int end = cyl->end.mbar; @@ -885,7 +890,7 @@ static void setup_gas_sensor_pressure(struct dive *dive, struct divecomputer *dc for (i = 0; i < MAX_CYLINDERS; i++) { if (seen[i] >= 0) { - cylinder_t *cyl = dive->cylinder + i; + const cylinder_t *cyl = dive->cylinder + i; add_plot_pressure(pi, first[i], i, cyl->start); add_plot_pressure(pi, last[i], i, cyl->end); @@ -907,7 +912,7 @@ static void setup_gas_sensor_pressure(struct dive *dive, struct divecomputer *dc #ifndef SUBSURFACE_MOBILE /* calculate DECO STOP / TTS / NDL */ -static void calculate_ndl_tts(struct deco_state *ds, struct dive *dive, struct plot_data *entry, struct gasmix *gasmix, double surface_pressure,enum divemode_t divemode) +static void calculate_ndl_tts(struct deco_state *ds, const struct dive *dive, struct plot_data *entry, struct gasmix gasmix, double surface_pressure,enum divemode_t divemode) { /* FIXME: This should be configurable */ /* ascent speed up to first deco stop */ @@ -990,7 +995,7 @@ static void calculate_ndl_tts(struct deco_state *ds, struct dive *dive, struct p /* Let's try to do some deco calculations. */ -void calculate_deco_information(struct deco_state *ds, struct deco_state *planner_ds, struct dive *dive, struct divecomputer *dc, struct plot_info *pi, bool print_mode) +void calculate_deco_information(struct deco_state *ds, const struct deco_state *planner_ds, const struct dive *dive, const struct divecomputer *dc, struct plot_info *pi, bool print_mode) { int i, count_iteration = 0; double surface_pressure = (dc->surface_pressure.mbar ? dc->surface_pressure.mbar : get_surface_pressure_in_mbar(dive, true)) / 1000.0; @@ -1016,8 +1021,8 @@ void calculate_deco_information(struct deco_state *ds, struct deco_state *planne int last_ndl_tts_calc_time = 0, first_ceiling = 0, current_ceiling, last_ceiling = 0, final_tts = 0 , time_clear_ceiling = 0; if (decoMode() == VPMB) ds->first_ceiling_pressure.mbar = depth_to_mbar(first_ceiling, dive); - struct gasmix *gasmix = NULL; - struct event *ev = NULL, *evd = NULL; + struct gasmix gasmix = { 0 }; + const struct event *ev = NULL, *evd = NULL; enum divemode_t current_divemode = UNDEF_COMP_TYPE; for (i = 1; i < pi->nr; i++) { @@ -1205,8 +1210,8 @@ static void calculate_gas_information_new(struct dive *dive, struct divecomputer { int i; double amb_pressure; - struct gasmix *gasmix = NULL; - struct event *evg = NULL, *evd = NULL; + struct gasmix gasmix = { 0 }; + const struct event *evg = NULL, *evd = NULL; enum divemode_t current_divemode = UNDEF_COMP_TYPE; for (i = 1; i < pi->nr; i++) { @@ -1219,8 +1224,10 @@ static void calculate_gas_information_new(struct dive *dive, struct divecomputer fill_pressures(&entry->pressures, amb_pressure, gasmix, (current_divemode == OC) ? 0.0 : entry->o2pressure.mbar / 1000.0, current_divemode); fn2 = (int)(1000.0 * entry->pressures.n2 / amb_pressure); fhe = (int)(1000.0 * entry->pressures.he / amb_pressure); - if (dc->divemode == PSCR) // OC pO2 is calulated for PSCR with or without external PO2 monitoring. - entry->scr_OC_pO2.mbar = (int) depth_to_mbar(entry->depth, dive) * get_o2(get_gasmix(dive, dc, entry->sec, &evg, gasmix)) / 1000; + if (dc->divemode == PSCR) { // OC pO2 is calulated for PSCR with or without external PO2 monitoring. + struct gasmix gasmix2 = get_gasmix(dive, dc, entry->sec, &evg, gasmix); + entry->scr_OC_pO2.mbar = (int) depth_to_mbar(entry->depth, dive) * get_o2(gasmix2) / 1000; + } /* Calculate MOD, EAD, END and EADD based on partial pressures calculated before * so there is no difference in calculating between OC and CC @@ -1385,11 +1392,10 @@ static void plot_string(struct plot_info *pi, struct plot_data *entry, struct me depthvalue = get_depth_units(entry->depth, NULL, &depth_unit); put_format_loc(b, translate("gettextFromC", "@: %d:%02d\nD: %.1f%s\n"), FRACTION(entry->sec, 60), depthvalue, depth_unit); for (cyl = 0; cyl < MAX_CYLINDERS; cyl++) { - struct gasmix *mix; int mbar = GET_PRESSURE(entry, cyl); if (!mbar) continue; - mix = &displayed_dive.cylinder[cyl].gasmix; + struct gasmix mix = displayed_dive.cylinder[cyl].gasmix; pressurevalue = get_pressure_units(mbar, &pressure_unit); put_format_loc(b, translate("gettextFromC", "P: %d%s (%s)\n"), pressurevalue, pressure_unit, gasname(mix)); } diff --git a/core/profile.h b/core/profile.h index 58c44d955..9e714a806 100644 --- a/core/profile.h +++ b/core/profile.h @@ -77,7 +77,7 @@ void compare_samples(struct plot_data *e1, struct plot_data *e2, char *buf, int struct plot_data *populate_plot_entries(struct dive *dive, struct divecomputer *dc, struct plot_info *pi); struct plot_info *analyze_plot_info(struct plot_info *pi); void create_plot_info_new(struct dive *dive, struct divecomputer *dc, struct plot_info *pi, bool fast, struct deco_state *planner_ds); -void calculate_deco_information(struct deco_state *ds, struct deco_state *planner_de, struct dive *dive, struct divecomputer *dc, struct plot_info *pi, bool print_mode); +void calculate_deco_information(struct deco_state *ds, const struct deco_state *planner_de, const struct dive *dive, const struct divecomputer *dc, struct plot_info *pi, bool print_mode); struct plot_data *get_plot_details_new(struct plot_info *pi, int time, struct membuffer *); /* diff --git a/core/qt-init.cpp b/core/qt-init.cpp index 5596b3f95..b2d178e8e 100644 --- a/core/qt-init.cpp +++ b/core/qt-init.cpp @@ -5,7 +5,7 @@ #include <QLibraryInfo> #include <QTextCodec> #include "qthelper.h" -#include "core/subsurface-qt/SettingsObjectWrapper.h" +#include "core/settings/qPref.h" char *settings_suffix = NULL; static QTranslator *qtTranslator, *ssrfTranslator; @@ -49,7 +49,7 @@ void init_qt_late() QCoreApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton); #endif // find plugins installed in the application directory (without this SVGs don't work on Windows) - SettingsObjectWrapper::instance()->load(); + qPref::load(); QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath()); QLocale loc; diff --git a/core/qthelper.cpp b/core/qthelper.cpp index fd9a8212b..fd7934885 100644 --- a/core/qthelper.cpp +++ b/core/qthelper.cpp @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "qthelper.h" +#include "core/settings/qPrefLanguage.h" +#include "core/settings/qPrefUpdateManager.h" #include "subsurface-string.h" #include "subsurface-string.h" #include "gettextfromc.h" @@ -15,12 +17,10 @@ #include "exif.h" #include "file.h" #include "imagedownloader.h" -#include "prefs-macros.h" #include <QFile> #include <QRegExp> #include <QDir> #include <QDebug> -#include <QSettings> #include <QStandardPaths> #include <QJsonDocument> #include <QNetworkReply> @@ -400,7 +400,7 @@ void selectedDivesGasUsed(QVector<QPair<QString, int> > &gasUsedOrdered) get_gas_used(d, diveGases); for (j = 0; j < MAX_CYLINDERS; j++) if (diveGases[j].mliter) { - QString gasName = gasname(&d->cylinder[j].gasmix); + QString gasName = gasname(d->cylinder[j].gasmix); gasUsed[gasName] += diveGases[j].mliter; } } @@ -445,16 +445,20 @@ QString uiLanguage(QLocale *callerLoc) QString shortDateFormat; QString dateFormat; QString timeFormat; - QSettings s; - QVariant v; - s.beginGroup("Language"); - GET_BOOL("UseSystemLanguage", locale.use_system_language); - if (!prefs.locale.use_system_language) { - loc = QLocale(s.value("UiLangLocale", QLocale().uiLanguages().first()).toString()); + // Language settings are already loaded, see qPref::load() + // so no need to reload them + + // remark this method used "useSystemLanguage", which is not set + // instead use_system_language is loaded from disk + + // set loc as system language or selected language + if (!qPrefLanguage::use_system_language()) { + loc = QLocale(qPrefLanguage::lang_locale()); } else { loc = QLocale(QLocale().uiLanguages().first()); } + QStringList languages = loc.uiLanguages(); QString uiLang; if (languages[0].contains('-')) @@ -465,13 +469,8 @@ QString uiLanguage(QLocale *callerLoc) uiLang = languages[2]; else uiLang = languages[0]; + prefs.locale.lang_locale = copy_qstring(uiLang); - GET_BOOL("time_format_override", time_format_override); - GET_BOOL("date_format_override", date_format_override); - GET_TXT("time_format", time_format); - GET_TXT("date_format", date_format); - GET_TXT("date_format_short", date_format_short); - s.endGroup(); // there's a stupid Qt bug on MacOS where uiLanguages doesn't give us the country info if (!uiLang.contains('-') && uiLang != loc.bcp47Name()) { @@ -1228,8 +1227,8 @@ extern "C" char *picturedir_string() QString get_gas_string(struct gasmix gas) { - uint o2 = (get_o2(&gas) + 5) / 10, he = (get_he(&gas) + 5) / 10; - QString result = gasmix_is_air(&gas) ? gettextFromC::tr("AIR") : he == 0 ? (o2 == 100 ? gettextFromC::tr("OXYGEN") : QString("EAN%1").arg(o2, 2, 10, QChar('0'))) : QString("%1/%2").arg(o2).arg(he); + uint o2 = (get_o2(gas) + 5) / 10, he = (get_he(gas) + 5) / 10; + QString result = gasmix_is_air(gas) ? gettextFromC::tr("AIR") : he == 0 ? (o2 == 100 ? gettextFromC::tr("OXYGEN") : QString("EAN%1").arg(o2, 2, 10, QChar('0'))) : QString("%1/%2").arg(o2).arg(he); return result; } @@ -1455,19 +1454,12 @@ void init_proxy() QString getUUID() { - // This is a correct usage of QSettings, - // it's not a setting per se - the user cannot change it - // and thus, don't need to be on the prefs structure - // and this is the *only* point of access from it, QString uuidString; - QSettings settings; - settings.beginGroup("UpdateManager"); - if (settings.contains("UUID")) { - uuidString = settings.value("UUID").toString(); - } else { + uuidString = qPrefUpdateManager::uuidString(); + if (uuidString != "") { QUuid uuid = QUuid::createUuid(); uuidString = uuid.toString(); - settings.setValue("UUID", uuidString); + qPrefUpdateManager::set_uuidString(uuidString); } uuidString.replace("{", "").replace("}", ""); return uuidString; diff --git a/core/save-git.c b/core/save-git.c index fcfbd93d1..2824b22ca 100644 --- a/core/save-git.c +++ b/core/save-git.c @@ -126,10 +126,10 @@ static void save_extra_data(struct membuffer *b, struct extra_data *ed) } } -static void put_gasmix(struct membuffer *b, struct gasmix *mix) +static void put_gasmix(struct membuffer *b, struct gasmix mix) { - int o2 = mix->o2.permille; - int he = mix->he.permille; + int o2 = mix.o2.permille; + int he = mix.he.permille; if (o2) { put_format(b, " o2=%u.%u%%", FRACTION(o2, 10)); @@ -154,7 +154,7 @@ static void save_cylinder_info(struct membuffer *b, struct dive *dive) put_pressure(b, cylinder->type.workingpressure, " workpressure=", "bar"); show_utf8(b, " description=", description, ""); strip_mb(b); - put_gasmix(b, &cylinder->gasmix); + put_gasmix(b, cylinder->gasmix); put_pressure(b, cylinder->start, " start=", "bar"); put_pressure(b, cylinder->end, " end=", "bar"); if (cylinder->cylinder_use != OC_GAS) @@ -382,7 +382,7 @@ static void save_one_event(struct membuffer *b, struct dive *dive, struct event show_index(b, ev->value, "value=", ""); show_utf8(b, " name=", ev->name, ""); if (event_is_gaschange(ev)) { - struct gasmix *mix = get_gasmix_from_event(dive, ev); + struct gasmix mix = get_gasmix_from_event(dive, ev); if (ev->gas.index >= 0) show_integer(b, ev->gas.index, "cylinder=", ""); put_gasmix(b, mix); diff --git a/core/save-html.c b/core/save-html.c index 2081b2eab..38f48e8c4 100644 --- a/core/save-html.c +++ b/core/save-html.c @@ -30,7 +30,9 @@ void save_photos(struct membuffer *b, const char *photos_dir, struct dive *dive) put_string(b, separator); separator = ", "; char *fname = get_file_name(local_file_path(pic)); - put_format(b, "{\"filename\":\"%s\"}", fname); + put_string(b, "{\"filename\":\""); + put_quoted(b, fname, 1, 0); + put_string(b, "\"}"); copy_image_and_overwrite(local_file_path(pic), photos_dir, fname); free(fname); pic = pic->next; @@ -79,7 +81,9 @@ void put_HTML_bookmarks(struct membuffer *b, struct dive *dive) do { put_string(b, separator); separator = ", "; - put_format(b, "{\"name\":\"%s\",", ev->name); + put_string(b, "{\"name\":\""); + put_quoted(b, ev->name, 1, 0); + put_string(b, "\","); put_format(b, "\"value\":\"%d\",", ev->value); put_format(b, "\"type\":\"%d\",", ev->type); put_format(b, "\"time\":\"%d\"}", ev->time.seconds); @@ -413,7 +417,7 @@ void write_trip(struct membuffer *b, dive_trip_t *trip, int *dive_no, bool selec found_sel_dive = 1; put_format(b, "%c {", *sep); (*sep) = ','; - put_format(b, "\"name\":\"%s\",", trip->location); + write_attribute(b, "name", trip->location, ", "); put_format(b, "\"dives\":["); } put_string(b, separator); diff --git a/core/save-xml.c b/core/save-xml.c index e3af000a4..fea2b1430 100644 --- a/core/save-xml.c +++ b/core/save-xml.c @@ -127,10 +127,10 @@ static void save_overview(struct membuffer *b, struct dive *dive) show_utf8(b, dive->suit, " <suit>", "</suit>\n", 0); } -static void put_gasmix(struct membuffer *b, struct gasmix *mix) +static void put_gasmix(struct membuffer *b, struct gasmix mix) { - int o2 = mix->o2.permille; - int he = mix->he.permille; + int o2 = mix.o2.permille; + int he = mix.he.permille; if (o2) { put_format(b, " o2='%u.%u%%'", FRACTION(o2, 10)); @@ -155,7 +155,7 @@ static void save_cylinder_info(struct membuffer *b, struct dive *dive) put_milli(b, " size='", volume, " l'"); put_pressure(b, cylinder->type.workingpressure, " workpressure='", " bar'"); show_utf8(b, description, " description='", "'", 1); - put_gasmix(b, &cylinder->gasmix); + put_gasmix(b, cylinder->gasmix); put_pressure(b, cylinder->start, " start='", " bar'"); put_pressure(b, cylinder->end, " end='", " bar'"); if (cylinder->cylinder_use != OC_GAS) @@ -307,7 +307,7 @@ static void save_one_event(struct membuffer *b, struct dive *dive, struct event show_index(b, ev->value, "value='", "'"); show_utf8(b, ev->name, " name='", "'", 1); if (event_is_gaschange(ev)) { - struct gasmix *mix = get_gasmix_from_event(dive, ev); + struct gasmix mix = get_gasmix_from_event(dive, ev); if (ev->gas.index >= 0) show_integer(b, ev->gas.index, "cylinder='", "'"); put_gasmix(b, mix); diff --git a/core/serial_ftdi.c b/core/serial_ftdi.c index d6c97f577..86d27c9ff 100644 --- a/core/serial_ftdi.c +++ b/core/serial_ftdi.c @@ -127,11 +127,11 @@ static int serial_ftdi_open_device (struct ftdi_context *ftdi_ctx) { INFO(0, "serial_ftdi_open_device called"); int accepted_pids[] = { - 24577, 24592, 24593, // 0x6001, 0x6010, 0x6011x - Suunto (Smart Interface), Heinrichs Weikamp - 24597, // 0x6015 - possibly Aqualung - 62560, // 0xF460, Oceanic - 63104, // 0xF680, Suunto - 34768, // 0x87D0, Cressi (Leonardo) + 0x6001, 0x6010, 0x6011, // Suunto (Smart Interface), Heinrichs Weikamp + 0x6015, // possibly Aqualung + 0xF460, // Oceanic + 0xF680, // Suunto + 0x87D0, // Cressi (Leonardo) }; int num_accepted_pids = 6; int i, pid, ret; diff --git a/core/settings/qPref.cpp b/core/settings/qPref.cpp index 90aaa8fea..90aedd925 100644 --- a/core/settings/qPref.cpp +++ b/core/settings/qPref.cpp @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "qPref.h" #include "qPrefPrivate.h" -#include "ssrf-version.h" qPref::qPref(QObject *parent) : QObject(parent) { @@ -14,25 +13,21 @@ qPref *qPref::instance() void qPref::loadSync(bool doSync) { - qPrefAnimations::instance()->loadSync(doSync); + if (!doSync) + uiLanguage(NULL); + qPrefCloudStorage::instance()->loadSync(doSync); qPrefDisplay::instance()->loadSync(doSync); qPrefDiveComputer::instance()->loadSync(doSync); qPrefDivePlanner::instance()->loadSync(doSync); // qPrefFaceook does not use disk. + qPrefGeneral::instance()->loadSync(doSync); + qPrefGeocoding::instance()->loadSync(doSync); + qPrefLanguage::instance()->loadSync(doSync); qPrefLocationService::instance()->loadSync(doSync); + qPrefPartialPressureGas::instance()->loadSync(doSync); qPrefProxy::instance()->loadSync(doSync); qPrefTechnicalDetails::instance()->loadSync(doSync); qPrefUnits::instance()->loadSync(doSync); qPrefUpdateManager::instance()->loadSync(doSync); } - -const QString qPref::canonical_version() const -{ - return QString(CANONICAL_VERSION_STRING); -} - -const QString qPref::mobile_version() const -{ - return QString(MOBILE_VERSION_STRING); -} diff --git a/core/settings/qPref.h b/core/settings/qPref.h index 89e0b0951..036b3c6b2 100644 --- a/core/settings/qPref.h +++ b/core/settings/qPref.h @@ -1,17 +1,21 @@ // SPDX-License-Identifier: GPL-2.0 #ifndef QPREF_H #define QPREF_H - #include "core/pref.h" +#include "ssrf-version.h" + #include <QObject> -#include "qPrefAnimations.h" #include "qPrefCloudStorage.h" #include "qPrefDisplay.h" #include "qPrefDiveComputer.h" #include "qPrefDivePlanner.h" #include "qPrefFacebook.h" +#include "qPrefGeneral.h" +#include "qPrefGeocoding.h" +#include "qPrefLanguage.h" #include "qPrefLocationService.h" +#include "qPrefPartialPressureGas.h" #include "qPrefProxy.h" #include "qPrefTechnicalDetails.h" #include "qPrefUnit.h" @@ -28,9 +32,8 @@ public: static qPref *instance(); // Load/Sync local settings (disk) and struct preference - void loadSync(bool doSync); - void load() { loadSync(false); } - void sync() { loadSync(true); } + static void load() { loadSync(false); } + static void sync() { loadSync(true); } public: enum cloud_status { @@ -41,8 +44,11 @@ public: CS_NOCLOUD }; - const QString canonical_version() const; - const QString mobile_version() const; + static const QString canonical_version() { return QString(CANONICAL_VERSION_STRING); } + static const QString mobile_version() { return QString(MOBILE_VERSION_STRING); } + +private: + static void loadSync(bool doSync); }; #endif diff --git a/core/settings/qPrefAnimations.cpp b/core/settings/qPrefAnimations.cpp deleted file mode 100644 index 9be8900c5..000000000 --- a/core/settings/qPrefAnimations.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "qPref.h" -#include "qPrefPrivate.h" - -static const QString group = QStringLiteral("Animations"); - -qPrefAnimations::qPrefAnimations(QObject *parent) : QObject(parent) -{ -} -qPrefAnimations *qPrefAnimations::instance() -{ - static qPrefAnimations *self = new qPrefAnimations; - return self; -} - -void qPrefAnimations::loadSync(bool doSync) -{ - disk_animation_speed(doSync); -} - -HANDLE_PREFERENCE_INT(Animations, "/animation_speed", animation_speed); diff --git a/core/settings/qPrefAnimations.h b/core/settings/qPrefAnimations.h deleted file mode 100644 index c24a6590e..000000000 --- a/core/settings/qPrefAnimations.h +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#ifndef QPREFANIMATIONS_H -#define QPREFANIMATIONS_H -#include "core/pref.h" - -#include <QObject> - -class qPrefAnimations : public QObject { - Q_OBJECT - Q_PROPERTY(int animation_speed READ animation_speed WRITE set_animation_speed NOTIFY animation_speed_changed); - -public: - qPrefAnimations(QObject *parent = NULL); - static qPrefAnimations *instance(); - - // Load/Sync local settings (disk) and struct preference - void loadSync(bool doSync); - void load() { loadSync(false); } - void sync() { loadSync(true); } - -public: - static int animation_speed() { return prefs.animation_speed; } - -public slots: - void set_animation_speed(int value); - -signals: - void animation_speed_changed(int value); - -private: - // functions to load/sync variable with disk - void disk_animation_speed(bool doSync); -}; - -#endif diff --git a/core/settings/qPrefCloudStorage.cpp b/core/settings/qPrefCloudStorage.cpp index c3e9c60a7..9392a24c0 100644 --- a/core/settings/qPrefCloudStorage.cpp +++ b/core/settings/qPrefCloudStorage.cpp @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -#include "qPref.h" +#include "qPrefCloudStorage.h" #include "qPrefPrivate.h" static const QString group = QStringLiteral("CloudStorage"); @@ -7,7 +7,6 @@ static const QString group = QStringLiteral("CloudStorage"); qPrefCloudStorage::qPrefCloudStorage(QObject *parent) : QObject(parent) { } - qPrefCloudStorage *qPrefCloudStorage::instance() { static qPrefCloudStorage *self = new qPrefCloudStorage; @@ -40,15 +39,15 @@ void qPrefCloudStorage::set_cloud_base_url(const QString &value) } disk_cloud_base_url(true); - emit cloud_base_url_changed(value); + emit instance()->cloud_base_url_changed(value); } } void qPrefCloudStorage::disk_cloud_base_url(bool doSync) { if (doSync) { - qPrefPrivate::instance()->setting.setValue(group + "/cloud_base_url", prefs.cloud_base_url); + qPrefPrivate::propSetValue(group + "/cloud_base_url", prefs.cloud_base_url); } else { - prefs.cloud_base_url = copy_qstring(qPrefPrivate::instance()->setting.value(group + "/cloud_base_url", default_prefs.cloud_base_url).toString()); + prefs.cloud_base_url = copy_qstring(qPrefPrivate::propValue(group + "/cloud_base_url", default_prefs.cloud_base_url).toString()); qPrefPrivate::copy_txt(&prefs.cloud_git_url, QString(prefs.cloud_base_url) + "/git"); } } @@ -65,7 +64,7 @@ void qPrefCloudStorage::set_cloud_storage_newpassword(const QString &value) qPrefPrivate::copy_txt(&prefs.cloud_storage_newpassword, value); // NOT saved on disk, because it is only temporary - emit cloud_storage_newpassword_changed(value); + emit instance()->cloud_storage_newpassword_changed(value); } void qPrefCloudStorage::set_cloud_storage_password(const QString &value) @@ -73,16 +72,16 @@ void qPrefCloudStorage::set_cloud_storage_password(const QString &value) if (value != prefs.cloud_storage_password) { qPrefPrivate::copy_txt(&prefs.cloud_storage_password, value); disk_cloud_storage_password(true); - emit cloud_storage_password_changed(value); + emit instance()->cloud_storage_password_changed(value); } } void qPrefCloudStorage::disk_cloud_storage_password(bool doSync) { if (doSync) { if (prefs.save_password_local) - qPrefPrivate::instance()->setting.setValue(group + "/password", prefs.cloud_storage_password); + qPrefPrivate::propSetValue(group + "/password", prefs.cloud_storage_password); } else { - prefs.cloud_storage_password = copy_qstring(qPrefPrivate::instance()->setting.value(group + "/password", default_prefs.cloud_storage_password).toString()); + prefs.cloud_storage_password = copy_qstring(qPrefPrivate::propValue(group + "/password", default_prefs.cloud_storage_password).toString()); } } @@ -103,14 +102,23 @@ void qPrefCloudStorage::disk_userid(bool doSync) { if (doSync) { // always save in new position (part of cloud storage group) - qPrefPrivate::instance()->setting.setValue(group + "subsurface_webservice_uid", prefs.userid); + qPrefPrivate::propSetValue(group + "subsurface_webservice_uid", prefs.userid); } else { //WARNING: UserId was stored outside of any group. // try to read from new location, if it fails read from old location - prefs.userid = copy_qstring(qPrefPrivate::instance()->setting.value(group + "subsurface_webservice_uid", "NoUserIdHere").toString()); + prefs.userid = copy_qstring(qPrefPrivate::propValue(group + "subsurface_webservice_uid", "NoUserIdHere").toString()); if (QString(prefs.userid) == "NoUserIdHere") { const QString group = QStringLiteral(""); - prefs.userid = copy_qstring(qPrefPrivate::instance()->setting.value(group + "subsurface_webservice_uid", default_prefs.userid).toString()); + prefs.userid = copy_qstring(qPrefPrivate::propValue(group + "subsurface_webservice_uid", default_prefs.userid).toString()); } } } + +bool qPrefCloudStorage::loadFromCloud(const QString& email) +{ + return qPrefPrivate::propValue(QString("loadFromCloud") + email, false).toBool(); +} +void qPrefCloudStorage::set_loadFromCloud(const QString& email, bool done) +{ + qPrefPrivate::propSetValue(QString("loadFromCloud") + email, done); +} diff --git a/core/settings/qPrefCloudStorage.h b/core/settings/qPrefCloudStorage.h index 6f32aef95..4684399a0 100644 --- a/core/settings/qPrefCloudStorage.h +++ b/core/settings/qPrefCloudStorage.h @@ -26,9 +26,9 @@ public: static qPrefCloudStorage *instance(); // Load/Sync local settings (disk) and struct preference - void loadSync(bool doSync); - void load() { loadSync(false); } - void sync() { loadSync(true); } + static void loadSync(bool doSync); + static void load() { loadSync(false); } + static void sync() { loadSync(true); } public: static QString cloud_base_url() { return prefs.cloud_base_url; } @@ -45,19 +45,23 @@ public: static bool save_userid_local() { return prefs.save_userid_local; } static QString userid() { return prefs.userid; } + static bool loadFromCloud(const QString& email); + public slots: - void set_cloud_base_url(const QString &value); - void set_cloud_storage_email(const QString &value); - void set_cloud_storage_email_encoded(const QString &value); - void set_cloud_storage_newpassword(const QString &value); - void set_cloud_storage_password(const QString &value); - void set_cloud_storage_pin(const QString &value); - void set_cloud_timeout(int value); - void set_cloud_verification_status(int value); - void set_git_local_only(bool value); - void set_save_password_local(bool value); - void set_save_userid_local(bool value); - void set_userid(const QString &value); + static void set_cloud_base_url(const QString &value); + static void set_cloud_storage_email(const QString &value); + static void set_cloud_storage_email_encoded(const QString &value); + static void set_cloud_storage_newpassword(const QString &value); + static void set_cloud_storage_password(const QString &value); + static void set_cloud_storage_pin(const QString &value); + static void set_cloud_timeout(int value); + static void set_cloud_verification_status(int value); + static void set_git_local_only(bool value); + static void set_save_password_local(bool value); + static void set_save_userid_local(bool value); + static void set_userid(const QString &value); + + static void set_loadFromCloud(const QString& email, bool done); signals: void cloud_base_url_changed(const QString &value); @@ -75,18 +79,18 @@ signals: private: // functions to load/sync variable with disk - void disk_cloud_base_url(bool doSync); - void disk_cloud_storage_email(bool doSync); - void disk_cloud_storage_email_encoded(bool doSync); - void disk_cloud_storage_newpassword(bool doSync); - void disk_cloud_storage_password(bool doSync); - void disk_cloud_storage_pin(bool doSync); - void disk_cloud_timeout(bool doSync); - void disk_cloud_verification_status(bool doSync); - void disk_git_local_only(bool doSync); - void disk_save_password_local(bool doSync); - void disk_save_userid_local(bool doSync); - void disk_userid(bool doSync); + static void disk_cloud_base_url(bool doSync); + static void disk_cloud_storage_email(bool doSync); + static void disk_cloud_storage_email_encoded(bool doSync); + static void disk_cloud_storage_newpassword(bool doSync); + static void disk_cloud_storage_password(bool doSync); + static void disk_cloud_storage_pin(bool doSync); + static void disk_cloud_timeout(bool doSync); + static void disk_cloud_verification_status(bool doSync); + static void disk_git_local_only(bool doSync); + static void disk_save_password_local(bool doSync); + static void disk_save_userid_local(bool doSync); + static void disk_userid(bool doSync); }; #endif diff --git a/core/settings/qPrefDisplay.cpp b/core/settings/qPrefDisplay.cpp index 809a4fe77..680fdc923 100644 --- a/core/settings/qPrefDisplay.cpp +++ b/core/settings/qPrefDisplay.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "core/subsurface-string.h" -#include "qPref.h" +#include "qPrefDisplay.h" #include "qPrefPrivate.h" #include <QApplication> @@ -8,6 +8,39 @@ static const QString group = QStringLiteral("Display"); +QPointF qPrefDisplay::st_tooltip_position; +static const QPointF st_tooltip_position_default = QPointF(0,0); + +QString qPrefDisplay::st_lastDir; +static const QString st_lastDir_default = ""; + +QString qPrefDisplay::st_theme; +static const QString st_theme_default = "Blue"; + +QString qPrefDisplay::st_UserSurvey; +static const QString st_UserSurvey_default = ""; + +QByteArray qPrefDisplay::st_mainSplitter; +static const QByteArray st_mainSplitter_default = ""; + +QByteArray qPrefDisplay::st_topSplitter; +static const QByteArray st_topSplitter_default = ""; + +QByteArray qPrefDisplay::st_bottomSplitter; +static const QByteArray st_bottomSplitter_default = ""; + +bool qPrefDisplay::st_maximized; +static bool st_maximized_default = false; + +QByteArray qPrefDisplay::st_geometry; +static const QByteArray st_geometry_default = 0; + +QByteArray qPrefDisplay::st_windowState; +static const QByteArray st_windowState_default = 0; + +int qPrefDisplay::st_lastState; +static int st_lastState_default = false; + qPrefDisplay::qPrefDisplay(QObject *parent) : QObject(parent) { } @@ -19,11 +52,16 @@ qPrefDisplay *qPrefDisplay::instance() void qPrefDisplay::loadSync(bool doSync) { + disk_animation_speed(doSync); disk_divelist_font(doSync); disk_font_size(doSync); disk_display_invalid_dives(doSync); disk_show_developer(doSync); - disk_theme(doSync); + if (!doSync) { + load_tooltip_position(); + load_theme(); + load_UserSurvey(); + } } void qPrefDisplay::set_divelist_font(const QString &value) @@ -38,13 +76,13 @@ void qPrefDisplay::set_divelist_font(const QString &value) disk_divelist_font(true); qApp->setFont(QFont(newValue)); - emit divelist_font_changed(value); + emit instance()->divelist_font_changed(value); } } void qPrefDisplay::disk_divelist_font(bool doSync) { if (doSync) - qPrefPrivate::instance()->setting.setValue(group + "/divelist_font", prefs.divelist_font); + qPrefPrivate::propSetValue(group + "/divelist_font", prefs.divelist_font); else setCorrectFont(); } @@ -58,38 +96,35 @@ void qPrefDisplay::set_font_size(double value) QFont defaultFont = qApp->font(); defaultFont.setPointSizeF(prefs.font_size); qApp->setFont(defaultFont); - emit font_size_changed(value); + emit instance()->font_size_changed(value); } } void qPrefDisplay::disk_font_size(bool doSync) { if (doSync) - qPrefPrivate::instance()->setting.setValue(group + "/font_size", prefs.font_size); + qPrefPrivate::propSetValue(group + "/font_size", prefs.font_size); else setCorrectFont(); } +//JAN static const QString group = QStringLiteral("Animations"); +HANDLE_PREFERENCE_INT(Display, "/animation_speed", animation_speed); + HANDLE_PREFERENCE_BOOL(Display, "/displayinvalid", display_invalid_dives); HANDLE_PREFERENCE_BOOL(Display, "/show_developer", show_developer); -HANDLE_PREFERENCE_TXT(Display, "/theme", theme); - - void qPrefDisplay::setCorrectFont() { - QSettings s; - QVariant v; - // get the font from the settings or our defaults // respect the system default font size if none is explicitly set - QFont defaultFont = s.value(group + "/divelist_font", prefs.divelist_font).value<QFont>(); + QFont defaultFont = qPrefPrivate::propValue(group + "/divelist_font", prefs.divelist_font).value<QFont>(); if (IS_FP_SAME(system_divelist_default_font_size, -1.0)) { prefs.font_size = qApp->font().pointSizeF(); system_divelist_default_font_size = prefs.font_size; // this way we don't save it on exit } - prefs.font_size = s.value(group + "/font_size", prefs.font_size).toFloat(); + prefs.font_size = qPrefPrivate::propValue(group + "/font_size", prefs.font_size).toFloat(); // painful effort to ignore previous default fonts on Windows - ridiculous QString fontName = defaultFont.toString(); if (fontName.contains(",")) @@ -103,5 +138,27 @@ void qPrefDisplay::setCorrectFont() defaultFont.setPointSizeF(prefs.font_size); qApp->setFont(defaultFont); - prefs.display_invalid_dives = qPrefPrivate::instance()->setting.value(group + "/displayinvalid", default_prefs.display_invalid_dives).toBool(); + prefs.display_invalid_dives = qPrefPrivate::propValue(group + "/displayinvalid", default_prefs.display_invalid_dives).toBool(); } + +HANDLE_PROP_QSTRING(Display, "FileDialog/LastDir", lastDir); + +HANDLE_PROP_QSTRING(Display, "Theme/currentTheme", theme); + +HANDLE_PROP_QPOINTF(Display, "ProfileMap/tooltip_position", tooltip_position); + +HANDLE_PROP_QSTRING(Display, "UserSurvey/SurveyDone", UserSurvey); + +HANDLE_PROP_QBYTEARRAY(Display, "MainWindow/mainSplitter", mainSplitter); + +HANDLE_PROP_QBYTEARRAY(Display, "MainWindow/topSplitter", topSplitter); + +HANDLE_PROP_QBYTEARRAY(Display, "MainWindow/bottomSplitter", bottomSplitter); + +HANDLE_PROP_BOOL(Display, "MainWindow/maximized", maximized); + +HANDLE_PROP_QBYTEARRAY(Display, "MainWindow/geometry", geometry); + +HANDLE_PROP_QBYTEARRAY(Display, "MainWindow/windowState", windowState); + +HANDLE_PROP_INT(Display, "MainWindow/lastState", lastState); diff --git a/core/settings/qPrefDisplay.h b/core/settings/qPrefDisplay.h index 804f4a258..5a7eb7aac 100644 --- a/core/settings/qPrefDisplay.h +++ b/core/settings/qPrefDisplay.h @@ -4,54 +4,125 @@ #include "core/pref.h" #include <QObject> +#include <QPointF> class qPrefDisplay : public QObject { Q_OBJECT + Q_PROPERTY(int animation_speed READ animation_speed WRITE set_animation_speed NOTIFY animation_speed_changed); Q_PROPERTY(QString divelist_font READ divelist_font WRITE set_divelist_font NOTIFY divelist_font_changed); Q_PROPERTY(double font_size READ font_size WRITE set_font_size NOTIFY font_size_changed); Q_PROPERTY(bool display_invalid_dives READ display_invalid_dives WRITE set_display_invalid_dives NOTIFY display_invalid_dives_changed); + Q_PROPERTY(QString lastDir READ lastDir WRITE set_lastDir NOTIFY lastDir_changed); Q_PROPERTY(bool show_developer READ show_developer WRITE set_show_developer NOTIFY show_developer_changed); Q_PROPERTY(QString theme READ theme WRITE set_theme NOTIFY theme_changed); + Q_PROPERTY(QPointF tooltip_position READ tooltip_position WRITE set_tooltip_position NOTIFY tooltip_position_changed); + Q_PROPERTY(QString UserSurvey READ UserSurvey WRITE set_UserSurvey NOTIFY UserSurvey_changed); + Q_PROPERTY(QByteArray mainSplitter READ mainSplitter WRITE set_mainSplitter NOTIFY mainSplitter_changed); + Q_PROPERTY(QByteArray topSplitter READ topSplitter WRITE set_topSplitter NOTIFY topSplitter_changed); + Q_PROPERTY(QByteArray bottomSplitter READ bottomSplitter WRITE set_bottomSplitter NOTIFY bottomSplitter_changed); + Q_PROPERTY(bool maximized READ maximized WRITE set_maximized NOTIFY maximized_changed); + Q_PROPERTY(QByteArray geometry READ geometry WRITE set_geometry NOTIFY geometry_changed); + Q_PROPERTY(QByteArray windowState READ windowState WRITE set_windowState NOTIFY windowState_changed); + Q_PROPERTY(int lastState READ lastState WRITE set_lastState NOTIFY lastState_changed); public: qPrefDisplay(QObject *parent = NULL); static qPrefDisplay *instance(); // Load/Sync local settings (disk) and struct preference - void loadSync(bool doSync); - void load() { loadSync(false); } - void sync() { loadSync(true); } + static void loadSync(bool doSync); + static void load() { loadSync(false); } + static void sync() { loadSync(true); } public: + static int animation_speed() { return prefs.animation_speed; } static QString divelist_font() { return prefs.divelist_font; } static double font_size() { return prefs.font_size; } static bool display_invalid_dives() { return prefs.display_invalid_dives; } + static QString lastDir() { return st_lastDir; ; } static bool show_developer() { return prefs.show_developer; } - static QString theme() { return prefs.theme; } + static QString theme() { return st_theme; } + static QPointF tooltip_position() { return st_tooltip_position; } + static QString UserSurvey() { return st_UserSurvey; } + static QByteArray mainSplitter() { return st_mainSplitter; } + static QByteArray topSplitter() { return st_topSplitter; } + static QByteArray bottomSplitter() { return st_bottomSplitter; } + static bool maximized() { return st_maximized; } + static QByteArray geometry() { return st_geometry; } + static QByteArray windowState() { return st_windowState; } + static int lastState() { return st_lastState; } public slots: - void set_divelist_font(const QString &value); - void set_font_size(double value); - void set_display_invalid_dives(bool value); - void set_show_developer(bool value); - void set_theme(const QString &value); + static void set_animation_speed(int value); + static void set_divelist_font(const QString &value); + static void set_font_size(double value); + static void set_display_invalid_dives(bool value); + static void set_lastDir(const QString &value); + static void set_show_developer(bool value); + static void set_theme(const QString &value); + static void set_tooltip_position(const QPointF &value); + static void set_UserSurvey(const QString &value); + static void set_mainSplitter(const QByteArray &value); + static void set_topSplitter(const QByteArray &value); + static void set_bottomSplitter(const QByteArray &value); + static void set_maximized(bool value); + static void set_geometry(const QByteArray& value); + static void set_windowState(const QByteArray& value); + static void set_lastState(int value); signals: + void animation_speed_changed(int value); void divelist_font_changed(const QString &value); void font_size_changed(double value); void display_invalid_dives_changed(bool value); + void lastDir_changed(const QString &value); void show_developer_changed(bool value); void theme_changed(const QString &value); + void tooltip_position_changed(const QPointF &value); + void UserSurvey_changed(const QString &value); + void mainSplitter_changed(const QByteArray &value); + void topSplitter_changed(const QByteArray &value); + void bottomSplitter_changed(const QByteArray &value); + void maximized_changed(bool value); + void geometry_changed(const QByteArray& value); + void windowState_changed(const QByteArray& value); + void lastState_changed(int value); private: // functions to load/sync variable with disk - void disk_divelist_font(bool doSync); - void disk_font_size(bool doSync); - void disk_display_invalid_dives(bool doSync); - void disk_show_developer(bool doSync); - void disk_theme(bool doSync); + static void disk_animation_speed(bool doSync); + static void disk_divelist_font(bool doSync); + static void disk_font_size(bool doSync); + static void disk_display_invalid_dives(bool doSync); + static void disk_show_developer(bool doSync); + + // functions to handle class variables + static void load_lastDir(); + static void load_theme(); + static void load_tooltip_position(); + static void load_UserSurvey(); + static void load_mainSplitter(); + static void load_topSplitter(); + static void load_bottomSplitter(); + static void load_maximized(); + static void load_geometry(); + static void load_windowState(); + static void load_lastState(); // font helper function - void setCorrectFont(); + static void setCorrectFont(); + + // Class variables not present in structure preferences + static QString st_lastDir; + static QString st_theme; + static QPointF st_tooltip_position; + static QString st_UserSurvey; + static QByteArray st_mainSplitter; + static QByteArray st_topSplitter; + static QByteArray st_bottomSplitter; + static bool st_maximized; + static QByteArray st_geometry; + static QByteArray st_windowState; + static int st_lastState; }; #endif diff --git a/core/settings/qPrefDiveComputer.cpp b/core/settings/qPrefDiveComputer.cpp index 04928dbfb..105ab96b7 100644 --- a/core/settings/qPrefDiveComputer.cpp +++ b/core/settings/qPrefDiveComputer.cpp @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -#include "qPref.h" +#include "qPrefDiveComputer.h" #include "qPrefPrivate.h" static const QString group = QStringLiteral("DiveComputer"); diff --git a/core/settings/qPrefDiveComputer.h b/core/settings/qPrefDiveComputer.h index dda0b9500..99ff6575b 100644 --- a/core/settings/qPrefDiveComputer.h +++ b/core/settings/qPrefDiveComputer.h @@ -18,9 +18,9 @@ public: static qPrefDiveComputer *instance(); // Load/Sync local settings (disk) and struct preference - void loadSync(bool doSync); - void load() { loadSync(false); } - void sync() { loadSync(true); } + static void loadSync(bool doSync); + static void load() { loadSync(false); } + static void sync() { loadSync(true); } public: static QString device() { return prefs.dive_computer.device; } @@ -30,11 +30,11 @@ public: static QString vendor() { return prefs.dive_computer.vendor; } public slots: - void set_device(const QString &device); - void set_device_name(const QString &device_name); - void set_download_mode(int mode); - void set_product(const QString &product); - void set_vendor(const QString &vendor); + static void set_device(const QString &device); + static void set_device_name(const QString &device_name); + static void set_download_mode(int mode); + static void set_product(const QString &product); + static void set_vendor(const QString &vendor); signals: void device_changed(const QString &device); @@ -45,11 +45,11 @@ signals: private: // functions to load/sync variable with disk - void disk_device(bool doSync); - void disk_device_name(bool doSync); - void disk_download_mode(bool doSync); - void disk_product(bool doSync); - void disk_vendor(bool doSync); + static void disk_device(bool doSync); + static void disk_device_name(bool doSync); + static void disk_download_mode(bool doSync); + static void disk_product(bool doSync); + static void disk_vendor(bool doSync); }; #endif diff --git a/core/settings/qPrefDivePlanner.cpp b/core/settings/qPrefDivePlanner.cpp index abeb4f402..02e39f535 100644 --- a/core/settings/qPrefDivePlanner.cpp +++ b/core/settings/qPrefDivePlanner.cpp @@ -1,9 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "core/subsurface-string.h" +#include "qPrefDivePlanner.h" #include "qPrefPrivate.h" -#include "qPref.h" - -#include <QSettings> static const QString group = QStringLiteral("Planner"); diff --git a/core/settings/qPrefDivePlanner.h b/core/settings/qPrefDivePlanner.h index 77af1b8b9..fa6ecb80c 100644 --- a/core/settings/qPrefDivePlanner.h +++ b/core/settings/qPrefDivePlanner.h @@ -38,9 +38,9 @@ public: static qPrefDivePlanner *instance(); // Load/Sync local settings (disk) and struct preference - void loadSync(bool doSync); - void load() { loadSync(false); } - void sync() { loadSync(true); } + static void loadSync(bool doSync); + static void load() { loadSync(false); } + static void sync() { loadSync(true); } public: static int ascratelast6m() { return prefs.ascratelast6m; } @@ -70,31 +70,31 @@ public: static bool verbatim_plan() { return prefs.verbatim_plan; } public slots: - void set_ascratelast6m(int value); - void set_ascratestops(int value); - void set_ascrate50(int value); - void set_ascrate75(int value); - void set_bestmixend(depth_t value); - void set_bottompo2(int value); - void set_bottomsac(int value); - void set_decopo2(int value); - void set_decosac(int value); - void set_descrate(int value); - void set_display_duration(bool value); - void set_display_runtime(bool value); - void set_display_transitions(bool value); - void set_display_variations(bool value); - void set_doo2breaks(bool value); - void set_drop_stone_mode(bool value); - void set_last_stop(bool value); - void set_min_switch_duration(int value); - void set_planner_deco_mode(deco_mode value); - void set_problemsolvingtime(int value); - void set_reserve_gas(int value); - void set_sacfactor(int value); - void set_safetystop(bool value); - void set_switch_at_req_stop(bool value); - void set_verbatim_plan(bool value); + static void set_ascratelast6m(int value); + static void set_ascratestops(int value); + static void set_ascrate50(int value); + static void set_ascrate75(int value); + static void set_bestmixend(depth_t value); + static void set_bottompo2(int value); + static void set_bottomsac(int value); + static void set_decopo2(int value); + static void set_decosac(int value); + static void set_descrate(int value); + static void set_display_duration(bool value); + static void set_display_runtime(bool value); + static void set_display_transitions(bool value); + static void set_display_variations(bool value); + static void set_doo2breaks(bool value); + static void set_drop_stone_mode(bool value); + static void set_last_stop(bool value); + static void set_min_switch_duration(int value); + static void set_planner_deco_mode(deco_mode value); + static void set_problemsolvingtime(int value); + static void set_reserve_gas(int value); + static void set_sacfactor(int value); + static void set_safetystop(bool value); + static void set_switch_at_req_stop(bool value); + static void set_verbatim_plan(bool value); signals: void ascratelast6m_changed(int value); @@ -124,32 +124,32 @@ signals: void verbatim_plan_changed(bool value); private: - void disk_ascratelast6m(bool doSync); - void disk_ascratestops(bool doSync); - void disk_ascrate50(bool doSync); - void disk_ascrate75(bool doSync); - void disk_bestmixend(bool doSync); - void disk_bottompo2(bool doSync); - void disk_bottomsac(bool doSync); - void disk_decopo2(bool doSync); - void disk_decosac(bool doSync); - void disk_descrate(bool doSync); - void disk_display_deco_mode(bool doSync); - void disk_display_duration(bool doSync); - void disk_display_runtime(bool doSync); - void disk_display_transitions(bool doSync); - void disk_display_variations(bool doSync); - void disk_doo2breaks(bool doSync); - void disk_drop_stone_mode(bool doSync); - void disk_last_stop(bool doSync); - void disk_min_switch_duration(bool doSync); - void disk_planner_deco_mode(bool doSync); - void disk_problemsolvingtime(bool doSync); - void disk_reserve_gas(bool doSync); - void disk_sacfactor(bool doSync); - void disk_safetystop(bool doSync); - void disk_switch_at_req_stop(bool doSync); - void disk_verbatim_plan(bool doSync); + static void disk_ascratelast6m(bool doSync); + static void disk_ascratestops(bool doSync); + static void disk_ascrate50(bool doSync); + static void disk_ascrate75(bool doSync); + static void disk_bestmixend(bool doSync); + static void disk_bottompo2(bool doSync); + static void disk_bottomsac(bool doSync); + static void disk_decopo2(bool doSync); + static void disk_decosac(bool doSync); + static void disk_descrate(bool doSync); + static void disk_display_deco_mode(bool doSync); + static void disk_display_duration(bool doSync); + static void disk_display_runtime(bool doSync); + static void disk_display_transitions(bool doSync); + static void disk_display_variations(bool doSync); + static void disk_doo2breaks(bool doSync); + static void disk_drop_stone_mode(bool doSync); + static void disk_last_stop(bool doSync); + static void disk_min_switch_duration(bool doSync); + static void disk_planner_deco_mode(bool doSync); + static void disk_problemsolvingtime(bool doSync); + static void disk_reserve_gas(bool doSync); + static void disk_sacfactor(bool doSync); + static void disk_safetystop(bool doSync); + static void disk_switch_at_req_stop(bool doSync); + static void disk_verbatim_plan(bool doSync); }; #endif diff --git a/core/settings/qPrefFacebook.cpp b/core/settings/qPrefFacebook.cpp index b96008920..8728313ab 100644 --- a/core/settings/qPrefFacebook.cpp +++ b/core/settings/qPrefFacebook.cpp @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -#include "qPref.h" +#include "qPrefFacebook.h" #include "qPrefPrivate.h" static const QString group = QStringLiteral("WebApps/Facebook"); @@ -21,23 +21,23 @@ void qPrefFacebook::loadSync(bool doSync) void qPrefFacebook::set_access_token(const QString &value) { if (value != prefs.facebook.access_token) { - qPrefPrivate::instance()->copy_txt(&prefs.facebook.access_token, value); - emit access_token_changed(value); + qPrefPrivate::copy_txt(&prefs.facebook.access_token, value); + emit instance()->access_token_changed(value); } } void qPrefFacebook::set_album_id(const QString &value) { if (value != prefs.facebook.album_id) { - qPrefPrivate::instance()->copy_txt(&prefs.facebook.album_id, value); - emit album_id_changed(value); + qPrefPrivate::copy_txt(&prefs.facebook.album_id, value); + emit instance()->album_id_changed(value); } } void qPrefFacebook::set_user_id(const QString &value) { if (value != prefs.facebook.user_id) { - qPrefPrivate::instance()->copy_txt(&prefs.facebook.user_id, value); - emit access_token_changed(value); + qPrefPrivate::copy_txt(&prefs.facebook.user_id, value); + emit instance()->access_token_changed(value); } } diff --git a/core/settings/qPrefFacebook.h b/core/settings/qPrefFacebook.h index 60c037583..0493b8ca9 100644 --- a/core/settings/qPrefFacebook.h +++ b/core/settings/qPrefFacebook.h @@ -17,9 +17,9 @@ public: static qPrefFacebook *instance(); // Load/Sync local settings (disk) and struct preference - void loadSync(bool doSync); - void load() {loadSync(false); } - void sync() {loadSync(true); } + static void loadSync(bool doSync); + static void load() {loadSync(false); } + static void sync() {loadSync(true); } public: static QString access_token() { return prefs.facebook.access_token; } @@ -27,9 +27,9 @@ public: static QString user_id() { return prefs.facebook.user_id; } public slots: - void set_access_token(const QString& value); - void set_album_id(const QString& value); - void set_user_id(const QString& value); + static void set_access_token(const QString& value); + static void set_album_id(const QString& value); + static void set_user_id(const QString& value); signals: void access_token_changed(const QString& value); @@ -37,9 +37,9 @@ signals: void user_id_changed(const QString& value); private: - void disk_access_token(bool doSync); - void disk_album_id(bool doSync); - void disk_user_id(bool doSync); + static void disk_access_token(bool doSync); + static void disk_album_id(bool doSync); + static void disk_user_id(bool doSync); }; #endif diff --git a/core/settings/qPrefGeneral.cpp b/core/settings/qPrefGeneral.cpp new file mode 100644 index 000000000..8dfe67668 --- /dev/null +++ b/core/settings/qPrefGeneral.cpp @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "qPrefGeneral.h" +#include "qPrefPrivate.h" + + +static const QString group = QStringLiteral("GeneralSettings"); + +QString qPrefGeneral::st_diveshareExport_uid; +static const QString st_diveshareExport_uid_default = ""; + +bool qPrefGeneral::st_diveshareExport_private; +static const bool st_diveshareExport_private_default = false; + +qPrefGeneral::qPrefGeneral(QObject *parent) : QObject(parent) +{ +} +qPrefGeneral *qPrefGeneral::instance() +{ + static qPrefGeneral *self = new qPrefGeneral; + return self; +} + + +void qPrefGeneral::loadSync(bool doSync) +{ + disk_auto_recalculate_thumbnails(doSync); + disk_auto_recalculate_thumbnails(doSync); + disk_default_cylinder(doSync); + disk_default_filename(doSync); + disk_default_file_behavior(doSync); + disk_defaultsetpoint(doSync); + disk_extract_video_thumbnails(doSync); + disk_extract_video_thumbnails_position(doSync); + disk_ffmpeg_executable(doSync); + disk_o2consumption(doSync); + disk_pscr_ratio(doSync); + disk_use_default_file(doSync); + if (!doSync) { + load_diveshareExport_uid(); + load_diveshareExport_private(); + } +} + +HANDLE_PREFERENCE_BOOL(General, "/auto_recalculate_thumbnails", auto_recalculate_thumbnails); + +HANDLE_PREFERENCE_TXT(General, "/default_cylinder", default_cylinder); + +HANDLE_PREFERENCE_TXT(General, "default_filename", default_filename); + + +void qPrefGeneral::set_default_file_behavior(enum def_file_behavior value) +{ + if (value != prefs.default_file_behavior || + prefs.default_file_behavior != UNDEFINED_DEFAULT_FILE) { + + if (value == UNDEFINED_DEFAULT_FILE) { + // undefined, so check if there's a filename set and + // use that, otherwise go with no default file + prefs.default_file_behavior = QString(prefs.default_filename).isEmpty() ? NO_DEFAULT_FILE : LOCAL_DEFAULT_FILE; + } else { + prefs.default_file_behavior = value; + } + disk_default_file_behavior(true); + emit qPrefGeneral::instance()->default_file_behavior_changed(value); + } +} +void qPrefGeneral::disk_default_file_behavior(bool doSync) +{ + if (doSync) { + qPrefPrivate::propSetValue(group + "/default_file_behavior", prefs.default_file_behavior); + } else { + prefs.default_file_behavior = (enum def_file_behavior)qPrefPrivate::propValue(group + "/default_file_behavior", default_prefs.default_file_behavior).toInt(); + if (prefs.default_file_behavior == UNDEFINED_DEFAULT_FILE) + // undefined, so check if there's a filename set and + // use that, otherwise go with no default file + prefs.default_file_behavior = QString(prefs.default_filename).isEmpty() ? NO_DEFAULT_FILE : LOCAL_DEFAULT_FILE; + } +} + +HANDLE_PREFERENCE_INT(General, "/defaultsetpoint", defaultsetpoint); + +HANDLE_PREFERENCE_BOOL(General, "/extract_video_thumbnails", extract_video_thumbnails); + +HANDLE_PREFERENCE_INT(General, "/extract_video_thumbnails_position", extract_video_thumbnails_position); + +HANDLE_PREFERENCE_TXT(General, "/ffmpeg_executable", ffmpeg_executable); + +HANDLE_PREFERENCE_INT(General, "/o2consumption", o2consumption); + +HANDLE_PREFERENCE_INT(General, "/pscr_ratio", pscr_ratio); + +HANDLE_PREFERENCE_BOOL(General, "/use_default_file", use_default_file); + +HANDLE_PROP_QSTRING(General, "diveshareExport/uid", diveshareExport_uid); + +HANDLE_PROP_BOOL(General, "diveshareExport/private", diveshareExport_private); diff --git a/core/settings/qPrefGeneral.h b/core/settings/qPrefGeneral.h new file mode 100644 index 000000000..4d35c3817 --- /dev/null +++ b/core/settings/qPrefGeneral.h @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef QPREFGENERAL_H +#define QPREFGENERAL_H +#include "core/pref.h" + +#include <QObject> + +class qPrefGeneral : public QObject { + Q_OBJECT + Q_PROPERTY(bool auto_recalculate_thumbnails READ auto_recalculate_thumbnails WRITE set_auto_recalculate_thumbnails NOTIFY auto_recalculate_thumbnails_changed); + Q_PROPERTY(QString default_cylinder READ default_cylinder WRITE set_default_cylinder NOTIFY default_cylinder_changed); + Q_PROPERTY(QString default_filename READ default_filename WRITE set_default_filename NOTIFY default_filename_changed); + Q_PROPERTY(enum def_file_behavior default_file_behavior READ default_file_behavior WRITE set_default_file_behavior NOTIFY default_file_behavior_changed); + Q_PROPERTY(int defaultsetpoint READ defaultsetpoint WRITE set_defaultsetpoint NOTIFY defaultsetpoint_changed); + Q_PROPERTY(bool extract_video_thumbnails READ extract_video_thumbnails WRITE set_extract_video_thumbnails NOTIFY extract_video_thumbnails_changed); + Q_PROPERTY(int extract_video_thumbnails_position READ extract_video_thumbnails_position WRITE set_extract_video_thumbnails_position NOTIFY extract_video_thumbnails_position_changed); + Q_PROPERTY(QString ffmpeg_executable READ ffmpeg_executable WRITE set_ffmpeg_executable NOTIFY ffmpeg_executable_changed); + Q_PROPERTY(int o2consumption READ o2consumption WRITE set_o2consumption NOTIFY o2consumption_changed); + Q_PROPERTY(int pscr_ratio READ pscr_ratio WRITE set_pscr_ratio NOTIFY pscr_ratio_changed); + Q_PROPERTY(bool use_default_file READ use_default_file WRITE set_use_default_file NOTIFY use_default_file_changed); + Q_PROPERTY(QString diveshareExport_uid READ diveshareExport_uid WRITE set_diveshareExport_uid NOTIFY diveshareExport_uid_changed); + Q_PROPERTY(bool diveshareExport_private READ diveshareExport_private WRITE set_diveshareExport_private NOTIFY diveshareExport_private_changed); + +public: + qPrefGeneral(QObject *parent = NULL); + static qPrefGeneral *instance(); + + // Load/Sync local settings (disk) and struct preference + static void loadSync(bool doSync); + static void load() { return loadSync(false); } + static void sync() { return loadSync(true); } + +public: + static bool auto_recalculate_thumbnails() { return prefs.auto_recalculate_thumbnails; } + static QString default_cylinder() { return prefs.default_cylinder; } + static QString default_filename() { return prefs.default_filename; } + static enum def_file_behavior default_file_behavior() { return prefs.default_file_behavior; } + static int defaultsetpoint() { return prefs.defaultsetpoint; } + static bool extract_video_thumbnails() { return prefs.extract_video_thumbnails; } + static int extract_video_thumbnails_position() { return prefs.extract_video_thumbnails_position; } + static QString ffmpeg_executable() { return prefs.ffmpeg_executable; } + static int o2consumption() { return prefs.o2consumption; } + static int pscr_ratio() { return prefs.pscr_ratio; } + static bool use_default_file() { return prefs.use_default_file; } + static QString diveshareExport_uid() { return st_diveshareExport_uid; } + static bool diveshareExport_private() { return st_diveshareExport_private; } + +public slots: + static void set_auto_recalculate_thumbnails(bool value); + static void set_default_cylinder(const QString& value); + static void set_default_filename(const QString& value); + static void set_default_file_behavior(enum def_file_behavior value); + static void set_defaultsetpoint(int value); + static void set_extract_video_thumbnails(bool value); + static void set_extract_video_thumbnails_position(int value); + static void set_ffmpeg_executable(const QString& value); + static void set_o2consumption(int value); + static void set_pscr_ratio(int value); + static void set_use_default_file(bool value); + static void set_diveshareExport_uid(const QString& value); + static void set_diveshareExport_private(bool value); + +signals: + void auto_recalculate_thumbnails_changed(bool value); + void default_cylinder_changed(const QString& value); + void default_filename_changed(const QString& value); + void default_file_behavior_changed(enum def_file_behavior value); + void defaultsetpoint_changed(int value); + void extract_video_thumbnails_changed(bool value); + void extract_video_thumbnails_position_changed(int value); + void ffmpeg_executable_changed(const QString& value); + void o2consumption_changed(int value); + void pscr_ratio_changed(int value); + void use_default_file_changed(bool value); + void diveshareExport_uid_changed(const QString& value); + void diveshareExport_private_changed(bool value); + +private: + static void disk_auto_recalculate_thumbnails(bool doSync); + static void disk_default_cylinder(bool doSync); + static void disk_default_filename(bool doSync); + static void disk_default_file_behavior(bool doSync); + static void disk_defaultsetpoint(bool doSync); + static void disk_extract_video_thumbnails(bool doSync); + static void disk_extract_video_thumbnails_position(bool doSync); + static void disk_ffmpeg_executable(bool doSync); + static void disk_o2consumption(bool doSync); + static void disk_pscr_ratio(bool doSync); + static void disk_use_default_file(bool doSync); + + // class variables are load only + static void load_diveshareExport_uid(); + static void load_diveshareExport_private(); + + // class variables + static QString st_diveshareExport_uid; + static bool st_diveshareExport_private; +}; + +#endif diff --git a/core/settings/qPrefGeocoding.cpp b/core/settings/qPrefGeocoding.cpp new file mode 100644 index 000000000..7bb043e0f --- /dev/null +++ b/core/settings/qPrefGeocoding.cpp @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "qPrefGeocoding.h" +#include "qPrefPrivate.h" + +static const QString group = QStringLiteral("geocoding"); + +qPrefGeocoding::qPrefGeocoding(QObject *parent) : QObject(parent) +{ +} +qPrefGeocoding *qPrefGeocoding::instance() +{ + static qPrefGeocoding *self = new qPrefGeocoding; + return self; +} + +void qPrefGeocoding::loadSync(bool doSync) +{ + disk_first_taxonomy_category(doSync); + disk_second_taxonomy_category(doSync); + disk_third_taxonomy_category(doSync); +} + + +void qPrefGeocoding::set_first_taxonomy_category(taxonomy_category value) +{ + if (value != prefs.geocoding.category[0]) { + prefs.geocoding.category[0] = value; + disk_first_taxonomy_category(true); + emit instance()->first_taxonomy_category_changed(value); + } +} +void qPrefGeocoding::disk_first_taxonomy_category(bool doSync) +{ + if (doSync) + qPrefPrivate::propSetValue(group + "/cat0", prefs.geocoding.category[0]); + else + prefs.geocoding.category[0] = (enum taxonomy_category)qPrefPrivate::propValue(group + "/cat0", default_prefs.geocoding.category[0]).toInt(); +} + + +void qPrefGeocoding::set_second_taxonomy_category(taxonomy_category value) +{ + if (value != prefs.geocoding.category[1]) { + prefs.geocoding.category[1] = value; + disk_second_taxonomy_category(true); + emit instance()->second_taxonomy_category_changed(value); + } +} +void qPrefGeocoding::disk_second_taxonomy_category(bool doSync) +{ + if (doSync) + qPrefPrivate::propSetValue(group + "/cat1", prefs.geocoding.category[1]); + else + prefs.geocoding.category[1] = (enum taxonomy_category)qPrefPrivate::propValue(group + "/cat1", default_prefs.geocoding.category[1]).toInt(); +} + + +void qPrefGeocoding::set_third_taxonomy_category(taxonomy_category value) +{ + if (value != prefs.geocoding.category[2]) { + prefs.geocoding.category[2] = value; + disk_third_taxonomy_category(true); + emit instance()->third_taxonomy_category_changed(value); + } +} +void qPrefGeocoding::disk_third_taxonomy_category(bool doSync) +{ + if (doSync) + qPrefPrivate::propSetValue(group + "/cat2", prefs.geocoding.category[2]); + else + prefs.geocoding.category[2] = (enum taxonomy_category)qPrefPrivate::propValue(group + "/cat2", default_prefs.geocoding.category[2]).toInt(); +} diff --git a/core/settings/qPrefGeocoding.h b/core/settings/qPrefGeocoding.h new file mode 100644 index 000000000..03c9f59c8 --- /dev/null +++ b/core/settings/qPrefGeocoding.h @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef QPREFGEOCODING_H +#define QPREFGEOCODING_H +#include "core/pref.h" + +#include <QObject> + + +class qPrefGeocoding : public QObject { + Q_OBJECT + Q_PROPERTY(taxonomy_category first_taxonomy_category READ first_taxonomy_category WRITE set_first_taxonomy_category NOTIFY first_taxonomy_category_changed); + Q_PROPERTY(taxonomy_category second_taxonomy_category READ second_taxonomy_category WRITE set_second_taxonomy_category NOTIFY second_taxonomy_category_changed); + Q_PROPERTY(taxonomy_category third_taxonomy_category READ third_taxonomy_category WRITE set_third_taxonomy_category NOTIFY third_taxonomy_category_changed); + +public: + qPrefGeocoding(QObject *parent = NULL); + static qPrefGeocoding *instance(); + + // Load/Sync local settings (disk) and struct preference + void loadSync(bool doSync); + void load() { loadSync(false); } + void sync() { loadSync(true); } + +public: + taxonomy_category first_taxonomy_category() { return prefs.geocoding.category[0]; } + taxonomy_category second_taxonomy_category() { return prefs.geocoding.category[1]; } + taxonomy_category third_taxonomy_category() { return prefs.geocoding.category[2]; } + +public slots: + static void set_first_taxonomy_category(taxonomy_category value); + static void set_second_taxonomy_category(taxonomy_category value); + static void set_third_taxonomy_category(taxonomy_category value); + +signals: + void first_taxonomy_category_changed(taxonomy_category value); + void second_taxonomy_category_changed(taxonomy_category value); + void third_taxonomy_category_changed(taxonomy_category value); + +private: + static void disk_first_taxonomy_category(bool doSync); + static void disk_second_taxonomy_category(bool doSync); + static void disk_third_taxonomy_category(bool doSync); +}; + +#endif diff --git a/core/settings/qPrefLanguage.cpp b/core/settings/qPrefLanguage.cpp new file mode 100644 index 000000000..75327ce32 --- /dev/null +++ b/core/settings/qPrefLanguage.cpp @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "qPrefLanguage.h" +#include "qPrefPrivate.h" + +static const QString group = QStringLiteral("Language"); + +qPrefLanguage::qPrefLanguage(QObject *parent) : QObject(parent) +{ +} + +qPrefLanguage *qPrefLanguage::instance() +{ + static qPrefLanguage *self = new qPrefLanguage; + return self; +} + +void qPrefLanguage::loadSync(bool doSync) +{ + disk_date_format(doSync); + disk_date_format_override(doSync); + disk_date_format_short(doSync); + disk_language(doSync); + disk_lang_locale(doSync); + disk_time_format(doSync); + disk_time_format_override(doSync); + disk_use_system_language(doSync); +} + +HANDLE_PREFERENCE_TXT(Language, "/date_format", date_format); + +HANDLE_PREFERENCE_BOOL(Language,"/date_format_override", date_format_override); + +HANDLE_PREFERENCE_TXT(Language, "/date_format_short", date_format_short); + +HANDLE_PREFERENCE_TXT_EXT(Language, "/UiLanguage", language, locale.); + +HANDLE_PREFERENCE_TXT_EXT(Language, "/UiLangLocale", lang_locale, locale.); + +HANDLE_PREFERENCE_TXT(Language, "/time_format", time_format); + +HANDLE_PREFERENCE_BOOL(Language, "/time_format_override", time_format_override); + +HANDLE_PREFERENCE_BOOL_EXT(Language, "/UseSystemLanguage", use_system_language, locale.); diff --git a/core/settings/qPrefLanguage.h b/core/settings/qPrefLanguage.h new file mode 100644 index 000000000..e004f79d3 --- /dev/null +++ b/core/settings/qPrefLanguage.h @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef QPREFLANGUAGE_H +#define QPREFLANGUAGE_H +#include "core/pref.h" + +#include <QObject> + +class qPrefLanguage : public QObject { + Q_OBJECT + Q_PROPERTY(QString date_format READ date_format WRITE set_date_format NOTIFY date_format_changed); + Q_PROPERTY(bool date_format_override READ date_format_override WRITE set_date_format_override NOTIFY date_format_override_changed); + Q_PROPERTY(QString date_format_short READ date_format_short WRITE set_date_format_short NOTIFY date_format_short_changed); + Q_PROPERTY(QString language READ language WRITE set_language NOTIFY language_changed); + Q_PROPERTY(QString lang_locale READ lang_locale WRITE set_lang_locale NOTIFY lang_locale_changed); + Q_PROPERTY(QString time_format READ time_format WRITE set_time_format NOTIFY time_format_changed); + Q_PROPERTY(bool time_format_override READ time_format_override WRITE set_time_format_override NOTIFY time_format_override_changed); + Q_PROPERTY(bool use_system_language READ use_system_language WRITE set_use_system_language NOTIFY use_system_language_changed); + +public: + qPrefLanguage(QObject *parent = NULL); + static qPrefLanguage *instance(); + + // Load/Sync local settings (disk) and struct preference + static void loadSync(bool doSync); + static void load() { loadSync(false); } + static void sync() { loadSync(true); } + +public: + static const QString date_format() { return prefs.date_format; } + static bool date_format_override() { return prefs.date_format_override; } + static const QString date_format_short() { return prefs.date_format_short; } + static const QString language() { return prefs.locale.language; } + static const QString lang_locale() { return prefs.locale.lang_locale; } + static const QString time_format() { return prefs.time_format; } + static bool time_format_override() { return prefs.time_format_override; } + static bool use_system_language() { return prefs.locale.use_system_language; } + +public slots: + static void set_date_format(const QString& value); + static void set_date_format_override(bool value); + static void set_date_format_short(const QString& value); + static void set_language(const QString& value); + static void set_lang_locale(const QString& value); + static void set_time_format(const QString& value); + static void set_time_format_override(bool value); + static void set_use_system_language(bool value); + +signals: + void date_format_changed(const QString& value); + void date_format_override_changed(bool value); + void date_format_short_changed(const QString& value); + void language_changed(const QString& value); + void lang_locale_changed(const QString& value); + void time_format_changed(const QString& value); + void time_format_override_changed(bool value); + void use_system_language_changed(bool value); + +private: + static void disk_date_format(bool doSync); + static void disk_date_format_override(bool doSync); + static void disk_date_format_short(bool doSync); + static void disk_language(bool doSync); + static void disk_lang_locale(bool doSync); + static void disk_time_format(bool doSync); + static void disk_time_format_override(bool doSync); + static void disk_use_system_language(bool doSync); +}; + +#endif diff --git a/core/settings/qPrefLocationService.cpp b/core/settings/qPrefLocationService.cpp index 84ebcc321..01f4ffb9a 100644 --- a/core/settings/qPrefLocationService.cpp +++ b/core/settings/qPrefLocationService.cpp @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include "qPrefLocationService.h" -#include "qPref.h" #include "qPrefPrivate.h" static const QString group = QStringLiteral("LocationService"); diff --git a/core/settings/qPrefLocationService.h b/core/settings/qPrefLocationService.h index e3aa43c29..676f2bbf8 100644 --- a/core/settings/qPrefLocationService.h +++ b/core/settings/qPrefLocationService.h @@ -16,17 +16,17 @@ public: static qPrefLocationService *instance(); // Load/Sync local settings (disk) and struct preference - void loadSync(bool doSync); - void load() { loadSync(false); } - void sync() { loadSync(true); } + static void loadSync(bool doSync); + static void load() { loadSync(false); } + static void sync() { loadSync(true); } public: - int distance_threshold() { return prefs.distance_threshold; } - int time_threshold() { return prefs.time_threshold; } + static int distance_threshold() { return prefs.distance_threshold; } + static int time_threshold() { return prefs.time_threshold; } public slots: - void set_distance_threshold(int value); - void set_time_threshold(int value); + static void set_distance_threshold(int value); + static void set_time_threshold(int value); signals: void distance_threshold_changed(int value); @@ -34,8 +34,8 @@ signals: private: - void disk_distance_threshold(bool doSync); - void disk_time_threshold(bool doSync); + static void disk_distance_threshold(bool doSync); + static void disk_time_threshold(bool doSync); }; #endif diff --git a/core/settings/qPrefPartialPressureGas.cpp b/core/settings/qPrefPartialPressureGas.cpp new file mode 100644 index 000000000..8d86899dc --- /dev/null +++ b/core/settings/qPrefPartialPressureGas.cpp @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "qPrefPartialPressureGas.h" +#include "qPrefPrivate.h" + +static const QString group = QStringLiteral("TecDetails"); + +qPrefPartialPressureGas::qPrefPartialPressureGas(QObject *parent) : QObject(parent) +{ +} +qPrefPartialPressureGas *qPrefPartialPressureGas::instance() +{ + static qPrefPartialPressureGas *self = new qPrefPartialPressureGas; + return self; +} + +void qPrefPartialPressureGas::loadSync(bool doSync) +{ + disk_phe(doSync); + disk_phe_threshold(doSync); + disk_pn2(doSync); + disk_pn2_threshold(doSync); + disk_po2(doSync); + disk_po2_threshold_min(doSync); + disk_po2_threshold_max(doSync); +} + + +HANDLE_PREFERENCE_BOOL_EXT(PartialPressureGas, "/phegraph", phe, pp_graphs.); + +HANDLE_PREFERENCE_DOUBLE_EXT(PartialPressureGas, "/phethreshold", phe_threshold, pp_graphs.); + +HANDLE_PREFERENCE_BOOL_EXT(PartialPressureGas, "/pn2graph", pn2, pp_graphs.); + +HANDLE_PREFERENCE_DOUBLE_EXT(PartialPressureGas, "/pn2threshold", pn2_threshold, pp_graphs.); + +HANDLE_PREFERENCE_BOOL_EXT(PartialPressureGas, "/po2graph", po2, pp_graphs.); + +HANDLE_PREFERENCE_DOUBLE_EXT(PartialPressureGas, "/po2thresholdmax", po2_threshold_max, pp_graphs.); + +HANDLE_PREFERENCE_DOUBLE_EXT(PartialPressureGas, "/po2thresholdmin", po2_threshold_min, pp_graphs.); diff --git a/core/settings/qPrefPartialPressureGas.h b/core/settings/qPrefPartialPressureGas.h new file mode 100644 index 000000000..c87711658 --- /dev/null +++ b/core/settings/qPrefPartialPressureGas.h @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef QPREFPARTICULARPRESSUREGAS_H +#define QPREFPARTICULARPRESSUREGAS_H +#include "core/pref.h" + +#include <QObject> + +class qPrefPartialPressureGas : public QObject { + Q_OBJECT + Q_PROPERTY(bool phe READ phe WRITE set_phe NOTIFY phe_changed); + Q_PROPERTY(double phe_threshold READ phe_threshold WRITE set_phe_threshold NOTIFY phe_threshold_changed); + Q_PROPERTY(bool pn2 READ pn2 WRITE set_pn2 NOTIFY pn2_changed); + Q_PROPERTY(double pn2_threshold READ pn2_threshold WRITE set_pn2_threshold NOTIFY pn2_threshold_changed); + Q_PROPERTY(bool po2 READ po2 WRITE set_po2 NOTIFY po2_changed); + Q_PROPERTY(double po2_threshold_max READ po2_threshold_max WRITE set_po2_threshold_max NOTIFY po2_threshold_max_changed); + Q_PROPERTY(double po2_threshold_min READ po2_threshold_min WRITE set_po2_threshold_min NOTIFY po2_threshold_min_changed); + +public: + qPrefPartialPressureGas(QObject *parent = NULL); + static qPrefPartialPressureGas *instance(); + + // Load/Sync local settings (disk) and struct preference + static void loadSync(bool doSync); + static void load() { loadSync(false); } + static void sync() { loadSync(true); } + +public: + static bool phe() { return prefs.pp_graphs.phe; } + static double phe_threshold() { return prefs.pp_graphs.phe_threshold; } + static bool pn2() { return prefs.pp_graphs.pn2; } + static double pn2_threshold() { return prefs.pp_graphs.pn2_threshold; } + static bool po2() { return prefs.pp_graphs.po2; } + static double po2_threshold_max() { return prefs.pp_graphs.po2_threshold_max; } + static double po2_threshold_min() { return prefs.pp_graphs.po2_threshold_min; } + +public slots: + static void set_phe(bool value); + static void set_phe_threshold(double value); + static void set_pn2(bool value); + static void set_pn2_threshold(double value); + static void set_po2(bool value); + static void set_po2_threshold_min(double value); + static void set_po2_threshold_max(double value); + +signals: + void phe_changed(bool value); + void phe_threshold_changed(double value); + void pn2_changed(bool value); + void pn2_threshold_changed(double value); + void po2_changed(bool value); + void po2_threshold_max_changed(double value); + void po2_threshold_min_changed(double value); + +private: + static void disk_phe(bool doSync); + static void disk_phe_threshold(bool doSync); + static void disk_pn2(bool doSync); + static void disk_pn2_threshold(bool doSync); + static void disk_po2(bool doSync); + static void disk_po2_threshold_min(bool doSync); + static void disk_po2_threshold_max(bool doSync); +}; + +#endif diff --git a/core/settings/qPrefPrivate.cpp b/core/settings/qPrefPrivate.cpp index 0275791cf..ff335a94f 100644 --- a/core/settings/qPrefPrivate.cpp +++ b/core/settings/qPrefPrivate.cpp @@ -1,17 +1,30 @@ // SPDX-License-Identifier: GPL-2.0 #include "qPrefPrivate.h" -qPrefPrivate::qPrefPrivate(QObject *parent) : QObject(parent) +#include <QSettings> + +void qPrefPrivate::copy_txt(const char **name, const QString &string) { + free((void *)*name); + *name = copy_qstring(string); } -qPrefPrivate *qPrefPrivate::instance() + +void qPrefPrivate::propSetValue(const QString &key, const QVariant &value) { - static qPrefPrivate *self = new qPrefPrivate; - return self; + // REMARK: making s static (which would be logical) does NOT work + // because it gets initialized too early. + // Having it as a local variable is light weight, because it is an + // interface class. + QSettings s; + s.setValue(key, value); } -void qPrefPrivate::copy_txt(const char **name, const QString &string) +QVariant qPrefPrivate::propValue(const QString &key, const QVariant &defaultValue) { - free((void *)*name); - *name = copy_qstring(string); + // REMARK: making s static (which would be logical) does NOT work + // because it gets initialized too early. + // Having it as a local variable is light weight, because it is an + // interface class. + QSettings s; + return s.value(key, defaultValue); } diff --git a/core/settings/qPrefPrivate.h b/core/settings/qPrefPrivate.h index efaa5382c..e3376a3a2 100644 --- a/core/settings/qPrefPrivate.h +++ b/core/settings/qPrefPrivate.h @@ -6,216 +6,201 @@ #include "core/qthelper.h" #include "qPref.h" #include <QObject> -#include <QSettings> #include <QVariant> // implementation class of the interface classes -class qPrefPrivate : public QObject { - Q_OBJECT +class qPrefPrivate { public: - friend class qPrefAnimations; - friend class qPrefCloudStorage; - friend class qPrefDisplay; - friend class qPrefDiveComputer; - friend class qPrefDivePlanner; - friend class qPrefFacebook; - friend class qPrefLocationService; - friend class qPrefProxy; - friend class qPrefTechnicalDetails; - friend class qPrefUnits; - friend class qPrefUpdateManager; - -private: - static qPrefPrivate *instance(); - - QSettings setting; - // Helper functions static void copy_txt(const char **name, const QString &string); - qPrefPrivate(QObject *parent = NULL); + static void propSetValue(const QString &key, const QVariant &value); + static QVariant propValue(const QString &key, const QVariant &defaultValue); + +private: + qPrefPrivate() {} }; //******* Macros to generate disk function -#define DISK_LOADSYNC_BOOL_EXT(usegroup, name, field, usestruct) \ - void qPref##usegroup::disk_##field(bool doSync) \ - { \ - if (doSync) \ - qPrefPrivate::instance()->setting.setValue(group + name, prefs.usestruct field); \ - else \ - prefs.usestruct field = qPrefPrivate::instance()->setting.value(group + name, default_prefs.usestruct field).toBool(); \ +#define DISK_LOADSYNC_BOOL_EXT(usegroup, name, field, usestruct) \ + void qPref##usegroup::disk_##field(bool doSync) \ + { \ + if (doSync) \ + qPrefPrivate::propSetValue(group + name, prefs.usestruct field); \ + else \ + prefs.usestruct field = qPrefPrivate::propValue(group + name, default_prefs.usestruct field).toBool(); \ } #define DISK_LOADSYNC_BOOL(usegroup, name, field) \ DISK_LOADSYNC_BOOL_EXT(usegroup, name, field, ) -#define DISK_LOADSYNC_DOUBLE_EXT(usegroup, name, field, usestruct) \ - void qPref##usegroup::disk_##field(bool doSync) \ - { \ - if (doSync) \ - qPrefPrivate::instance()->setting.setValue(group + name, prefs.usestruct field); \ - else \ - prefs.usestruct field = qPrefPrivate::instance()->setting.value(group + name, default_prefs.usestruct field).toDouble(); \ +#define DISK_LOADSYNC_DOUBLE_EXT(usegroup, name, field, usestruct) \ + void qPref##usegroup::disk_##field(bool doSync) \ + { \ + if (doSync) \ + qPrefPrivate::propSetValue(group + name, prefs.usestruct field); \ + else \ + prefs.usestruct field = qPrefPrivate::propValue(group + name, default_prefs.usestruct field).toDouble(); \ } #define DISK_LOADSYNC_DOUBLE(usegroup, name, field) \ DISK_LOADSYNC_DOUBLE_EXT(usegroup, name, field, ) -#define DISK_LOADSYNC_ENUM_EXT(usegroup, name, type, field, usestruct) \ - void qPref##usegroup::disk_##field(bool doSync) \ - { \ - if (doSync) \ - qPrefPrivate::instance()->setting.setValue(group + name, prefs.usestruct field); \ - else \ - prefs.usestruct field = (enum type)qPrefPrivate::instance()->setting.value(group + name, default_prefs.usestruct field).toInt(); \ +#define DISK_LOADSYNC_ENUM_EXT(usegroup, name, type, field, usestruct) \ + void qPref##usegroup::disk_##field(bool doSync) \ + { \ + if (doSync) \ + qPrefPrivate::propSetValue(group + name, prefs.usestruct field); \ + else \ + prefs.usestruct field = (enum type)qPrefPrivate::propValue(group + name, default_prefs.usestruct field).toInt(); \ } #define DISK_LOADSYNC_ENUM(usegroup, name, type, field) \ DISK_LOADSYNC_ENUM_EXT(usegroup, name, type, field, ) -#define DISK_LOADSYNC_INT_EXT(usegroup, name, field, usestruct) \ - void qPref##usegroup::disk_##field(bool doSync) \ - { \ - if (doSync) \ - qPrefPrivate::instance()->setting.setValue(group + name, prefs.usestruct field); \ - else \ - prefs.usestruct field = qPrefPrivate::instance()->setting.value(group + name, default_prefs.usestruct field).toInt(); \ +#define DISK_LOADSYNC_INT_EXT(usegroup, name, field, usestruct) \ + void qPref##usegroup::disk_##field(bool doSync) \ + { \ + if (doSync) \ + qPrefPrivate::propSetValue(group + name, prefs.usestruct field); \ + else \ + prefs.usestruct field = qPrefPrivate::propValue(group + name, default_prefs.usestruct field).toInt(); \ } #define DISK_LOADSYNC_INT(usegroup, name, field) \ DISK_LOADSYNC_INT_EXT(usegroup, name, field, ) -#define DISK_LOADSYNC_INT_DEF_EXT(usegroup, name, field, defval, usestruct) \ - void qPref##usegroup::disk_##field(bool doSync) \ - { \ - if (doSync) \ - qPrefPrivate::instance()->setting.setValue(group + name, prefs.usestruct field); \ - else \ - prefs.usestruct field = qPrefPrivate::instance()->setting.value(group + name, defval).toInt(); \ +#define DISK_LOADSYNC_INT_DEF_EXT(usegroup, name, field, defval, usestruct) \ + void qPref##usegroup::disk_##field(bool doSync) \ + { \ + if (doSync) \ + qPrefPrivate::propSetValue(group + name, prefs.usestruct field); \ + else \ + prefs.usestruct field = qPrefPrivate::propValue(group + name, defval).toInt(); \ } #define DISK_LOADSYNC_INT_DEF(usegroup, name, field, defval) \ DISK_LOADSYNC_INT_DEF_EXT(usegroup, name, field, defval, ) -#define DISK_LOADSYNC_STRUCT_EXT(usegroup, name, field, var, usestruct) \ - void qPref##usegroup::disk_##field(bool doSync) \ - { \ - if (doSync) \ - qPrefPrivate::instance()->setting.setValue(group + name, prefs.usestruct field . var); \ - else \ - prefs.usestruct field . var = qPrefPrivate::instance()->setting.value(group + name, default_prefs.usestruct field . var).toInt(); \ +#define DISK_LOADSYNC_STRUCT_EXT(usegroup, name, field, var, usestruct) \ + void qPref##usegroup::disk_##field(bool doSync) \ + { \ + if (doSync) \ + qPrefPrivate::propSetValue(group + name, prefs.usestruct field . var); \ + else \ + prefs.usestruct field . var = qPrefPrivate::propValue(group + name, default_prefs.usestruct field . var).toInt(); \ } #define DISK_LOADSYNC_STRUCT(usegroup, name, field, var) \ DISK_LOADSYNC_STRUCT_EXT(usegroup, name, field, var, ) -#define DISK_LOADSYNC_TXT_EXT(usegroup, name, field, usestruct) \ - void qPref##usegroup::disk_##field(bool doSync) \ - { \ - if (doSync) \ - qPrefPrivate::instance()->setting.setValue(group + name, prefs.usestruct field); \ - else \ - prefs.usestruct field = copy_qstring(qPrefPrivate::instance()->setting.value(group + name, default_prefs.usestruct field).toString()); \ +#define DISK_LOADSYNC_TXT_EXT(usegroup, name, field, usestruct) \ + void qPref##usegroup::disk_##field(bool doSync) \ + { \ + if (doSync) \ + qPrefPrivate::propSetValue(group + name, prefs.usestruct field); \ + else \ + prefs.usestruct field = copy_qstring(qPrefPrivate::propValue(group + name, default_prefs.usestruct field).toString()); \ } #define DISK_LOADSYNC_TXT(usegroup, name, field) \ DISK_LOADSYNC_TXT_EXT(usegroup, name, field, ) //******* Macros to generate set function #define SET_PREFERENCE_BOOL_EXT(usegroup, field, usestruct) \ - void qPref##usegroup::set_##field(bool value) \ - { \ - if (value != prefs.usestruct field) { \ - prefs.usestruct field = value; \ - disk_##field(true); \ - emit field##_changed(value); \ - } \ + void qPref##usegroup::set_##field(bool value) \ + { \ + if (value != prefs.usestruct field) { \ + prefs.usestruct field = value; \ + disk_##field(true); \ + emit qPref##usegroup::instance()->field##_changed(value); \ + } \ } #define SET_PREFERENCE_BOOL(usegroup, field) \ SET_PREFERENCE_BOOL_EXT(usegroup, field, ) #define SET_PREFERENCE_DOUBLE_EXT(usegroup, field, usestruct) \ - void qPref##usegroup::set_##field(double value) \ - { \ - if (value != prefs.usestruct field) { \ - prefs.usestruct field = value; \ - disk_##field(true); \ - emit field##_changed(value); \ - } \ + void qPref##usegroup::set_##field(double value) \ + { \ + if (value != prefs.usestruct field) { \ + prefs.usestruct field = value; \ + disk_##field(true); \ + emit qPref##usegroup::instance()->field##_changed(value); \ + } \ } #define SET_PREFERENCE_DOUBLE(usegroup, field) \ SET_PREFERENCE_DOUBLE_EXT(usegroup, field, ) #define SET_PREFERENCE_ENUM_EXT(usegroup, type, field, usestruct) \ - void qPref##usegroup::set_##field(type value) \ - { \ - if (value != prefs.usestruct field) { \ - prefs.usestruct field = value; \ - disk_##field(true); \ - emit field##_changed(value); \ - } \ + void qPref##usegroup::set_##field(type value) \ + { \ + if (value != prefs.usestruct field) { \ + prefs.usestruct field = value; \ + disk_##field(true); \ + emit qPref##usegroup::instance()->field##_changed(value); \ + } \ } #define SET_PREFERENCE_ENUM(usegroup, type, field) \ SET_PREFERENCE_ENUM_EXT(usegroup, type, field, ) #define SET_PREFERENCE_INT_EXT(usegroup, field, usestruct) \ - void qPref##usegroup::set_##field(int value) \ - { \ - if (value != prefs.usestruct field) { \ - prefs.usestruct field = value; \ - disk_##field(true); \ - emit field##_changed(value); \ - } \ + void qPref##usegroup::set_##field(int value) \ + { \ + if (value != prefs.usestruct field) { \ + prefs.usestruct field = value; \ + disk_##field(true); \ + emit qPref##usegroup::instance()->field##_changed(value); \ + } \ } #define SET_PREFERENCE_INT(usegroup, field) \ SET_PREFERENCE_INT_EXT(usegroup, field, ) #define SET_PREFERENCE_STRUCT_EXT(usegroup, type, field, var, usestruct) \ - void qPref##usegroup::set_##field(type value) \ - { \ - if (value. var != prefs.usestruct field . var) { \ - prefs.usestruct field . var = value . var; \ - disk_##field(true); \ - emit field##_changed(value); \ - } \ + void qPref##usegroup::set_##field(type value) \ + { \ + if (value. var != prefs.usestruct field . var) { \ + prefs.usestruct field . var = value . var; \ + disk_##field(true); \ + emit qPref##usegroup::instance()->field##_changed(value); \ + } \ } #define SET_PREFERENCE_STRUCT(usegroup, type, field, var) \ SET_PREFERENCE_STRUCT_EXT(usegroup, type, field, var, ) -#define SET_PREFERENCE_TXT_EXT(usegroup, field, usestruct) \ - void qPref##usegroup::set_##field(const QString &value) \ - { \ - if (value != prefs.usestruct field) { \ - qPrefPrivate::instance()->copy_txt(&prefs.usestruct field, value); \ - disk_##field(true); \ - emit field##_changed(value); \ - } \ +#define SET_PREFERENCE_TXT_EXT(usegroup, field, usestruct) \ + void qPref##usegroup::set_##field(const QString &value) \ + { \ + if (value != prefs.usestruct field) { \ + qPrefPrivate::copy_txt(&prefs.usestruct field, value); \ + disk_##field(true); \ + emit qPref##usegroup::instance()->field##_changed(value); \ + } \ } #define SET_PREFERENCE_TXT(usegroup, field) \ SET_PREFERENCE_TXT_EXT(usegroup, field, ) //******* Macros to generate set/set/loadsync combined #define HANDLE_PREFERENCE_BOOL_EXT(usegroup, name, field, usestruct) \ - SET_PREFERENCE_BOOL_EXT(usegroup, field, usestruct); \ + SET_PREFERENCE_BOOL_EXT(usegroup, field, usestruct); \ DISK_LOADSYNC_BOOL_EXT(usegroup, name, field, usestruct); #define HANDLE_PREFERENCE_BOOL(usegroup, name, field) \ HANDLE_PREFERENCE_BOOL_EXT(usegroup, name, field, ) #define HANDLE_PREFERENCE_DOUBLE_EXT(usegroup, name, field, usestruct) \ - SET_PREFERENCE_DOUBLE_EXT(usegroup, field, usestruct); \ + SET_PREFERENCE_DOUBLE_EXT(usegroup, field, usestruct); \ DISK_LOADSYNC_DOUBLE_EXT(usegroup, name, field, usestruct); #define HANDLE_PREFERENCE_DOUBLE(usegroup, name, field) \ HANDLE_PREFERENCE_DOUBLE_EXT(usegroup, name, field, ) #define HANDLE_PREFERENCE_ENUM_EXT(usegroup, type, name, field, usestruct) \ - SET_PREFERENCE_ENUM_EXT(usegroup, type, field, usestruct); \ + SET_PREFERENCE_ENUM_EXT(usegroup, type, field, usestruct); \ DISK_LOADSYNC_ENUM_EXT(usegroup, name, type, field, usestruct); #define HANDLE_PREFERENCE_ENUM(usegroup, type, name, field) \ HANDLE_PREFERENCE_ENUM_EXT(usegroup, type, name, field, ) #define HANDLE_PREFERENCE_INT_EXT(usegroup, name, field, usestruct) \ - SET_PREFERENCE_INT_EXT(usegroup, field, usestruct); \ + SET_PREFERENCE_INT_EXT(usegroup, field, usestruct); \ DISK_LOADSYNC_INT_EXT(usegroup, name, field, usestruct); #define HANDLE_PREFERENCE_INT(usegroup, name, field) \ HANDLE_PREFERENCE_INT_EXT(usegroup, name, field, ) #define HANDLE_PREFERENCE_INT_DEF_EXT(usegroup, name, field, defval, usestruct) \ - SET_PREFERENCE_INT_EXT(usegroup, field, usestruct); \ + SET_PREFERENCE_INT_EXT(usegroup, field, usestruct); \ DISK_LOADSYNC_INT_DEF_EXT(usegroup, name, field, defval, usestruct); #define HANDLE_PREFERENCE_INT_DEF(usegroup, name, field, defval) \ HANDLE_PREFERENCE_INT_DEF_EXT(usegroup, name, field, defval, ) @@ -227,9 +212,92 @@ private: HANDLE_PREFERENCE_STRUCT_EXT(usegroup, type, name, field, var, ) #define HANDLE_PREFERENCE_TXT_EXT(usegroup, name, field, usestruct) \ - SET_PREFERENCE_TXT_EXT(usegroup, field, usestruct); \ + SET_PREFERENCE_TXT_EXT(usegroup, field, usestruct); \ DISK_LOADSYNC_TXT_EXT(usegroup, name, field, usestruct); #define HANDLE_PREFERENCE_TXT(usegroup, name, field) \ HANDLE_PREFERENCE_TXT_EXT(usegroup, name, field, ) +#define HANDLE_PROP_QPOINTF(useclass, name, field) \ + void qPref##useclass::set_##field(const QPointF& value) \ + { \ + if (value != st_##field) { \ + st_##field = value; \ + qPrefPrivate::propSetValue(name, st_##field); \ + emit qPref##useclass::instance()->field##_changed(value); \ + } \ + } \ + void qPref##useclass::load_##field() \ + { \ + st_##field = qPrefPrivate::propValue(name, st_##field##_default).toPointF(); \ + } + +#define HANDLE_PROP_QSTRING(useclass, name, field) \ + void qPref##useclass::set_##field(const QString& value) \ + { \ + if (value != st_##field) { \ + st_##field = value; \ + qPrefPrivate::propSetValue(name, st_##field); \ + emit qPref##useclass::instance()->field##_changed(value); \ + } \ + } \ + void qPref##useclass::load_##field() \ + { \ + st_##field = qPrefPrivate::propValue(name, st_##field##_default).toString(); \ + } + +#define HANDLE_PROP_BOOL(useclass, name, field) \ + void qPref##useclass::set_##field(bool value) \ + { \ + if (value != st_##field) { \ + st_##field = value; \ + qPrefPrivate::propSetValue(name, st_##field); \ + emit qPref##useclass::instance()->field##_changed(value); \ + } \ + } \ + void qPref##useclass::load_##field() \ + { \ + st_##field = qPrefPrivate::propValue(name, st_##field##_default).toBool(); \ + } + +#define HANDLE_PROP_DOUBLE(useclass, name, field) \ + void qPref##useclass::set_##field(double value) \ + { \ + if (value != st_##field) { \ + st_##field = value; \ + qPrefPrivate::propSetValue(name, st_##field); \ + emit qPref##useclass::instance()->field##_changed(value); \ + } \ + } \ + void qPref##useclass::load_##field() \ + { \ + st_##field = qPrefPrivate::propValue(name, st_##field##_default).toDouble(); \ + } + +#define HANDLE_PROP_INT(useclass, name, field) \ + void qPref##useclass::set_##field(int value) \ + { \ + if (value != st_##field) { \ + st_##field = value; \ + qPrefPrivate::propSetValue(name, st_##field); \ + emit qPref##useclass::instance()->field##_changed(value); \ + } \ + } \ + void qPref##useclass::load_##field() \ + { \ + st_##field = qPrefPrivate::propValue(name, st_##field##_default).toInt(); \ + } + +#define HANDLE_PROP_QBYTEARRAY(useclass, name, field) \ + void qPref##useclass::set_##field(const QByteArray& value) \ + { \ + if (value != st_##field) { \ + st_##field = value; \ + qPrefPrivate::propSetValue(name, st_##field); \ + emit qPref##useclass::instance()->field##_changed(value); \ + } \ + } \ + void qPref##useclass::load_##field() \ + { \ + st_##field = qPrefPrivate::propValue(name, st_##field##_default).toByteArray(); \ + } #endif diff --git a/core/settings/qPrefProxy.cpp b/core/settings/qPrefProxy.cpp index 540d64dde..a1b491c10 100644 --- a/core/settings/qPrefProxy.cpp +++ b/core/settings/qPrefProxy.cpp @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -#include "qPref.h" +#include "qPrefProxy.h" #include "qPrefPrivate.h" #include <QNetworkProxy> diff --git a/core/settings/qPrefProxy.h b/core/settings/qPrefProxy.h index abca19c06..e1ead178e 100644 --- a/core/settings/qPrefProxy.h +++ b/core/settings/qPrefProxy.h @@ -20,9 +20,9 @@ public: static qPrefProxy *instance(); // Load/Sync local settings (disk) and struct preference - void loadSync(bool doSync); - void load() { loadSync(false); } - void sync() { loadSync(true); } + static void loadSync(bool doSync); + static void load() { loadSync(false); } + static void sync() { loadSync(true); } public: static bool proxy_auth() { return prefs.proxy_auth; } @@ -33,12 +33,12 @@ public: static QString proxy_user() { return prefs.proxy_user; } public slots: - void set_proxy_auth(bool value); - void set_proxy_host(const QString &value); - void set_proxy_pass(const QString &value); - void set_proxy_port(int value); - void set_proxy_type(int value); - void set_proxy_user(const QString &value); + static void set_proxy_auth(bool value); + static void set_proxy_host(const QString &value); + static void set_proxy_pass(const QString &value); + static void set_proxy_port(int value); + static void set_proxy_type(int value); + static void set_proxy_user(const QString &value); signals: void proxy_auth_changed(bool value); @@ -49,12 +49,12 @@ signals: void proxy_user_changed(const QString &value); private: - void disk_proxy_auth(bool doSync); - void disk_proxy_host(bool doSync); - void disk_proxy_pass(bool doSync); - void disk_proxy_port(bool doSync); - void disk_proxy_type(bool doSync); - void disk_proxy_user(bool doSync); + static void disk_proxy_auth(bool doSync); + static void disk_proxy_host(bool doSync); + static void disk_proxy_pass(bool doSync); + static void disk_proxy_port(bool doSync); + static void disk_proxy_type(bool doSync); + static void disk_proxy_user(bool doSync); }; #endif diff --git a/core/settings/qPrefTechnicalDetails.cpp b/core/settings/qPrefTechnicalDetails.cpp index 9482ba54d..038b5a9fc 100644 --- a/core/settings/qPrefTechnicalDetails.cpp +++ b/core/settings/qPrefTechnicalDetails.cpp @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -#include "qPref.h" +#include "qPrefTechnicalDetails.h" #include "qPrefPrivate.h" diff --git a/core/settings/qPrefTechnicalDetails.h b/core/settings/qPrefTechnicalDetails.h index 44981c2dc..b9a58c3c9 100644 --- a/core/settings/qPrefTechnicalDetails.h +++ b/core/settings/qPrefTechnicalDetails.h @@ -41,10 +41,11 @@ public: static qPrefTechnicalDetails *instance(); // Load/Sync local settings (disk) and struct preference - void loadSync(bool doSync); - void load() { loadSync(false); } - void sync() { loadSync(true); } + static void loadSync(bool doSync); + static void load() { loadSync(false); } + static void sync() { loadSync(true); } +public: static bool calcalltissues() { return prefs.calcalltissues; } static bool calcceiling() { return prefs.calcceiling; } static bool calcceiling3m() { return prefs.calcceiling3m; } @@ -74,33 +75,33 @@ public: static bool zoomed_plot() { return prefs.zoomed_plot; } public slots: - void set_calcalltissues(bool value); - void set_calcceiling(bool value); - void set_calcceiling3m(bool value); - void set_calcndltts(bool value); - void set_dcceiling(bool value); - void set_display_deco_mode(deco_mode value); - void set_display_unused_tanks(bool value); - void set_ead(bool value); - void set_gfhigh(int value); - void set_gflow(int value); - void set_gf_low_at_maxdepth(bool value); - void set_hrgraph(bool value); - void set_mod(bool value); - void set_modpO2(double value); - void set_percentagegraph(bool value); - void set_redceiling(bool value); - void set_rulergraph(bool value); - void set_show_average_depth(bool value); - void set_show_ccr_sensors(bool value); - void set_show_ccr_setpoint(bool value); - void set_show_icd(bool value); - void set_show_pictures_in_profile(bool value); - void set_show_sac(bool value); - void set_show_scr_ocpo2(bool value); - void set_tankbar(bool value); - void set_vpmb_conservatism(int value); - void set_zoomed_plot(bool value); + static void set_calcalltissues(bool value); + static void set_calcceiling(bool value); + static void set_calcceiling3m(bool value); + static void set_calcndltts(bool value); + static void set_dcceiling(bool value); + static void set_display_deco_mode(deco_mode value); + static void set_display_unused_tanks(bool value); + static void set_ead(bool value); + static void set_gfhigh(int value); + static void set_gflow(int value); + static void set_gf_low_at_maxdepth(bool value); + static void set_hrgraph(bool value); + static void set_mod(bool value); + static void set_modpO2(double value); + static void set_percentagegraph(bool value); + static void set_redceiling(bool value); + static void set_rulergraph(bool value); + static void set_show_average_depth(bool value); + static void set_show_ccr_sensors(bool value); + static void set_show_ccr_setpoint(bool value); + static void set_show_icd(bool value); + static void set_show_pictures_in_profile(bool value); + static void set_show_sac(bool value); + static void set_show_scr_ocpo2(bool value); + static void set_tankbar(bool value); + static void set_vpmb_conservatism(int value); + static void set_zoomed_plot(bool value); signals: void calcalltissues_changed(bool value); @@ -132,33 +133,33 @@ signals: void zoomed_plot_changed(bool value); private: - void disk_calcalltissues(bool doSync); - void disk_calcceiling(bool doSync); - void disk_calcceiling3m(bool doSync); - void disk_calcndltts(bool doSync); - void disk_dcceiling(bool doSync); - void disk_display_deco_mode(bool doSync); - void disk_display_unused_tanks(bool doSync); - void disk_ead(bool doSync); - void disk_gfhigh(bool doSync); - void disk_gflow(bool doSync); - void disk_gf_low_at_maxdepth(bool doSync); - void disk_hrgraph(bool doSync); - void disk_mod(bool doSync); - void disk_modpO2(bool doSync); - void disk_percentagegraph(bool doSync); - void disk_redceiling(bool doSync); - void disk_rulergraph(bool doSync); - void disk_show_average_depth(bool doSync); - void disk_show_ccr_sensors(bool doSync); - void disk_show_ccr_setpoint(bool doSync); - void disk_show_icd(bool doSync); - void disk_show_pictures_in_profile(bool doSync); - void disk_show_sac(bool doSync); - void disk_show_scr_ocpo2(bool doSync); - void disk_tankbar(bool doSync); - void disk_vpmb_conservatism(bool doSync); - void disk_zoomed_plot(bool doSync); + static void disk_calcalltissues(bool doSync); + static void disk_calcceiling(bool doSync); + static void disk_calcceiling3m(bool doSync); + static void disk_calcndltts(bool doSync); + static void disk_dcceiling(bool doSync); + static void disk_display_deco_mode(bool doSync); + static void disk_display_unused_tanks(bool doSync); + static void disk_ead(bool doSync); + static void disk_gfhigh(bool doSync); + static void disk_gflow(bool doSync); + static void disk_gf_low_at_maxdepth(bool doSync); + static void disk_hrgraph(bool doSync); + static void disk_mod(bool doSync); + static void disk_modpO2(bool doSync); + static void disk_percentagegraph(bool doSync); + static void disk_redceiling(bool doSync); + static void disk_rulergraph(bool doSync); + static void disk_show_average_depth(bool doSync); + static void disk_show_ccr_sensors(bool doSync); + static void disk_show_ccr_setpoint(bool doSync); + static void disk_show_icd(bool doSync); + static void disk_show_pictures_in_profile(bool doSync); + static void disk_show_sac(bool doSync); + static void disk_show_scr_ocpo2(bool doSync); + static void disk_tankbar(bool doSync); + static void disk_vpmb_conservatism(bool doSync); + static void disk_zoomed_plot(bool doSync); }; #endif diff --git a/core/settings/qPrefUnit.cpp b/core/settings/qPrefUnit.cpp index b0b45a881..c48421fd4 100644 --- a/core/settings/qPrefUnit.cpp +++ b/core/settings/qPrefUnit.cpp @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -#include "qPref.h" +#include "qPrefUnit.h" #include "qPrefPrivate.h" @@ -63,7 +63,7 @@ void qPrefUnits::set_unit_system(const QString& value) prefs.unit_system = PERSONALIZE; } disk_unit_system(true); - emit unit_system_changed(value); + emit instance()->unit_system_changed(value); } } DISK_LOADSYNC_ENUM(Units, "/unit_system", unit_system_values, unit_system); diff --git a/core/settings/qPrefUnit.h b/core/settings/qPrefUnit.h index 70ccadadd..bc4273546 100644 --- a/core/settings/qPrefUnit.h +++ b/core/settings/qPrefUnit.h @@ -24,9 +24,9 @@ public: static qPrefUnits *instance(); // Load/Sync local settings (disk) and struct preference - void loadSync(bool doSync); - void load() { loadSync(false); } - void sync() { loadSync(true); } + static void loadSync(bool doSync); + static void load() { loadSync(false); } + static void sync() { loadSync(true); } public: static bool coordinates_traditional() { return prefs.coordinates_traditional; } @@ -41,16 +41,16 @@ public: static units::WEIGHT weight() { return prefs.units.weight; } public slots: - void set_coordinates_traditional(bool value); - void set_duration_units(units::DURATION value); - void set_length(units::LENGTH value); - void set_pressure(units::PRESSURE value); - void set_show_units_table(bool value); - void set_temperature(units::TEMPERATURE value); - void set_unit_system(const QString& value); - void set_vertical_speed_time(units::TIME value); - void set_volume(units::VOLUME value); - void set_weight(units::WEIGHT value); + static void set_coordinates_traditional(bool value); + static void set_duration_units(units::DURATION value); + static void set_length(units::LENGTH value); + static void set_pressure(units::PRESSURE value); + static void set_show_units_table(bool value); + static void set_temperature(units::TEMPERATURE value); + static void set_unit_system(const QString& value); + static void set_vertical_speed_time(units::TIME value); + static void set_volume(units::VOLUME value); + static void set_weight(units::WEIGHT value); signals: void coordinates_traditional_changed(bool value); @@ -65,16 +65,16 @@ signals: void weight_changed(int value); private: - void disk_coordinates_traditional(bool doSync); - void disk_duration_units(bool doSync); - void disk_length(bool doSync); - void disk_pressure(bool doSync); - void disk_show_units_table(bool doSync); - void disk_temperature(bool doSync); - void disk_unit_system(bool doSync); - void disk_vertical_speed_time(bool doSync); - void disk_volume(bool doSync); - void disk_weight(bool doSync); + static void disk_coordinates_traditional(bool doSync); + static void disk_duration_units(bool doSync); + static void disk_length(bool doSync); + static void disk_pressure(bool doSync); + static void disk_show_units_table(bool doSync); + static void disk_temperature(bool doSync); + static void disk_unit_system(bool doSync); + static void disk_vertical_speed_time(bool doSync); + static void disk_volume(bool doSync); + static void disk_weight(bool doSync); }; #endif diff --git a/core/settings/qPrefUpdateManager.cpp b/core/settings/qPrefUpdateManager.cpp index 2c8b8d70e..709631519 100644 --- a/core/settings/qPrefUpdateManager.cpp +++ b/core/settings/qPrefUpdateManager.cpp @@ -1,10 +1,13 @@ // SPDX-License-Identifier: GPL-2.0 -#include "qPref.h" +#include "qPrefUpdateManager.h" #include "qPrefPrivate.h" static const QString group = QStringLiteral("UpdateManager"); +QString qPrefUpdateManager::st_uuidString; +static const QString st_uuidString_default = ""; + qPrefUpdateManager::qPrefUpdateManager(QObject *parent) : QObject(parent) { } @@ -21,6 +24,9 @@ void qPrefUpdateManager::loadSync(bool doSync) disk_dont_check_for_updates(doSync); disk_last_version_used(doSync); disk_next_check(doSync); + if (!doSync) { + load_uuidString(); + } } @@ -30,7 +36,7 @@ void qPrefUpdateManager::set_dont_check_exists(bool value) { if (value != prefs.update_manager.dont_check_exists) { prefs.update_manager.dont_check_exists = value; - emit dont_check_exists_changed(value); + emit instance()->dont_check_exists_changed(value); } // DO NOT STORE ON DISK } @@ -41,12 +47,19 @@ HANDLE_PREFERENCE_TXT_EXT(UpdateManager, "/LastVersionUsed", last_version_used, void qPrefUpdateManager::set_next_check(const QDate& value) { - QString valueString = value.toString("dd/MM/yyyy"); - if (valueString != prefs.update_manager.next_check) { - qPrefPrivate::copy_txt(&prefs.update_manager.next_check, valueString); + long time_value = value.toJulianDay(); + if (time_value != prefs.update_manager.next_check) { + prefs.update_manager.next_check = time_value; disk_next_check(true); - emit next_check_changed(value); + emit instance()->next_check_changed(value); } } -DISK_LOADSYNC_TXT_EXT(UpdateManager, "/NextCheck", next_check, update_manager.); +void qPrefUpdateManager::disk_next_check(bool doSync) +{ + if (doSync) + qPrefPrivate::propSetValue(group + "/NextCheck", prefs.update_manager.next_check); + else + prefs.update_manager.next_check = qPrefPrivate::propValue(group + "/NextCheck", 0).toInt(); +} +HANDLE_PROP_QSTRING(UpdateManager, "UodateManager/UUID", uuidString); diff --git a/core/settings/qPrefUpdateManager.h b/core/settings/qPrefUpdateManager.h index 19943d2b7..151c2edc4 100644 --- a/core/settings/qPrefUpdateManager.h +++ b/core/settings/qPrefUpdateManager.h @@ -12,38 +12,48 @@ class qPrefUpdateManager : public QObject { Q_PROPERTY(bool dont_check_exists READ dont_check_exists WRITE set_dont_check_exists NOTIFY dont_check_exists_changed); Q_PROPERTY(const QString last_version_used READ last_version_used WRITE set_last_version_used NOTIFY last_version_used_changed); Q_PROPERTY(const QDate next_check READ next_check WRITE set_next_check NOTIFY next_check_changed); + Q_PROPERTY(const QString uuidString READ uuidString WRITE set_uuidString NOTIFY uuidString_changed); public: qPrefUpdateManager(QObject *parent = NULL); static qPrefUpdateManager *instance(); // Load/Sync local settings (disk) and struct preference - void loadSync(bool doSync); - void load() { loadSync(false); } - void sync() { loadSync(true); } + static void loadSync(bool doSync); + static void load() { loadSync(false); } + static void sync() { loadSync(true); } public: - bool dont_check_for_updates() { return prefs.update_manager.dont_check_for_updates; } - bool dont_check_exists() { return prefs.update_manager.dont_check_exists; } - const QString last_version_used() { return prefs.update_manager.last_version_used; } - const QDate next_check() { return QDate::fromString(QString(prefs.update_manager.next_check), "dd/MM/yyyy"); } + static bool dont_check_for_updates() { return prefs.update_manager.dont_check_for_updates; } + static bool dont_check_exists() { return prefs.update_manager.dont_check_exists; } + static const QString last_version_used() { return prefs.update_manager.last_version_used; } + static const QDate next_check() { return QDate::fromJulianDay(prefs.update_manager.next_check); } + static const QString uuidString() { return st_uuidString; } public slots: - void set_dont_check_for_updates(bool value); - void set_dont_check_exists(bool value); - void set_last_version_used(const QString& value); - void set_next_check(const QDate& value); + static void set_dont_check_for_updates(bool value); + static void set_dont_check_exists(bool value); + static void set_last_version_used(const QString& value); + static void set_next_check(const QDate& value); + static void set_uuidString(const QString& value); signals: void dont_check_for_updates_changed(bool value); void dont_check_exists_changed(bool value); void last_version_used_changed(const QString& value); void next_check_changed(const QDate& value); + void uuidString_changed(const QString& value); private: - void disk_dont_check_for_updates(bool doSync); - void disk_last_version_used(bool doSync); - void disk_next_check(bool doSync); + static void disk_dont_check_for_updates(bool doSync); + static void disk_last_version_used(bool doSync); + static void disk_next_check(bool doSync); + + // load only for class variables + static void load_uuidString(); + + // class variables not present in structure preferences + static QString st_uuidString; }; #endif diff --git a/core/statistics.c b/core/statistics.c index 58d851611..beeb258a6 100644 --- a/core/statistics.c +++ b/core/statistics.c @@ -236,10 +236,10 @@ void process_selected_dives(void) #define SOME_GAS 5000 // 5bar drop in cylinder pressure makes cylinder used -bool has_gaschange_event(struct dive *dive, struct divecomputer *dc, int idx) +bool has_gaschange_event(const struct dive *dive, const struct divecomputer *dc, int idx) { bool first_gas_explicit = false; - struct event *event = get_next_event(dc->events, "gaschange"); + const struct event *event = get_next_event(dc->events, "gaschange"); while (event) { if (dc->sample && (event->time.seconds == 0 || (dc->samples && dc->sample[0].time.seconds == event->time.seconds))) @@ -257,9 +257,9 @@ bool has_gaschange_event(struct dive *dive, struct divecomputer *dc, int idx) return !first_gas_explicit && idx == 0; } -bool is_cylinder_used(struct dive *dive, int idx) +bool is_cylinder_used(const struct dive *dive, int idx) { - struct divecomputer *dc; + const struct divecomputer *dc; if (cylinder_none(&dive->cylinder[idx])) return false; @@ -276,9 +276,9 @@ bool is_cylinder_used(struct dive *dive, int idx) return false; } -bool is_cylinder_prot(struct dive *dive, int idx) +bool is_cylinder_prot(const struct dive *dive, int idx) { - struct divecomputer *dc; + const struct divecomputer *dc; if (cylinder_none(&dive->cylinder[idx])) return false; @@ -309,14 +309,14 @@ static void get_gas_parts(struct gasmix mix, volume_t vol, int o2_in_topup, volu { volume_t air = {}; - if (gasmix_is_air(&mix)) { + if (gasmix_is_air(mix)) { o2->mliter = 0; he->mliter = 0; return; } - air.mliter = lrint(((double)vol.mliter * (1000 - get_he(&mix) - get_o2(&mix))) / (1000 - o2_in_topup)); - he->mliter = lrint(((double)vol.mliter * get_he(&mix)) / 1000.0); + air.mliter = lrint(((double)vol.mliter * (1000 - get_he(mix) - get_o2(mix))) / (1000 - o2_in_topup)); + he->mliter = lrint(((double)vol.mliter * get_he(mix)) / 1000.0); o2->mliter += vol.mliter - he->mliter - air.mliter; } diff --git a/core/subsurface-qt/DiveObjectHelper.cpp b/core/subsurface-qt/DiveObjectHelper.cpp index 15291554d..a69c73ddc 100644 --- a/core/subsurface-qt/DiveObjectHelper.cpp +++ b/core/subsurface-qt/DiveObjectHelper.cpp @@ -207,7 +207,7 @@ QString DiveObjectHelper::gas() const gas = m_dive->cylinder[i].type.description; if (!gas.isEmpty()) gas += QChar(' '); - gas += gasname(&m_dive->cylinder[i].gasmix); + gas += gasname(m_dive->cylinder[i].gasmix); // if has a description and if such gas is not already present if (!gas.isEmpty() && gases.indexOf(gas) == -1) { if (!gases.isEmpty()) diff --git a/core/subsurface-qt/SettingsObjectWrapper.cpp b/core/subsurface-qt/SettingsObjectWrapper.cpp deleted file mode 100644 index 84ffc5a26..000000000 --- a/core/subsurface-qt/SettingsObjectWrapper.cpp +++ /dev/null @@ -1,625 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "SettingsObjectWrapper.h" -#include <QSettings> -#include <QApplication> -#include <QFont> -#include <QDate> - -#include "core/qthelper.h" -#include "core/prefs-macros.h" - -PartialPressureGasSettings::PartialPressureGasSettings(QObject* parent): - QObject(parent) -{ - -} - -bool PartialPressureGasSettings::showPo2() const -{ - return prefs.pp_graphs.po2; -} - -bool PartialPressureGasSettings::showPn2() const -{ - return prefs.pp_graphs.pn2; -} - -bool PartialPressureGasSettings::showPhe() const -{ - return prefs.pp_graphs.phe; -} - -double PartialPressureGasSettings::po2ThresholdMin() const -{ - return prefs.pp_graphs.po2_threshold_min; -} - -double PartialPressureGasSettings::po2ThresholdMax() const -{ - return prefs.pp_graphs.po2_threshold_max; -} - - -double PartialPressureGasSettings::pn2Threshold() const -{ - return prefs.pp_graphs.pn2_threshold; -} - -double PartialPressureGasSettings::pheThreshold() const -{ - return prefs.pp_graphs.phe_threshold; -} - -void PartialPressureGasSettings::setShowPo2(bool value) -{ - if (value == prefs.pp_graphs.po2) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("po2graph", value); - prefs.pp_graphs.po2 = value; - emit showPo2Changed(value); -} - -void PartialPressureGasSettings::setShowPn2(bool value) -{ - if (value == prefs.pp_graphs.pn2) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("pn2graph", value); - prefs.pp_graphs.pn2 = value; - emit showPn2Changed(value); -} - -void PartialPressureGasSettings::setShowPhe(bool value) -{ - if (value == prefs.pp_graphs.phe) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("phegraph", value); - prefs.pp_graphs.phe = value; - emit showPheChanged(value); -} - -void PartialPressureGasSettings::setPo2ThresholdMin(double value) -{ - if (value == prefs.pp_graphs.po2_threshold_min) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("po2thresholdmin", value); - prefs.pp_graphs.po2_threshold_min = value; - emit po2ThresholdMinChanged(value); -} - -void PartialPressureGasSettings::setPo2ThresholdMax(double value) -{ - if (value == prefs.pp_graphs.po2_threshold_max) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("po2thresholdmax", value); - prefs.pp_graphs.po2_threshold_max = value; - emit po2ThresholdMaxChanged(value); -} - -void PartialPressureGasSettings::setPn2Threshold(double value) -{ - if (value == prefs.pp_graphs.pn2_threshold) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("pn2threshold", value); - prefs.pp_graphs.pn2_threshold = value; - emit pn2ThresholdChanged(value); -} - -void PartialPressureGasSettings::setPheThreshold(double value) -{ - if (value == prefs.pp_graphs.phe_threshold) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("phethreshold", value); - prefs.pp_graphs.phe_threshold = value; - emit pheThresholdChanged(value); -} - -GeocodingPreferences::GeocodingPreferences(QObject *parent) : - QObject(parent) -{ - -} - -taxonomy_category GeocodingPreferences::firstTaxonomyCategory() const -{ - return prefs.geocoding.category[0]; -} - -taxonomy_category GeocodingPreferences::secondTaxonomyCategory() const -{ - return prefs.geocoding.category[1]; -} - -taxonomy_category GeocodingPreferences::thirdTaxonomyCategory() const -{ - return prefs.geocoding.category[2]; -} - -void GeocodingPreferences::setFirstTaxonomyCategory(taxonomy_category value) -{ - if (value == prefs.geocoding.category[0]) - return; - QSettings s; - s.beginGroup(group); - s.setValue("cat0", value); - prefs.geocoding.category[0] = value; - emit firstTaxonomyCategoryChanged(value); -} - -void GeocodingPreferences::setSecondTaxonomyCategory(taxonomy_category value) -{ - if (value == prefs.geocoding.category[1]) - return; - QSettings s; - s.beginGroup(group); - s.setValue("cat1", value); - prefs.geocoding.category[1]= value; - emit secondTaxonomyCategoryChanged(value); -} - -void GeocodingPreferences::setThirdTaxonomyCategory(taxonomy_category value) -{ - if (value == prefs.geocoding.category[2]) - return; - QSettings s; - s.beginGroup(group); - s.setValue("cat2", value); - prefs.geocoding.category[2] = value; - emit thirdTaxonomyCategoryChanged(value); -} - -GeneralSettingsObjectWrapper::GeneralSettingsObjectWrapper(QObject *parent) : - QObject(parent) -{ -} - -QString GeneralSettingsObjectWrapper::defaultFilename() const -{ - return prefs.default_filename; -} - -QString GeneralSettingsObjectWrapper::defaultCylinder() const -{ - return prefs.default_cylinder; -} - -short GeneralSettingsObjectWrapper::defaultFileBehavior() const -{ - return prefs.default_file_behavior; -} - -bool GeneralSettingsObjectWrapper::useDefaultFile() const -{ - return prefs.use_default_file; -} - -int GeneralSettingsObjectWrapper::defaultSetPoint() const -{ - return prefs.defaultsetpoint; -} - -int GeneralSettingsObjectWrapper::o2Consumption() const -{ - return prefs.o2consumption; -} - -int GeneralSettingsObjectWrapper::pscrRatio() const -{ - return prefs.pscr_ratio; -} - -bool GeneralSettingsObjectWrapper::autoRecalculateThumbnails() const -{ - return prefs.auto_recalculate_thumbnails; -} - -bool GeneralSettingsObjectWrapper::extractVideoThumbnails() const -{ - return prefs.extract_video_thumbnails; -} - -int GeneralSettingsObjectWrapper::extractVideoThumbnailsPosition() const -{ - return prefs.extract_video_thumbnails_position; -} - -QString GeneralSettingsObjectWrapper::ffmpegExecutable() const -{ - return prefs.ffmpeg_executable; -} - -void GeneralSettingsObjectWrapper::setDefaultFilename(const QString& value) -{ - if (value == prefs.default_filename) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("default_filename", value); - free((void *)prefs.default_filename); - prefs.default_filename = copy_qstring(value); - emit defaultFilenameChanged(value); -} - -void GeneralSettingsObjectWrapper::setDefaultCylinder(const QString& value) -{ - if (value == prefs.default_cylinder) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("default_cylinder", value); - free((void *)prefs.default_cylinder); - prefs.default_cylinder = copy_qstring(value); - emit defaultCylinderChanged(value); -} - -void GeneralSettingsObjectWrapper::setDefaultFileBehavior(short value) -{ - if (value == prefs.default_file_behavior && prefs.default_file_behavior != UNDEFINED_DEFAULT_FILE) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("default_file_behavior", value); - - prefs.default_file_behavior = value; - if (prefs.default_file_behavior == UNDEFINED_DEFAULT_FILE) { - // undefined, so check if there's a filename set and - // use that, otherwise go with no default file - if (QString(prefs.default_filename).isEmpty()) - prefs.default_file_behavior = NO_DEFAULT_FILE; - else - prefs.default_file_behavior = LOCAL_DEFAULT_FILE; - } - emit defaultFileBehaviorChanged(value); -} - -void GeneralSettingsObjectWrapper::setUseDefaultFile(bool value) -{ - if (value == prefs.use_default_file) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("use_default_file", value); - prefs.use_default_file = value; - emit useDefaultFileChanged(value); -} - -void GeneralSettingsObjectWrapper::setDefaultSetPoint(int value) -{ - if (value == prefs.defaultsetpoint) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("defaultsetpoint", value); - prefs.defaultsetpoint = value; - emit defaultSetPointChanged(value); -} - -void GeneralSettingsObjectWrapper::setO2Consumption(int value) -{ - if (value == prefs.o2consumption) - return; - QSettings s; - s.beginGroup(group); - s.setValue("o2consumption", value); - prefs.o2consumption = value; - emit o2ConsumptionChanged(value); -} - -void GeneralSettingsObjectWrapper::setPscrRatio(int value) -{ - if (value == prefs.pscr_ratio) - return; - QSettings s; - s.beginGroup(group); - s.setValue("pscr_ratio", value); - prefs.pscr_ratio = value; - emit pscrRatioChanged(value); -} - -void GeneralSettingsObjectWrapper::setAutoRecalculateThumbnails(bool value) -{ - if (value == prefs.auto_recalculate_thumbnails) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("auto_recalculate_thumbnails", value); - prefs.auto_recalculate_thumbnails = value; - emit autoRecalculateThumbnailsChanged(value); -} - -void GeneralSettingsObjectWrapper::setExtractVideoThumbnails(bool value) -{ - if (value == prefs.extract_video_thumbnails) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("extract_video_thumbnails", value); - prefs.extract_video_thumbnails = value; - emit extractVideoThumbnailsChanged(value); -} - -void GeneralSettingsObjectWrapper::setExtractVideoThumbnailsPosition(int value) -{ - if (value == prefs.extract_video_thumbnails_position) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("extract_video_thumbnails_position", value); - prefs.extract_video_thumbnails_position = value; - emit extractVideoThumbnailsPositionChanged(value); -} - -void GeneralSettingsObjectWrapper::setFfmpegExecutable(const QString &value) -{ - if (value == prefs.ffmpeg_executable) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("ffmpeg_executable", value); - free((void *)prefs.ffmpeg_executable); - prefs.ffmpeg_executable = copy_qstring(value); - emit ffmpegExecutableChanged(value); -} - -LanguageSettingsObjectWrapper::LanguageSettingsObjectWrapper(QObject *parent) : - QObject(parent) -{ -} - -QString LanguageSettingsObjectWrapper::language() const -{ - return prefs.locale.language; -} - -QString LanguageSettingsObjectWrapper::timeFormat() const -{ - return prefs.time_format; -} - -QString LanguageSettingsObjectWrapper::dateFormat() const -{ - return prefs.date_format; -} - -QString LanguageSettingsObjectWrapper::dateFormatShort() const -{ - return prefs.date_format_short; -} - -bool LanguageSettingsObjectWrapper::timeFormatOverride() const -{ - return prefs.time_format_override; -} - -bool LanguageSettingsObjectWrapper::dateFormatOverride() const -{ - return prefs.date_format_override; -} - -bool LanguageSettingsObjectWrapper::useSystemLanguage() const -{ - return prefs.locale.use_system_language; -} - -QString LanguageSettingsObjectWrapper::langLocale() const -{ - return prefs.locale.lang_locale; -} - -void LanguageSettingsObjectWrapper::setUseSystemLanguage(bool value) -{ - if (value == prefs.locale.use_system_language) - return; - QSettings s; - s.beginGroup(group); - s.setValue("UseSystemLanguage", value); - prefs.locale.use_system_language = value; - emit useSystemLanguageChanged(value); -} - -void LanguageSettingsObjectWrapper::setLangLocale(const QString &value) -{ - if (value == prefs.locale.lang_locale) - return; - QSettings s; - s.beginGroup(group); - s.setValue("UiLangLocale", value); - free((void *)prefs.locale.lang_locale); - prefs.locale.lang_locale = copy_qstring(value); - emit langLocaleChanged(value); -} - -void LanguageSettingsObjectWrapper::setLanguage(const QString& value) -{ - if (value == prefs.locale.language) - return; - QSettings s; - s.beginGroup(group); - s.setValue("UiLanguage", value); - free((void *)prefs.locale.language); - prefs.locale.language = copy_qstring(value); - emit languageChanged(value); -} - -void LanguageSettingsObjectWrapper::setTimeFormat(const QString& value) -{ - if (value == prefs.time_format) - return; - QSettings s; - s.beginGroup(group); - s.setValue("time_format", value); - free((void *)prefs.time_format); - prefs.time_format = copy_qstring(value); - emit timeFormatChanged(value); -} - -void LanguageSettingsObjectWrapper::setDateFormat(const QString& value) -{ - if (value == prefs.date_format) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("date_format", value); - free((void *)prefs.date_format); - prefs.date_format = copy_qstring(value); - emit dateFormatChanged(value); -} - -void LanguageSettingsObjectWrapper::setDateFormatShort(const QString& value) -{ - if (value == prefs.date_format_short) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("date_format_short", value); - free((void *)prefs.date_format_short); - prefs.date_format_short = copy_qstring(value); - emit dateFormatShortChanged(value); -} - -void LanguageSettingsObjectWrapper::setTimeFormatOverride(bool value) -{ - if (value == prefs.time_format_override) - return; - QSettings s; - s.beginGroup(group); - s.setValue("time_format_override", value); - prefs.time_format_override = value; - emit timeFormatOverrideChanged(value); -} - -void LanguageSettingsObjectWrapper::setDateFormatOverride(bool value) -{ - if (value == prefs.date_format_override) - return; - - QSettings s; - s.beginGroup(group); - s.setValue("date_format_override", value); - prefs.date_format_override = value; - emit dateFormatOverrideChanged(value); -} - - -SettingsObjectWrapper::SettingsObjectWrapper(QObject* parent): -QObject(parent), - techDetails(new qPrefTechnicalDetails(this)), - pp_gas(new PartialPressureGasSettings(this)), - facebook(new qPrefFacebook(this)), - geocoding(new GeocodingPreferences(this)), - proxy(new qPrefProxy(this)), - cloud_storage(new qPrefCloudStorage(this)), - planner_settings(new qPrefDivePlanner(this)), - unit_settings(new qPrefUnits(this)), - general_settings(new GeneralSettingsObjectWrapper(this)), - display_settings(new qPrefDisplay(this)), - language_settings(new LanguageSettingsObjectWrapper(this)), - animation_settings(new qPrefAnimations(this)), - location_settings(new qPrefLocationService(this)), - update_manager_settings(new qPrefUpdateManager(this)), - dive_computer_settings(new qPrefDiveComputer(this)) -{ -} - -void SettingsObjectWrapper::load() -{ - QSettings s; - QVariant v; - - uiLanguage(NULL); - - qPrefUnits::instance()->load(); - qPrefTechnicalDetails::instance()->load(); - - s.beginGroup("GeneralSettings"); - GET_TXT("default_filename", default_filename); - GET_INT("default_file_behavior", default_file_behavior); - if (prefs.default_file_behavior == UNDEFINED_DEFAULT_FILE) { - // undefined, so check if there's a filename set and - // use that, otherwise go with no default file - if (QString(prefs.default_filename).isEmpty()) - prefs.default_file_behavior = NO_DEFAULT_FILE; - else - prefs.default_file_behavior = LOCAL_DEFAULT_FILE; - } - GET_TXT("default_cylinder", default_cylinder); - GET_BOOL("use_default_file", use_default_file); - GET_INT("defaultsetpoint", defaultsetpoint); - GET_INT("o2consumption", o2consumption); - GET_INT("pscr_ratio", pscr_ratio); - GET_BOOL("auto_recalculate_thumbnails", auto_recalculate_thumbnails); - s.endGroup(); - - qPrefAnimations::instance()->load(); - qPrefCloudStorage::instance()->load(); - qPrefDisplay::instance()->load(); - qPrefProxy::instance()->load(); - - // GeoManagement - s.beginGroup("geocoding"); - - GET_ENUM("cat0", taxonomy_category, geocoding.category[0]); - GET_ENUM("cat1", taxonomy_category, geocoding.category[1]); - GET_ENUM("cat2", taxonomy_category, geocoding.category[2]); - s.endGroup(); - - // GPS service time and distance thresholds - qPrefLocationService::instance()->load(); - - qPrefDivePlanner::instance()->load(); - qPrefDiveComputer::instance()->load(); - qPrefUpdateManager::instance()->load(); - - s.beginGroup("Language"); - GET_BOOL("UseSystemLanguage", locale.use_system_language); - GET_TXT("UiLanguage", locale.language); - GET_TXT("UiLangLocale", locale.lang_locale); - GET_TXT("time_format", time_format); - GET_TXT("date_format", date_format); - GET_TXT("date_format_short", date_format_short); - GET_BOOL("time_format_override", time_format_override); - GET_BOOL("date_format_override", date_format_override); - s.endGroup(); -} - -void SettingsObjectWrapper::sync() -{ - qPrefDisplay::instance()->sync(); -} - -SettingsObjectWrapper* SettingsObjectWrapper::instance() -{ - static SettingsObjectWrapper settings; - return &settings; -} diff --git a/core/subsurface-qt/SettingsObjectWrapper.h b/core/subsurface-qt/SettingsObjectWrapper.h deleted file mode 100644 index 3af79404e..000000000 --- a/core/subsurface-qt/SettingsObjectWrapper.h +++ /dev/null @@ -1,230 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#ifndef SETTINGSOBJECTWRAPPER_H -#define SETTINGSOBJECTWRAPPER_H - -#include <QObject> -#include <QDate> - -#include "core/pref.h" -#include "core/settings/qPref.h" - -/* Wrapper class for the Settings. This will allow - * seamlessy integration of the settings with the QML - * and QWidget frontends. This class will be huge, since - * I need tons of properties, one for each option. */ - -/* Control the state of the Partial Pressure Graphs preferences */ -class PartialPressureGasSettings : public QObject { - Q_OBJECT - Q_PROPERTY(bool show_po2 READ showPo2 WRITE setShowPo2 NOTIFY showPo2Changed) - Q_PROPERTY(bool show_pn2 READ showPn2 WRITE setShowPn2 NOTIFY showPn2Changed) - Q_PROPERTY(bool show_phe READ showPhe WRITE setShowPhe NOTIFY showPheChanged) - Q_PROPERTY(double po2_threshold_min READ po2ThresholdMin WRITE setPo2ThresholdMin NOTIFY po2ThresholdMinChanged) - Q_PROPERTY(double po2_threshold_max READ po2ThresholdMax WRITE setPo2ThresholdMax NOTIFY po2ThresholdMaxChanged) - Q_PROPERTY(double pn2_threshold READ pn2Threshold WRITE setPn2Threshold NOTIFY pn2ThresholdChanged) - Q_PROPERTY(double phe_threshold READ pheThreshold WRITE setPheThreshold NOTIFY pheThresholdChanged) - -public: - PartialPressureGasSettings(QObject *parent); - bool showPo2() const; - bool showPn2() const; - bool showPhe() const; - double po2ThresholdMin() const; - double po2ThresholdMax() const; - double pn2Threshold() const; - double pheThreshold() const; - -public slots: - void setShowPo2(bool value); - void setShowPn2(bool value); - void setShowPhe(bool value); - void setPo2ThresholdMin(double value); - void setPo2ThresholdMax(double value); - void setPn2Threshold(double value); - void setPheThreshold(double value); - -signals: - void showPo2Changed(bool value); - void showPn2Changed(bool value); - void showPheChanged(bool value); - void po2ThresholdMaxChanged(double value); - void po2ThresholdMinChanged(double value); - void pn2ThresholdChanged(double value); - void pheThresholdChanged(double value); - -private: - const QString group = QStringLiteral("TecDetails"); -}; - -/* Control the state of the Geocoding preferences */ -class GeocodingPreferences : public QObject { - Q_OBJECT - Q_PROPERTY(taxonomy_category first_category READ firstTaxonomyCategory WRITE setFirstTaxonomyCategory NOTIFY firstTaxonomyCategoryChanged) - Q_PROPERTY(taxonomy_category second_category READ secondTaxonomyCategory WRITE setSecondTaxonomyCategory NOTIFY secondTaxonomyCategoryChanged) - Q_PROPERTY(taxonomy_category third_category READ thirdTaxonomyCategory WRITE setThirdTaxonomyCategory NOTIFY thirdTaxonomyCategoryChanged) -public: - GeocodingPreferences(QObject *parent); - taxonomy_category firstTaxonomyCategory() const; - taxonomy_category secondTaxonomyCategory() const; - taxonomy_category thirdTaxonomyCategory() const; - -public slots: - void setFirstTaxonomyCategory(taxonomy_category value); - void setSecondTaxonomyCategory(taxonomy_category value); - void setThirdTaxonomyCategory(taxonomy_category value); - -signals: - void firstTaxonomyCategoryChanged(taxonomy_category value); - void secondTaxonomyCategoryChanged(taxonomy_category value); - void thirdTaxonomyCategoryChanged(taxonomy_category value); -private: - const QString group = QStringLiteral("geocoding"); -}; - -class GeneralSettingsObjectWrapper : public QObject { - Q_OBJECT - Q_PROPERTY(QString default_filename READ defaultFilename WRITE setDefaultFilename NOTIFY defaultFilenameChanged) - Q_PROPERTY(QString default_cylinder READ defaultCylinder WRITE setDefaultCylinder NOTIFY defaultCylinderChanged) - Q_PROPERTY(short default_file_behavior READ defaultFileBehavior WRITE setDefaultFileBehavior NOTIFY defaultFileBehaviorChanged) - Q_PROPERTY(bool use_default_file READ useDefaultFile WRITE setUseDefaultFile NOTIFY useDefaultFileChanged) - Q_PROPERTY(int defaultsetpoint READ defaultSetPoint WRITE setDefaultSetPoint NOTIFY defaultSetPointChanged) - Q_PROPERTY(int o2consumption READ o2Consumption WRITE setO2Consumption NOTIFY o2ConsumptionChanged) - Q_PROPERTY(int pscr_ratio READ pscrRatio WRITE setPscrRatio NOTIFY pscrRatioChanged) - Q_PROPERTY(bool auto_recalculate_thumbnails READ autoRecalculateThumbnails WRITE setAutoRecalculateThumbnails NOTIFY autoRecalculateThumbnailsChanged) - Q_PROPERTY(bool extract_video_thumbnails READ extractVideoThumbnails WRITE setExtractVideoThumbnails NOTIFY extractVideoThumbnailsChanged) - Q_PROPERTY(int extract_video_thumbnails_position READ extractVideoThumbnailsPosition WRITE setExtractVideoThumbnailsPosition NOTIFY extractVideoThumbnailsPositionChanged) - Q_PROPERTY(QString ffmpeg_executable READ ffmpegExecutable WRITE setFfmpegExecutable NOTIFY ffmpegExecutableChanged) - -public: - GeneralSettingsObjectWrapper(QObject *parent); - QString defaultFilename() const; - QString defaultCylinder() const; - short defaultFileBehavior() const; - bool useDefaultFile() const; - int defaultSetPoint() const; - int o2Consumption() const; - int pscrRatio() const; - bool autoRecalculateThumbnails() const; - bool extractVideoThumbnails() const; - int extractVideoThumbnailsPosition() const; - QString ffmpegExecutable() const; - -public slots: - void setDefaultFilename (const QString& value); - void setDefaultCylinder (const QString& value); - void setDefaultFileBehavior (short value); - void setUseDefaultFile (bool value); - void setDefaultSetPoint (int value); - void setO2Consumption (int value); - void setPscrRatio (int value); - void setAutoRecalculateThumbnails (bool value); - void setExtractVideoThumbnails (bool value); - void setExtractVideoThumbnailsPosition (int value); - void setFfmpegExecutable (const QString &value); - -signals: - void defaultFilenameChanged(const QString& value); - void defaultCylinderChanged(const QString& value); - void defaultFileBehaviorChanged(short value); - void useDefaultFileChanged(bool value); - void defaultSetPointChanged(int value); - void o2ConsumptionChanged(int value); - void pscrRatioChanged(int value); - void autoRecalculateThumbnailsChanged(int value); - void extractVideoThumbnailsChanged(bool value); - void extractVideoThumbnailsPositionChanged(int value); - void ffmpegExecutableChanged(const QString &value); -private: - const QString group = QStringLiteral("GeneralSettings"); -}; - -class LanguageSettingsObjectWrapper : public QObject { - Q_OBJECT - Q_PROPERTY(QString language READ language WRITE setLanguage NOTIFY languageChanged) - Q_PROPERTY(QString time_format READ timeFormat WRITE setTimeFormat NOTIFY timeFormatChanged) - Q_PROPERTY(QString date_format READ dateFormat WRITE setDateFormat NOTIFY dateFormatChanged) - Q_PROPERTY(QString date_format_short READ dateFormatShort WRITE setDateFormatShort NOTIFY dateFormatShortChanged) - Q_PROPERTY(QString lang_locale READ langLocale WRITE setLangLocale NOTIFY langLocaleChanged) - Q_PROPERTY(bool time_format_override READ timeFormatOverride WRITE setTimeFormatOverride NOTIFY timeFormatOverrideChanged) - Q_PROPERTY(bool date_format_override READ dateFormatOverride WRITE setDateFormatOverride NOTIFY dateFormatOverrideChanged) - Q_PROPERTY(bool use_system_language READ useSystemLanguage WRITE setUseSystemLanguage NOTIFY useSystemLanguageChanged) - -public: - LanguageSettingsObjectWrapper(QObject *parent); - QString language() const; - QString langLocale() const; - QString timeFormat() const; - QString dateFormat() const; - QString dateFormatShort() const; - bool timeFormatOverride() const; - bool dateFormatOverride() const; - bool useSystemLanguage() const; - -public slots: - void setLangLocale (const QString& value); - void setLanguage (const QString& value); - void setTimeFormat (const QString& value); - void setDateFormat (const QString& value); - void setDateFormatShort (const QString& value); - void setTimeFormatOverride (bool value); - void setDateFormatOverride (bool value); - void setUseSystemLanguage (bool value); -signals: - void languageChanged(const QString& value); - void langLocaleChanged(const QString& value); - void timeFormatChanged(const QString& value); - void dateFormatChanged(const QString& value); - void dateFormatShortChanged(const QString& value); - void timeFormatOverrideChanged(bool value); - void dateFormatOverrideChanged(bool value); - void useSystemLanguageChanged(bool value); - -private: - const QString group = QStringLiteral("Language"); -}; - -class SettingsObjectWrapper : public QObject { - Q_OBJECT - - Q_PROPERTY(qPrefTechnicalDetails* techical_details MEMBER techDetails CONSTANT) - Q_PROPERTY(PartialPressureGasSettings* pp_gas MEMBER pp_gas CONSTANT) - Q_PROPERTY(qPrefFacebook* facebook MEMBER facebook CONSTANT) - Q_PROPERTY(GeocodingPreferences* geocoding MEMBER geocoding CONSTANT) - Q_PROPERTY(qPrefProxy* proxy MEMBER proxy CONSTANT) - Q_PROPERTY(qPrefCloudStorage* cloud_storage MEMBER cloud_storage CONSTANT) - Q_PROPERTY(qPrefDivePlanner* planner MEMBER planner_settings CONSTANT) - Q_PROPERTY(qPrefUnits* units MEMBER unit_settings CONSTANT) - Q_PROPERTY(GeneralSettingsObjectWrapper* general MEMBER general_settings CONSTANT) - Q_PROPERTY(qPrefDisplay* display MEMBER display_settings CONSTANT) - Q_PROPERTY(LanguageSettingsObjectWrapper* language MEMBER language_settings CONSTANT) - Q_PROPERTY(qPrefAnimations* animation MEMBER animation_settings CONSTANT) - Q_PROPERTY(qPrefLocationService* Location MEMBER location_settings CONSTANT) - - Q_PROPERTY(qPrefUpdateManager* update MEMBER update_manager_settings CONSTANT) - Q_PROPERTY(qPrefDiveComputer* dive_computer MEMBER dive_computer_settings CONSTANT) -public: - static SettingsObjectWrapper *instance(); - - qPrefTechnicalDetails *techDetails; - PartialPressureGasSettings *pp_gas; - qPrefFacebook *facebook; - GeocodingPreferences *geocoding; - qPrefProxy *proxy; - qPrefCloudStorage *cloud_storage; - qPrefDivePlanner *planner_settings; - qPrefUnits *unit_settings; - GeneralSettingsObjectWrapper *general_settings; - qPrefDisplay *display_settings; - LanguageSettingsObjectWrapper *language_settings; - qPrefAnimations *animation_settings; - qPrefLocationService *location_settings; - qPrefUpdateManager *update_manager_settings; - qPrefDiveComputer *dive_computer_settings; - - void sync(); - void load(); -private: - SettingsObjectWrapper(QObject *parent = NULL); -}; - -#endif diff --git a/core/unix.c b/core/unix.c index 963d25ac5..a75bcd792 100644 --- a/core/unix.c +++ b/core/unix.c @@ -48,7 +48,8 @@ void subsurface_user_info(struct user_info *user) struct membuffer mb = {}; gethostname(hostname, sizeof(hostname)); put_format(&mb, "%s@%s", username, hostname); - user->email = mb_cstring(&mb); // 'email' is heap allocated + mb_cstring(&mb); + user->email = detach_buffer(&mb); } } |