mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
core: turn C dive-table into an owning table
This is a humongous commit, because it touches all parts of the code. It removes the last user of our horrible TABLE macros, which simulate std::vector<> in a very clumsy way. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
f00c30ad4a
commit
b95ac3f79c
73 changed files with 1030 additions and 1230 deletions
|
@ -74,6 +74,7 @@ set(SUBSURFACE_CORE_LIB_SRCS
|
|||
divelogexportlogic.h
|
||||
divesite.cpp
|
||||
divesite.h
|
||||
divesitetable.h
|
||||
divesitehelpers.cpp
|
||||
divesitehelpers.h
|
||||
downloadfromdcthread.cpp
|
||||
|
@ -179,6 +180,7 @@ set(SUBSURFACE_CORE_LIB_SRCS
|
|||
time.cpp
|
||||
trip.cpp
|
||||
trip.h
|
||||
triptable.h
|
||||
uemis-downloader.cpp
|
||||
uemis.cpp
|
||||
uemis.h
|
||||
|
|
|
@ -601,7 +601,7 @@ static void cochran_parse_samples(struct dive *dive, const unsigned char *log,
|
|||
|
||||
static void cochran_parse_dive(const unsigned char *decode, unsigned mod,
|
||||
const unsigned char *in, unsigned size,
|
||||
struct dive_table *table)
|
||||
struct dive_table &table)
|
||||
{
|
||||
unsigned char *buf = (unsigned char *)malloc(size);
|
||||
struct divecomputer *dc;
|
||||
|
@ -784,7 +784,7 @@ static void cochran_parse_dive(const unsigned char *decode, unsigned mod,
|
|||
dc->duration.seconds = duration;
|
||||
}
|
||||
|
||||
record_dive_to_table(dive.release(), table);
|
||||
table.record_dive(std::move(dive));
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
@ -819,7 +819,7 @@ int try_to_open_cochran(const char *, std::string &mem, struct divelog *log)
|
|||
break;
|
||||
|
||||
cochran_parse_dive(decode, mod, (unsigned char *)mem.data() + dive1,
|
||||
dive2 - dive1, log->dives.get());
|
||||
dive2 - dive1, log->dives);
|
||||
}
|
||||
|
||||
return 1; // no further processing needed
|
||||
|
|
|
@ -698,12 +698,12 @@ int datatrak_import(std::string &mem, std::string &wl_mem, struct divelog *log)
|
|||
rc = 1;
|
||||
goto out;
|
||||
} else {
|
||||
record_dive_to_table(ptdive.release(), log->dives.get());
|
||||
log->dives.record_dive(std::move(ptdive));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
out:
|
||||
sort_dive_table(log->dives.get());
|
||||
log->dives.sort();
|
||||
return rc;
|
||||
bail:
|
||||
return 1;
|
||||
|
|
|
@ -2376,10 +2376,10 @@ static void force_fixup_dive(struct dive *d)
|
|||
*/
|
||||
static std::array<std::unique_ptr<dive>, 2> split_dive_at(const struct dive &dive, int a, int b)
|
||||
{
|
||||
int nr = get_divenr(&dive);
|
||||
size_t nr = divelog.dives.get_idx(&dive);
|
||||
|
||||
/* if we can't find the dive in the dive list, don't bother */
|
||||
if (nr < 0)
|
||||
if (nr == std::string::npos)
|
||||
return {};
|
||||
|
||||
/* Splitting should leave at least 3 samples per dive */
|
||||
|
@ -2461,7 +2461,7 @@ static std::array<std::unique_ptr<dive>, 2> split_dive_at(const struct dive &div
|
|||
* Otherwise the tail is unnumbered.
|
||||
*/
|
||||
if (d2->number) {
|
||||
if (divelog.dives->nr == nr + 1)
|
||||
if (divelog.dives.size() == nr + 1)
|
||||
d2->number++;
|
||||
else
|
||||
d2->number = 0;
|
||||
|
@ -2893,9 +2893,9 @@ depth_t gas_mnd(struct gasmix mix, depth_t end, const struct dive *dive, int rou
|
|||
|
||||
struct dive *get_dive(int nr)
|
||||
{
|
||||
if (nr >= divelog.dives->nr || nr < 0)
|
||||
return NULL;
|
||||
return divelog.dives->dives[nr];
|
||||
if (nr < 0 || static_cast<size_t>(nr) >= divelog.dives.size())
|
||||
return nullptr;
|
||||
return divelog.dives[nr].get();
|
||||
}
|
||||
|
||||
struct dive_site *get_dive_site_for_dive(const struct dive *dive)
|
||||
|
@ -2933,42 +2933,6 @@ const struct divecomputer *get_dive_dc(const struct dive *dive, int nr)
|
|||
return get_dive_dc((struct dive *)dive, nr);
|
||||
}
|
||||
|
||||
struct dive *get_dive_by_uniq_id(int id)
|
||||
{
|
||||
int i;
|
||||
struct dive *dive = NULL;
|
||||
|
||||
for_each_dive (i, dive) {
|
||||
if (dive->id == id)
|
||||
break;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (dive == NULL) {
|
||||
report_info("Invalid id %x passed to get_dive_by_diveid, try to fix the code", id);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
return dive;
|
||||
}
|
||||
|
||||
int get_idx_by_uniq_id(int id)
|
||||
{
|
||||
int i;
|
||||
struct dive *dive = NULL;
|
||||
|
||||
for_each_dive (i, dive) {
|
||||
if (dive->id == id)
|
||||
break;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (dive == NULL) {
|
||||
report_info("Invalid id %x passed to get_dive_by_diveid, try to fix the code", id);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
return i;
|
||||
}
|
||||
|
||||
bool dive_site_has_gps_location(const struct dive_site *ds)
|
||||
{
|
||||
return ds && has_location(&ds->location);
|
||||
|
|
21
core/dive.h
21
core/dive.h
|
@ -139,7 +139,6 @@ extern depth_t gas_mod(struct gasmix mix, pressure_t po2_limit, const struct div
|
|||
extern depth_t gas_mnd(struct gasmix mix, depth_t end, const struct dive *dive, int roundto);
|
||||
|
||||
extern struct dive *get_dive(int nr);
|
||||
extern struct dive *get_dive_from_table(int nr, const struct dive_table *dt);
|
||||
extern struct dive_site *get_dive_site_for_dive(const struct dive *dive);
|
||||
extern std::string get_dive_country(const struct dive *dive);
|
||||
extern std::string get_dive_location(const struct dive *dive);
|
||||
|
@ -153,18 +152,6 @@ extern std::unique_ptr<dive> clone_make_first_dc(const struct dive &d, int dc_nu
|
|||
extern std::unique_ptr<dive> clone_delete_divecomputer(const struct dive &d, int dc_number);
|
||||
extern std::array<std::unique_ptr<dive>, 2> split_divecomputer(const struct dive &src, int num);
|
||||
|
||||
/*
|
||||
* Iterate over each dive, with the first parameter being the index
|
||||
* iterator variable, and the second one being the dive one.
|
||||
*
|
||||
* I don't think anybody really wants the index, and we could make
|
||||
* it local to the for-loop, but that would make us requires C99.
|
||||
*/
|
||||
#define for_each_dive(_i, _x) \
|
||||
for ((_i) = 0; ((_x) = get_dive(_i)) != NULL; (_i)++)
|
||||
|
||||
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(const struct dive_site *ds);
|
||||
extern int dive_has_gps_location(const struct dive *dive);
|
||||
extern location_t dive_get_gps_location(const struct dive *d);
|
||||
|
@ -173,19 +160,18 @@ extern bool time_during_dive_with_offset(const struct dive *dive, timestamp_t wh
|
|||
|
||||
extern int save_dives(const char *filename);
|
||||
extern int save_dives_logic(const char *filename, bool select_only, bool anonymize);
|
||||
extern int save_dive(FILE *f, struct dive *dive, bool anonymize);
|
||||
extern int save_dive(FILE *f, const struct dive &dive, bool anonymize);
|
||||
extern int export_dives_xslt(const char *filename, bool selected, const int units, const char *export_xslt, bool anonymize);
|
||||
|
||||
extern int save_dive_sites_logic(const char *filename, const struct dive_site *sites[], int nr_sites, bool anonymize);
|
||||
|
||||
struct membuffer;
|
||||
extern void save_one_dive_to_mb(struct membuffer *b, struct dive *dive, bool anonymize);
|
||||
extern void save_one_dive_to_mb(struct membuffer *b, const struct dive &dive, bool anonymize);
|
||||
|
||||
extern void subsurface_console_init();
|
||||
extern void subsurface_console_exit();
|
||||
extern bool subsurface_user_is_root();
|
||||
|
||||
extern void record_dive_to_table(struct dive *dive, struct dive_table *table);
|
||||
extern void clear_dive(struct dive *dive);
|
||||
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);
|
||||
|
@ -193,7 +179,8 @@ extern struct std::unique_ptr<dive> move_dive(struct dive *s);
|
|||
|
||||
extern int legacy_format_o2pressures(const struct dive *dive, const struct divecomputer *dc);
|
||||
|
||||
extern bool dive_less_than(const struct dive *a, const struct dive *b);
|
||||
extern bool dive_less_than(const struct dive &a, const struct dive &b);
|
||||
extern bool dive_less_than_ptr(const struct dive *a, const struct dive *b);
|
||||
extern bool dive_or_trip_less_than(struct dive_or_trip a, struct dive_or_trip b);
|
||||
extern struct dive *fixup_dive(struct dive *dive);
|
||||
extern pressure_t calculate_surface_pressure(const struct dive *dive);
|
||||
|
|
|
@ -74,10 +74,8 @@ ShownChange DiveFilter::update(const QVector<dive *> &dives) const
|
|||
|
||||
void DiveFilter::reset()
|
||||
{
|
||||
int i;
|
||||
dive *d;
|
||||
shown_dives = divelog.dives->nr;
|
||||
for_each_dive(i, d)
|
||||
shown_dives = static_cast<int>(divelog.dives.size());
|
||||
for (auto &d: divelog.dives)
|
||||
d->hidden_by_filter = false;
|
||||
updateAll();
|
||||
}
|
||||
|
@ -85,26 +83,24 @@ void DiveFilter::reset()
|
|||
ShownChange DiveFilter::updateAll() const
|
||||
{
|
||||
ShownChange res;
|
||||
int i;
|
||||
dive *d;
|
||||
std::vector<dive *> selection = getDiveSelection();
|
||||
std::vector<dive *> removeFromSelection;
|
||||
// There are three modes: divesite, fulltext, normal
|
||||
if (diveSiteMode()) {
|
||||
for_each_dive(i, d) {
|
||||
for (auto &d: divelog.dives) {
|
||||
bool newStatus = range_contains(dive_sites, d->dive_site);
|
||||
updateDiveStatus(d, newStatus, res, removeFromSelection);
|
||||
updateDiveStatus(d.get(), newStatus, res, removeFromSelection);
|
||||
}
|
||||
} else if (filterData.fullText.doit()) {
|
||||
FullTextResult ft = fulltext_find_dives(filterData.fullText, filterData.fulltextStringMode);
|
||||
for_each_dive(i, d) {
|
||||
bool newStatus = ft.dive_matches(d) && showDive(d);
|
||||
updateDiveStatus(d, newStatus, res, removeFromSelection);
|
||||
for (auto &d: divelog.dives) {
|
||||
bool newStatus = ft.dive_matches(d.get()) && showDive(d.get());
|
||||
updateDiveStatus(d.get(), newStatus, res, removeFromSelection);
|
||||
}
|
||||
} else {
|
||||
for_each_dive(i, d) {
|
||||
bool newStatus = showDive(d);
|
||||
updateDiveStatus(d, newStatus, res, removeFromSelection);
|
||||
for (auto &d: divelog.dives) {
|
||||
bool newStatus = showDive(d.get());
|
||||
updateDiveStatus(d.get(), newStatus, res, removeFromSelection);
|
||||
}
|
||||
}
|
||||
updateSelection(selection, std::vector<dive *>(), removeFromSelection);
|
||||
|
@ -204,7 +200,7 @@ bool DiveFilter::diveSiteMode() const
|
|||
|
||||
QString DiveFilter::shownText() const
|
||||
{
|
||||
int num = divelog.dives->nr;
|
||||
size_t num = divelog.dives.size();
|
||||
if (diveSiteMode() || filterData.validFilter())
|
||||
return gettextFromC::tr("%L1/%L2 shown").arg(shown_dives).arg(num);
|
||||
else
|
||||
|
@ -230,11 +226,9 @@ std::vector<dive *> DiveFilter::visibleDives() const
|
|||
std::vector<dive *> res;
|
||||
res.reserve(shown_dives);
|
||||
|
||||
int i;
|
||||
dive *d;
|
||||
for_each_dive(i, d) {
|
||||
for (auto &d: divelog.dives) {
|
||||
if (!d->hidden_by_filter)
|
||||
res.push_back(d);
|
||||
res.push_back(d.get());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -20,9 +20,14 @@
|
|||
#include "git-access.h"
|
||||
#include "selection.h"
|
||||
#include "sample.h"
|
||||
#include "table.h"
|
||||
#include "trip.h"
|
||||
|
||||
void dive_table::record_dive(std::unique_ptr<dive> d)
|
||||
{
|
||||
fixup_dive(d.get());
|
||||
put(std::move(d));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get "maximal" dive gas for a dive.
|
||||
* Rules:
|
||||
|
@ -201,7 +206,6 @@ static double calculate_cns_dive(const struct dive *dive)
|
|||
* so we calculated it "by hand" */
|
||||
static int calculate_cns(struct dive *dive)
|
||||
{
|
||||
int i, divenr;
|
||||
double cns = 0.0;
|
||||
timestamp_t last_starttime, last_endtime = 0;
|
||||
|
||||
|
@ -209,16 +213,18 @@ static int calculate_cns(struct dive *dive)
|
|||
if (dive->cns)
|
||||
return dive->cns;
|
||||
|
||||
divenr = get_divenr(dive);
|
||||
i = divenr >= 0 ? divenr : divelog.dives->nr;
|
||||
size_t divenr = divelog.dives.get_idx(dive);
|
||||
int i = divenr != std::string::npos ? static_cast<int>(divenr)
|
||||
: static_cast<int>(divelog.dives.size());
|
||||
int nr_dives = static_cast<int>(divelog.dives.size());
|
||||
#if DECO_CALC_DEBUG & 2
|
||||
if (i >= 0 && i < dive_table.nr)
|
||||
printf("\n\n*** CNS for dive #%d %d\n", i, get_dive(i)->number);
|
||||
if (static_cast<size_t>(i) < divelog.table->size())
|
||||
printf("\n\n*** CNS for dive #%d %d\n", i, (*divelog.table)[i]->number);
|
||||
else
|
||||
printf("\n\n*** CNS for dive #%d\n", i);
|
||||
#endif
|
||||
/* Look at next dive in dive list table and correct i when needed */
|
||||
while (i < divelog.dives->nr - 1) {
|
||||
while (i < nr_dives - 1) {
|
||||
struct dive *pdive = get_dive(i);
|
||||
if (!pdive || pdive->when > dive->when)
|
||||
break;
|
||||
|
@ -237,7 +243,7 @@ static int calculate_cns(struct dive *dive)
|
|||
last_starttime = dive->when;
|
||||
/* Walk backwards to check previous dives - how far do we need to go back? */
|
||||
while (i--) {
|
||||
if (i == divenr && i > 0)
|
||||
if (static_cast<size_t>(i) == divenr && i > 0)
|
||||
i--;
|
||||
#if DECO_CALC_DEBUG & 2
|
||||
printf("Check if dive #%d %d has to be considered as prev dive: ", i, get_dive(i)->number);
|
||||
|
@ -263,7 +269,7 @@ static int calculate_cns(struct dive *dive)
|
|||
#endif
|
||||
}
|
||||
/* Walk forward and add dives and surface intervals to CNS */
|
||||
while (++i < divelog.dives->nr) {
|
||||
while (++i < nr_dives) {
|
||||
#if DECO_CALC_DEBUG & 2
|
||||
printf("Check if dive #%d %d will be really added to CNS calc: ", i, get_dive(i)->number);
|
||||
#endif
|
||||
|
@ -283,7 +289,7 @@ static int calculate_cns(struct dive *dive)
|
|||
break;
|
||||
}
|
||||
/* Don't add the copy of the dive itself */
|
||||
if (i == divenr) {
|
||||
if (static_cast<size_t>(i) == divenr) {
|
||||
#if DECO_CALC_DEBUG & 2
|
||||
printf("No - copy of dive\n");
|
||||
#endif
|
||||
|
@ -406,20 +412,6 @@ static void add_dive_to_deco(struct deco_state *ds, struct dive *dive, bool in_p
|
|||
}
|
||||
}
|
||||
|
||||
int get_divenr(const struct dive *dive)
|
||||
{
|
||||
int i;
|
||||
const struct dive *d;
|
||||
// tempting as it may be, don't die when called with dive=NULL
|
||||
if (dive) {
|
||||
for_each_dive(i, d) {
|
||||
if (d->id == dive->id) // don't compare pointers, we could be passing in a copy of the dive
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* take into account previous dives until there is a 48h gap between dives */
|
||||
/* return last surface time before this dive or dummy value of 48h */
|
||||
/* return negative surface time if dives are overlapping */
|
||||
|
@ -427,7 +419,6 @@ int get_divenr(const struct dive *dive)
|
|||
* to create the deco_state */
|
||||
int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_planner)
|
||||
{
|
||||
int i, divenr = -1;
|
||||
int surface_time = 48 * 60 * 60;
|
||||
timestamp_t last_endtime = 0, last_starttime = 0;
|
||||
bool deco_init = false;
|
||||
|
@ -436,16 +427,18 @@ int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_p
|
|||
if (!dive)
|
||||
return false;
|
||||
|
||||
divenr = get_divenr(dive);
|
||||
i = divenr >= 0 ? divenr : divelog.dives->nr;
|
||||
int nr_dives = static_cast<int>(divelog.dives.size());
|
||||
size_t divenr = divelog.dives.get_idx(dive);
|
||||
int i = divenr != std::string::npos ? static_cast<int>(divenr)
|
||||
: static_cast<int>(divelog.dives.size());
|
||||
#if DECO_CALC_DEBUG & 2
|
||||
if (i >= 0 && i < dive_table.nr)
|
||||
if (i < dive_table.nr)
|
||||
printf("\n\n*** Init deco for dive #%d %d\n", i, get_dive(i)->number);
|
||||
else
|
||||
printf("\n\n*** Init deco for dive #%d\n", i);
|
||||
#endif
|
||||
/* Look at next dive in dive list table and correct i when needed */
|
||||
while (i < divelog.dives->nr - 1) {
|
||||
while (i + 1 < nr_dives) {
|
||||
struct dive *pdive = get_dive(i);
|
||||
if (!pdive || pdive->when > dive->when)
|
||||
break;
|
||||
|
@ -464,7 +457,7 @@ int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_p
|
|||
last_starttime = dive->when;
|
||||
/* Walk backwards to check previous dives - how far do we need to go back? */
|
||||
while (i--) {
|
||||
if (i == divenr && i > 0)
|
||||
if (static_cast<size_t>(i) == divenr && i > 0)
|
||||
i--;
|
||||
#if DECO_CALC_DEBUG & 2
|
||||
printf("Check if dive #%d %d has to be considered as prev dive: ", i, get_dive(i)->number);
|
||||
|
@ -490,7 +483,7 @@ int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_p
|
|||
#endif
|
||||
}
|
||||
/* Walk forward an add dives and surface intervals to deco */
|
||||
while (++i < divelog.dives->nr) {
|
||||
while (++i < nr_dives) {
|
||||
#if DECO_CALC_DEBUG & 2
|
||||
printf("Check if dive #%d %d will be really added to deco calc: ", i, get_dive(i)->number);
|
||||
#endif
|
||||
|
@ -510,7 +503,7 @@ int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_p
|
|||
break;
|
||||
}
|
||||
/* Don't add the copy of the dive itself */
|
||||
if (i == divenr) {
|
||||
if (static_cast<size_t>(i) == divenr) {
|
||||
#if DECO_CALC_DEBUG & 2
|
||||
printf("No - copy of dive\n");
|
||||
#endif
|
||||
|
@ -635,71 +628,55 @@ static int comp_dc(const struct dive *d1, const struct dive *d2)
|
|||
* We might also consider sorting by end-time and other criteria,
|
||||
* but see the caveat above (editing means reordering of the dives).
|
||||
*/
|
||||
int comp_dives(const struct dive *a, const struct dive *b)
|
||||
int comp_dives(const struct dive &a, const struct dive &b)
|
||||
{
|
||||
int cmp;
|
||||
if (a == b)
|
||||
if (&a == &b)
|
||||
return 0; /* reflexivity */
|
||||
if (a->when < b->when)
|
||||
if (a.when < b.when)
|
||||
return -1;
|
||||
if (a->when > b->when)
|
||||
if (a.when > b.when)
|
||||
return 1;
|
||||
if (a->divetrip != b->divetrip) {
|
||||
if (!b->divetrip)
|
||||
if (a.divetrip != b.divetrip) {
|
||||
if (!b.divetrip)
|
||||
return -1;
|
||||
if (!a->divetrip)
|
||||
if (!a.divetrip)
|
||||
return 1;
|
||||
if (trip_date(*a->divetrip) < trip_date(*b->divetrip))
|
||||
if (trip_date(*a.divetrip) < trip_date(*b.divetrip))
|
||||
return -1;
|
||||
if (trip_date(*a->divetrip) > trip_date(*b->divetrip))
|
||||
if (trip_date(*a.divetrip) > trip_date(*b.divetrip))
|
||||
return 1;
|
||||
}
|
||||
if (a->number < b->number)
|
||||
if (a.number < b.number)
|
||||
return -1;
|
||||
if (a->number > b->number)
|
||||
if (a.number > b.number)
|
||||
return 1;
|
||||
if ((cmp = comp_dc(a, b)) != 0)
|
||||
if ((cmp = comp_dc(&a, &b)) != 0)
|
||||
return cmp;
|
||||
if (a->id < b->id)
|
||||
if (a.id < b.id)
|
||||
return -1;
|
||||
if (a->id > b->id)
|
||||
if (a.id > b.id)
|
||||
return 1;
|
||||
return a < b ? -1 : 1; /* give up. */
|
||||
return &a < &b ? -1 : 1; /* give up. */
|
||||
}
|
||||
|
||||
/* Dive table functions */
|
||||
static void free_dive(dive *d)
|
||||
int comp_dives_ptr(const struct dive *a, const struct dive *b)
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
static MAKE_GROW_TABLE(dive_table, struct dive *, dives)
|
||||
MAKE_GET_INSERTION_INDEX(dive_table, struct dive *, dives, dive_less_than)
|
||||
MAKE_ADD_TO(dive_table, struct dive *, dives)
|
||||
static MAKE_REMOVE_FROM(dive_table, dives)
|
||||
static MAKE_GET_IDX(dive_table, struct dive *, dives)
|
||||
MAKE_SORT(dive_table, struct dive *, dives, comp_dives)
|
||||
MAKE_REMOVE(dive_table, struct dive *, dive)
|
||||
MAKE_CLEAR_TABLE(dive_table, dives, dive)
|
||||
MAKE_MOVE_TABLE(dive_table, dives)
|
||||
|
||||
void insert_dive(struct dive_table *table, struct dive *d)
|
||||
{
|
||||
int idx = dive_table_get_insertion_index(table, d);
|
||||
add_to_dive_table(table, idx, d);
|
||||
return comp_dives(*a, *b);
|
||||
}
|
||||
|
||||
/*
|
||||
* Walk the dives from the oldest dive in the given table, and see if we
|
||||
* can autogroup them. But only do this when the user selected autogrouping.
|
||||
*/
|
||||
static void autogroup_dives(struct dive_table *table, struct trip_table &trip_table)
|
||||
static void autogroup_dives(struct dive_table &table, struct trip_table &trip_table)
|
||||
{
|
||||
if (!divelog.autogroup)
|
||||
return;
|
||||
|
||||
for (auto &entry: get_dives_to_autogroup(table)) {
|
||||
for (int i = entry.from; i < entry.to; ++i)
|
||||
add_dive_to_trip(table->dives[i], entry.trip);
|
||||
for (auto it = table.begin() + entry.from; it != table.begin() + entry.to; ++it)
|
||||
add_dive_to_trip(it->get(), entry.trip);
|
||||
/* If this was newly allocated, add trip to list */
|
||||
if (entry.created_trip)
|
||||
trip_table.put(std::move(entry.created_trip));
|
||||
|
@ -710,35 +687,20 @@ static void autogroup_dives(struct dive_table *table, struct trip_table &trip_ta
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Remove a dive from a dive table. This assumes that the
|
||||
* dive was already removed from any trip and deselected.
|
||||
* It simply shrinks the table and frees the trip */
|
||||
void delete_dive_from_table(struct dive_table *table, int idx)
|
||||
{
|
||||
delete table->dives[idx];
|
||||
remove_from_dive_table(table, idx);
|
||||
}
|
||||
|
||||
struct dive *get_dive_from_table(int nr, const struct dive_table *dt)
|
||||
{
|
||||
if (nr >= dt->nr || nr < 0)
|
||||
return NULL;
|
||||
return dt->dives[nr];
|
||||
}
|
||||
|
||||
/* This removes a dive from the global dive table but doesn't free the
|
||||
* resources associated with the dive. The caller must removed the dive
|
||||
* from the trip-list. Returns a pointer to the unregistered dive.
|
||||
* The unregistered dive has the selection- and hidden-flags cleared. */
|
||||
struct dive *unregister_dive(int idx)
|
||||
std::unique_ptr<dive> dive_table::unregister_dive(int idx)
|
||||
{
|
||||
struct dive *dive = get_dive(idx);
|
||||
if (!dive)
|
||||
return NULL; /* this should never happen */
|
||||
if (idx < 0 || static_cast<size_t>(idx) >= size())
|
||||
return {}; /* this should never happen */
|
||||
|
||||
auto dive = pull_at(idx);
|
||||
|
||||
/* When removing a dive from the global dive table,
|
||||
* we also have to unregister its fulltext cache. */
|
||||
fulltext_unregister(dive);
|
||||
remove_from_dive_table(divelog.dives.get(), idx);
|
||||
fulltext_unregister(dive.get());
|
||||
if (dive->selected)
|
||||
amount_selected--;
|
||||
dive->selected = false;
|
||||
|
@ -755,21 +717,20 @@ struct dive *register_dive(std::unique_ptr<dive> d)
|
|||
// dives have been added, their status will be updated.
|
||||
d->hidden_by_filter = true;
|
||||
|
||||
int idx = dive_table_get_insertion_index(divelog.dives.get(), d.get());
|
||||
fulltext_register(d.get()); // Register the dive's fulltext cache
|
||||
invalidate_dive_cache(d.get()); // Ensure that dive is written in git_save()
|
||||
add_to_dive_table(divelog.dives.get(), idx, d.get());
|
||||
auto [res, idx] = divelog.dives.put(std::move(d));
|
||||
|
||||
return d.release();
|
||||
return res;
|
||||
}
|
||||
|
||||
void process_loaded_dives()
|
||||
{
|
||||
sort_dive_table(divelog.dives.get());
|
||||
divelog.dives.sort();
|
||||
divelog.trips->sort();
|
||||
|
||||
/* Autogroup dives if desired by user. */
|
||||
autogroup_dives(divelog.dives.get(), *divelog.trips);
|
||||
autogroup_dives(divelog.dives, *divelog.trips);
|
||||
|
||||
fulltext_populate();
|
||||
|
||||
|
@ -785,13 +746,11 @@ void process_loaded_dives()
|
|||
* that the dives are neither selected, not part of a trip, as
|
||||
* is the case of freshly imported dives.
|
||||
*/
|
||||
static void merge_imported_dives(struct dive_table *table)
|
||||
static void merge_imported_dives(struct dive_table &table)
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < table->nr; i++) {
|
||||
struct dive *prev = table->dives[i - 1];
|
||||
struct dive *dive = table->dives[i];
|
||||
struct dive_site *ds;
|
||||
for (size_t i = 1; i < table.size(); i++) {
|
||||
auto &prev = table[i - 1];
|
||||
auto &dive = table[i];
|
||||
|
||||
/* only try to merge overlapping dives - or if one of the dives has
|
||||
* zero duration (that might be a gps marker from the webservice) */
|
||||
|
@ -804,20 +763,19 @@ static void merge_imported_dives(struct dive_table *table)
|
|||
continue;
|
||||
|
||||
/* Add dive to dive site; try_to_merge() does not do that! */
|
||||
ds = merged->dive_site;
|
||||
struct dive_site *ds = merged->dive_site;
|
||||
if (ds) {
|
||||
merged->dive_site = NULL;
|
||||
ds->add_dive(merged.get());
|
||||
}
|
||||
unregister_dive_from_dive_site(prev);
|
||||
unregister_dive_from_dive_site(dive);
|
||||
unregister_dive_from_trip(prev);
|
||||
unregister_dive_from_trip(dive);
|
||||
unregister_dive_from_dive_site(prev.get());
|
||||
unregister_dive_from_dive_site(dive.get());
|
||||
unregister_dive_from_trip(prev.get());
|
||||
unregister_dive_from_trip(dive.get());
|
||||
|
||||
/* Overwrite the first of the two dives and remove the second */
|
||||
delete prev;
|
||||
table->dives[i - 1] = merged.release();
|
||||
delete_dive_from_table(table, i);
|
||||
table[i - 1] = std::move(merged);
|
||||
table.erase(table.begin() + i);
|
||||
|
||||
/* Redo the new 'i'th dive */
|
||||
i--;
|
||||
|
@ -831,45 +789,46 @@ static void merge_imported_dives(struct dive_table *table)
|
|||
* table. On failure everything stays unchanged.
|
||||
* If "prefer_imported" is true, use data of the new dive.
|
||||
*/
|
||||
static bool try_to_merge_into(struct dive &dive_to_add, struct dive &old_dive, bool prefer_imported,
|
||||
static bool try_to_merge_into(struct dive &dive_to_add, struct dive *old_dive, bool prefer_imported,
|
||||
/* output parameters: */
|
||||
struct dive_table *dives_to_add, struct dive_table *dives_to_remove)
|
||||
struct dive_table &dives_to_add, struct std::vector<dive *> &dives_to_remove)
|
||||
{
|
||||
auto merged = try_to_merge(old_dive, dive_to_add, prefer_imported);
|
||||
auto merged = try_to_merge(*old_dive, dive_to_add, prefer_imported);
|
||||
if (!merged)
|
||||
return false;
|
||||
|
||||
merged->divetrip = old_dive.divetrip;
|
||||
insert_dive(dives_to_remove, &old_dive);
|
||||
insert_dive(dives_to_add, merged.release());
|
||||
merged->divetrip = old_dive->divetrip;
|
||||
range_insert_sorted(dives_to_remove, old_dive, comp_dives_ptr);
|
||||
dives_to_add.put(std::move(merged));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check if a dive is ranked after the last dive of the global dive list */
|
||||
static bool dive_is_after_last(struct dive *d)
|
||||
static bool dive_is_after_last(const struct dive &d)
|
||||
{
|
||||
if (divelog.dives->nr == 0)
|
||||
if (divelog.dives.empty())
|
||||
return true;
|
||||
return dive_less_than(divelog.dives->dives[divelog.dives->nr - 1], d);
|
||||
return dive_less_than(*divelog.dives.back(), d);
|
||||
}
|
||||
|
||||
/* Merge dives from "dives_from" into "dives_to". Overlapping dives will be merged,
|
||||
* non-overlapping dives will be moved. The results will be added to the "dives_to_add"
|
||||
* table. Dives that were merged are added to the "dives_to_remove" table.
|
||||
* Any newly added (not merged) dive will be assigned to the trip of the "trip"
|
||||
* paremeter. If "delete_from" is non-null dives will be removed from this table.
|
||||
/* Merge dives from "dives_from", owned by "delete" into the owned by "dives_to".
|
||||
* Overlapping dives will be merged, non-overlapping dives will be moved. The results
|
||||
* will be added to the "dives_to_add" table. Dives that were merged are added to
|
||||
* the "dives_to_remove" table. Any newly added (not merged) dive will be assigned
|
||||
* to the trip of the "trip" paremeter. If "delete_from" is non-null dives will be
|
||||
* removed from this table.
|
||||
* This function supposes that all input tables are sorted.
|
||||
* Returns true if any dive was added (not merged) that is not past the
|
||||
* last dive of the global dive list (i.e. the sequence will change).
|
||||
* The integer pointed to by "num_merged" will be increased for every
|
||||
* The integer referenced by "num_merged" will be increased for every
|
||||
* merged dive that is added to "dives_to_add" */
|
||||
static bool merge_dive_tables(const std::vector<dive *> &dives_from, struct dive_table *delete_from,
|
||||
static bool merge_dive_tables(const std::vector<dive *> &dives_from, struct dive_table &delete_from,
|
||||
const std::vector<dive *> &dives_to,
|
||||
bool prefer_imported, struct dive_trip *trip,
|
||||
/* output parameters: */
|
||||
struct dive_table *dives_to_add, struct dive_table *dives_to_remove,
|
||||
int *num_merged)
|
||||
struct dive_table &dives_to_add, struct std::vector<dive *> &dives_to_remove,
|
||||
int &num_merged)
|
||||
{
|
||||
bool sequence_changed = false;
|
||||
|
||||
|
@ -884,11 +843,18 @@ static bool merge_dive_tables(const std::vector<dive *> &dives_from, struct dive
|
|||
*/
|
||||
size_t j = 0; /* Index in dives_to */
|
||||
size_t last_merged_into = std::string::npos;
|
||||
for (auto dive_to_add: dives_from) {
|
||||
remove_dive(dive_to_add, delete_from);
|
||||
for (dive *add: dives_from) {
|
||||
/* This gets an owning pointer to the dive to add and removes it from
|
||||
* the delete_from table. If the dive is not explicitly stored, it will
|
||||
* be automatically deleting when ending the loop iteration */
|
||||
auto [dive_to_add, idx] = delete_from.pull(add);
|
||||
if (!dive_to_add) {
|
||||
report_info("merging unknown dives!");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Find insertion point. */
|
||||
while (j < dives_to.size() && dive_less_than(dives_to[j], dive_to_add))
|
||||
while (j < dives_to.size() && dive_less_than(*dives_to[j], *dive_to_add))
|
||||
j++;
|
||||
|
||||
/* Try to merge into previous dive.
|
||||
|
@ -899,11 +865,10 @@ static bool merge_dive_tables(const std::vector<dive *> &dives_from, struct dive
|
|||
* transitive. But let's just go *completely* sure for the odd corner-case. */
|
||||
if (j > 0 && (last_merged_into == std::string::npos || j > last_merged_into + 1) &&
|
||||
dives_to[j - 1]->endtime() > dive_to_add->when) {
|
||||
if (try_to_merge_into(*dive_to_add, *dives_to[j - 1], prefer_imported,
|
||||
if (try_to_merge_into(*dive_to_add, dives_to[j - 1], prefer_imported,
|
||||
dives_to_add, dives_to_remove)) {
|
||||
delete dive_to_add;
|
||||
last_merged_into = j - 1;
|
||||
(*num_merged)++;
|
||||
num_merged++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -912,19 +877,16 @@ static bool merge_dive_tables(const std::vector<dive *> &dives_from, struct dive
|
|||
* Try to merge into next dive. */
|
||||
if (j < dives_to.size() && (last_merged_into == std::string::npos || j > last_merged_into) &&
|
||||
dive_to_add->endtime() > dives_to[j]->when) {
|
||||
if (try_to_merge_into(*dive_to_add, *dives_to[j], prefer_imported,
|
||||
if (try_to_merge_into(*dive_to_add, dives_to[j], prefer_imported,
|
||||
dives_to_add, dives_to_remove)) {
|
||||
delete dive_to_add;
|
||||
last_merged_into = j;
|
||||
(*num_merged)++;
|
||||
num_merged++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* We couldnt merge dives, simply add to list of dives to-be-added. */
|
||||
insert_dive(dives_to_add, dive_to_add);
|
||||
sequence_changed |= !dive_is_after_last(dive_to_add);
|
||||
dive_to_add->divetrip = trip;
|
||||
sequence_changed |= !dive_is_after_last(*dive_to_add);
|
||||
dives_to_add.put(std::move(dive_to_add));
|
||||
}
|
||||
|
||||
return sequence_changed;
|
||||
|
@ -933,46 +895,34 @@ static bool merge_dive_tables(const std::vector<dive *> &dives_from, struct dive
|
|||
/* Merge the dives of the trip "from" and the dive_table "dives_from" into the trip "to"
|
||||
* and dive_table "dives_to". If "prefer_imported" is true, dive data of "from" takes
|
||||
* precedence */
|
||||
void add_imported_dives(struct divelog *import_log, int flags)
|
||||
void add_imported_dives(struct divelog &import_log, int flags)
|
||||
{
|
||||
int i, idx;
|
||||
struct dive_table dives_to_add = empty_dive_table;
|
||||
struct dive_table dives_to_remove = empty_dive_table;
|
||||
struct trip_table trips_to_add;
|
||||
dive_site_table dive_sites_to_add;
|
||||
device_table devices_to_add;
|
||||
|
||||
/* Process imported dives and generate lists of dives
|
||||
* to-be-added and to-be-removed */
|
||||
process_imported_dives(import_log, flags, &dives_to_add, &dives_to_remove, trips_to_add,
|
||||
dive_sites_to_add, devices_to_add);
|
||||
auto [dives_to_add, dives_to_remove, trips_to_add, dive_sites_to_add, devices_to_add] =
|
||||
process_imported_dives(import_log, flags);
|
||||
|
||||
/* Start by deselecting all dives, so that we don't end up with an invalid selection */
|
||||
select_single_dive(NULL);
|
||||
|
||||
/* Add new dives to trip and site to get reference count correct. */
|
||||
for (i = 0; i < dives_to_add.nr; i++) {
|
||||
struct dive *d = dives_to_add.dives[i];
|
||||
for (auto &d: dives_to_add) {
|
||||
struct dive_trip *trip = d->divetrip;
|
||||
struct dive_site *site = d->dive_site;
|
||||
d->divetrip = NULL;
|
||||
d->dive_site = NULL;
|
||||
add_dive_to_trip(d, trip);
|
||||
add_dive_to_trip(d.get(), trip);
|
||||
if (site)
|
||||
site->add_dive(d);
|
||||
site->add_dive(d.get());
|
||||
}
|
||||
|
||||
/* Remove old dives */
|
||||
for (i = 0; i < dives_to_remove.nr; i++) {
|
||||
idx = get_divenr(dives_to_remove.dives[i]);
|
||||
divelog.delete_single_dive(idx);
|
||||
}
|
||||
dives_to_remove.nr = 0;
|
||||
divelog.delete_multiple_dives(dives_to_remove);
|
||||
|
||||
/* Add new dives */
|
||||
for (i = 0; i < dives_to_add.nr; i++)
|
||||
insert_dive(divelog.dives.get(), dives_to_add.dives[i]);
|
||||
dives_to_add.nr = 0;
|
||||
for (auto &d: dives_to_add)
|
||||
divelog.dives.put(std::move(d));
|
||||
dives_to_add.clear();
|
||||
|
||||
/* Add new trips */
|
||||
for (auto &trip: trips_to_add)
|
||||
|
@ -989,10 +939,7 @@ void add_imported_dives(struct divelog *import_log, int flags)
|
|||
|
||||
/* We might have deleted the old selected dive.
|
||||
* Choose the newest dive as selected (if any) */
|
||||
current_dive = divelog.dives->nr > 0 ? divelog.dives->dives[divelog.dives->nr - 1] : NULL;
|
||||
|
||||
free(dives_to_add.dives);
|
||||
free(dives_to_remove.dives);
|
||||
current_dive = !divelog.dives.empty() ? divelog.dives.back().get() : nullptr;
|
||||
|
||||
/* Inform frontend of reset data. This should reset all the models. */
|
||||
emit_reset_signal();
|
||||
|
@ -1008,14 +955,14 @@ void add_imported_dives(struct divelog *import_log, int flags)
|
|||
* Returns true if trip was merged. In this case, the trip will be
|
||||
* freed.
|
||||
*/
|
||||
static bool try_to_merge_trip(dive_trip &trip_import, struct dive_table *import_table, bool prefer_imported,
|
||||
static bool try_to_merge_trip(dive_trip &trip_import, struct dive_table &import_table, bool prefer_imported,
|
||||
/* output parameters: */
|
||||
struct dive_table *dives_to_add, struct dive_table *dives_to_remove,
|
||||
bool *sequence_changed, int *start_renumbering_at)
|
||||
struct dive_table &dives_to_add, std::vector<dive *> &dives_to_remove,
|
||||
bool &sequence_changed, int &start_renumbering_at)
|
||||
{
|
||||
for (auto &trip_old: *divelog.trips) {
|
||||
if (trips_overlap(trip_import, *trip_old)) {
|
||||
*sequence_changed |= merge_dive_tables(trip_import.dives, import_table, trip_old->dives,
|
||||
sequence_changed |= merge_dive_tables(trip_import.dives, import_table, trip_old->dives,
|
||||
prefer_imported, trip_old.get(),
|
||||
dives_to_add, dives_to_remove,
|
||||
start_renumbering_at);
|
||||
|
@ -1033,27 +980,21 @@ static bool try_to_merge_trip(dive_trip &trip_import, struct dive_table *import_
|
|||
static std::vector<dive *> dive_table_to_non_owning(const dive_table &dives)
|
||||
{
|
||||
std::vector<dive *> res;
|
||||
res.reserve(dives.nr);
|
||||
for (int i = 0; i < dives.nr; ++i)
|
||||
res.push_back(dives.dives[i]);
|
||||
res.reserve(dives.size());
|
||||
for (auto &d: dives)
|
||||
res.push_back(d.get());
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Process imported dives: take a table of dives to be imported and
|
||||
* generate five lists:
|
||||
* 1) Dives to be added
|
||||
* 2) Dives to be removed
|
||||
* 3) Trips to be added
|
||||
* 4) Dive sites to be added
|
||||
* 5) Devices to be added
|
||||
* The dives to be added are owning (i.e. the caller is responsible
|
||||
* for freeing them).
|
||||
* The dives, trips and sites in "import_table", "import_trip_table"
|
||||
* and "import_sites_table" are consumed. On return, the tables have
|
||||
* size 0. "import_trip_table" may be NULL if all dives are not associated
|
||||
* with a trip.
|
||||
* The output tables should be empty - if not, their content
|
||||
* will be cleared!
|
||||
* 1) Dives to be added (newly created, owned)
|
||||
* 2) Dives to be removed (old, non-owned, references global divelog)
|
||||
* 3) Trips to be added (newly created, owned)
|
||||
* 4) Dive sites to be added (newly created, owned)
|
||||
* 5) Devices to be added (newly created, owned)
|
||||
* The dives, trips and sites in import_log are consumed.
|
||||
* On return, the tables have * size 0.
|
||||
*
|
||||
* Note: The new dives will have their divetrip- and divesites-fields
|
||||
* set, but will *not* be part of the trip and site. The caller has to
|
||||
|
@ -1072,90 +1013,70 @@ static std::vector<dive *> dive_table_to_non_owning(const dive_table &dives)
|
|||
* - If IMPORT_ADD_TO_NEW_TRIP is true, dives that are not assigned
|
||||
* to a trip will be added to a newly generated trip.
|
||||
*/
|
||||
void process_imported_dives(struct divelog *import_log, int flags,
|
||||
/* output parameters: */
|
||||
struct dive_table *dives_to_add, struct dive_table *dives_to_remove,
|
||||
struct trip_table &trips_to_add, dive_site_table &sites_to_add,
|
||||
device_table &devices_to_add)
|
||||
process_imported_dives_result process_imported_dives(struct divelog &import_log, int flags)
|
||||
{
|
||||
int i, j, nr, start_renumbering_at = 0;
|
||||
int start_renumbering_at = 0;
|
||||
bool sequence_changed = false;
|
||||
bool new_dive_has_number = false;
|
||||
bool last_old_dive_is_numbered;
|
||||
|
||||
/* Make sure that output parameters don't contain garbage */
|
||||
clear_dive_table(dives_to_add);
|
||||
clear_dive_table(dives_to_remove);
|
||||
trips_to_add.clear();
|
||||
sites_to_add.clear();
|
||||
devices_to_add.clear();
|
||||
process_imported_dives_result res;
|
||||
|
||||
/* If no dives were imported, don't bother doing anything */
|
||||
if (import_log.dives.empty())
|
||||
return res;
|
||||
|
||||
/* Check if any of the new dives has a number. This will be
|
||||
* important later to decide if we want to renumber the added
|
||||
* dives */
|
||||
for (int i = 0; i < import_log->dives->nr; i++) {
|
||||
if (import_log->dives->dives[i]->number > 0) {
|
||||
new_dive_has_number = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If no dives were imported, don't bother doing anything */
|
||||
if (!import_log->dives->nr)
|
||||
return;
|
||||
bool new_dive_has_number = std::any_of(import_log.dives.begin(), import_log.dives.end(),
|
||||
[](auto &d) { return d->number > 0; });
|
||||
|
||||
/* Add only the devices that we don't know about yet. */
|
||||
for (auto &dev: import_log->devices) {
|
||||
for (auto &dev: import_log.devices) {
|
||||
if (!device_exists(divelog.devices, dev))
|
||||
add_to_device_table(devices_to_add, dev);
|
||||
add_to_device_table(res.devices_to_add, dev);
|
||||
}
|
||||
|
||||
/* Sort the table of dives to be imported and combine mergable dives */
|
||||
sort_dive_table(import_log->dives.get());
|
||||
merge_imported_dives(import_log->dives.get());
|
||||
import_log.dives.sort();
|
||||
merge_imported_dives(import_log.dives);
|
||||
|
||||
/* Autogroup tripless dives if desired by user. But don't autogroup
|
||||
* if tripless dives should be added to a new trip. */
|
||||
if (!(flags & IMPORT_ADD_TO_NEW_TRIP))
|
||||
autogroup_dives(import_log->dives.get(), *import_log->trips);
|
||||
autogroup_dives(import_log.dives, *import_log.trips);
|
||||
|
||||
/* If dive sites already exist, use the existing versions. */
|
||||
for (auto &new_ds: *import_log->sites) {
|
||||
struct dive_site *old_ds = divelog.sites->get_same(*new_ds);
|
||||
|
||||
for (auto &new_ds: *import_log.sites) {
|
||||
/* Check if it dive site is actually used by new dives. */
|
||||
for (j = 0; j < import_log->dives->nr; j++) {
|
||||
if (import_log->dives->dives[j]->dive_site == new_ds.get())
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == import_log->dives->nr) {
|
||||
/* Dive site not even used. */
|
||||
if (std::none_of(import_log.dives.begin(), import_log.dives.end(), [ds=new_ds.get()]
|
||||
(auto &d) { return d->dive_site == ds; }))
|
||||
continue;
|
||||
}
|
||||
|
||||
struct dive_site *old_ds = divelog.sites->get_same(*new_ds);
|
||||
if (!old_ds) {
|
||||
/* Dive site doesn't exist. Add it to list of dive sites to be added. */
|
||||
new_ds->dives.clear(); /* Caller is responsible for adding dives to site */
|
||||
sites_to_add.put(std::move(new_ds));
|
||||
res.sites_to_add.put(std::move(new_ds));
|
||||
} else {
|
||||
/* Dive site already exists - use the old one. */
|
||||
for (j = 0; j < import_log->dives->nr; j++) {
|
||||
if (import_log->dives->dives[j]->dive_site == new_ds.get())
|
||||
import_log->dives->dives[j]->dive_site = old_ds;
|
||||
for (auto &d: import_log.dives) {
|
||||
if (d->dive_site == new_ds.get())
|
||||
d->dive_site = old_ds;
|
||||
}
|
||||
}
|
||||
}
|
||||
import_log->sites->clear();
|
||||
import_log.sites->clear();
|
||||
|
||||
/* Merge overlapping trips. Since both trip tables are sorted, we
|
||||
* could be smarter here, but realistically not a whole lot of trips
|
||||
* will be imported so do a simple n*m loop until someone complains.
|
||||
*/
|
||||
for (auto &trip_import: *import_log->trips) {
|
||||
for (auto &trip_import: *import_log.trips) {
|
||||
if ((flags & IMPORT_MERGE_ALL_TRIPS) || trip_import->autogen) {
|
||||
if (try_to_merge_trip(*trip_import, import_log->dives.get(), flags & IMPORT_PREFER_IMPORTED, dives_to_add, dives_to_remove,
|
||||
&sequence_changed, &start_renumbering_at))
|
||||
if (try_to_merge_trip(*trip_import, import_log.dives, flags & IMPORT_PREFER_IMPORTED,
|
||||
res.dives_to_add, res.dives_to_remove,
|
||||
sequence_changed, start_renumbering_at))
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1163,43 +1084,43 @@ void process_imported_dives(struct divelog *import_log, int flags,
|
|||
* First, add dives to list of dives to add */
|
||||
for (struct dive *d: trip_import->dives) {
|
||||
/* Add dive to list of dives to-be-added. */
|
||||
insert_dive(dives_to_add, d);
|
||||
sequence_changed |= !dive_is_after_last(d);
|
||||
|
||||
remove_dive(d, import_log->dives.get());
|
||||
auto [owned, idx] = import_log.dives.pull(d);
|
||||
if (!owned)
|
||||
continue;
|
||||
sequence_changed |= !dive_is_after_last(*owned);
|
||||
res.dives_to_add.put(std::move(owned));
|
||||
}
|
||||
|
||||
trip_import->dives.clear(); /* Caller is responsible for adding dives to trip */
|
||||
|
||||
/* Finally, add trip to list of trips to add */
|
||||
trips_to_add.put(std::move(trip_import));
|
||||
res.trips_to_add.put(std::move(trip_import));
|
||||
}
|
||||
import_log->trips->clear(); /* All trips were consumed */
|
||||
import_log.trips->clear(); /* All trips were consumed */
|
||||
|
||||
if ((flags & IMPORT_ADD_TO_NEW_TRIP) && import_log->dives->nr > 0) {
|
||||
if ((flags & IMPORT_ADD_TO_NEW_TRIP) && !import_log.dives.empty()) {
|
||||
/* Create a new trip for unassigned dives, if desired. */
|
||||
auto [new_trip, idx] = trips_to_add.put(
|
||||
create_trip_from_dive(import_log->dives->dives[0])
|
||||
auto [new_trip, idx] = res.trips_to_add.put(
|
||||
create_trip_from_dive(import_log.dives.front().get())
|
||||
);
|
||||
|
||||
/* Add all remaining dives to this trip */
|
||||
for (i = 0; i < import_log->dives->nr; i++) {
|
||||
struct dive *d = import_log->dives->dives[i];
|
||||
for (auto &d: import_log.dives) {
|
||||
sequence_changed |= !dive_is_after_last(*d);
|
||||
d->divetrip = new_trip;
|
||||
insert_dive(dives_to_add, d);
|
||||
sequence_changed |= !dive_is_after_last(d);
|
||||
res.dives_to_add.put(std::move(d));
|
||||
}
|
||||
|
||||
import_log->dives->nr = 0; /* All dives were consumed */
|
||||
} else if (import_log->dives->nr > 0) {
|
||||
/* The remaining dives in import_log->dives are those that don't belong to
|
||||
import_log.dives.clear(); /* All dives were consumed */
|
||||
} else if (!import_log.dives.empty()) {
|
||||
/* The remaining dives in import_log.dives are those that don't belong to
|
||||
* a trip and the caller does not want them to be associated to a
|
||||
* new trip. Merge them into the global table. */
|
||||
sequence_changed |= merge_dive_tables(dive_table_to_non_owning(*import_log->dives),
|
||||
import_log->dives.get(),
|
||||
dive_table_to_non_owning(*divelog.dives),
|
||||
sequence_changed |= merge_dive_tables(dive_table_to_non_owning(import_log.dives),
|
||||
import_log.dives,
|
||||
dive_table_to_non_owning(divelog.dives),
|
||||
flags & IMPORT_PREFER_IMPORTED, NULL,
|
||||
dives_to_add, dives_to_remove, &start_renumbering_at);
|
||||
res.dives_to_add, res.dives_to_remove, start_renumbering_at);
|
||||
}
|
||||
|
||||
/* If new dives were only added at the end, renumber the added dives.
|
||||
|
@ -1207,26 +1128,25 @@ void process_imported_dives(struct divelog *import_log, int flags,
|
|||
* - The last dive in the old dive table had a number itself (if there is a last dive).
|
||||
* - None of the new dives has a number.
|
||||
*/
|
||||
last_old_dive_is_numbered = divelog.dives->nr == 0 || divelog.dives->dives[divelog.dives->nr - 1]->number > 0;
|
||||
last_old_dive_is_numbered = divelog.dives.empty() || divelog.dives.back()->number > 0;
|
||||
|
||||
/* We counted the number of merged dives that were added to dives_to_add.
|
||||
* Skip those. Since sequence_changed is false all added dives are *after*
|
||||
* all merged dives. */
|
||||
if (!sequence_changed && last_old_dive_is_numbered && !new_dive_has_number) {
|
||||
nr = divelog.dives->nr > 0 ? divelog.dives->dives[divelog.dives->nr - 1]->number : 0;
|
||||
for (i = start_renumbering_at; i < dives_to_add->nr; i++)
|
||||
dives_to_add->dives[i]->number = ++nr;
|
||||
int nr = !divelog.dives.empty() ? divelog.dives.back()->number : 0;
|
||||
for (auto it = res.dives_to_add.begin() + start_renumbering_at; it < res.dives_to_add.end(); ++it)
|
||||
(*it)->number = ++nr;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct dive *get_last_valid_dive()
|
||||
{
|
||||
int i;
|
||||
for (i = divelog.dives->nr - 1; i >= 0; i--) {
|
||||
if (!divelog.dives->dives[i]->invalid)
|
||||
return divelog.dives->dives[i];
|
||||
}
|
||||
return NULL;
|
||||
auto it = std::find_if(divelog.dives.rbegin(), divelog.dives.rend(),
|
||||
[](auto &d) { return !d->invalid; });
|
||||
return it != divelog.dives.rend() ? it->get() : nullptr;
|
||||
}
|
||||
|
||||
/* return the number a dive gets when inserted at the given index.
|
||||
|
@ -1238,7 +1158,7 @@ static struct dive *get_last_valid_dive()
|
|||
*/
|
||||
int get_dive_nr_at_idx(int idx)
|
||||
{
|
||||
if (idx < divelog.dives->nr)
|
||||
if (static_cast<size_t>(idx) < divelog.dives.size())
|
||||
return 0;
|
||||
struct dive *last_dive = get_last_valid_dive();
|
||||
if (!last_dive)
|
||||
|
@ -1246,6 +1166,19 @@ int get_dive_nr_at_idx(int idx)
|
|||
return last_dive->number ? last_dive->number + 1 : 0;
|
||||
}
|
||||
|
||||
/* lookup of trip in main trip_table based on its id */
|
||||
dive *dive_table::get_by_uniq_id(int id) const
|
||||
{
|
||||
auto it = std::find_if(begin(), end(), [id](auto &d) { return d->id == id; });
|
||||
#ifdef DEBUG
|
||||
if (it == end()) {
|
||||
report_info("Invalid id %x passed to get_dive_by_diveid, try to fix the code", id);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
return it != end() ? it->get() : nullptr;
|
||||
}
|
||||
|
||||
static int min_datafile_version;
|
||||
|
||||
int get_min_datafile_version()
|
||||
|
@ -1278,11 +1211,16 @@ void clear_dive_file_data()
|
|||
emit_reset_signal();
|
||||
}
|
||||
|
||||
bool dive_less_than(const struct dive *a, const struct dive *b)
|
||||
bool dive_less_than(const struct dive &a, const struct dive &b)
|
||||
{
|
||||
return comp_dives(a, b) < 0;
|
||||
}
|
||||
|
||||
bool dive_less_than_ptr(const struct dive *a, const struct dive *b)
|
||||
{
|
||||
return comp_dives(*a, *b) < 0;
|
||||
}
|
||||
|
||||
/* When comparing a dive to a trip, use the first dive of the trip. */
|
||||
static int comp_dive_to_trip(struct dive *a, struct dive_trip *b)
|
||||
{
|
||||
|
@ -1290,7 +1228,7 @@ static int comp_dive_to_trip(struct dive *a, struct dive_trip *b)
|
|||
* with no (or worse a negative number of) dives. */
|
||||
if (!b || b->dives.empty())
|
||||
return -1;
|
||||
return comp_dives(a, b->dives[0]);
|
||||
return comp_dives(*a, *b->dives[0]);
|
||||
}
|
||||
|
||||
static int comp_dive_or_trip(struct dive_or_trip a, struct dive_or_trip b)
|
||||
|
@ -1308,7 +1246,7 @@ static int comp_dive_or_trip(struct dive_or_trip a, struct dive_or_trip b)
|
|||
if (!b.dive && !b.trip)
|
||||
return 1;
|
||||
if (a.dive && b.dive)
|
||||
return comp_dives(a.dive, b.dive);
|
||||
return comp_dives(*a.dive, *b.dive);
|
||||
if (a.trip && b.trip)
|
||||
return comp_trips(*a.trip, *b.trip);
|
||||
if (a.dive)
|
||||
|
@ -1334,18 +1272,15 @@ bool dive_or_trip_less_than(struct dive_or_trip a, struct dive_or_trip b)
|
|||
*/
|
||||
timestamp_t get_surface_interval(timestamp_t when)
|
||||
{
|
||||
int i;
|
||||
timestamp_t prev_end;
|
||||
|
||||
/* find previous dive. might want to use a binary search. */
|
||||
for (i = divelog.dives->nr - 1; i >= 0; --i) {
|
||||
if (divelog.dives->dives[i]->when < when)
|
||||
break;
|
||||
}
|
||||
if (i < 0)
|
||||
auto it = std::find_if(divelog.dives.rbegin(), divelog.dives.rend(),
|
||||
[when] (auto &d) { return d->when < when; });
|
||||
if (it == divelog.dives.rend())
|
||||
return -1;
|
||||
|
||||
prev_end = divelog.dives->dives[i]->endtime();
|
||||
prev_end = (*it)->endtime();
|
||||
if (prev_end > when)
|
||||
return 0;
|
||||
return when - prev_end;
|
||||
|
@ -1355,43 +1290,31 @@ timestamp_t get_surface_interval(timestamp_t when)
|
|||
* then newer dives. */
|
||||
struct dive *find_next_visible_dive(timestamp_t when)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (!divelog.dives->nr)
|
||||
return NULL;
|
||||
if (divelog.dives.empty())
|
||||
return nullptr;
|
||||
|
||||
/* we might want to use binary search here */
|
||||
for (i = 0; i < divelog.dives->nr; i++) {
|
||||
if (when <= get_dive(i)->when)
|
||||
break;
|
||||
auto it = std::find_if(divelog.dives.begin(), divelog.dives.end(),
|
||||
[when] (auto &d) { return d->when <= when; });
|
||||
|
||||
for (auto it2 = it; it2 != divelog.dives.begin(); --it2) {
|
||||
if (!(*std::prev(it2))->hidden_by_filter)
|
||||
return it2->get();
|
||||
}
|
||||
|
||||
for (j = i - 1; j > 0; j--) {
|
||||
if (!get_dive(j)->hidden_by_filter)
|
||||
return get_dive(j);
|
||||
for (auto it2 = it; it2 != divelog.dives.end(); ++it2) {
|
||||
if (!(*it2)->hidden_by_filter)
|
||||
return it2->get();
|
||||
}
|
||||
|
||||
for (j = i; j < divelog.dives->nr; j++) {
|
||||
if (!get_dive(j)->hidden_by_filter)
|
||||
return get_dive(j);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool has_dive(unsigned int deviceid, unsigned int diveid)
|
||||
{
|
||||
int i;
|
||||
struct dive *dive;
|
||||
|
||||
for_each_dive (i, dive) {
|
||||
for (auto &dc: dive->dcs) {
|
||||
if (dc.deviceid != deviceid)
|
||||
continue;
|
||||
if (dc.diveid != diveid)
|
||||
continue;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return std::any_of(divelog.dives.begin(), divelog.dives.end(), [deviceid,diveid] (auto &d) {
|
||||
return std::any_of(d->dcs.begin(), d->dcs.end(), [deviceid,diveid] (auto &dc) {
|
||||
return dc.deviceid == deviceid && dc.diveid == diveid;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,27 +2,29 @@
|
|||
#ifndef DIVELIST_H
|
||||
#define DIVELIST_H
|
||||
|
||||
#include "triptable.h"
|
||||
#include "divesitetable.h"
|
||||
#include "units.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
struct dive;
|
||||
struct divelog;
|
||||
struct trip_table;
|
||||
class dive_site_table;
|
||||
struct device;
|
||||
struct deco_state;
|
||||
|
||||
struct dive_table {
|
||||
int nr, allocated;
|
||||
struct dive **dives;
|
||||
int comp_dives(const struct dive &a, const struct dive &b);
|
||||
int comp_dives_ptr(const struct dive *a, const struct dive *b);
|
||||
|
||||
struct dive_table : public sorted_owning_table<dive, &comp_dives> {
|
||||
dive *get_by_uniq_id(int id) const;
|
||||
void record_dive(std::unique_ptr<dive> d); // call fixup_dive() before adding dive to table.
|
||||
std::unique_ptr<dive> unregister_dive(int idx);
|
||||
};
|
||||
static const struct dive_table empty_dive_table = { 0, 0, (struct dive **)0 };
|
||||
|
||||
/* this is used for both git and xml format */
|
||||
#define DATAFORMAT_VERSION 3
|
||||
|
||||
extern void sort_dive_table(struct dive_table *table);
|
||||
extern void update_cylinder_related_info(struct dive *);
|
||||
extern int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_planner);
|
||||
|
||||
|
@ -33,30 +35,26 @@ extern void process_loaded_dives();
|
|||
#define IMPORT_IS_DOWNLOADED (1 << 1)
|
||||
#define IMPORT_MERGE_ALL_TRIPS (1 << 2)
|
||||
#define IMPORT_ADD_TO_NEW_TRIP (1 << 3)
|
||||
extern void add_imported_dives(struct divelog *log, int flags);
|
||||
extern void process_imported_dives(struct divelog *import_log, int flags,
|
||||
struct dive_table *dives_to_add, struct dive_table *dives_to_remove,
|
||||
struct trip_table &trips_to_add, dive_site_table &sites_to_add,
|
||||
std::vector<device> &devices_to_add);
|
||||
extern void add_imported_dives(struct divelog &log, int flags);
|
||||
|
||||
struct process_imported_dives_result {
|
||||
dive_table dives_to_add;
|
||||
std::vector<dive *> dives_to_remove;
|
||||
trip_table trips_to_add;
|
||||
dive_site_table sites_to_add;
|
||||
std::vector<device> devices_to_add;
|
||||
};
|
||||
|
||||
extern process_imported_dives_result process_imported_dives(struct divelog &import_log, int flags);
|
||||
|
||||
extern int dive_table_get_insertion_index(struct dive_table *table, struct dive *dive);
|
||||
extern void add_to_dive_table(struct dive_table *table, int idx, struct dive *dive);
|
||||
extern void insert_dive(struct dive_table *table, struct dive *d);
|
||||
extern void get_dive_gas(const struct dive *dive, int *o2_p, int *he_p, int *o2low_p);
|
||||
extern int get_divenr(const struct dive *dive);
|
||||
extern int remove_dive(const struct dive *dive, struct dive_table *table);
|
||||
extern int get_dive_nr_at_idx(int idx);
|
||||
extern timestamp_t get_surface_interval(timestamp_t when);
|
||||
extern void delete_dive_from_table(struct dive_table *table, int idx);
|
||||
extern struct dive *find_next_visible_dive(timestamp_t when);
|
||||
|
||||
extern int comp_dives(const struct dive *a, const struct dive *b);
|
||||
|
||||
int get_min_datafile_version();
|
||||
void report_datafile_version(int version);
|
||||
void clear_dive_file_data();
|
||||
void clear_dive_table(struct dive_table *table);
|
||||
struct dive *unregister_dive(int idx);
|
||||
struct dive *register_dive(std::unique_ptr<dive> d);
|
||||
extern bool has_dive(unsigned int deviceid, unsigned int diveid);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "divelist.h"
|
||||
#include "divesite.h"
|
||||
#include "device.h"
|
||||
#include "dive.h"
|
||||
#include "errorhelper.h"
|
||||
#include "filterpreset.h"
|
||||
#include "trip.h"
|
||||
|
@ -10,21 +11,14 @@
|
|||
struct divelog divelog;
|
||||
|
||||
divelog::divelog() :
|
||||
dives(std::make_unique<dive_table>()),
|
||||
trips(std::make_unique<trip_table>()),
|
||||
sites(std::make_unique<dive_site_table>()),
|
||||
filter_presets(std::make_unique<filter_preset_table>()),
|
||||
autogroup(false)
|
||||
{
|
||||
*dives = empty_dive_table;
|
||||
}
|
||||
|
||||
divelog::~divelog()
|
||||
{
|
||||
if (dives)
|
||||
clear_dive_table(dives.get());
|
||||
}
|
||||
|
||||
divelog::~divelog() = default;
|
||||
divelog::divelog(divelog &&) = default;
|
||||
struct divelog &divelog::operator=(divelog &&) = default;
|
||||
|
||||
|
@ -32,11 +26,11 @@ struct divelog &divelog::operator=(divelog &&) = default;
|
|||
* dive log and the trip, but doesn't deal with updating dive trips, etc */
|
||||
void divelog::delete_single_dive(int idx)
|
||||
{
|
||||
if (idx < 0 || idx > dives->nr) {
|
||||
report_info("Warning: deleting unexisting dive with index %d", idx);
|
||||
if (idx < 0 || static_cast<size_t>(idx) >= dives.size()) {
|
||||
report_info("Warning: deleting non-existing dive with index %d", idx);
|
||||
return;
|
||||
}
|
||||
struct dive *dive = dives->dives[idx];
|
||||
struct dive *dive = dives[idx].get();
|
||||
struct dive_trip *trip = unregister_dive_from_trip(dive);
|
||||
|
||||
// Deleting a dive may change the order of trips!
|
||||
|
@ -46,15 +40,58 @@ void divelog::delete_single_dive(int idx)
|
|||
if (trip && trip->dives.empty())
|
||||
trips->pull(trip);
|
||||
unregister_dive_from_dive_site(dive);
|
||||
delete_dive_from_table(dives.get(), idx);
|
||||
dives.erase(dives.begin() + idx);
|
||||
}
|
||||
|
||||
void divelog::delete_multiple_dives(const std::vector<dive *> &dives_to_delete)
|
||||
{
|
||||
bool trips_changed = false;
|
||||
|
||||
for (dive *d: dives_to_delete) {
|
||||
// Delete dive from trip and delete trip if empty
|
||||
struct dive_trip *trip = unregister_dive_from_trip(d);
|
||||
if (trip && trip->dives.empty()) {
|
||||
trips_changed = true;
|
||||
trips->pull(trip);
|
||||
}
|
||||
|
||||
unregister_dive_from_dive_site(d);
|
||||
dives.pull(d);
|
||||
}
|
||||
|
||||
// Deleting a dive may change the order of trips!
|
||||
if (trips_changed)
|
||||
trips->sort();
|
||||
}
|
||||
|
||||
void divelog::clear()
|
||||
{
|
||||
while (dives->nr > 0)
|
||||
delete_dive_from_table(dives.get(), dives->nr - 1);
|
||||
dives.clear();
|
||||
sites->clear();
|
||||
trips->clear();
|
||||
devices.clear();
|
||||
filter_presets->clear();
|
||||
}
|
||||
|
||||
/* check if we have a trip right before / after this dive */
|
||||
bool divelog::is_trip_before_after(const struct dive *dive, bool before) const
|
||||
{
|
||||
auto it = std::find_if(dives.begin(), dives.end(),
|
||||
[dive](auto &d) { return d.get() == dive; });
|
||||
if (it == dives.end())
|
||||
return false;
|
||||
|
||||
if (before) {
|
||||
do {
|
||||
if (it == dives.begin())
|
||||
return false;
|
||||
--it;
|
||||
} while ((*it)->invalid);
|
||||
return (*it)->divetrip != nullptr;
|
||||
} else {
|
||||
++it;
|
||||
while (it != dives.end() && (*it)->invalid)
|
||||
++it;
|
||||
return it != dives.end() && (*it)->divetrip != nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,17 +3,18 @@
|
|||
#ifndef DIVELOG_H
|
||||
#define DIVELOG_H
|
||||
|
||||
#include "divelist.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
struct dive_table;
|
||||
struct trip_table;
|
||||
class dive_site_table;
|
||||
struct device;
|
||||
struct filter_preset_table;
|
||||
|
||||
struct divelog {
|
||||
std::unique_ptr<dive_table> dives;
|
||||
dive_table dives;
|
||||
std::unique_ptr<trip_table> trips;
|
||||
std::unique_ptr<dive_site_table> sites;
|
||||
std::vector<device> devices;
|
||||
|
@ -26,7 +27,9 @@ struct divelog {
|
|||
divelog &operator=(divelog &&); // move assignment (argument is consumed).
|
||||
|
||||
void delete_single_dive(int idx);
|
||||
void delete_multiple_dives(const std::vector<dive *> &dives);
|
||||
void clear();
|
||||
bool is_trip_before_after(const struct dive *dive, bool before) const;
|
||||
};
|
||||
|
||||
extern struct divelog divelog;
|
||||
|
|
|
@ -11,6 +11,13 @@
|
|||
|
||||
#include <math.h>
|
||||
|
||||
int divesite_comp_uuid(const dive_site &ds1, const dive_site &ds2)
|
||||
{
|
||||
if (ds1.uuid == ds2.uuid)
|
||||
return 0;
|
||||
return ds1.uuid < ds2.uuid ? -1 : 1;
|
||||
}
|
||||
|
||||
template <typename PRED>
|
||||
dive_site *get_by_predicate(const dive_site_table &ds_table, PRED pred)
|
||||
{
|
||||
|
|
|
@ -3,13 +3,10 @@
|
|||
#define DIVESITE_H
|
||||
|
||||
#include "divelist.h"
|
||||
#include "owning_table.h"
|
||||
#include "taxonomy.h"
|
||||
#include "units.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
struct dive_site
|
||||
{
|
||||
uint32_t uuid = 0;
|
||||
|
@ -33,32 +30,11 @@ struct dive_site
|
|||
void add_dive(struct dive *d);
|
||||
};
|
||||
|
||||
inline int divesite_comp_uuid(const dive_site &ds1, const dive_site &ds2)
|
||||
{
|
||||
if (ds1.uuid == ds2.uuid)
|
||||
return 0;
|
||||
return ds1.uuid < ds2.uuid ? -1 : 1;
|
||||
}
|
||||
|
||||
class dive_site_table : public sorted_owning_table<dive_site, &divesite_comp_uuid> {
|
||||
public:
|
||||
put_result register_site(std::unique_ptr<dive_site> site); // Creates or changes UUID if duplicate
|
||||
dive_site *get_by_uuid(uint32_t uuid) const;
|
||||
dive_site *alloc_or_get(uint32_t uuid);
|
||||
dive_site *create(const std::string &name);
|
||||
dive_site *create(const std::string &name, const location_t);
|
||||
dive_site *find_or_create(const std::string &name);
|
||||
dive_site *get_by_name(const std::string &name) const;
|
||||
dive_site *get_by_gps(const location_t *) const;
|
||||
dive_site *get_by_gps_and_name(const std::string &name, const location_t) const;
|
||||
dive_site *get_by_gps_proximity(location_t, int distance) const;
|
||||
dive_site *get_same(const struct dive_site &) const;
|
||||
void purge_empty();
|
||||
};
|
||||
|
||||
struct dive_site *unregister_dive_from_dive_site(struct dive *d);
|
||||
int divesite_comp_uuid(const dive_site &ds1, const dive_site &ds2);
|
||||
|
||||
/* Make pointer-to-dive_site a "Qt metatype" so that we can pass it through QVariants */
|
||||
#include <QObject>
|
||||
Q_DECLARE_METATYPE(dive_site *);
|
||||
|
||||
#endif // DIVESITE_H
|
||||
|
|
27
core/divesitetable.h
Normal file
27
core/divesitetable.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#ifndef DIVESITETABLE_H
|
||||
#define DIVESITETABLE_H
|
||||
|
||||
#include "owning_table.h"
|
||||
#include "units.h"
|
||||
|
||||
struct dive_site;
|
||||
int divesite_comp_uuid(const dive_site &ds1, const dive_site &ds2);
|
||||
|
||||
class dive_site_table : public sorted_owning_table<dive_site, &divesite_comp_uuid> {
|
||||
public:
|
||||
put_result register_site(std::unique_ptr<dive_site> site); // Creates or changes UUID if duplicate
|
||||
dive_site *get_by_uuid(uint32_t uuid) const;
|
||||
dive_site *alloc_or_get(uint32_t uuid);
|
||||
dive_site *create(const std::string &name);
|
||||
dive_site *create(const std::string &name, const location_t);
|
||||
dive_site *find_or_create(const std::string &name);
|
||||
dive_site *get_by_name(const std::string &name) const;
|
||||
dive_site *get_by_gps(const location_t *) const;
|
||||
dive_site *get_by_gps_and_name(const std::string &name, const location_t) const;
|
||||
dive_site *get_by_gps_proximity(location_t, int distance) const;
|
||||
dive_site *get_same(const struct dive_site &) const;
|
||||
void purge_empty();
|
||||
};
|
||||
|
||||
#endif // DIVESITETABLE_H
|
|
@ -112,9 +112,9 @@ void DownloadThread::run()
|
|||
internalData->vendor.c_str(), internalData->product.c_str());
|
||||
report_info("Finishing download thread: %s", error.c_str());
|
||||
} else {
|
||||
if (!log.dives->nr)
|
||||
if (log.dives.empty())
|
||||
error = tr("No new dives downloaded from dive computer").toStdString();
|
||||
report_info("Finishing download thread: %d dives downloaded", log.dives->nr);
|
||||
report_info("Finishing download thread: %d dives downloaded", static_cast<int>(log.dives.size()));
|
||||
}
|
||||
qPrefDiveComputer::set_vendor(internalData->vendor.c_str());
|
||||
qPrefDiveComputer::set_product(internalData->product.c_str());
|
||||
|
|
|
@ -284,8 +284,7 @@ void reset_tank_info_table(std::vector<tank_info> &table)
|
|||
add_default_tank_infos(table);
|
||||
|
||||
/* Add cylinders from dive list */
|
||||
for (int i = 0; i < divelog.dives->nr; ++i) {
|
||||
const struct dive *dive = divelog.dives->dives[i];
|
||||
for (auto &dive: divelog.dives) {
|
||||
for (auto &cyl: dive->cylinders)
|
||||
add_cylinder_description(cyl.type);
|
||||
}
|
||||
|
|
|
@ -143,11 +143,9 @@ void FullText::populate()
|
|||
// we want this to be two calls as the second text is overwritten below by the lines starting with "\r"
|
||||
uiNotification(QObject::tr("Create full text index"));
|
||||
uiNotification(QObject::tr("start processing"));
|
||||
int i;
|
||||
dive *d;
|
||||
for_each_dive(i, d)
|
||||
registerDive(d);
|
||||
uiNotification(QObject::tr("%1 dives processed").arg(divelog.dives->nr));
|
||||
for (auto &d: divelog.dives)
|
||||
registerDive(d.get());
|
||||
uiNotification(QObject::tr("%1 dives processed").arg(divelog.dives.size()));
|
||||
}
|
||||
|
||||
void FullText::registerDive(struct dive *d)
|
||||
|
@ -170,9 +168,7 @@ void FullText::unregisterDive(struct dive *d)
|
|||
|
||||
void FullText::unregisterAll()
|
||||
{
|
||||
int i;
|
||||
dive *d;
|
||||
for_each_dive(i, d)
|
||||
for (auto &d: divelog.dives)
|
||||
d->full_text.reset();
|
||||
words.clear();
|
||||
}
|
||||
|
|
|
@ -443,7 +443,7 @@ int try_to_open_csv(std::string &mem, enum csv_format type, struct divelog *log)
|
|||
break;
|
||||
p = end + 1;
|
||||
}
|
||||
record_dive_to_table(dive.release(), log->dives.get());
|
||||
log->dives.record_dive(std::move(dive));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -749,7 +749,7 @@ int parse_txt_file(const char *filename, const char *csv, struct divelog *log)
|
|||
if (!lineptr || !*lineptr)
|
||||
break;
|
||||
}
|
||||
record_dive_to_table(dive.release(), log->dives.get());
|
||||
log->dives.record_dive(std::move(dive));
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
|
|
|
@ -537,7 +537,7 @@ static int might_be_same_dc(const struct divecomputer &a, const struct divecompu
|
|||
return a.deviceid == b.deviceid;
|
||||
}
|
||||
|
||||
static bool match_one_dive(const struct divecomputer &a, struct dive *dive)
|
||||
static bool match_one_dive(const struct divecomputer &a, const struct dive &dive)
|
||||
{
|
||||
/*
|
||||
* Walk the existing dive computer data,
|
||||
|
@ -545,13 +545,13 @@ static bool match_one_dive(const struct divecomputer &a, struct dive *dive)
|
|||
* the same dive computer but a different
|
||||
* dive ID).
|
||||
*/
|
||||
for (auto &b: dive->dcs) {
|
||||
for (auto &b: dive.dcs) {
|
||||
if (match_one_dc(a, b) > 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Ok, no exact dive computer match. Does the date match? */
|
||||
for (auto &b: dive->dcs) {
|
||||
for (auto &b: dive.dcs) {
|
||||
if (a.when == b.when && might_be_same_dc(a, b))
|
||||
return true;
|
||||
}
|
||||
|
@ -562,17 +562,10 @@ static bool match_one_dive(const struct divecomputer &a, struct dive *dive)
|
|||
/*
|
||||
* Check if this dive already existed before the import
|
||||
*/
|
||||
static int find_dive(const struct divecomputer &match)
|
||||
static bool find_dive(const struct divecomputer &match)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = divelog.dives->nr - 1; i >= 0; i--) {
|
||||
struct dive *old = divelog.dives->dives[i];
|
||||
|
||||
if (match_one_dive(match, old))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return std::any_of(divelog.dives.rbegin(), divelog.dives.rend(),
|
||||
[&match] (auto &old) { return match_one_dive(match, *old);} );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -871,7 +864,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
|
|||
dive->dcs[0].samples[1].temperature.mkelvin > dive->dcs[0].samples[0].temperature.mkelvin)
|
||||
dive->dcs[0].samples[0].temperature.mkelvin = dive->dcs[0].samples[1].temperature.mkelvin;
|
||||
|
||||
record_dive_to_table(dive.release(), devdata->log->dives.get());
|
||||
devdata->log->dives.record_dive(std::move(dive));
|
||||
return true;
|
||||
|
||||
error_exit:
|
||||
|
@ -1509,7 +1502,7 @@ std::string do_libdivecomputer_import(device_data_t *data)
|
|||
|
||||
dc_device_close(data->device);
|
||||
data->device = NULL;
|
||||
if (!data->log->dives->nr)
|
||||
if (data->log->dives.empty())
|
||||
dev_info(data, translate("gettextFromC", "No new dives downloaded from dive computer"));
|
||||
}
|
||||
dc_iostream_close(data->iostream);
|
||||
|
|
|
@ -131,7 +131,7 @@ static int handle_event_ver3(int code, const unsigned char *ps, unsigned int ps_
|
|||
return skip;
|
||||
}
|
||||
|
||||
static void parse_dives(int log_version, const unsigned char *buf, unsigned int buf_size, struct dive_table *table, dive_site_table &sites)
|
||||
static void parse_dives(int log_version, const unsigned char *buf, unsigned int buf_size, struct dive_table &table, dive_site_table &sites)
|
||||
{
|
||||
unsigned int ptr = 0;
|
||||
unsigned char model;
|
||||
|
@ -407,8 +407,7 @@ static void parse_dives(int log_version, const unsigned char *buf, unsigned int
|
|||
}
|
||||
|
||||
// End dive
|
||||
record_dive_to_table(dive.release(), table);
|
||||
dive = NULL;
|
||||
table.record_dive(std::move(dive));
|
||||
|
||||
// Advance ptr for next dive
|
||||
ptr += ps_ptr + 4;
|
||||
|
@ -438,7 +437,7 @@ int try_to_open_liquivision(const char *, std::string &mem, struct divelog *log)
|
|||
}
|
||||
ptr += 4;
|
||||
|
||||
parse_dives(log_version, buf + ptr, buf_size - ptr, log->dives.get(), *log->sites);
|
||||
parse_dives(log_version, buf + ptr, buf_size - ptr, log->dives, *log->sites);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1390,7 +1390,7 @@ static void finish_active_trip(struct git_parser_state *state)
|
|||
static void finish_active_dive(struct git_parser_state *state)
|
||||
{
|
||||
if (state->active_dive)
|
||||
record_dive_to_table(state->active_dive.release(), state->log->dives.get());
|
||||
state->log->dives.record_dive(std::move(state->active_dive));
|
||||
}
|
||||
|
||||
static void create_new_dive(timestamp_t when, struct git_parser_state *state)
|
||||
|
|
|
@ -169,6 +169,5 @@ void ostctools_import(const char *file, struct divelog *log)
|
|||
else if (it == ostcdive->dcs[0].extra_data.end())
|
||||
add_extra_data(&ostcdive->dcs[0], "Serial", ostcdive->dcs[0].serial);
|
||||
|
||||
record_dive_to_table(ostcdive.release(), log->dives.get());
|
||||
sort_dive_table(log->dives.get());
|
||||
log->dives.record_dive(std::move(ostcdive));
|
||||
}
|
||||
|
|
|
@ -124,6 +124,7 @@ public:
|
|||
this->insert(it, std::move(item));
|
||||
return { ptr, idx };
|
||||
}
|
||||
|
||||
// Optimized version of get_idx(), which uses binary search
|
||||
// If not found, fall back to linear search and emit a warning.
|
||||
// Note: this is probaly slower than a linesr search. But for now,
|
||||
|
@ -140,6 +141,15 @@ public:
|
|||
}
|
||||
return it - this->begin();
|
||||
}
|
||||
|
||||
// Get place where insertion would take place
|
||||
size_t get_insertion_index(const T *item) const {
|
||||
auto it = std::lower_bound(this->begin(), this->end(), item,
|
||||
[] (const auto &i1, const auto &i2)
|
||||
{ return CMP(*i1, *i2) < 0; });
|
||||
return it - this->begin();
|
||||
}
|
||||
|
||||
// Note: this is silly - finding the pointer by a linear search
|
||||
// is probably significantly faster than doing a binary search.
|
||||
// But it helps finding consistency problems for now. Remove in
|
||||
|
@ -152,6 +162,7 @@ public:
|
|||
}
|
||||
return { this->pull_at(idx), idx };
|
||||
}
|
||||
|
||||
void sort() {
|
||||
std::sort(this->begin(), this->end(), [](const auto &a, const auto &b) { return CMP(*a, *b) < 0; });
|
||||
}
|
||||
|
|
|
@ -31,14 +31,6 @@ struct divecomputer *get_dc(struct parser_state *state)
|
|||
return state->cur_dc ?: &state->cur_dive->dcs[0];
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a dive into the dive_table array
|
||||
*/
|
||||
void record_dive_to_table(struct dive *dive, struct dive_table *table)
|
||||
{
|
||||
add_to_dive_table(table, table->nr, fixup_dive(dive));
|
||||
}
|
||||
|
||||
void start_match(const char *type, const char *name, char *buffer)
|
||||
{
|
||||
if (verbose > 2)
|
||||
|
@ -270,7 +262,12 @@ void dive_end(struct parser_state *state)
|
|||
if (is_dive(state)) {
|
||||
if (state->cur_trip)
|
||||
add_dive_to_trip(state->cur_dive.get(), state->cur_trip.get());
|
||||
record_dive_to_table(state->cur_dive.release(), state->log->dives.get());
|
||||
// Note: we add dives in an unsorted way. The caller of the parsing
|
||||
// function must sort dives.
|
||||
fixup_dive(state->cur_dive.get());
|
||||
state->log->dives.push_back(std::move(state->cur_dive));
|
||||
// This would add dives in a sorted way:
|
||||
// state->log->dives.record_dive(std::move(state->cur_dive));
|
||||
}
|
||||
state->cur_dive.reset();
|
||||
state->cur_dc = NULL;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "picture.h"
|
||||
#include "dive.h"
|
||||
#include "divelist.h"
|
||||
#include "divelog.h"
|
||||
#if !defined(SUBSURFACE_MOBILE)
|
||||
#include "metadata.h"
|
||||
#endif
|
||||
|
@ -30,11 +32,11 @@ int get_picture_idx(const picture_table &t, const std::string &filename)
|
|||
|
||||
#if !defined(SUBSURFACE_MOBILE)
|
||||
/* Return distance of timestamp to time of dive. Result is always positive, 0 means during dive. */
|
||||
static timestamp_t time_from_dive(const struct dive *d, timestamp_t timestamp)
|
||||
static timestamp_t time_from_dive(const struct dive &d, timestamp_t timestamp)
|
||||
{
|
||||
timestamp_t end_time = d->endtime();
|
||||
if (timestamp < d->when)
|
||||
return d->when - timestamp;
|
||||
timestamp_t end_time = d.endtime();
|
||||
if (timestamp < d.when)
|
||||
return d.when - timestamp;
|
||||
else if (timestamp > end_time)
|
||||
return timestamp - end_time;
|
||||
else
|
||||
|
@ -44,16 +46,15 @@ static timestamp_t time_from_dive(const struct dive *d, timestamp_t timestamp)
|
|||
/* Return dive closest selected dive to given timestamp or NULL if no dives are selected. */
|
||||
static struct dive *nearest_selected_dive(timestamp_t timestamp)
|
||||
{
|
||||
struct dive *d, *res = NULL;
|
||||
int i;
|
||||
timestamp_t offset, min = 0;
|
||||
struct dive *res = NULL;
|
||||
timestamp_t min = 0;
|
||||
|
||||
for_each_dive(i, d) {
|
||||
for (auto &d: divelog.dives) {
|
||||
if (!d->selected)
|
||||
continue;
|
||||
offset = time_from_dive(d, timestamp);
|
||||
timestamp_t offset = time_from_dive(*d, timestamp);
|
||||
if (!res || offset < min) {
|
||||
res = d;
|
||||
res = d.get();
|
||||
min = offset;
|
||||
}
|
||||
|
||||
|
@ -71,7 +72,7 @@ static struct dive *nearest_selected_dive(timestamp_t timestamp)
|
|||
// only add pictures that have timestamps between 30 minutes before the dive and
|
||||
// 30 minutes after the dive ends
|
||||
static constexpr timestamp_t d30min = 30 * 60;
|
||||
static bool dive_check_picture_time(const struct dive *d, timestamp_t timestamp)
|
||||
static bool dive_check_picture_time(const struct dive &d, timestamp_t timestamp)
|
||||
{
|
||||
return time_from_dive(d, timestamp) < d30min;
|
||||
}
|
||||
|
@ -93,7 +94,7 @@ std::pair<std::optional<picture>, dive *> create_picture(const std::string &file
|
|||
return { {}, nullptr };
|
||||
if (get_picture_idx(dive->pictures, filename) >= 0)
|
||||
return { {}, nullptr };
|
||||
if (!match_all && !dive_check_picture_time(dive, timestamp))
|
||||
if (!match_all && !dive_check_picture_time(*dive, timestamp))
|
||||
return { {}, nullptr };
|
||||
|
||||
struct picture picture;
|
||||
|
@ -105,12 +106,8 @@ std::pair<std::optional<picture>, dive *> create_picture(const std::string &file
|
|||
|
||||
bool picture_check_valid_time(timestamp_t timestamp, timestamp_t shift_time)
|
||||
{
|
||||
int i;
|
||||
struct dive *dive;
|
||||
|
||||
for_each_dive (i, dive)
|
||||
if (dive->selected && dive_check_picture_time(dive, timestamp + shift_time))
|
||||
return true;
|
||||
return false;
|
||||
return std::any_of(divelog.dives.begin(), divelog.dives.end(),
|
||||
[t = timestamp + shift_time] (auto &d)
|
||||
{ return d->selected && dive_check_picture_time(*d, t); });
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -301,7 +301,7 @@ static void create_dive_from_plan(struct diveplan *diveplan, struct dive *dive,
|
|||
dc->last_manual_time.seconds = last_manual_point;
|
||||
|
||||
#if DEBUG_PLAN & 32
|
||||
save_dive(stdout, dive);
|
||||
save_dive(stdout, *dive);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -988,14 +988,14 @@ static QString get_dive_only_date_string(timestamp_t when)
|
|||
|
||||
QString get_first_dive_date_string()
|
||||
{
|
||||
const dive_table &dives = *divelog.dives;
|
||||
return dives.nr > 0 ? get_dive_only_date_string(dives.dives[0]->when) : gettextFromC::tr("no dives");
|
||||
const dive_table &dives = divelog.dives;
|
||||
return !dives.empty() ? get_dive_only_date_string(dives[0]->when) : gettextFromC::tr("no dives");
|
||||
}
|
||||
|
||||
QString get_last_dive_date_string()
|
||||
{
|
||||
const dive_table &dives = *divelog.dives;
|
||||
return dives.nr > 0 ? get_dive_only_date_string(dives.dives[dives.nr - 1]->when) : gettextFromC::tr("no dives");
|
||||
const dive_table &dives = divelog.dives;
|
||||
return !dives.empty() ? get_dive_only_date_string(dives.back()->when) : gettextFromC::tr("no dives");
|
||||
}
|
||||
|
||||
std::string get_current_date()
|
||||
|
|
|
@ -46,7 +46,7 @@ static void cond_put_format(int cond, struct membuffer *b, const char *fmt, ...)
|
|||
}
|
||||
}
|
||||
|
||||
#define SAVE(str, x) cond_put_format(dive->x, b, str " %d\n", dive->x)
|
||||
#define SAVE(str, x) cond_put_format(dive.x, b, str " %d\n", dive.x)
|
||||
|
||||
static void quote(struct membuffer *b, const char *text)
|
||||
{
|
||||
|
@ -96,12 +96,12 @@ static void show_utf8(struct membuffer *b, const char *prefix, const char *value
|
|||
}
|
||||
}
|
||||
|
||||
static void save_overview(struct membuffer *b, struct dive *dive)
|
||||
static void save_overview(struct membuffer *b, const struct dive &dive)
|
||||
{
|
||||
show_utf8(b, "divemaster ", dive->diveguide.c_str(), "\n");
|
||||
show_utf8(b, "buddy ", dive->buddy.c_str(), "\n");
|
||||
show_utf8(b, "suit ", dive->suit.c_str(), "\n");
|
||||
show_utf8(b, "notes ", dive->notes.c_str(), "\n");
|
||||
show_utf8(b, "divemaster ", dive.diveguide.c_str(), "\n");
|
||||
show_utf8(b, "buddy ", dive.buddy.c_str(), "\n");
|
||||
show_utf8(b, "suit ", dive.suit.c_str(), "\n");
|
||||
show_utf8(b, "notes ", dive.notes.c_str(), "\n");
|
||||
}
|
||||
|
||||
static void save_tags(struct membuffer *b, const tag_list &tags)
|
||||
|
@ -138,9 +138,9 @@ static void put_gasmix(struct membuffer *b, struct gasmix mix)
|
|||
}
|
||||
}
|
||||
|
||||
static void save_cylinder_info(struct membuffer *b, struct dive *dive)
|
||||
static void save_cylinder_info(struct membuffer *b, const struct dive &dive)
|
||||
{
|
||||
for (auto &cyl: dive->cylinders) {
|
||||
for (auto &cyl: dive.cylinders) {
|
||||
int volume = cyl.type.size.mliter;
|
||||
int use = cyl.cylinder_use;
|
||||
|
||||
|
@ -161,9 +161,9 @@ static void save_cylinder_info(struct membuffer *b, struct dive *dive)
|
|||
}
|
||||
}
|
||||
|
||||
static void save_weightsystem_info(struct membuffer *b, const struct dive *dive)
|
||||
static void save_weightsystem_info(struct membuffer *b, const struct dive &dive)
|
||||
{
|
||||
for (auto &ws: dive->weightsystems) {
|
||||
for (auto &ws: dive.weightsystems) {
|
||||
int grams = ws.weight.grams;
|
||||
|
||||
put_string(b, "weightsystem");
|
||||
|
@ -173,12 +173,12 @@ static void save_weightsystem_info(struct membuffer *b, const struct dive *dive)
|
|||
}
|
||||
}
|
||||
|
||||
static void save_dive_temperature(struct membuffer *b, struct dive *dive)
|
||||
static void save_dive_temperature(struct membuffer *b, const struct dive &dive)
|
||||
{
|
||||
if (dive->airtemp.mkelvin != dive->dc_airtemp().mkelvin)
|
||||
put_temperature(b, dive->airtemp, "airtemp ", "°C\n");
|
||||
if (dive->watertemp.mkelvin != dive->dc_watertemp().mkelvin)
|
||||
put_temperature(b, dive->watertemp, "watertemp ", "°C\n");
|
||||
if (dive.airtemp.mkelvin != dive.dc_airtemp().mkelvin)
|
||||
put_temperature(b, dive.airtemp, "airtemp ", "°C\n");
|
||||
if (dive.watertemp.mkelvin != dive.dc_watertemp().mkelvin)
|
||||
put_temperature(b, dive.watertemp, "watertemp ", "°C\n");
|
||||
}
|
||||
|
||||
static void save_depths(struct membuffer *b, const struct divecomputer &dc)
|
||||
|
@ -356,13 +356,13 @@ static void save_sample(struct membuffer *b, const struct sample &sample, struct
|
|||
put_format(b, "\n");
|
||||
}
|
||||
|
||||
static void save_samples(struct membuffer *b, struct dive *dive, const struct divecomputer &dc)
|
||||
static void save_samples(struct membuffer *b, const struct dive &dive, const struct divecomputer &dc)
|
||||
{
|
||||
int o2sensor;
|
||||
struct sample dummy;
|
||||
|
||||
/* Is this a CCR dive with the old-style "o2pressure" sensor? */
|
||||
o2sensor = legacy_format_o2pressures(dive, &dc);
|
||||
o2sensor = legacy_format_o2pressures(&dive, &dc);
|
||||
if (o2sensor >= 0) {
|
||||
dummy.sensor[0] = !o2sensor;
|
||||
dummy.sensor[1] = o2sensor;
|
||||
|
@ -372,7 +372,7 @@ static void save_samples(struct membuffer *b, struct dive *dive, const struct di
|
|||
save_sample(b, s, dummy, o2sensor);
|
||||
}
|
||||
|
||||
static void save_one_event(struct membuffer *b, struct dive *dive, const struct event &ev)
|
||||
static void save_one_event(struct membuffer *b, const struct dive &dive, const struct event &ev)
|
||||
{
|
||||
put_format(b, "event %d:%02d", FRACTION_TUPLE(ev.time.seconds, 60));
|
||||
show_index(b, ev.type, "type=", "");
|
||||
|
@ -384,7 +384,7 @@ static void save_one_event(struct membuffer *b, struct dive *dive, const struct
|
|||
show_index(b, ev.value, "value=", "");
|
||||
show_utf8(b, " name=", ev.name.c_str(), "");
|
||||
if (ev.is_gaschange()) {
|
||||
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);
|
||||
|
@ -392,13 +392,13 @@ static void save_one_event(struct membuffer *b, struct dive *dive, const struct
|
|||
put_string(b, "\n");
|
||||
}
|
||||
|
||||
static void save_events(struct membuffer *b, struct dive *dive, const struct divecomputer &dc)
|
||||
static void save_events(struct membuffer *b, const struct dive &dive, const struct divecomputer &dc)
|
||||
{
|
||||
for (auto &ev: dc.events)
|
||||
save_one_event(b, dive, ev);
|
||||
}
|
||||
|
||||
static void save_dc(struct membuffer *b, struct dive *dive, const struct divecomputer &dc)
|
||||
static void save_dc(struct membuffer *b, const struct dive &dive, const struct divecomputer &dc)
|
||||
{
|
||||
show_utf8(b, "model ", dc.model.c_str(), "\n");
|
||||
if (dc.last_manual_time.seconds)
|
||||
|
@ -407,9 +407,9 @@ static void save_dc(struct membuffer *b, struct dive *dive, const struct divecom
|
|||
put_format(b, "deviceid %08x\n", dc.deviceid);
|
||||
if (dc.diveid)
|
||||
put_format(b, "diveid %08x\n", dc.diveid);
|
||||
if (dc.when && dc.when != dive->when)
|
||||
if (dc.when && dc.when != dive.when)
|
||||
show_date(b, dc.when);
|
||||
if (dc.duration.seconds && dc.duration.seconds != dive->dcs[0].duration.seconds)
|
||||
if (dc.duration.seconds && dc.duration.seconds != dive.dcs[0].duration.seconds)
|
||||
put_duration(b, dc.duration, "duration ", "min\n");
|
||||
if (dc.divemode != OC) {
|
||||
put_format(b, "dctype %s\n", divemode_text[dc.divemode]);
|
||||
|
@ -431,28 +431,28 @@ static void save_dc(struct membuffer *b, struct dive *dive, const struct divecom
|
|||
* Note that we don't save the date and time or dive
|
||||
* number: they are encoded in the filename.
|
||||
*/
|
||||
static void create_dive_buffer(struct dive *dive, struct membuffer *b)
|
||||
static void create_dive_buffer(const struct dive &dive, struct membuffer *b)
|
||||
{
|
||||
pressure_t surface_pressure = un_fixup_surface_pressure(dive);
|
||||
if (dive->dcs[0].duration.seconds > 0)
|
||||
put_format(b, "duration %u:%02u min\n", FRACTION_TUPLE(dive->dcs[0].duration.seconds, 60));
|
||||
pressure_t surface_pressure = un_fixup_surface_pressure(&dive);
|
||||
if (dive.dcs[0].duration.seconds > 0)
|
||||
put_format(b, "duration %u:%02u min\n", FRACTION_TUPLE(dive.dcs[0].duration.seconds, 60));
|
||||
SAVE("rating", rating);
|
||||
SAVE("visibility", visibility);
|
||||
SAVE("wavesize", wavesize);
|
||||
SAVE("current", current);
|
||||
SAVE("surge", surge);
|
||||
SAVE("chill", chill);
|
||||
if (dive->user_salinity)
|
||||
put_format(b, "watersalinity %d g/l\n", (int)(dive->user_salinity/10));
|
||||
if (dive.user_salinity)
|
||||
put_format(b, "watersalinity %d g/l\n", (int)(dive.user_salinity/10));
|
||||
if (surface_pressure.mbar)
|
||||
SAVE("airpressure", surface_pressure.mbar);
|
||||
cond_put_format(dive->notrip, b, "notrip\n");
|
||||
cond_put_format(dive->invalid, b, "invalid\n");
|
||||
save_tags(b, dive->tags);
|
||||
if (dive->dive_site)
|
||||
put_format(b, "divesiteid %08x\n", dive->dive_site->uuid);
|
||||
if (verbose && dive->dive_site)
|
||||
report_info("removed reference to non-existant dive site with uuid %08x\n", dive->dive_site->uuid);
|
||||
cond_put_format(dive.notrip, b, "notrip\n");
|
||||
cond_put_format(dive.invalid, b, "invalid\n");
|
||||
save_tags(b, dive.tags);
|
||||
if (dive.dive_site)
|
||||
put_format(b, "divesiteid %08x\n", dive.dive_site->uuid);
|
||||
if (verbose && dive.dive_site)
|
||||
report_info("removed reference to non-existant dive site with uuid %08x\n", dive.dive_site->uuid);
|
||||
save_overview(b, dive);
|
||||
save_cylinder_info(b, dive);
|
||||
save_weightsystem_info(b, dive);
|
||||
|
@ -565,12 +565,12 @@ static struct dir *mktree(git_repository *repo, struct dir *dir, const char *fmt
|
|||
* We do *not* want to use localized weekdays and cause peoples save
|
||||
* formats to depend on their locale.
|
||||
*/
|
||||
static void create_dive_name(struct dive *dive, struct membuffer *name, struct tm *dirtm)
|
||||
static void create_dive_name(struct dive &dive, struct membuffer *name, struct tm *dirtm)
|
||||
{
|
||||
struct tm tm;
|
||||
static const char weekday[7][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||
|
||||
utc_mkdate(dive->when, &tm);
|
||||
utc_mkdate(dive.when, &tm);
|
||||
if (tm.tm_year != dirtm->tm_year)
|
||||
put_format(name, "%04u-", tm.tm_year);
|
||||
if (tm.tm_mon != dirtm->tm_mon)
|
||||
|
@ -600,7 +600,7 @@ static int blob_insert(git_repository *repo, struct dir *tree, struct membuffer
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int save_one_divecomputer(git_repository *repo, struct dir *tree, struct dive *dive, const struct divecomputer &dc, int idx)
|
||||
static int save_one_divecomputer(git_repository *repo, struct dir *tree, const struct dive &dive, const struct divecomputer &dc, int idx)
|
||||
{
|
||||
int ret;
|
||||
membuffer buf;
|
||||
|
@ -635,17 +635,17 @@ static int save_one_picture(git_repository *repo, struct dir *dir, const struct
|
|||
sign, h, FRACTION_TUPLE(offset, 60));
|
||||
}
|
||||
|
||||
static int save_pictures(git_repository *repo, struct dir *dir, struct dive *dive)
|
||||
static int save_pictures(git_repository *repo, struct dir *dir, const struct dive &dive)
|
||||
{
|
||||
if (!dive->pictures.empty()) {
|
||||
if (!dive.pictures.empty()) {
|
||||
dir = mktree(repo, dir, "Pictures");
|
||||
for (auto &picture: dive->pictures)
|
||||
for (auto &picture: dive.pictures)
|
||||
save_one_picture(repo, dir, picture);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int save_one_dive(git_repository *repo, struct dir *tree, struct dive *dive, struct tm *tm, bool cached_ok)
|
||||
static int save_one_dive(git_repository *repo, struct dir *tree, struct dive &dive, struct tm *tm, bool cached_ok)
|
||||
{
|
||||
membuffer buf, name;
|
||||
struct dir *subdir;
|
||||
|
@ -658,9 +658,9 @@ static int save_one_dive(git_repository *repo, struct dir *tree, struct dive *di
|
|||
* If the dive git ID is valid, we just create the whole directory
|
||||
* with that ID
|
||||
*/
|
||||
if (cached_ok && dive_cache_is_valid(dive)) {
|
||||
if (cached_ok && dive_cache_is_valid(&dive)) {
|
||||
git_oid oid;
|
||||
git_oid_fromraw(&oid, dive->git_id);
|
||||
git_oid_fromraw(&oid, dive.git_id);
|
||||
ret = tree_insert(tree->files, mb_cstring(&name), 1,
|
||||
&oid, GIT_FILEMODE_TREE);
|
||||
if (ret)
|
||||
|
@ -672,7 +672,7 @@ static int save_one_dive(git_repository *repo, struct dir *tree, struct dive *di
|
|||
subdir->unique = true;
|
||||
|
||||
create_dive_buffer(dive, &buf);
|
||||
nr = dive->number;
|
||||
nr = dive.number;
|
||||
ret = blob_insert(repo, subdir, &buf,
|
||||
"Dive%c%d", nr ? '-' : 0, nr);
|
||||
if (ret)
|
||||
|
@ -683,8 +683,8 @@ static int save_one_dive(git_repository *repo, struct dir *tree, struct dive *di
|
|||
* computer, use index 0 for that (which disables the index
|
||||
* generation when naming it).
|
||||
*/
|
||||
nr = dive->dcs.size() > 1 ? 1 : 0;
|
||||
for (auto &dc: dive->dcs)
|
||||
nr = dive.dcs.size() > 1 ? 1 : 0;
|
||||
for (auto &dc: dive.dcs)
|
||||
save_one_divecomputer(repo, subdir, dive, dc, nr++);
|
||||
|
||||
/* Save the picture data, if any */
|
||||
|
@ -782,8 +782,6 @@ static void verify_shared_date(timestamp_t when, struct tm *tm)
|
|||
|
||||
static int save_one_trip(git_repository *repo, struct dir *tree, dive_trip *trip, struct tm *tm, bool cached_ok)
|
||||
{
|
||||
int i;
|
||||
struct dive *dive;
|
||||
struct dir *subdir;
|
||||
membuffer name;
|
||||
timestamp_t first, last;
|
||||
|
@ -799,7 +797,7 @@ static int save_one_trip(git_repository *repo, struct dir *tree, dive_trip *trip
|
|||
/* Make sure we write out the dates to the dives consistently */
|
||||
first = MAX_TIMESTAMP;
|
||||
last = MIN_TIMESTAMP;
|
||||
for_each_dive(i, dive) {
|
||||
for (auto &dive: divelog.dives) {
|
||||
if (dive->divetrip != trip)
|
||||
continue;
|
||||
if (dive->when < first)
|
||||
|
@ -811,9 +809,9 @@ static int save_one_trip(git_repository *repo, struct dir *tree, dive_trip *trip
|
|||
verify_shared_date(last, tm);
|
||||
|
||||
/* Save each dive in the directory */
|
||||
for_each_dive(i, dive) {
|
||||
for (auto &dive: divelog.dives) {
|
||||
if (dive->divetrip == trip)
|
||||
save_one_dive(repo, subdir, dive, tm, cached_ok);
|
||||
save_one_dive(repo, subdir, *dive, tm, cached_ok);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -981,9 +979,6 @@ static void save_filter_presets(git_repository *repo, struct dir *tree)
|
|||
|
||||
static int create_git_tree(git_repository *repo, struct dir *root, bool select_only, bool cached_ok)
|
||||
{
|
||||
int i;
|
||||
struct dive *dive;
|
||||
|
||||
git_storage_update_progress(translate("gettextFromC", "Start saving data"));
|
||||
save_settings(repo, root);
|
||||
|
||||
|
@ -995,7 +990,7 @@ static int create_git_tree(git_repository *repo, struct dir *root, bool select_o
|
|||
|
||||
/* save the dives */
|
||||
git_storage_update_progress(translate("gettextFromC", "Start saving dives"));
|
||||
for_each_dive(i, dive) {
|
||||
for (auto &dive: divelog.dives) {
|
||||
struct tm tm;
|
||||
struct dir *tree;
|
||||
|
||||
|
@ -1024,7 +1019,7 @@ static int create_git_tree(git_repository *repo, struct dir *root, bool select_o
|
|||
continue;
|
||||
}
|
||||
|
||||
save_one_dive(repo, tree, dive, &tm, cached_ok);
|
||||
save_one_dive(repo, tree, *dive, &tm, cached_ok);
|
||||
}
|
||||
git_storage_update_progress(translate("gettextFromC", "Done creating local cache"));
|
||||
return 0;
|
||||
|
@ -1095,7 +1090,7 @@ int get_authorship(git_repository *repo, git_signature **authorp)
|
|||
|
||||
static void create_commit_message(struct membuffer *msg, bool create_empty)
|
||||
{
|
||||
int nr = divelog.dives->nr;
|
||||
int nr = static_cast<int>(divelog.dives.size());
|
||||
struct dive *dive = get_dive(nr-1);
|
||||
std::string changes_made = get_changes_made();
|
||||
|
||||
|
|
|
@ -43,13 +43,13 @@ static void copy_image_and_overwrite(const std::string &cfileName, const std::st
|
|||
report_info("copy of %s to %s failed", cfileName.c_str(), newName.c_str());
|
||||
}
|
||||
|
||||
static void save_photos(struct membuffer *b, const char *photos_dir, const struct dive *dive)
|
||||
static void save_photos(struct membuffer *b, const char *photos_dir, const struct dive &dive)
|
||||
{
|
||||
if (dive->pictures.empty())
|
||||
if (dive.pictures.empty())
|
||||
return;
|
||||
|
||||
const char *separator = "\"photos\":[";
|
||||
for (auto &picture: dive->pictures) {
|
||||
for (auto &picture: dive.pictures) {
|
||||
put_string(b, separator);
|
||||
separator = ", ";
|
||||
std::string fname = get_file_name(local_file_path(picture));
|
||||
|
@ -61,11 +61,11 @@ static void save_photos(struct membuffer *b, const char *photos_dir, const struc
|
|||
put_string(b, "],");
|
||||
}
|
||||
|
||||
static void write_divecomputers(struct membuffer *b, const struct dive *dive)
|
||||
static void write_divecomputers(struct membuffer *b, const struct dive &dive)
|
||||
{
|
||||
put_string(b, "\"divecomputers\":[");
|
||||
const char *separator = "";
|
||||
for (auto &dc: dive->dcs) {
|
||||
for (auto &dc: dive.dcs) {
|
||||
put_string(b, separator);
|
||||
separator = ", ";
|
||||
put_format(b, "{");
|
||||
|
@ -83,17 +83,17 @@ static void write_divecomputers(struct membuffer *b, const struct dive *dive)
|
|||
put_string(b, "],");
|
||||
}
|
||||
|
||||
static void write_dive_status(struct membuffer *b, const struct dive *dive)
|
||||
static void write_dive_status(struct membuffer *b, const struct dive &dive)
|
||||
{
|
||||
put_format(b, "\"sac\":\"%d\",", dive->sac);
|
||||
put_format(b, "\"otu\":\"%d\",", dive->otu);
|
||||
put_format(b, "\"cns\":\"%d\",", dive->cns);
|
||||
put_format(b, "\"sac\":\"%d\",", dive.sac);
|
||||
put_format(b, "\"otu\":\"%d\",", dive.otu);
|
||||
put_format(b, "\"cns\":\"%d\",", dive.cns);
|
||||
}
|
||||
|
||||
static void put_HTML_bookmarks(struct membuffer *b, const struct dive *dive)
|
||||
static void put_HTML_bookmarks(struct membuffer *b, const struct dive &dive)
|
||||
{
|
||||
const char *separator = "\"events\":[";
|
||||
for (const auto &ev: dive->dcs[0].events) {
|
||||
for (const auto &ev: dive.dcs[0].events) {
|
||||
put_string(b, separator);
|
||||
separator = ", ";
|
||||
put_string(b, "{\"name\":\"");
|
||||
|
@ -106,13 +106,13 @@ static void put_HTML_bookmarks(struct membuffer *b, const struct dive *dive)
|
|||
put_string(b, "],");
|
||||
}
|
||||
|
||||
static void put_weightsystem_HTML(struct membuffer *b, const struct dive *dive)
|
||||
static void put_weightsystem_HTML(struct membuffer *b, const struct dive &dive)
|
||||
{
|
||||
put_string(b, "\"Weights\":[");
|
||||
|
||||
const char *separator = "";
|
||||
|
||||
for (auto &ws: dive->weightsystems) {
|
||||
for (auto &ws: dive.weightsystems) {
|
||||
int grams = ws.weight.grams;
|
||||
|
||||
put_string(b, separator);
|
||||
|
@ -125,14 +125,14 @@ static void put_weightsystem_HTML(struct membuffer *b, const struct dive *dive)
|
|||
put_string(b, "],");
|
||||
}
|
||||
|
||||
static void put_cylinder_HTML(struct membuffer *b, const struct dive *dive)
|
||||
static void put_cylinder_HTML(struct membuffer *b, const struct dive &dive)
|
||||
{
|
||||
const char *separator = "\"Cylinders\":[";
|
||||
|
||||
if (dive->cylinders.empty())
|
||||
if (dive.cylinders.empty())
|
||||
put_string(b, separator);
|
||||
|
||||
for (auto &cyl: dive->cylinders) {
|
||||
for (auto &cyl: dive.cylinders) {
|
||||
put_format(b, "%s{", separator);
|
||||
separator = ", ";
|
||||
write_attribute(b, "Type", cyl.type.description.c_str(), ", ");
|
||||
|
@ -172,25 +172,25 @@ static void put_cylinder_HTML(struct membuffer *b, const struct dive *dive)
|
|||
}
|
||||
|
||||
|
||||
static void put_HTML_samples(struct membuffer *b, const struct dive *dive)
|
||||
static void put_HTML_samples(struct membuffer *b, const struct dive &dive)
|
||||
{
|
||||
put_format(b, "\"maxdepth\":%d,", dive->dcs[0].maxdepth.mm);
|
||||
put_format(b, "\"duration\":%d,", dive->dcs[0].duration.seconds);
|
||||
put_format(b, "\"maxdepth\":%d,", dive.dcs[0].maxdepth.mm);
|
||||
put_format(b, "\"duration\":%d,", dive.dcs[0].duration.seconds);
|
||||
|
||||
if (dive->dcs[0].samples.empty())
|
||||
if (dive.dcs[0].samples.empty())
|
||||
return;
|
||||
|
||||
const char *separator = "\"samples\":[";
|
||||
for (auto &s: dive->dcs[0].samples) {
|
||||
for (auto &s: dive.dcs[0].samples) {
|
||||
put_format(b, "%s[%d,%d,%d,%d]", separator, s.time.seconds, s.depth.mm, s.pressure[0].mbar, s.temperature.mkelvin);
|
||||
separator = ", ";
|
||||
}
|
||||
put_string(b, "],");
|
||||
}
|
||||
|
||||
static void put_HTML_coordinates(struct membuffer *b, const struct dive *dive)
|
||||
static void put_HTML_coordinates(struct membuffer *b, const struct dive &dive)
|
||||
{
|
||||
struct dive_site *ds = get_dive_site_for_dive(dive);
|
||||
struct dive_site *ds = get_dive_site_for_dive(&dive);
|
||||
if (!ds)
|
||||
return;
|
||||
degrees_t latitude = ds->location.lat;
|
||||
|
@ -206,10 +206,10 @@ static void put_HTML_coordinates(struct membuffer *b, const struct dive *dive)
|
|||
put_string(b, "},");
|
||||
}
|
||||
|
||||
void put_HTML_date(struct membuffer *b, const struct dive *dive, const char *pre, const char *post)
|
||||
void put_HTML_date(struct membuffer *b, const struct dive &dive, const char *pre, const char *post)
|
||||
{
|
||||
struct tm tm;
|
||||
utc_mkdate(dive->when, &tm);
|
||||
utc_mkdate(dive.when, &tm);
|
||||
put_format(b, "%s%04u-%02u-%02u%s", pre, tm.tm_year, tm.tm_mon + 1, tm.tm_mday, post);
|
||||
}
|
||||
|
||||
|
@ -219,11 +219,11 @@ void put_HTML_quoted(struct membuffer *b, const char *text)
|
|||
put_quoted(b, text, is_attribute, is_html);
|
||||
}
|
||||
|
||||
void put_HTML_notes(struct membuffer *b, const struct dive *dive, const char *pre, const char *post)
|
||||
void put_HTML_notes(struct membuffer *b, const struct dive &dive, const char *pre, const char *post)
|
||||
{
|
||||
put_string(b, pre);
|
||||
if (!dive->notes.empty())
|
||||
put_HTML_quoted(b, dive->notes.c_str());
|
||||
if (!dive.notes.empty())
|
||||
put_HTML_quoted(b, dive.notes.c_str());
|
||||
else
|
||||
put_string(b, "--");
|
||||
put_string(b, post);
|
||||
|
@ -263,24 +263,24 @@ void put_HTML_weight_units(struct membuffer *b, unsigned int grams, const char *
|
|||
put_format(b, "%s%.1f %s%s", pre, value, unit, post);
|
||||
}
|
||||
|
||||
void put_HTML_time(struct membuffer *b, const struct dive *dive, const char *pre, const char *post)
|
||||
void put_HTML_time(struct membuffer *b, const struct dive &dive, const char *pre, const char *post)
|
||||
{
|
||||
struct tm tm;
|
||||
utc_mkdate(dive->when, &tm);
|
||||
utc_mkdate(dive.when, &tm);
|
||||
put_format(b, "%s%02u:%02u:%02u%s", pre, tm.tm_hour, tm.tm_min, tm.tm_sec, post);
|
||||
}
|
||||
|
||||
void put_HTML_depth(struct membuffer *b, const struct dive *dive, const char *pre, const char *post)
|
||||
void put_HTML_depth(struct membuffer *b, const struct dive &dive, const char *pre, const char *post)
|
||||
{
|
||||
const char *unit;
|
||||
double value;
|
||||
const struct units *units_p = get_units();
|
||||
|
||||
if (!dive->maxdepth.mm) {
|
||||
if (!dive.maxdepth.mm) {
|
||||
put_format(b, "%s--%s", pre, post);
|
||||
return;
|
||||
}
|
||||
value = get_depth_units(dive->maxdepth.mm, NULL, &unit);
|
||||
value = get_depth_units(dive.maxdepth.mm, NULL, &unit);
|
||||
|
||||
switch (units_p->length) {
|
||||
case units::METERS:
|
||||
|
@ -293,41 +293,41 @@ void put_HTML_depth(struct membuffer *b, const struct dive *dive, const char *pr
|
|||
}
|
||||
}
|
||||
|
||||
void put_HTML_airtemp(struct membuffer *b, const struct dive *dive, const char *pre, const char *post)
|
||||
void put_HTML_airtemp(struct membuffer *b, const struct dive &dive, const char *pre, const char *post)
|
||||
{
|
||||
const char *unit;
|
||||
double value;
|
||||
|
||||
if (!dive->airtemp.mkelvin) {
|
||||
if (!dive.airtemp.mkelvin) {
|
||||
put_format(b, "%s--%s", pre, post);
|
||||
return;
|
||||
}
|
||||
value = get_temp_units(dive->airtemp.mkelvin, &unit);
|
||||
value = get_temp_units(dive.airtemp.mkelvin, &unit);
|
||||
put_format(b, "%s%.1f %s%s", pre, value, unit, post);
|
||||
}
|
||||
|
||||
void put_HTML_watertemp(struct membuffer *b, const struct dive *dive, const char *pre, const char *post)
|
||||
void put_HTML_watertemp(struct membuffer *b, const struct dive &dive, const char *pre, const char *post)
|
||||
{
|
||||
const char *unit;
|
||||
double value;
|
||||
|
||||
if (!dive->watertemp.mkelvin) {
|
||||
if (!dive.watertemp.mkelvin) {
|
||||
put_format(b, "%s--%s", pre, post);
|
||||
return;
|
||||
}
|
||||
value = get_temp_units(dive->watertemp.mkelvin, &unit);
|
||||
value = get_temp_units(dive.watertemp.mkelvin, &unit);
|
||||
put_format(b, "%s%.1f %s%s", pre, value, unit, post);
|
||||
}
|
||||
|
||||
static void put_HTML_tags(struct membuffer *b, const struct dive *dive, const char *pre, const char *post)
|
||||
static void put_HTML_tags(struct membuffer *b, const struct dive &dive, const char *pre, const char *post)
|
||||
{
|
||||
put_string(b, pre);
|
||||
|
||||
if (dive->tags.empty())
|
||||
if (dive.tags.empty())
|
||||
put_string(b, "[\"--\"");
|
||||
|
||||
const char *separator = "[";
|
||||
for (const divetag *tag: dive->tags) {
|
||||
for (const divetag *tag: dive.tags) {
|
||||
put_format(b, "%s\"", separator);
|
||||
separator = ", ";
|
||||
put_HTML_quoted(b, tag->name.c_str());
|
||||
|
@ -338,30 +338,30 @@ static void put_HTML_tags(struct membuffer *b, const struct dive *dive, const ch
|
|||
}
|
||||
|
||||
/* if exporting list_only mode, we neglect exporting the samples, bookmarks and cylinders */
|
||||
static void write_one_dive(struct membuffer *b, const struct dive *dive, const char *photos_dir, int *dive_no, bool list_only)
|
||||
static void write_one_dive(struct membuffer *b, const struct dive &dive, const char *photos_dir, int *dive_no, bool list_only)
|
||||
{
|
||||
put_string(b, "{");
|
||||
put_format(b, "\"number\":%d,", *dive_no);
|
||||
put_format(b, "\"subsurface_number\":%d,", dive->number);
|
||||
put_format(b, "\"subsurface_number\":%d,", dive.number);
|
||||
put_HTML_date(b, dive, "\"date\":\"", "\",");
|
||||
put_HTML_time(b, dive, "\"time\":\"", "\",");
|
||||
write_attribute(b, "location", get_dive_location(dive).c_str(), ", ");
|
||||
write_attribute(b, "location", get_dive_location(&dive).c_str(), ", ");
|
||||
put_HTML_coordinates(b, dive);
|
||||
put_format(b, "\"rating\":%d,", dive->rating);
|
||||
put_format(b, "\"visibility\":%d,", dive->visibility);
|
||||
put_format(b, "\"current\":%d,", dive->current);
|
||||
put_format(b, "\"wavesize\":%d,", dive->wavesize);
|
||||
put_format(b, "\"surge\":%d,", dive->surge);
|
||||
put_format(b, "\"chill\":%d,", dive->chill);
|
||||
put_format(b, "\"rating\":%d,", dive.rating);
|
||||
put_format(b, "\"visibility\":%d,", dive.visibility);
|
||||
put_format(b, "\"current\":%d,", dive.current);
|
||||
put_format(b, "\"wavesize\":%d,", dive.wavesize);
|
||||
put_format(b, "\"surge\":%d,", dive.surge);
|
||||
put_format(b, "\"chill\":%d,", dive.chill);
|
||||
put_format(b, "\"dive_duration\":\"%u:%02u min\",",
|
||||
FRACTION_TUPLE(dive->duration.seconds, 60));
|
||||
FRACTION_TUPLE(dive.duration.seconds, 60));
|
||||
put_string(b, "\"temperature\":{");
|
||||
put_HTML_airtemp(b, dive, "\"air\":\"", "\",");
|
||||
put_HTML_watertemp(b, dive, "\"water\":\"", "\"");
|
||||
put_string(b, " },");
|
||||
write_attribute(b, "buddy", dive->buddy.c_str(), ", ");
|
||||
write_attribute(b, "diveguide", dive->diveguide.c_str(), ", ");
|
||||
write_attribute(b, "suit", dive->suit.c_str(), ", ");
|
||||
write_attribute(b, "buddy", dive.buddy.c_str(), ", ");
|
||||
write_attribute(b, "diveguide", dive.diveguide.c_str(), ", ");
|
||||
write_attribute(b, "suit", dive.suit.c_str(), ", ");
|
||||
put_HTML_tags(b, dive, "\"tags\":", ",");
|
||||
if (!list_only) {
|
||||
put_cylinder_HTML(b, dive);
|
||||
|
@ -380,12 +380,10 @@ static void write_one_dive(struct membuffer *b, const struct dive *dive, const c
|
|||
|
||||
static void write_no_trip(struct membuffer *b, int *dive_no, bool selected_only, const char *photos_dir, const bool list_only, char *sep)
|
||||
{
|
||||
int i;
|
||||
const struct dive *dive;
|
||||
const char *separator = "";
|
||||
bool found_sel_dive = 0;
|
||||
|
||||
for_each_dive (i, dive) {
|
||||
for (auto &dive: divelog.dives) {
|
||||
// write dive if it doesn't belong to any trip and the dive is selected
|
||||
// or we are in exporting all dives mode.
|
||||
if (!dive->divetrip && (dive->selected || !selected_only)) {
|
||||
|
@ -398,7 +396,7 @@ static void write_no_trip(struct membuffer *b, int *dive_no, bool selected_only,
|
|||
}
|
||||
put_string(b, separator);
|
||||
separator = ", ";
|
||||
write_one_dive(b, dive, photos_dir, dive_no, list_only);
|
||||
write_one_dive(b, *dive, photos_dir, dive_no, list_only);
|
||||
}
|
||||
}
|
||||
if (found_sel_dive)
|
||||
|
@ -424,7 +422,7 @@ static void write_trip(struct membuffer *b, dive_trip *trip, int *dive_no, bool
|
|||
}
|
||||
put_string(b, separator);
|
||||
separator = ", ";
|
||||
write_one_dive(b, dive, photos_dir, dive_no, list_only);
|
||||
write_one_dive(b, *dive, photos_dir, dive_no, list_only);
|
||||
}
|
||||
|
||||
// close the trip object if contain dives.
|
||||
|
@ -434,15 +432,14 @@ static void write_trip(struct membuffer *b, dive_trip *trip, int *dive_no, bool
|
|||
|
||||
static void write_trips(struct membuffer *b, const char *photos_dir, bool selected_only, const bool list_only)
|
||||
{
|
||||
int i, dive_no = 0;
|
||||
const struct dive *dive;
|
||||
int dive_no = 0;
|
||||
char sep_ = ' ';
|
||||
char *sep = &sep_;
|
||||
|
||||
for (auto &trip: *divelog.trips)
|
||||
trip->saved = 0;
|
||||
|
||||
for_each_dive (i, dive) {
|
||||
for (auto &dive: divelog.dives) {
|
||||
dive_trip *trip = dive->divetrip;
|
||||
|
||||
/*Continue if the dive have no trips or we have seen this trip before*/
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
|
||||
struct dive;
|
||||
|
||||
void put_HTML_date(struct membuffer *b, const struct dive *dive, const char *pre, const char *post);
|
||||
void put_HTML_depth(struct membuffer *b, const struct dive *dive, const char *pre, const char *post);
|
||||
void put_HTML_airtemp(struct membuffer *b, const struct dive *dive, const char *pre, const char *post);
|
||||
void put_HTML_watertemp(struct membuffer *b, const struct dive *dive, const char *pre, const char *post);
|
||||
void put_HTML_time(struct membuffer *b, const struct dive *dive, const char *pre, const char *post);
|
||||
void put_HTML_notes(struct membuffer *b, const struct dive *dive, const char *pre, const char *post);
|
||||
void put_HTML_date(struct membuffer *b, const struct dive &dive, const char *pre, const char *post);
|
||||
void put_HTML_depth(struct membuffer *b, const struct dive &dive, const char *pre, const char *post);
|
||||
void put_HTML_airtemp(struct membuffer *b, const struct dive &dive, const char *pre, const char *post);
|
||||
void put_HTML_watertemp(struct membuffer *b, const struct dive &dive, const char *pre, const char *post);
|
||||
void put_HTML_time(struct membuffer *b, const struct dive &dive, const char *pre, const char *post);
|
||||
void put_HTML_notes(struct membuffer *b, const struct dive &dive, const char *pre, const char *post);
|
||||
void put_HTML_quoted(struct membuffer *b, const char *text);
|
||||
void put_HTML_pressure_units(struct membuffer *b, pressure_t pressure, const char *pre, const char *post);
|
||||
void put_HTML_weight_units(struct membuffer *b, unsigned int grams, const char *pre, const char *post);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "core/save-profiledata.h"
|
||||
#include "core/dive.h"
|
||||
#include "core/divelist.h"
|
||||
#include "core/divelog.h"
|
||||
#include "core/profile.h"
|
||||
#include "core/errorhelper.h"
|
||||
#include "core/file.h"
|
||||
|
@ -203,14 +205,12 @@ static void put_st_event(struct membuffer *b, const plot_data &entry, const plot
|
|||
|
||||
static void save_profiles_buffer(struct membuffer *b, bool select_only)
|
||||
{
|
||||
int i;
|
||||
struct dive *dive;
|
||||
struct deco_state *planner_deco_state = NULL;
|
||||
|
||||
for_each_dive(i, dive) {
|
||||
for(auto &dive: divelog.dives) {
|
||||
if (select_only && !dive->selected)
|
||||
continue;
|
||||
plot_info pi = create_plot_info_new(dive, &dive->dcs[0], planner_deco_state);
|
||||
plot_info pi = create_plot_info_new(dive.get(), &dive->dcs[0], planner_deco_state);
|
||||
put_headers(b, pi.nr_cylinders);
|
||||
|
||||
for (int i = 0; i < pi.nr; i++)
|
||||
|
|
|
@ -100,67 +100,67 @@ static void show_utf8_blanked(struct membuffer *b, const char *text, const char
|
|||
show_utf8(b, copy.c_str(), pre, post, is_attribute);
|
||||
}
|
||||
|
||||
static void save_depths(struct membuffer *b, struct divecomputer *dc)
|
||||
static void save_depths(struct membuffer *b, const struct divecomputer &dc)
|
||||
{
|
||||
/* What's the point of this dive entry again? */
|
||||
if (!dc->maxdepth.mm && !dc->meandepth.mm)
|
||||
if (!dc.maxdepth.mm && !dc.meandepth.mm)
|
||||
return;
|
||||
|
||||
put_string(b, " <depth");
|
||||
put_depth(b, dc->maxdepth, " max='", " m'");
|
||||
put_depth(b, dc->meandepth, " mean='", " m'");
|
||||
put_depth(b, dc.maxdepth, " max='", " m'");
|
||||
put_depth(b, dc.meandepth, " mean='", " m'");
|
||||
put_string(b, " />\n");
|
||||
}
|
||||
|
||||
static void save_dive_temperature(struct membuffer *b, struct dive *dive)
|
||||
static void save_dive_temperature(struct membuffer *b, const struct dive &dive)
|
||||
{
|
||||
if (!dive->airtemp.mkelvin && !dive->watertemp.mkelvin)
|
||||
if (!dive.airtemp.mkelvin && !dive.watertemp.mkelvin)
|
||||
return;
|
||||
if (dive->airtemp.mkelvin == dive->dc_airtemp().mkelvin && dive->watertemp.mkelvin == dive->dc_watertemp().mkelvin)
|
||||
if (dive.airtemp.mkelvin == dive.dc_airtemp().mkelvin && dive.watertemp.mkelvin == dive.dc_watertemp().mkelvin)
|
||||
return;
|
||||
|
||||
put_string(b, " <divetemperature");
|
||||
if (dive->airtemp.mkelvin != dive->dc_airtemp().mkelvin)
|
||||
put_temperature(b, dive->airtemp, " air='", " C'");
|
||||
if (dive->watertemp.mkelvin != dive->dc_watertemp().mkelvin)
|
||||
put_temperature(b, dive->watertemp, " water='", " C'");
|
||||
if (dive.airtemp.mkelvin != dive.dc_airtemp().mkelvin)
|
||||
put_temperature(b, dive.airtemp, " air='", " C'");
|
||||
if (dive.watertemp.mkelvin != dive.dc_watertemp().mkelvin)
|
||||
put_temperature(b, dive.watertemp, " water='", " C'");
|
||||
put_string(b, "/>\n");
|
||||
}
|
||||
|
||||
static void save_temperatures(struct membuffer *b, struct divecomputer *dc)
|
||||
static void save_temperatures(struct membuffer *b, const struct divecomputer &dc)
|
||||
{
|
||||
if (!dc->airtemp.mkelvin && !dc->watertemp.mkelvin)
|
||||
if (!dc.airtemp.mkelvin && !dc.watertemp.mkelvin)
|
||||
return;
|
||||
put_string(b, " <temperature");
|
||||
put_temperature(b, dc->airtemp, " air='", " C'");
|
||||
put_temperature(b, dc->watertemp, " water='", " C'");
|
||||
put_temperature(b, dc.airtemp, " air='", " C'");
|
||||
put_temperature(b, dc.watertemp, " water='", " C'");
|
||||
put_string(b, " />\n");
|
||||
}
|
||||
|
||||
static void save_airpressure(struct membuffer *b, struct divecomputer *dc)
|
||||
static void save_airpressure(struct membuffer *b, const struct divecomputer &dc)
|
||||
{
|
||||
if (!dc->surface_pressure.mbar)
|
||||
if (!dc.surface_pressure.mbar)
|
||||
return;
|
||||
put_string(b, " <surface");
|
||||
put_pressure(b, dc->surface_pressure, " pressure='", " bar'");
|
||||
put_pressure(b, dc.surface_pressure, " pressure='", " bar'");
|
||||
put_string(b, " />\n");
|
||||
}
|
||||
|
||||
static void save_salinity(struct membuffer *b, struct divecomputer *dc)
|
||||
static void save_salinity(struct membuffer *b, const struct divecomputer &dc)
|
||||
{
|
||||
if (!dc->salinity)
|
||||
if (!dc.salinity)
|
||||
return;
|
||||
put_string(b, " <water");
|
||||
put_salinity(b, dc->salinity, " salinity='", " g/l'");
|
||||
put_salinity(b, dc.salinity, " salinity='", " g/l'");
|
||||
put_string(b, " />\n");
|
||||
}
|
||||
|
||||
static void save_overview(struct membuffer *b, struct dive *dive, bool anonymize)
|
||||
static void save_overview(struct membuffer *b, const struct dive &dive, bool anonymize)
|
||||
{
|
||||
show_utf8_blanked(b, dive->diveguide.c_str(), " <divemaster>", "</divemaster>\n", 0, anonymize);
|
||||
show_utf8_blanked(b, dive->buddy.c_str(), " <buddy>", "</buddy>\n", 0, anonymize);
|
||||
show_utf8_blanked(b, dive->notes.c_str(), " <notes>", "</notes>\n", 0, anonymize);
|
||||
show_utf8_blanked(b, dive->suit.c_str(), " <suit>", "</suit>\n", 0, anonymize);
|
||||
show_utf8_blanked(b, dive.diveguide.c_str(), " <divemaster>", "</divemaster>\n", 0, anonymize);
|
||||
show_utf8_blanked(b, dive.buddy.c_str(), " <buddy>", "</buddy>\n", 0, anonymize);
|
||||
show_utf8_blanked(b, dive.notes.c_str(), " <notes>", "</notes>\n", 0, anonymize);
|
||||
show_utf8_blanked(b, dive.suit.c_str(), " <suit>", "</suit>\n", 0, anonymize);
|
||||
}
|
||||
|
||||
static void put_gasmix(struct membuffer *b, struct gasmix mix)
|
||||
|
@ -175,9 +175,9 @@ static void put_gasmix(struct membuffer *b, struct gasmix mix)
|
|||
}
|
||||
}
|
||||
|
||||
static void save_cylinder_info(struct membuffer *b, struct dive *dive)
|
||||
static void save_cylinder_info(struct membuffer *b, const struct dive &dive)
|
||||
{
|
||||
for (auto &cyl: dive->cylinders) {
|
||||
for (auto &cyl: dive.cylinders) {
|
||||
int volume = cyl.type.size.mliter;
|
||||
int use = cyl.cylinder_use;
|
||||
|
||||
|
@ -197,9 +197,9 @@ static void save_cylinder_info(struct membuffer *b, struct dive *dive)
|
|||
}
|
||||
}
|
||||
|
||||
static void save_weightsystem_info(struct membuffer *b, const struct dive *dive)
|
||||
static void save_weightsystem_info(struct membuffer *b, const struct dive &dive)
|
||||
{
|
||||
for (auto &ws: dive->weightsystems) {
|
||||
for (auto &ws: dive.weightsystems) {
|
||||
int grams = ws.weight.grams;
|
||||
|
||||
put_format(b, " <weightsystem");
|
||||
|
@ -341,7 +341,7 @@ static void save_sample(struct membuffer *b, const struct sample &sample, struct
|
|||
put_format(b, " />\n");
|
||||
}
|
||||
|
||||
static void save_one_event(struct membuffer *b, struct dive *dive, const struct event &ev)
|
||||
static void save_one_event(struct membuffer *b, const struct dive &dive, const struct event &ev)
|
||||
{
|
||||
put_format(b, " <event time='%d:%02d min'", FRACTION_TUPLE(ev.time.seconds, 60));
|
||||
show_index(b, ev.type, "type='", "'");
|
||||
|
@ -352,7 +352,7 @@ static void save_one_event(struct membuffer *b, struct dive *dive, const struct
|
|||
show_index(b, ev.value, "value='", "'");
|
||||
show_utf8(b, ev.name.c_str(), " name='", "'", 1);
|
||||
if (ev.is_gaschange()) {
|
||||
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);
|
||||
|
@ -361,9 +361,9 @@ static void save_one_event(struct membuffer *b, struct dive *dive, const struct
|
|||
}
|
||||
|
||||
|
||||
static void save_events(struct membuffer *b, struct dive *dive, const struct divecomputer *dc)
|
||||
static void save_events(struct membuffer *b, const struct dive &dive, const struct divecomputer &dc)
|
||||
{
|
||||
for (auto &ev: dc->events)
|
||||
for (auto &ev: dc.events)
|
||||
save_one_event(b, dive, ev);
|
||||
}
|
||||
|
||||
|
@ -381,9 +381,9 @@ static void save_tags(struct membuffer *b, const tag_list &tags)
|
|||
}
|
||||
}
|
||||
|
||||
static void save_extra_data(struct membuffer *b, const struct divecomputer *dc)
|
||||
static void save_extra_data(struct membuffer *b, const struct divecomputer &dc)
|
||||
{
|
||||
for (const auto &ed: dc->extra_data) {
|
||||
for (const auto &ed: dc.extra_data) {
|
||||
if (!ed.key.empty() && !ed.value.empty()) {
|
||||
put_string(b, " <extradata");
|
||||
show_utf8(b, ed.key.c_str(), " key='", "'", 1);
|
||||
|
@ -406,49 +406,48 @@ static void show_date(struct membuffer *b, timestamp_t when)
|
|||
tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
}
|
||||
|
||||
static void save_samples(struct membuffer *b, struct dive *dive, struct divecomputer *dc)
|
||||
static void save_samples(struct membuffer *b, const struct dive &dive, const struct divecomputer &dc)
|
||||
{
|
||||
int o2sensor;
|
||||
struct sample dummy;
|
||||
|
||||
/* Set up default pressure sensor indices */
|
||||
o2sensor = legacy_format_o2pressures(dive, dc);
|
||||
int o2sensor = legacy_format_o2pressures(&dive, &dc);
|
||||
if (o2sensor >= 0) {
|
||||
dummy.sensor[0] = !o2sensor;
|
||||
dummy.sensor[1] = o2sensor;
|
||||
}
|
||||
|
||||
for (const auto &s: dc->samples)
|
||||
for (const auto &s: dc.samples)
|
||||
save_sample(b, s, dummy, o2sensor);
|
||||
}
|
||||
|
||||
static void save_dc(struct membuffer *b, struct dive *dive, struct divecomputer *dc)
|
||||
static void save_dc(struct membuffer *b, const struct dive &dive, const struct divecomputer &dc)
|
||||
{
|
||||
put_format(b, " <divecomputer");
|
||||
show_utf8(b, dc->model.c_str(), " model='", "'", 1);
|
||||
if (dc->last_manual_time.seconds)
|
||||
put_duration(b, dc->last_manual_time, " last-manual-time='", " min'");
|
||||
if (dc->deviceid)
|
||||
put_format(b, " deviceid='%08x'", dc->deviceid);
|
||||
if (dc->diveid)
|
||||
put_format(b, " diveid='%08x'", dc->diveid);
|
||||
if (dc->when && dc->when != dive->when)
|
||||
show_date(b, dc->when);
|
||||
if (dc->duration.seconds && dc->duration.seconds != dive->dcs[0].duration.seconds)
|
||||
put_duration(b, dc->duration, " duration='", " min'");
|
||||
if (dc->divemode != OC) {
|
||||
int i = (int)dc->divemode;
|
||||
show_utf8(b, dc.model.c_str(), " model='", "'", 1);
|
||||
if (dc.last_manual_time.seconds)
|
||||
put_duration(b, dc.last_manual_time, " last-manual-time='", " min'");
|
||||
if (dc.deviceid)
|
||||
put_format(b, " deviceid='%08x'", dc.deviceid);
|
||||
if (dc.diveid)
|
||||
put_format(b, " diveid='%08x'", dc.diveid);
|
||||
if (dc.when && dc.when != dive.when)
|
||||
show_date(b, dc.when);
|
||||
if (dc.duration.seconds && dc.duration.seconds != dive.dcs[0].duration.seconds)
|
||||
put_duration(b, dc.duration, " duration='", " min'");
|
||||
if (dc.divemode != OC) {
|
||||
int i = (int)dc.divemode;
|
||||
if (i >= 0 && i < NUM_DIVEMODE)
|
||||
show_utf8(b, divemode_text[i], " dctype='", "'", 1);
|
||||
if (dc->no_o2sensors)
|
||||
put_format(b," no_o2sensors='%d'", dc->no_o2sensors);
|
||||
if (dc.no_o2sensors)
|
||||
put_format(b," no_o2sensors='%d'", dc.no_o2sensors);
|
||||
}
|
||||
put_format(b, ">\n");
|
||||
save_depths(b, dc);
|
||||
save_temperatures(b, dc);
|
||||
save_airpressure(b, dc);
|
||||
save_salinity(b, dc);
|
||||
put_duration(b, dc->surfacetime, " <surfacetime>", " min</surfacetime>\n");
|
||||
put_duration(b, dc.surfacetime, " <surfacetime>", " min</surfacetime>\n");
|
||||
save_extra_data(b, dc);
|
||||
save_events(b, dive, dc);
|
||||
save_samples(b, dive, dc);
|
||||
|
@ -475,50 +474,50 @@ static void save_picture(struct membuffer *b, const struct picture &pic)
|
|||
put_string(b, "/>\n");
|
||||
}
|
||||
|
||||
void save_one_dive_to_mb(struct membuffer *b, struct dive *dive, bool anonymize)
|
||||
void save_one_dive_to_mb(struct membuffer *b, const struct dive &dive, bool anonymize)
|
||||
{
|
||||
pressure_t surface_pressure = un_fixup_surface_pressure(dive);
|
||||
pressure_t surface_pressure = un_fixup_surface_pressure(&dive);
|
||||
|
||||
put_string(b, "<dive");
|
||||
if (dive->number)
|
||||
put_format(b, " number='%d'", dive->number);
|
||||
if (dive->notrip)
|
||||
if (dive.number)
|
||||
put_format(b, " number='%d'", dive.number);
|
||||
if (dive.notrip)
|
||||
put_format(b, " tripflag='NOTRIP'");
|
||||
if (dive->rating)
|
||||
put_format(b, " rating='%d'", dive->rating);
|
||||
if (dive->visibility)
|
||||
put_format(b, " visibility='%d'", dive->visibility);
|
||||
if (dive->wavesize)
|
||||
put_format(b, " wavesize='%d'", dive->wavesize);
|
||||
if (dive->current)
|
||||
put_format(b, " current='%d'", dive->current);
|
||||
if (dive->surge)
|
||||
put_format(b, " surge='%d'", dive->surge);
|
||||
if (dive->chill)
|
||||
put_format(b, " chill='%d'", dive->chill);
|
||||
if (dive->invalid)
|
||||
if (dive.rating)
|
||||
put_format(b, " rating='%d'", dive.rating);
|
||||
if (dive.visibility)
|
||||
put_format(b, " visibility='%d'", dive.visibility);
|
||||
if (dive.wavesize)
|
||||
put_format(b, " wavesize='%d'", dive.wavesize);
|
||||
if (dive.current)
|
||||
put_format(b, " current='%d'", dive.current);
|
||||
if (dive.surge)
|
||||
put_format(b, " surge='%d'", dive.surge);
|
||||
if (dive.chill)
|
||||
put_format(b, " chill='%d'", dive.chill);
|
||||
if (dive.invalid)
|
||||
put_format(b, " invalid='1'");
|
||||
|
||||
// These three are calculated, and not read when loading.
|
||||
// But saving them into the XML is useful for data export.
|
||||
if (dive->sac > 100)
|
||||
put_format(b, " sac='%d.%03d l/min'", FRACTION_TUPLE(dive->sac, 1000));
|
||||
if (dive->otu)
|
||||
put_format(b, " otu='%d'", dive->otu);
|
||||
if (dive->maxcns)
|
||||
put_format(b, " cns='%d%%'", dive->maxcns);
|
||||
if (dive.sac > 100)
|
||||
put_format(b, " sac='%d.%03d l/min'", FRACTION_TUPLE(dive.sac, 1000));
|
||||
if (dive.otu)
|
||||
put_format(b, " otu='%d'", dive.otu);
|
||||
if (dive.maxcns)
|
||||
put_format(b, " cns='%d%%'", dive.maxcns);
|
||||
|
||||
save_tags(b, dive->tags);
|
||||
if (dive->dive_site)
|
||||
put_format(b, " divesiteid='%8x'", dive->dive_site->uuid);
|
||||
if (dive->user_salinity)
|
||||
put_salinity(b, dive->user_salinity, " watersalinity='", " g/l'");
|
||||
show_date(b, dive->when);
|
||||
save_tags(b, dive.tags);
|
||||
if (dive.dive_site)
|
||||
put_format(b, " divesiteid='%8x'", dive.dive_site->uuid);
|
||||
if (dive.user_salinity)
|
||||
put_salinity(b, dive.user_salinity, " watersalinity='", " g/l'");
|
||||
show_date(b, dive.when);
|
||||
if (surface_pressure.mbar)
|
||||
put_pressure(b, surface_pressure, " airpressure='", " bar'");
|
||||
if (dive->dcs[0].duration.seconds > 0)
|
||||
if (dive.dcs[0].duration.seconds > 0)
|
||||
put_format(b, " duration='%u:%02u min'>\n",
|
||||
FRACTION_TUPLE(dive->dcs[0].duration.seconds, 60));
|
||||
FRACTION_TUPLE(dive.dcs[0].duration.seconds, 60));
|
||||
else
|
||||
put_format(b, ">\n");
|
||||
save_overview(b, dive, anonymize);
|
||||
|
@ -526,14 +525,14 @@ void save_one_dive_to_mb(struct membuffer *b, struct dive *dive, bool anonymize)
|
|||
save_weightsystem_info(b, dive);
|
||||
save_dive_temperature(b, dive);
|
||||
/* Save the dive computer data */
|
||||
for (auto &dc: dive->dcs)
|
||||
save_dc(b, dive, &dc);
|
||||
for (auto &picture: dive->pictures)
|
||||
for (auto &dc: dive.dcs)
|
||||
save_dc(b, dive, dc);
|
||||
for (auto &picture: dive.pictures)
|
||||
save_picture(b, picture);
|
||||
put_format(b, "</dive>\n");
|
||||
}
|
||||
|
||||
int save_dive(FILE *f, struct dive *dive, bool anonymize)
|
||||
int save_dive(FILE *f, const struct dive &dive, bool anonymize)
|
||||
{
|
||||
membuffer buf;
|
||||
|
||||
|
@ -545,9 +544,6 @@ int save_dive(FILE *f, struct dive *dive, bool anonymize)
|
|||
|
||||
static void save_trip(struct membuffer *b, dive_trip &trip, bool anonymize)
|
||||
{
|
||||
int i;
|
||||
struct dive *dive;
|
||||
|
||||
put_format(b, "<trip");
|
||||
show_date(b, trip_date(trip));
|
||||
show_utf8(b, trip.location.c_str(), " location=\'", "\'", 1);
|
||||
|
@ -560,9 +556,9 @@ static void save_trip(struct membuffer *b, dive_trip &trip, bool anonymize)
|
|||
* list in the trip, we just traverse the global dive array and
|
||||
* check the divetrip pointer..
|
||||
*/
|
||||
for_each_dive(i, dive) {
|
||||
for (auto &dive: divelog.dives) {
|
||||
if (dive->divetrip == &trip)
|
||||
save_one_dive_to_mb(b, dive, anonymize);
|
||||
save_one_dive_to_mb(b, *dive, anonymize);
|
||||
}
|
||||
|
||||
put_format(b, "</trip>\n");
|
||||
|
@ -640,9 +636,6 @@ static void save_filter_presets(struct membuffer *b)
|
|||
|
||||
static void save_dives_buffer(struct membuffer *b, bool select_only, bool anonymize)
|
||||
{
|
||||
int i;
|
||||
struct dive *dive;
|
||||
|
||||
put_format(b, "<divelog program='subsurface' version='%d'>\n<settings>\n", DATAFORMAT_VERSION);
|
||||
|
||||
/* save the dive computer nicknames, if any */
|
||||
|
@ -692,19 +685,17 @@ static void save_dives_buffer(struct membuffer *b, bool select_only, bool anonym
|
|||
save_filter_presets(b);
|
||||
|
||||
/* save the dives */
|
||||
for_each_dive(i, dive) {
|
||||
for (auto &dive: divelog.dives) {
|
||||
if (select_only) {
|
||||
|
||||
if (!dive->selected)
|
||||
continue;
|
||||
save_one_dive_to_mb(b, dive, anonymize);
|
||||
|
||||
save_one_dive_to_mb(b, *dive, anonymize);
|
||||
} else {
|
||||
dive_trip *trip = dive->divetrip;
|
||||
|
||||
/* Bare dive without a trip? */
|
||||
if (!trip) {
|
||||
save_one_dive_to_mb(b, dive, anonymize);
|
||||
save_one_dive_to_mb(b, *dive, anonymize);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,32 +16,20 @@ static int amount_trips_selected;
|
|||
|
||||
struct dive *first_selected_dive()
|
||||
{
|
||||
int idx;
|
||||
struct dive *d;
|
||||
|
||||
for_each_dive (idx, d) {
|
||||
if (d->selected)
|
||||
return d;
|
||||
}
|
||||
return NULL;
|
||||
auto it = std::find_if(divelog.dives.begin(), divelog.dives.end(),
|
||||
[](auto &d) { return d->selected; });
|
||||
return it != divelog.dives.end() ? it->get() : nullptr;
|
||||
}
|
||||
|
||||
struct dive *last_selected_dive()
|
||||
{
|
||||
int idx;
|
||||
struct dive *d, *ret = NULL;
|
||||
|
||||
for_each_dive (idx, d) {
|
||||
if (d->selected)
|
||||
ret = d;
|
||||
}
|
||||
return ret;
|
||||
auto it = std::find_if(divelog.dives.rbegin(), divelog.dives.rend(),
|
||||
[](auto &d) { return d->selected; });
|
||||
return it != divelog.dives.rend() ? it->get() : nullptr;
|
||||
}
|
||||
|
||||
bool consecutive_selected()
|
||||
{
|
||||
struct dive *d;
|
||||
int i;
|
||||
bool consecutive = true;
|
||||
bool firstfound = false;
|
||||
bool lastfound = false;
|
||||
|
@ -49,7 +37,7 @@ bool consecutive_selected()
|
|||
if (amount_selected == 0 || amount_selected == 1)
|
||||
return true;
|
||||
|
||||
for_each_dive(i, d) {
|
||||
for (auto &d: divelog.dives) {
|
||||
if (d->selected) {
|
||||
if (!firstfound)
|
||||
firstfound = true;
|
||||
|
@ -65,11 +53,8 @@ bool consecutive_selected()
|
|||
#if DEBUG_SELECTION_TRACKING
|
||||
void dump_selection()
|
||||
{
|
||||
int i;
|
||||
struct dive *dive;
|
||||
|
||||
printf("currently selected are %u dives:", amount_selected);
|
||||
for_each_dive(i, dive) {
|
||||
for (auto &dive: divelog.dives) {
|
||||
if (dive->selected)
|
||||
printf(" %d", i);
|
||||
}
|
||||
|
@ -137,10 +122,8 @@ QVector<dive *> setSelectionCore(const std::vector<dive *> &selection, dive *cur
|
|||
divesToSelect.reserve(selection.size());
|
||||
|
||||
// TODO: We might want to keep track of selected dives in a more efficient way!
|
||||
int i;
|
||||
dive *d;
|
||||
amount_selected = 0; // We recalculate amount_selected
|
||||
for_each_dive(i, d) {
|
||||
for (auto &d: divelog.dives) {
|
||||
// We only modify dives that are currently visible.
|
||||
if (d->hidden_by_filter) {
|
||||
d->selected = false; // Note, not necessary, just to be sure
|
||||
|
@ -150,11 +133,11 @@ QVector<dive *> setSelectionCore(const std::vector<dive *> &selection, dive *cur
|
|||
|
||||
// Search the dive in the list of selected dives.
|
||||
// TODO: By sorting the list in the same way as the backend, this could be made more efficient.
|
||||
bool newState = std::find(selection.begin(), selection.end(), d) != selection.end();
|
||||
bool newState = std::find(selection.begin(), selection.end(), d.get()) != selection.end();
|
||||
|
||||
if (newState) {
|
||||
++amount_selected;
|
||||
divesToSelect.push_back(d);
|
||||
divesToSelect.push_back(d.get());
|
||||
}
|
||||
d->selected = newState;
|
||||
}
|
||||
|
@ -217,10 +200,8 @@ void setTripSelection(dive_trip *trip, dive *currentDive)
|
|||
return;
|
||||
|
||||
current_dive = currentDive;
|
||||
for (int i = 0; i < divelog.dives->nr; ++i) {
|
||||
dive &d = *divelog.dives->dives[i];
|
||||
d.selected = d.divetrip == trip;
|
||||
}
|
||||
for (auto &d: divelog.dives)
|
||||
d->selected = d->divetrip == trip;
|
||||
for (auto &t: *divelog.trips)
|
||||
t->selected = t.get() == trip;
|
||||
|
||||
|
@ -245,11 +226,9 @@ std::vector<dive *> getDiveSelection()
|
|||
std::vector<dive *> res;
|
||||
res.reserve(amount_selected);
|
||||
|
||||
int i;
|
||||
dive *d;
|
||||
for_each_dive(i, d) {
|
||||
for (auto &d: divelog.dives) {
|
||||
if (d->selected)
|
||||
res.push_back(d);
|
||||
res.push_back(d.get());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -257,7 +236,7 @@ std::vector<dive *> getDiveSelection()
|
|||
bool diveInSelection(const std::vector<dive *> &selection, const dive *d)
|
||||
{
|
||||
// Do a binary search using the ordering of the dive list.
|
||||
auto it = std::lower_bound(selection.begin(), selection.end(), d, dive_less_than);
|
||||
auto it = std::lower_bound(selection.begin(), selection.end(), d, dive_less_than_ptr);
|
||||
return it != selection.end() && *it == d;
|
||||
}
|
||||
|
||||
|
@ -265,7 +244,7 @@ void updateSelection(std::vector<dive *> &selection, const std::vector<dive *> &
|
|||
{
|
||||
// We could sort the array and merge the vectors as we do in the undo code. But is it necessary?
|
||||
for (dive *d: add) {
|
||||
auto it = std::lower_bound(selection.begin(), selection.end(), d, dive_less_than);
|
||||
auto it = std::lower_bound(selection.begin(), selection.end(), d, dive_less_than_ptr);
|
||||
if (it != selection.end() && *it == d)
|
||||
continue; // Ooops. Already there?
|
||||
selection.insert(it, d);
|
||||
|
@ -273,7 +252,7 @@ void updateSelection(std::vector<dive *> &selection, const std::vector<dive *> &
|
|||
|
||||
// Likewise, we could sort the array and be smarter here. Again, is it necessary?
|
||||
for (dive *d: remove) {
|
||||
auto it = std::lower_bound(selection.begin(), selection.end(), d, dive_less_than);
|
||||
auto it = std::lower_bound(selection.begin(), selection.end(), d, dive_less_than_ptr);
|
||||
if (it == selection.end() || *it != d)
|
||||
continue; // Ooops. Not there?
|
||||
selection.erase(it);
|
||||
|
@ -283,10 +262,9 @@ void updateSelection(std::vector<dive *> &selection, const std::vector<dive *> &
|
|||
// Select the first dive that is visible
|
||||
void select_newest_visible_dive()
|
||||
{
|
||||
for (int i = divelog.dives->nr - 1; i >= 0; --i) {
|
||||
dive *d = divelog.dives->dives[i];
|
||||
if (!d->hidden_by_filter)
|
||||
return select_single_dive(d);
|
||||
for (auto it = divelog.dives.rbegin(); it != divelog.dives.rend(); ++it) {
|
||||
if (!(*it)->hidden_by_filter)
|
||||
return select_single_dive(it->get());
|
||||
}
|
||||
|
||||
// No visible dive -> deselect all
|
||||
|
|
|
@ -19,15 +19,15 @@
|
|||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static void process_temperatures(struct dive *dp, stats_t &stats)
|
||||
static void process_temperatures(const struct dive &dp, stats_t &stats)
|
||||
{
|
||||
temperature_t min_temp, mean_temp, max_temp = {.mkelvin = 0};
|
||||
|
||||
max_temp.mkelvin = dp->maxtemp.mkelvin;
|
||||
max_temp.mkelvin = dp.maxtemp.mkelvin;
|
||||
if (max_temp.mkelvin && (!stats.max_temp.mkelvin || max_temp.mkelvin > stats.max_temp.mkelvin))
|
||||
stats.max_temp.mkelvin = max_temp.mkelvin;
|
||||
|
||||
min_temp.mkelvin = dp->mintemp.mkelvin;
|
||||
min_temp.mkelvin = dp.mintemp.mkelvin;
|
||||
if (min_temp.mkelvin && (!stats.min_temp.mkelvin || min_temp.mkelvin < stats.min_temp.mkelvin))
|
||||
stats.min_temp.mkelvin = min_temp.mkelvin;
|
||||
|
||||
|
@ -42,10 +42,10 @@ static void process_temperatures(struct dive *dp, stats_t &stats)
|
|||
}
|
||||
}
|
||||
|
||||
static void process_dive(struct dive *dive, stats_t &stats)
|
||||
static void process_dive(const struct dive &dive, stats_t &stats)
|
||||
{
|
||||
int old_tadt, sac_time = 0;
|
||||
int32_t duration = dive->duration.seconds;
|
||||
int32_t duration = dive.duration.seconds;
|
||||
|
||||
old_tadt = stats.total_average_depth_time.seconds;
|
||||
stats.total_time.seconds += duration;
|
||||
|
@ -53,32 +53,32 @@ static void process_dive(struct dive *dive, stats_t &stats)
|
|||
stats.longest_time.seconds = duration;
|
||||
if (stats.shortest_time.seconds == 0 || duration < stats.shortest_time.seconds)
|
||||
stats.shortest_time.seconds = duration;
|
||||
if (dive->maxdepth.mm > stats.max_depth.mm)
|
||||
stats.max_depth.mm = dive->maxdepth.mm;
|
||||
if (stats.min_depth.mm == 0 || dive->maxdepth.mm < stats.min_depth.mm)
|
||||
stats.min_depth.mm = dive->maxdepth.mm;
|
||||
stats.combined_max_depth.mm += dive->maxdepth.mm;
|
||||
if (dive.maxdepth.mm > stats.max_depth.mm)
|
||||
stats.max_depth.mm = dive.maxdepth.mm;
|
||||
if (stats.min_depth.mm == 0 || dive.maxdepth.mm < stats.min_depth.mm)
|
||||
stats.min_depth.mm = dive.maxdepth.mm;
|
||||
stats.combined_max_depth.mm += dive.maxdepth.mm;
|
||||
|
||||
process_temperatures(dive, stats);
|
||||
|
||||
/* Maybe we should drop zero-duration dives */
|
||||
if (!duration)
|
||||
return;
|
||||
if (dive->meandepth.mm) {
|
||||
if (dive.meandepth.mm) {
|
||||
stats.total_average_depth_time.seconds += duration;
|
||||
stats.avg_depth.mm = lrint((1.0 * old_tadt * stats.avg_depth.mm +
|
||||
duration * dive->meandepth.mm) /
|
||||
duration * dive.meandepth.mm) /
|
||||
stats.total_average_depth_time.seconds);
|
||||
}
|
||||
if (dive->sac > 100) { /* less than .1 l/min is bogus, even with a pSCR */
|
||||
if (dive.sac > 100) { /* less than .1 l/min is bogus, even with a pSCR */
|
||||
sac_time = stats.total_sac_time.seconds + duration;
|
||||
stats.avg_sac.mliter = lrint((1.0 * stats.total_sac_time.seconds * stats.avg_sac.mliter +
|
||||
duration * dive->sac) /
|
||||
duration * dive.sac) /
|
||||
sac_time);
|
||||
if (dive->sac > stats.max_sac.mliter)
|
||||
stats.max_sac.mliter = dive->sac;
|
||||
if (stats.min_sac.mliter == 0 || dive->sac < stats.min_sac.mliter)
|
||||
stats.min_sac.mliter = dive->sac;
|
||||
if (dive.sac > stats.max_sac.mliter)
|
||||
stats.max_sac.mliter = dive.sac;
|
||||
if (stats.min_sac.mliter == 0 || dive.sac < stats.min_sac.mliter)
|
||||
stats.min_sac.mliter = dive.sac;
|
||||
stats.total_sac_time.seconds = sac_time;
|
||||
}
|
||||
}
|
||||
|
@ -91,8 +91,6 @@ static void process_dive(struct dive *dive, stats_t &stats)
|
|||
*/
|
||||
stats_summary calculate_stats_summary(bool selected_only)
|
||||
{
|
||||
int idx;
|
||||
struct dive *dp;
|
||||
struct tm tm;
|
||||
int current_year = -1;
|
||||
int current_month = 0;
|
||||
|
@ -128,7 +126,7 @@ stats_summary calculate_stats_summary(bool selected_only)
|
|||
|
||||
/* this relies on the fact that the dives in the dive_table
|
||||
* are in chronological order */
|
||||
for_each_dive (idx, dp) {
|
||||
for (auto &dp: divelog.dives) {
|
||||
if (selected_only && !dp->selected)
|
||||
continue;
|
||||
if (dp->invalid)
|
||||
|
@ -143,34 +141,34 @@ stats_summary calculate_stats_summary(bool selected_only)
|
|||
out.stats_yearly.emplace_back();
|
||||
out.stats_yearly.back().is_year = true;
|
||||
}
|
||||
process_dive(dp, out.stats_yearly.back());
|
||||
process_dive(*dp, out.stats_yearly.back());
|
||||
|
||||
out.stats_yearly.back().selection_size++;
|
||||
out.stats_yearly.back().period = current_year;
|
||||
|
||||
/* stats_by_type[0] is all the dives combined */
|
||||
out.stats_by_type[0].selection_size++;
|
||||
process_dive(dp, out.stats_by_type[0]);
|
||||
process_dive(*dp, out.stats_by_type[0]);
|
||||
|
||||
process_dive(dp, out.stats_by_type[dp->dcs[0].divemode + 1]);
|
||||
process_dive(*dp, out.stats_by_type[dp->dcs[0].divemode + 1]);
|
||||
out.stats_by_type[dp->dcs[0].divemode + 1].selection_size++;
|
||||
|
||||
/* stats_by_depth[0] is all the dives combined */
|
||||
out.stats_by_depth[0].selection_size++;
|
||||
process_dive(dp, out.stats_by_depth[0]);
|
||||
process_dive(*dp, out.stats_by_depth[0]);
|
||||
|
||||
int d_idx = dp->maxdepth.mm / (STATS_DEPTH_BUCKET * 1000);
|
||||
d_idx = std::clamp(d_idx, 0, STATS_MAX_DEPTH / STATS_DEPTH_BUCKET);
|
||||
process_dive(dp, out.stats_by_depth[d_idx + 1]);
|
||||
process_dive(*dp, out.stats_by_depth[d_idx + 1]);
|
||||
out.stats_by_depth[d_idx + 1].selection_size++;
|
||||
|
||||
/* stats_by_temp[0] is all the dives combined */
|
||||
out.stats_by_temp[0].selection_size++;
|
||||
process_dive(dp, out.stats_by_temp[0]);
|
||||
process_dive(*dp, out.stats_by_temp[0]);
|
||||
|
||||
int t_idx = ((int)mkelvin_to_C(dp->mintemp.mkelvin)) / STATS_TEMP_BUCKET;
|
||||
t_idx = std::clamp(t_idx, 0, STATS_MAX_TEMP / STATS_TEMP_BUCKET);
|
||||
process_dive(dp, out.stats_by_temp[t_idx + 1]);
|
||||
process_dive(*dp, out.stats_by_temp[t_idx + 1]);
|
||||
out.stats_by_temp[t_idx + 1].selection_size++;
|
||||
|
||||
if (dp->divetrip != NULL) {
|
||||
|
@ -182,11 +180,11 @@ stats_summary calculate_stats_summary(bool selected_only)
|
|||
/* stats_by_trip[0] is all the dives combined */
|
||||
/* TODO: yet, this doesn't seem to consider dives outside of trips !? */
|
||||
out.stats_by_trip[0].selection_size++;
|
||||
process_dive(dp, out.stats_by_trip[0]);
|
||||
process_dive(*dp, out.stats_by_trip[0]);
|
||||
out.stats_by_trip[0].is_trip = true;
|
||||
out.stats_by_trip[0].location = translate("gettextFromC", "All (by trip stats)");
|
||||
|
||||
process_dive(dp, out.stats_by_trip.back());
|
||||
process_dive(*dp, out.stats_by_trip.back());
|
||||
out.stats_by_trip.back().selection_size++;
|
||||
out.stats_by_trip.back().is_trip = true;
|
||||
out.stats_by_trip.back().location = dp->divetrip->location;
|
||||
|
@ -202,7 +200,7 @@ stats_summary calculate_stats_summary(bool selected_only)
|
|||
if (prev_month != current_month || prev_year != current_year)
|
||||
out.stats_monthly.emplace_back();
|
||||
}
|
||||
process_dive(dp, out.stats_monthly.back());
|
||||
process_dive(*dp, out.stats_monthly.back());
|
||||
out.stats_monthly.back().selection_size++;
|
||||
out.stats_monthly.back().period = current_month;
|
||||
prev_month = current_month;
|
||||
|
@ -230,25 +228,18 @@ stats_summary calculate_stats_summary(bool selected_only)
|
|||
return out;
|
||||
}
|
||||
|
||||
stats_summary::stats_summary()
|
||||
{
|
||||
}
|
||||
|
||||
stats_summary::~stats_summary()
|
||||
{
|
||||
}
|
||||
stats_summary::stats_summary() = default;
|
||||
stats_summary::~stats_summary() = default;
|
||||
|
||||
/* make sure we skip the selected summary entries */
|
||||
stats_t calculate_stats_selected()
|
||||
{
|
||||
stats_t stats_selection;
|
||||
struct dive *dive;
|
||||
unsigned int i, nr;
|
||||
unsigned int nr = 0;
|
||||
|
||||
nr = 0;
|
||||
for_each_dive(i, dive) {
|
||||
for (auto &dive: divelog.dives) {
|
||||
if (dive->selected && !dive->invalid) {
|
||||
process_dive(dive, stats_selection);
|
||||
process_dive(*dive, stats_selection);
|
||||
nr++;
|
||||
}
|
||||
}
|
||||
|
@ -336,16 +327,14 @@ static std::pair<volume_t, volume_t> get_gas_parts(struct gasmix mix, volume_t v
|
|||
|
||||
std::pair<volume_t, volume_t> selected_dives_gas_parts()
|
||||
{
|
||||
int i;
|
||||
struct dive *d;
|
||||
volume_t o2_tot, he_tot;
|
||||
for_each_dive (i, d) {
|
||||
for (auto &d: divelog.dives) {
|
||||
if (!d->selected || d->invalid)
|
||||
continue;
|
||||
int j = 0;
|
||||
for (auto &gas: get_gas_used(d)) {
|
||||
for (auto &gas: get_gas_used(d.get())) {
|
||||
if (gas.mliter) {
|
||||
auto [o2, he] = get_gas_parts(get_cylinder(d, j)->gasmix, gas, O2_IN_AIR);
|
||||
auto [o2, he] = get_gas_parts(get_cylinder(d.get(), j)->gasmix, gas, O2_IN_AIR);
|
||||
o2_tot.mliter += o2.mliter;
|
||||
he_tot.mliter += he.mliter;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "string-format.h"
|
||||
#include "dive.h"
|
||||
#include "divelist.h"
|
||||
#include "divelog.h"
|
||||
#include "divesite.h"
|
||||
#include "event.h"
|
||||
#include "format.h"
|
||||
|
@ -135,9 +137,7 @@ static void addStringToSortedList(QStringList &l, const std::string &s)
|
|||
QStringList formatFullCylinderList()
|
||||
{
|
||||
QStringList cylinders;
|
||||
struct dive *d;
|
||||
int i = 0;
|
||||
for_each_dive (i, d) {
|
||||
for (auto &d: divelog.dives) {
|
||||
for (const cylinder_t &cyl: d->cylinders)
|
||||
addStringToSortedList(cylinders, cyl.type.description);
|
||||
}
|
||||
|
|
|
@ -50,22 +50,6 @@ static timestamp_t trip_enddate(const struct dive_trip &trip)
|
|||
return trip.dives.back()->endtime();
|
||||
}
|
||||
|
||||
/* check if we have a trip right before / after this dive */
|
||||
bool is_trip_before_after(const struct dive *dive, bool before)
|
||||
{
|
||||
int idx = get_idx_by_uniq_id(dive->id);
|
||||
if (before) {
|
||||
const struct dive *d = get_dive(idx - 1);
|
||||
if (d && d->divetrip)
|
||||
return true;
|
||||
} else {
|
||||
const struct dive *d = get_dive(idx + 1);
|
||||
if (d && d->divetrip)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Add dive to a trip. Caller is responsible for removing dive
|
||||
* from trip beforehand. */
|
||||
void add_dive_to_trip(struct dive *dive, dive_trip *trip)
|
||||
|
@ -73,8 +57,8 @@ void add_dive_to_trip(struct dive *dive, dive_trip *trip)
|
|||
if (dive->divetrip == trip)
|
||||
return;
|
||||
if (dive->divetrip)
|
||||
report_info("Warning: adding dive to trip that has trip set\n");
|
||||
range_insert_sorted(trip->dives, dive, comp_dives);
|
||||
report_info("Warning: adding dive to trip, which already has a trip set");
|
||||
range_insert_sorted(trip->dives, dive, comp_dives_ptr);
|
||||
dive->divetrip = trip;
|
||||
}
|
||||
|
||||
|
@ -112,13 +96,10 @@ std::unique_ptr<dive_trip> create_trip_from_dive(const struct dive *dive)
|
|||
* exist, allocate a new trip. A unique_ptr is returned if a new trip
|
||||
* was allocated. The caller has to store it.
|
||||
*/
|
||||
std::pair<dive_trip *, std::unique_ptr<dive_trip>> get_trip_for_new_dive(const struct dive *new_dive)
|
||||
std::pair<dive_trip *, std::unique_ptr<dive_trip>> get_trip_for_new_dive(const struct divelog &log, const struct dive *new_dive)
|
||||
{
|
||||
dive *d;
|
||||
int i;
|
||||
|
||||
/* Find dive that is within TRIP_THRESHOLD of current dive */
|
||||
for_each_dive(i, d) {
|
||||
for (auto &d: log.dives) {
|
||||
/* Check if we're past the range of possible dives */
|
||||
if (d->when >= new_dive->when + TRIP_THRESHOLD)
|
||||
break;
|
||||
|
@ -164,7 +145,7 @@ bool trips_overlap(const struct dive_trip &t1, const struct dive_trip &t2)
|
|||
* manually injects the new trips. If there are no dives to be autogrouped,
|
||||
* return NULL.
|
||||
*/
|
||||
std::vector<dives_to_autogroup_result> get_dives_to_autogroup(struct dive_table *table)
|
||||
std::vector<dives_to_autogroup_result> get_dives_to_autogroup(const struct dive_table &table)
|
||||
{
|
||||
std::vector<dives_to_autogroup_result> res;
|
||||
struct dive *lastdive = NULL;
|
||||
|
@ -172,12 +153,11 @@ std::vector<dives_to_autogroup_result> get_dives_to_autogroup(struct dive_table
|
|||
/* Find first dive that should be merged and remember any previous
|
||||
* dive that could be merged into.
|
||||
*/
|
||||
for (int i = 0; i < table->nr; ++i) {
|
||||
struct dive *dive = table->dives[i];
|
||||
dive_trip *trip;
|
||||
for (size_t i = 0; i < table.size(); ++i) {
|
||||
auto &dive = table[i];
|
||||
|
||||
if (dive->divetrip) {
|
||||
lastdive = dive;
|
||||
lastdive = dive.get();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -190,9 +170,10 @@ std::vector<dives_to_autogroup_result> get_dives_to_autogroup(struct dive_table
|
|||
|
||||
/* We found a dive, let's see if we have to allocate a new trip */
|
||||
std::unique_ptr<dive_trip> allocated;
|
||||
dive_trip *trip;
|
||||
if (!lastdive || dive->when >= lastdive->when + TRIP_THRESHOLD) {
|
||||
/* allocate new trip */
|
||||
allocated = create_trip_from_dive(dive);
|
||||
allocated = create_trip_from_dive(dive.get());
|
||||
allocated->autogen = true;
|
||||
trip = allocated.get();
|
||||
} else {
|
||||
|
@ -201,16 +182,16 @@ std::vector<dives_to_autogroup_result> get_dives_to_autogroup(struct dive_table
|
|||
}
|
||||
|
||||
// Now, find all dives that will be added to this trip
|
||||
lastdive = dive;
|
||||
int to;
|
||||
for (to = i + 1; to < table->nr; to++) {
|
||||
dive = table->dives[to];
|
||||
lastdive = dive.get();
|
||||
size_t to;
|
||||
for (to = i + 1; to < table.size(); to++) {
|
||||
auto &dive = table[to];
|
||||
if (dive->divetrip || dive->notrip ||
|
||||
dive->when >= lastdive->when + TRIP_THRESHOLD)
|
||||
break;
|
||||
if (trip->location.empty())
|
||||
trip->location = get_dive_location(dive);
|
||||
lastdive = dive;
|
||||
trip->location = get_dive_location(dive.get());
|
||||
lastdive = dive.get();
|
||||
}
|
||||
res.push_back({ i, to, trip, std::move(allocated) });
|
||||
i = to - 1;
|
||||
|
@ -250,7 +231,7 @@ int comp_trips(const struct dive_trip &a, const struct dive_trip &b)
|
|||
return -1;
|
||||
if (b.dives.empty())
|
||||
return 1;
|
||||
return comp_dives(a.dives[0], b.dives[0]);
|
||||
return comp_dives(*a.dives[0], *b.dives[0]);
|
||||
}
|
||||
|
||||
static bool is_same_day(timestamp_t trip_when, timestamp_t dive_when)
|
||||
|
@ -285,5 +266,5 @@ int trip_shown_dives(const struct dive_trip *trip)
|
|||
|
||||
void dive_trip::sort_dives()
|
||||
{
|
||||
std::sort(dives.begin(), dives.end(), [] (dive *d1, dive *d2) { return comp_dives(d1, d2) < 0; });
|
||||
std::sort(dives.begin(), dives.end(), [] (dive *d1, dive *d2) { return comp_dives(*d1, *d2) < 0; });
|
||||
}
|
||||
|
|
17
core/trip.h
17
core/trip.h
|
@ -3,9 +3,8 @@
|
|||
#define TRIP_H
|
||||
|
||||
#include "divelist.h"
|
||||
#include "owning_table.h"
|
||||
|
||||
#include <string>
|
||||
struct divelog;
|
||||
|
||||
struct dive_trip
|
||||
{
|
||||
|
@ -26,10 +25,6 @@ struct dive_trip
|
|||
|
||||
int comp_trips(const dive_trip &t1, const dive_trip &t2);
|
||||
|
||||
struct trip_table : public sorted_owning_table<dive_trip, &comp_trips> {
|
||||
dive_trip *get_by_uniq_id(int tripId) const;
|
||||
};
|
||||
|
||||
extern void add_dive_to_trip(struct dive *, dive_trip *);
|
||||
extern struct dive_trip *unregister_dive_from_trip(struct dive *dive);
|
||||
|
||||
|
@ -40,18 +35,17 @@ extern dive_trip *create_and_hookup_trip_from_dive(const struct dive *dive, stru
|
|||
|
||||
// Result item of get_dives_to_autogroup()
|
||||
struct dives_to_autogroup_result {
|
||||
int from, to; // Group dives in the range [from, to)
|
||||
size_t from, to; // Group dives in the range [from, to)
|
||||
dive_trip *trip; // Pointer to trip
|
||||
std::unique_ptr<dive_trip> created_trip;
|
||||
// Is set if the trip was newly created - caller has to store it.
|
||||
};
|
||||
|
||||
extern std::vector<dives_to_autogroup_result> get_dives_to_autogroup(struct dive_table *table);
|
||||
extern std::pair<dive_trip *, std::unique_ptr<dive_trip>> get_trip_for_new_dive(const struct dive *new_dive);
|
||||
extern std::vector<dives_to_autogroup_result> get_dives_to_autogroup(const struct dive_table &table);
|
||||
extern std::pair<dive_trip *, std::unique_ptr<dive_trip>> get_trip_for_new_dive(const struct divelog &log, const struct dive *new_dive);
|
||||
extern bool trips_overlap(const struct dive_trip &t1, const struct dive_trip &t2);
|
||||
|
||||
extern std::unique_ptr<dive_trip> combine_trips(struct dive_trip *trip_a, struct dive_trip *trip_b);
|
||||
extern bool is_trip_before_after(const struct dive *dive, bool before);
|
||||
extern bool trip_is_single_day(const struct dive_trip &trip);
|
||||
extern int trip_shown_dives(const struct dive_trip *trip);
|
||||
|
||||
|
@ -59,10 +53,9 @@ extern int trip_shown_dives(const struct dive_trip *trip);
|
|||
extern void dump_trip_list();
|
||||
#endif
|
||||
|
||||
/* Make pointers to dive_trip and trip_table "Qt metatypes" so that they can be
|
||||
/* Make pointers to dive_trip "Qt metatypes" so that they can be
|
||||
* passed through QVariants and through QML. See comment in dive.h. */
|
||||
#include <QObject>
|
||||
Q_DECLARE_METATYPE(struct dive_trip *);
|
||||
Q_DECLARE_METATYPE(trip_table *);
|
||||
|
||||
#endif
|
||||
|
|
21
core/triptable.h
Normal file
21
core/triptable.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#ifndef TRIPTABLE_H
|
||||
#define TRIPTABLE_H
|
||||
|
||||
#include "owning_table.h"
|
||||
|
||||
struct dive_trip;
|
||||
|
||||
int comp_trips(const dive_trip &t1, const dive_trip &t2);
|
||||
|
||||
struct trip_table : public sorted_owning_table<dive_trip, &comp_trips> {
|
||||
dive_trip *get_by_uniq_id(int tripId) const;
|
||||
};
|
||||
|
||||
/* Make pointers to trip_table "Qt metatypes" so that they can be
|
||||
* passed through QVariants and through QML. See comment in dive.h. */
|
||||
#include <QObject>
|
||||
Q_DECLARE_METATYPE(trip_table *);
|
||||
|
||||
#endif
|
||||
|
|
@ -190,9 +190,9 @@ static std::unique_ptr<dive> uemis_start_dive(uint32_t deviceid)
|
|||
|
||||
static struct dive *get_dive_by_uemis_diveid(device_data_t *devdata, uint32_t object_id)
|
||||
{
|
||||
for (int i = 0; i < devdata->log->dives->nr; i++) {
|
||||
if (object_id == devdata->log->dives->dives[i]->dcs[0].diveid)
|
||||
return devdata->log->dives->dives[i];
|
||||
for (auto &d: devdata->log->dives) {
|
||||
if (object_id == d->dcs[0].diveid)
|
||||
return d.get();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -767,27 +767,13 @@ static void parse_tag(struct dive *dive, std::string_view tag, std::string_view
|
|||
|
||||
static bool uemis_delete_dive(device_data_t *devdata, uint32_t diveid)
|
||||
{
|
||||
struct dive *dive = NULL;
|
||||
auto it = std::find_if(devdata->log->dives.begin(), devdata->log->dives.end(),
|
||||
[diveid] (auto &d) { return d->dcs[0].diveid == diveid; });
|
||||
if (it == devdata->log->dives.end())
|
||||
return false;
|
||||
|
||||
if (devdata->log->dives->dives[devdata->log->dives->nr - 1]->dcs[0].diveid == diveid) {
|
||||
/* we hit the last one in the array */
|
||||
dive = devdata->log->dives->dives[devdata->log->dives->nr - 1];
|
||||
} else {
|
||||
for (int i = 0; i < devdata->log->dives->nr - 1; i++) {
|
||||
if (devdata->log->dives->dives[i]->dcs[0].diveid == diveid) {
|
||||
dive = devdata->log->dives->dives[i];
|
||||
for (int x = i; x < devdata->log->dives->nr - 1; x++)
|
||||
devdata->log->dives->dives[i] = devdata->log->dives->dives[x + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dive) {
|
||||
devdata->log->dives->dives[--devdata->log->dives->nr] = NULL;
|
||||
delete dive;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
devdata->log->dives.erase(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* This function is called for both dive log and dive information that we get
|
||||
|
@ -914,7 +900,7 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, std::s
|
|||
bp = bp.substr(1);
|
||||
if (bp[0] != '{' && bp.find("{{") != std::string::npos) {
|
||||
done = false;
|
||||
record_dive_to_table(owned_dive.release(), devdata->log->dives.get());
|
||||
devdata->log->dives.record_dive(std::move(owned_dive));
|
||||
owned_dive = uemis_start_dive(deviceid);
|
||||
}
|
||||
}
|
||||
|
@ -947,7 +933,7 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, std::s
|
|||
}
|
||||
if (is_log) {
|
||||
if (owned_dive->dcs[0].diveid)
|
||||
record_dive_to_table(owned_dive.release(), devdata->log->dives.get());
|
||||
devdata->log->dives.record_dive(std::move(owned_dive));
|
||||
else /* partial dive */
|
||||
return false;
|
||||
}
|
||||
|
@ -959,7 +945,6 @@ static std::pair<uint32_t, uint32_t> uemis_get_divenr(uint32_t deviceid, struct
|
|||
{
|
||||
uint32_t maxdiveid = 0;
|
||||
uint32_t mindiveid = 0xFFFFFFFF;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* If we are are retrying after a disconnect/reconnect, we
|
||||
|
@ -971,11 +956,10 @@ static std::pair<uint32_t, uint32_t> uemis_get_divenr(uint32_t deviceid, struct
|
|||
*
|
||||
* Otherwise, use the global dive table.
|
||||
*/
|
||||
if (!force && !table->nr)
|
||||
table = divelog.dives.get();
|
||||
if (!force && table->empty())
|
||||
table = &divelog.dives;
|
||||
|
||||
for (i = 0; i < table->nr; i++) {
|
||||
struct dive *d = table->dives[i];
|
||||
for (auto &d: *table) {
|
||||
if (!d)
|
||||
continue;
|
||||
for (auto &dc: d->dcs) {
|
||||
|
@ -1037,19 +1021,19 @@ static bool do_dump_buffer_to_file(std::string_view buf, const char *prefix)
|
|||
* return : ok if there is enough memory for a full round
|
||||
* full if the memory is exhausted
|
||||
*/
|
||||
static uemis_mem_status get_memory(struct dive_table *td, uemis_checkpoint checkpoint)
|
||||
static uemis_mem_status get_memory(struct dive_table &td, uemis_checkpoint checkpoint)
|
||||
{
|
||||
if (td->nr <= 0)
|
||||
if (td.empty())
|
||||
return uemis_mem_status::ok;
|
||||
|
||||
switch (checkpoint) {
|
||||
case uemis_checkpoint::log:
|
||||
if (filenr / td->nr > max_mem_used)
|
||||
max_mem_used = filenr / td->nr;
|
||||
if (filenr / static_cast<int>(td.size()) > max_mem_used)
|
||||
max_mem_used = filenr / static_cast<int>(td.size());
|
||||
|
||||
/* check if a full block of dive logs + dive details and dive spot fit into the UEMIS buffer */
|
||||
#if UEMIS_DEBUG & 4
|
||||
report_info("max_mem_used %d (from td->nr %d) * block_size %d > max_files %d - filenr %d?\n", max_mem_used, td->nr, uemis_log_block_size, uemis_max_files, filenr);
|
||||
report_info("max_mem_used %d (from td.size() %d) * block_size %d > max_files %d - filenr %d?\n", max_mem_used, static_cast<int>(td.size()), uemis_log_block_size, uemis_max_files, filenr);
|
||||
#endif
|
||||
if (max_mem_used * uemis_log_block_size > uemis_max_files - filenr)
|
||||
return uemis_mem_status::full;
|
||||
|
@ -1069,10 +1053,10 @@ static uemis_mem_status get_memory(struct dive_table *td, uemis_checkpoint check
|
|||
|
||||
/* we misuse the hidden_by_filter flag to mark a dive as deleted.
|
||||
* this will be picked up by some cleaning statement later. */
|
||||
static void do_delete_dives(struct dive_table *td, int idx)
|
||||
static void do_delete_dives(struct dive_table &td, size_t idx)
|
||||
{
|
||||
for (int x = idx; x < td->nr; x++)
|
||||
td->dives[x]->hidden_by_filter = true;
|
||||
for (auto it = td.begin() + idx; it != td.end(); ++it)
|
||||
(*it)->hidden_by_filter = true;
|
||||
}
|
||||
|
||||
static bool load_uemis_divespot(const std::string &mountpath, int divespot_id)
|
||||
|
@ -1128,9 +1112,9 @@ static void get_uemis_divespot(device_data_t *devdata, const std::string &mountp
|
|||
}
|
||||
}
|
||||
|
||||
static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status, device_data_t *data, const std::string &mountpath, const char deviceidnr)
|
||||
static bool get_matching_dive(size_t idx, int &newmax, uemis_mem_status &mem_status, device_data_t *data, const std::string &mountpath, const char deviceidnr)
|
||||
{
|
||||
struct dive *dive = data->log->dives->dives[idx];
|
||||
auto &dive = data->log->dives[idx];
|
||||
char log_file_no_to_find[20];
|
||||
bool found = false;
|
||||
bool found_below = false;
|
||||
|
@ -1151,7 +1135,7 @@ static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status
|
|||
#if UEMIS_DEBUG & 16
|
||||
do_dump_buffer_to_file(mbuf, "Dive");
|
||||
#endif
|
||||
mem_status = get_memory(data->log->dives.get(), uemis_checkpoint::single_dive);
|
||||
mem_status = get_memory(data->log->dives, uemis_checkpoint::single_dive);
|
||||
if (mem_status == uemis_mem_status::ok) {
|
||||
/* if the memory isn's completely full we can try to read more dive log vs. dive details
|
||||
* and the dive spots should fit into the UEMIS memory
|
||||
|
@ -1174,7 +1158,7 @@ static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status
|
|||
#endif
|
||||
int divespot_id = uemis_obj.get_divespot_id_by_diveid(dive->dcs[0].diveid);
|
||||
if (divespot_id >= 0)
|
||||
get_uemis_divespot(data, mountpath, divespot_id, dive);
|
||||
get_uemis_divespot(data, mountpath, divespot_id, dive.get());
|
||||
|
||||
} else {
|
||||
/* in this case we found a deleted file, so let's increment */
|
||||
|
@ -1215,7 +1199,7 @@ static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status
|
|||
} else {
|
||||
/* At this point the memory of the UEMIS is full, let's cleanup all dive log files were
|
||||
* we could not match the details to. */
|
||||
do_delete_dives(data->log->dives.get(), idx);
|
||||
do_delete_dives(data->log->dives, idx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1236,7 +1220,6 @@ std::string do_uemis_import(device_data_t *data)
|
|||
std::string deviceid;
|
||||
std::string result;
|
||||
bool once = true;
|
||||
int match_dive_and_log = 0;
|
||||
int dive_offset = 0;
|
||||
uemis_mem_status mem_status = uemis_mem_status::ok;
|
||||
|
||||
|
@ -1274,7 +1257,7 @@ std::string do_uemis_import(device_data_t *data)
|
|||
|
||||
param_buff[1] = "notempty";
|
||||
{
|
||||
auto [mindiveid, maxdiveid] = uemis_get_divenr(deviceidnr, data->log->dives.get(), force_download);
|
||||
auto [mindiveid, maxdiveid] = uemis_get_divenr(deviceidnr, &data->log->dives, force_download);
|
||||
newmax = maxdiveid;
|
||||
if (verbose)
|
||||
report_info("Uemis downloader: start looking at dive nr %d", newmax);
|
||||
|
@ -1292,13 +1275,13 @@ std::string do_uemis_import(device_data_t *data)
|
|||
report_info("d_u_i inner loop start %d end %d newmax %d\n", start, end, newmax);
|
||||
#endif
|
||||
/* start at the last filled download table index */
|
||||
match_dive_and_log = data->log->dives->nr;
|
||||
size_t match_dive_and_log = data->log->dives.size();
|
||||
newmax = start;
|
||||
std::string newmax_str = std::to_string(newmax);
|
||||
param_buff[2] = newmax_str.c_str();
|
||||
param_buff[3].clear();
|
||||
std::string mbuf = uemis_get_answer(mountpath, "getDivelogs", 3, 0, result);
|
||||
mem_status = get_memory(data->log->dives.get(), uemis_checkpoint::details);
|
||||
mem_status = get_memory(data->log->dives, uemis_checkpoint::details);
|
||||
/* first, remove any leading garbage... this needs to start with a '{' */
|
||||
std::string_view realmbuf = mbuf;
|
||||
size_t pos = realmbuf.find('{');
|
||||
|
@ -1341,7 +1324,7 @@ std::string do_uemis_import(device_data_t *data)
|
|||
* What the following part does is to optimize the mapping by using
|
||||
* dive_to_read = the dive details entry that need to be read using the object_id
|
||||
* logFileNoToFind = map the logfilenr of the dive details with the object_id = diveid from the get dive logs */
|
||||
for (int i = match_dive_and_log; i < data->log->dives->nr; i++) {
|
||||
for (size_t i = match_dive_and_log; i < data->log->dives.size(); i++) {
|
||||
if (!get_matching_dive(i, newmax, mem_status, data, mountpath, deviceidnr))
|
||||
break;
|
||||
if (import_thread_cancelled)
|
||||
|
@ -1351,7 +1334,7 @@ std::string do_uemis_import(device_data_t *data)
|
|||
start = end;
|
||||
|
||||
/* Do some memory checking here */
|
||||
mem_status = get_memory(data->log->dives.get(), uemis_checkpoint::log);
|
||||
mem_status = get_memory(data->log->dives, uemis_checkpoint::log);
|
||||
if (mem_status != uemis_mem_status::ok) {
|
||||
#if UEMIS_DEBUG & 4
|
||||
report_info("d_u_i out of memory, bailing\n");
|
||||
|
@ -1365,7 +1348,7 @@ std::string do_uemis_import(device_data_t *data)
|
|||
// Resetting to original state
|
||||
filenr = 0;
|
||||
max_mem_used = -1;
|
||||
mem_status = get_memory(data->log->dives.get(), uemis_checkpoint::details);
|
||||
mem_status = get_memory(data->log->dives, uemis_checkpoint::details);
|
||||
if (uemis_get_answer(mountpath, "getDeviceId", 0, 1, result).empty())
|
||||
goto bail;
|
||||
if (deviceid != param_buff[0]) {
|
||||
|
@ -1408,7 +1391,7 @@ std::string do_uemis_import(device_data_t *data)
|
|||
* be deleted from the download_table.
|
||||
*/
|
||||
if (mem_status == uemis_mem_status::full)
|
||||
do_delete_dives(data->log->dives.get(), match_dive_and_log);
|
||||
do_delete_dives(data->log->dives, match_dive_and_log);
|
||||
#if UEMIS_DEBUG & 4
|
||||
report_info("d_u_i out of memory, bailing instead of processing\n");
|
||||
#endif
|
||||
|
@ -1425,9 +1408,9 @@ std::string do_uemis_import(device_data_t *data)
|
|||
|
||||
/* Regardless on where we are with the memory situation, it's time now
|
||||
* to see if we have to clean some dead bodies from our download table */
|
||||
for (int next_table_index = 0; next_table_index < data->log->dives->nr; ) {
|
||||
if (data->log->dives->dives[next_table_index]->hidden_by_filter)
|
||||
uemis_delete_dive(data, data->log->dives->dives[next_table_index]->dcs[0].diveid);
|
||||
for (size_t next_table_index = 0; next_table_index < data->log->dives.size(); ) {
|
||||
if (data->log->dives[next_table_index]->hidden_by_filter)
|
||||
uemis_delete_dive(data, data->log->dives[next_table_index]->dcs[0].diveid);
|
||||
else
|
||||
next_table_index++;
|
||||
}
|
||||
|
@ -1446,7 +1429,7 @@ bail:
|
|||
else
|
||||
result = param_buff[2];
|
||||
}
|
||||
if (!data->log->dives->nr)
|
||||
if (data->log->dives.empty())
|
||||
result = translate("gettextFromC", ERR_NO_FILES);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -7,8 +7,11 @@
|
|||
#include "core/errorhelper.h"
|
||||
#include "core/qthelper.h"
|
||||
#include "core/dive.h"
|
||||
#include "core/membuffer.h"
|
||||
#include "core/divelist.h"
|
||||
#include "core/divelog.h"
|
||||
#include "core/divesite.h"
|
||||
#include "core/membuffer.h"
|
||||
#include "core/range.h"
|
||||
#include "core/cloudstorage.h"
|
||||
#include "core/xmlparams.h"
|
||||
#ifndef SUBSURFACE_MOBILE
|
||||
|
@ -87,9 +90,7 @@ bool uploadDiveLogsDE::prepareDives(const QString &tempfile, bool selected)
|
|||
}
|
||||
|
||||
/* walk the dive list in chronological order */
|
||||
int i;
|
||||
struct dive *dive;
|
||||
for_each_dive (i, dive) {
|
||||
for (auto [i, dive]: enumerated_range(divelog.dives)) {
|
||||
char filename[PATH_MAX];
|
||||
int streamsize;
|
||||
char *membuf;
|
||||
|
@ -131,7 +132,7 @@ bool uploadDiveLogsDE::prepareDives(const QString &tempfile, bool selected)
|
|||
put_format(&mb, "</site>\n</divesites>\n");
|
||||
}
|
||||
|
||||
save_one_dive_to_mb(&mb, dive, false);
|
||||
save_one_dive_to_mb(&mb, *dive, false);
|
||||
|
||||
if (ds) {
|
||||
put_format(&mb, "</divelog>\n");
|
||||
|
|
|
@ -10,10 +10,12 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "dive.h"
|
||||
#include "membuffer.h"
|
||||
#include "divelist.h"
|
||||
#include "divelog.h"
|
||||
#include "divesite.h"
|
||||
#include "errorhelper.h"
|
||||
#include "file.h"
|
||||
#include "membuffer.h"
|
||||
#include "save-html.h"
|
||||
#include "format.h"
|
||||
#include "worldmap-save.h"
|
||||
|
@ -28,43 +30,39 @@ static const char *getGoogleApi()
|
|||
|
||||
static void writeMarkers(struct membuffer *b, bool selected_only)
|
||||
{
|
||||
int i, dive_no = 0;
|
||||
struct dive *dive;
|
||||
std::string pre, post;
|
||||
int dive_no = 0;
|
||||
|
||||
for_each_dive (i, dive) {
|
||||
if (selected_only) {
|
||||
if (!dive->selected)
|
||||
for (auto &dive: divelog.dives) {
|
||||
if (selected_only && !dive->selected)
|
||||
continue;
|
||||
}
|
||||
struct dive_site *ds = get_dive_site_for_dive(dive);
|
||||
struct dive_site *ds = get_dive_site_for_dive(dive.get());
|
||||
if (!dive_site_has_gps_location(ds))
|
||||
continue;
|
||||
put_degrees(b, ds->location.lat, "temp = new google.maps.Marker({position: new google.maps.LatLng(", "");
|
||||
put_degrees(b, ds->location.lon, ",", ")});\n");
|
||||
put_string(b, "markers.push(temp);\ntempinfowindow = new google.maps.InfoWindow({content: '<div id=\"content\">'+'<div id=\"siteNotice\">'+'</div>'+'<div id=\"bodyContent\">");
|
||||
pre = format_string_std("<p>%s ", translate("gettextFromC", "Date:"));
|
||||
put_HTML_date(b, dive, pre.c_str(), "</p>");
|
||||
std::string pre = format_string_std("<p>%s ", translate("gettextFromC", "Date:"));
|
||||
put_HTML_date(b, *dive, pre.c_str(), "</p>");
|
||||
pre = format_string_std("<p>%s ", translate("gettextFromC", "Time:"));
|
||||
put_HTML_time(b, dive, pre.c_str(), "</p>");
|
||||
put_HTML_time(b, *dive, pre.c_str(), "</p>");
|
||||
pre = format_string_std("<p>%s ", translate("gettextFromC", "Duration:"));
|
||||
post = format_string_std(" %s</p>", translate("gettextFromC", "min"));
|
||||
std::string post = format_string_std(" %s</p>", translate("gettextFromC", "min"));
|
||||
put_duration(b, dive->duration, pre.c_str(), post.c_str());
|
||||
put_string(b, "<p> ");
|
||||
put_HTML_quoted(b, translate("gettextFromC", "Max. depth:"));
|
||||
put_HTML_depth(b, dive, " ", "</p>");
|
||||
put_HTML_depth(b, *dive, " ", "</p>");
|
||||
put_string(b, "<p> ");
|
||||
put_HTML_quoted(b, translate("gettextFromC", "Air temp.:"));
|
||||
put_HTML_airtemp(b, dive, " ", "</p>");
|
||||
put_HTML_airtemp(b, *dive, " ", "</p>");
|
||||
put_string(b, "<p> ");
|
||||
put_HTML_quoted(b, translate("gettextFromC", "Water temp.:"));
|
||||
put_HTML_watertemp(b, dive, " ", "</p>");
|
||||
put_HTML_watertemp(b, *dive, " ", "</p>");
|
||||
pre = format_string_std("<p>%s <b>", translate("gettextFromC", "Location:"));
|
||||
put_string(b, pre.c_str());
|
||||
put_HTML_quoted(b, get_dive_location(dive).c_str());
|
||||
put_HTML_quoted(b, get_dive_location(dive.get()).c_str());
|
||||
put_string(b, "</b></p>");
|
||||
pre = format_string_std("<p> %s ", translate("gettextFromC", "Notes:"));
|
||||
put_HTML_notes(b, dive, pre.c_str(), " </p>");
|
||||
put_HTML_notes(b, *dive, pre.c_str(), " </p>");
|
||||
put_string(b, "</p>'+'</div>'+'</div>'});\ninfowindows.push(tempinfowindow);\n");
|
||||
put_format(b, "google.maps.event.addListener(markers[%d], 'mouseover', function() {\ninfowindows[%d].open(map,markers[%d]);}", dive_no, dive_no, dive_no);
|
||||
put_format(b, ");google.maps.event.addListener(markers[%d], 'mouseout', function() {\ninfowindows[%d].close();});\n", dive_no, dive_no);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue