diff --git a/Subsurface-mobile.pro b/Subsurface-mobile.pro index 3b79311e6..029f19356 100644 --- a/Subsurface-mobile.pro +++ b/Subsurface-mobile.pro @@ -97,6 +97,7 @@ SOURCES += subsurface-mobile-main.cpp \ core/taxonomy.cpp \ core/time.cpp \ core/trip.cpp \ + core/triptable.cpp \ core/units.cpp \ core/uemis.cpp \ core/btdiscovery.cpp \ diff --git a/commands/command_divelist.cpp b/commands/command_divelist.cpp index 923451e00..b38dcc14d 100644 --- a/commands/command_divelist.cpp +++ b/commands/command_divelist.cpp @@ -67,7 +67,7 @@ void DiveListBase::diveSiteCountChanged(struct dive_site *ds) dive *DiveListBase::addDive(DiveToAdd &d) { if (d.trip) - add_dive_to_trip(d.dive.get(), d.trip); + d.trip->add_dive(d.dive.get()); if (d.site) { d.site->add_dive(d.dive.get()); diveSiteCountChanged(d.site); @@ -267,7 +267,7 @@ static std::unique_ptr moveDiveToTrip(DiveToTrip &diveToTrip) // Store old trip and get new trip we should associate this dive with std::swap(trip, diveToTrip.trip); if (trip) - add_dive_to_trip(diveToTrip.dive, trip); + trip->add_dive(diveToTrip.dive); invalidate_dive_cache(diveToTrip.dive); // Ensure that dive is written in git_save() return res; } diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 22237a79f..60343fe98 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -180,6 +180,7 @@ set(SUBSURFACE_CORE_LIB_SRCS time.cpp trip.cpp trip.h + triptable.cpp triptable.h uemis-downloader.cpp uemis.cpp diff --git a/core/divelist.cpp b/core/divelist.cpp index c60bddce0..b3ae8d10e 100644 --- a/core/divelist.cpp +++ b/core/divelist.cpp @@ -642,9 +642,9 @@ int comp_dives(const struct dive &a, const struct dive &b) return -1; if (!a.divetrip) return 1; - if (trip_date(*a.divetrip) < trip_date(*b.divetrip)) + if (a.divetrip->date() < b.divetrip->date()) return -1; - if (trip_date(*a.divetrip) > trip_date(*b.divetrip)) + if (a.divetrip->date() > b.divetrip->date()) return 1; } if (a.number < b.number) @@ -676,7 +676,7 @@ static void autogroup_dives(struct dive_table &table, struct trip_table &trip_ta for (auto &entry: get_dives_to_autogroup(table)) { for (auto it = table.begin() + entry.from; it != table.begin() + entry.to; ++it) - add_dive_to_trip(it->get(), entry.trip); + entry.trip->add_dive(it->get()); /* If this was newly allocated, add trip to list */ if (entry.created_trip) trip_table.put(std::move(entry.created_trip)); @@ -911,7 +911,7 @@ void add_imported_dives(struct divelog &import_log, int flags) struct dive_site *site = d->dive_site; d->divetrip = NULL; d->dive_site = NULL; - add_dive_to_trip(d.get(), trip); + trip->add_dive(d.get()); if (site) site->add_dive(d.get()); } diff --git a/core/load-git.cpp b/core/load-git.cpp index e88a11694..b2d08af45 100644 --- a/core/load-git.cpp +++ b/core/load-git.cpp @@ -1401,7 +1401,7 @@ static void create_new_dive(timestamp_t when, struct git_parser_state *state) state->active_dive->when = when; if (state->active_trip) - add_dive_to_trip(state->active_dive.get(), state->active_trip.get()); + state->active_trip->add_dive(state->active_dive.get()); } static bool validate_date(int yyyy, int mm, int dd) diff --git a/core/parse.cpp b/core/parse.cpp index 5b2f83fe2..5aef2d0c9 100644 --- a/core/parse.cpp +++ b/core/parse.cpp @@ -261,7 +261,7 @@ void dive_end(struct parser_state *state) return; if (is_dive(state)) { if (state->cur_trip) - add_dive_to_trip(state->cur_dive.get(), state->cur_trip.get()); + state->cur_trip->add_dive(state->cur_dive.get()); // Note: we add dives in an unsorted way. The caller of the parsing // function must sort dives. fixup_dive(state->cur_dive.get()); diff --git a/core/save-git.cpp b/core/save-git.cpp index ac0e24306..a8e1e6c8e 100644 --- a/core/save-git.cpp +++ b/core/save-git.cpp @@ -1004,7 +1004,7 @@ static int create_git_tree(git_repository *repo, struct dir *root, bool select_o } /* Create the date-based hierarchy */ - utc_mkdate(trip ? trip_date(*trip) : dive->when, &tm); + utc_mkdate(trip ? trip->date() : dive->when, &tm); tree = mktree(repo, root, "%04d", tm.tm_year); tree = mktree(repo, tree, "%02d", tm.tm_mon + 1); diff --git a/core/save-xml.cpp b/core/save-xml.cpp index 85ed6cc21..40b64850a 100644 --- a/core/save-xml.cpp +++ b/core/save-xml.cpp @@ -545,7 +545,7 @@ int save_dive(FILE *f, const struct dive &dive, bool anonymize) static void save_trip(struct membuffer *b, dive_trip &trip, bool anonymize) { put_format(b, "\n"); show_utf8(b, trip.notes.c_str(), "", "\n", 0); diff --git a/core/string-format.cpp b/core/string-format.cpp index 71d21f8e2..95050c260 100644 --- a/core/string-format.cpp +++ b/core/string-format.cpp @@ -301,8 +301,8 @@ QString formatMinutes(int seconds) QString formatTripTitle(const dive_trip &trip) { - timestamp_t when = trip_date(trip); - bool getday = trip_is_single_day(trip); + timestamp_t when = trip.date(); + bool getday = trip.is_single_day(); QDateTime localTime = timestampToDateTime(when); diff --git a/core/trip.cpp b/core/trip.cpp index 311fc5b78..1869dbd75 100644 --- a/core/trip.cpp +++ b/core/trip.cpp @@ -9,38 +9,17 @@ #include "subsurface-string.h" #include "selection.h" -#ifdef DEBUG_TRIP -void dump_trip_list() -{ - timestamp_t last_time = 0; - - for (auto &trip: divelog.trips) { - struct tm tm; - utc_mkdate(trip_date(*trip), &tm); - if (trip_date(*trip) < last_time) - printf("\n\ntrip_table OUT OF ORDER!!!\n\n\n"); - printf("%s trip %d to \"%s\" on %04u-%02u-%02u %02u:%02u:%02u (%d dives - %p)\n", - trip->autogen ? "autogen " : "", - i + 1, trip->location.c_str(), - tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, - static_cast(trip->dives.size()), trip.get()); - last_time = trip_date(*trip); - } - printf("-----\n"); -} -#endif - dive_trip::dive_trip() : id(dive_getUniqID()) { } dive_trip::~dive_trip() = default; -timestamp_t trip_date(const struct dive_trip &trip) +timestamp_t dive_trip::date() const { - if (trip.dives.empty()) + if (dives.empty()) return 0; - return trip.dives[0]->when; + return dives[0]->when; } static timestamp_t trip_enddate(const struct dive_trip &trip) @@ -52,14 +31,14 @@ static timestamp_t trip_enddate(const struct dive_trip &trip) /* 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) +void dive_trip::add_dive(struct dive *dive) { - if (dive->divetrip == trip) + if (dive->divetrip == this) return; if (dive->divetrip) 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; + range_insert_sorted(dives, dive, comp_dives_ptr); + dive->divetrip = this; } /* remove a dive from the trip it's associated to, but don't delete the @@ -115,13 +94,6 @@ std::pair> get_trip_for_new_dive(const s return { t, std::move(trip) }; } -/* lookup of trip in main trip_table based on its id */ -dive_trip *trip_table::get_by_uniq_id(int tripId) const -{ - auto it = std::find_if(begin(), end(), [tripId](auto &t) { return t->id == tripId; }); - return it != end() ? it->get() : nullptr; -} - /* Check if two trips overlap time-wise up to trip threshold. */ bool trips_overlap(const struct dive_trip &t1, const struct dive_trip &t2) { @@ -129,10 +101,10 @@ bool trips_overlap(const struct dive_trip &t1, const struct dive_trip &t2) if (t1.dives.empty() || t2.dives.empty()) return 0; - if (trip_date(t1) < trip_date(t2)) - return trip_enddate(t1) + TRIP_THRESHOLD >= trip_date(t2); + if (t1.date() < t2.date()) + return trip_enddate(t1) + TRIP_THRESHOLD >= t2.date(); else - return trip_enddate(t2) + TRIP_THRESHOLD >= trip_date(t1); + return trip_enddate(t2) + TRIP_THRESHOLD >= t1.date(); } /* @@ -250,17 +222,16 @@ static bool is_same_day(timestamp_t trip_when, timestamp_t dive_when) return (tmd.tm_mday == tmt.tm_mday) && (tmd.tm_mon == tmt.tm_mon) && (tmd.tm_year == tmt.tm_year); } -bool trip_is_single_day(const struct dive_trip &trip) +bool dive_trip::is_single_day() const { - if (trip.dives.size() <= 1) + if (dives.size() <= 1) return true; - return is_same_day(trip.dives.front()->when, - trip.dives.back()->when); + return is_same_day(dives.front()->when, dives.back()->when); } -int trip_shown_dives(const struct dive_trip *trip) +int dive_trip::shown_dives() const { - return std::count_if(trip->dives.begin(), trip->dives.end(), + return std::count_if(dives.begin(), dives.end(), [](const dive *d) { return !d->hidden_by_filter; }); } diff --git a/core/trip.h b/core/trip.h index 1ada441bd..2aa5f274b 100644 --- a/core/trip.h +++ b/core/trip.h @@ -17,21 +17,21 @@ struct dive_trip bool autogen = false; bool selected = false; - void sort_dives(); - dive_trip(); ~dive_trip(); + + void sort_dives(); + void add_dive(struct dive *); + timestamp_t date() const; + bool is_single_day() const; + int shown_dives() const; }; int comp_trips(const dive_trip &t1, const dive_trip &t2); -extern void add_dive_to_trip(struct dive *, dive_trip *); extern struct dive_trip *unregister_dive_from_trip(struct dive *dive); -extern timestamp_t trip_date(const struct dive_trip &trip); - extern std::unique_ptr create_trip_from_dive(const struct dive *dive); -extern dive_trip *create_and_hookup_trip_from_dive(const struct dive *dive, struct trip_table &trip_table_arg); // Result item of get_dives_to_autogroup() struct dives_to_autogroup_result { @@ -46,12 +46,6 @@ extern std::pair> get_trip_for_new_dive( extern bool trips_overlap(const struct dive_trip &t1, const struct dive_trip &t2); extern std::unique_ptr combine_trips(struct dive_trip *trip_a, struct dive_trip *trip_b); -extern bool trip_is_single_day(const struct dive_trip &trip); -extern int trip_shown_dives(const struct dive_trip *trip); - -#ifdef DEBUG_TRIP -extern void dump_trip_list(); -#endif /* Make pointers to dive_trip "Qt metatypes" so that they can be * passed through QVariants and through QML. See comment in dive.h. */ diff --git a/core/triptable.cpp b/core/triptable.cpp new file mode 100644 index 000000000..841a6b609 --- /dev/null +++ b/core/triptable.cpp @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "triptable.h" +#include "trip.h" + +#ifdef DEBUG_TRIP +void dump_trip_list() +{ + timestamp_t last_time = 0; + + for (auto &trip: divelog.trips) { + struct tm tm; + utc_mkdate(trip->date(), &tm); + if (trip->date() < last_time) + printf("\n\ntrip_table OUT OF ORDER!!!\n\n\n"); + printf("%s trip %d to \"%s\" on %04u-%02u-%02u %02u:%02u:%02u (%d dives - %p)\n", + trip->autogen ? "autogen " : "", + i + 1, trip->location.c_str(), + tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, + static_cast(trip->dives.size()), trip.get()); + last_time = trip->date(); + } + printf("-----\n"); +} +#endif + +/* lookup of trip in main trip_table based on its id */ +dive_trip *trip_table::get_by_uniq_id(int tripId) const +{ + auto it = std::find_if(begin(), end(), [tripId](auto &t) { return t->id == tripId; }); + return it != end() ? it->get() : nullptr; +} diff --git a/core/triptable.h b/core/triptable.h index 1b4facc0c..73cba9652 100644 --- a/core/triptable.h +++ b/core/triptable.h @@ -12,6 +12,10 @@ struct trip_table : public sorted_owning_table { dive_trip *get_by_uniq_id(int tripId) const; }; +#ifdef DEBUG_TRIP +extern void dump_trip_list(); +#endif + /* Make pointers to trip_table "Qt metatypes" so that they can be * passed through QVariants and through QML. See comment in dive.h. */ #include diff --git a/desktop-widgets/tab-widgets/TabDiveNotes.cpp b/desktop-widgets/tab-widgets/TabDiveNotes.cpp index b0a50e83c..439659a84 100644 --- a/desktop-widgets/tab-widgets/TabDiveNotes.cpp +++ b/desktop-widgets/tab-widgets/TabDiveNotes.cpp @@ -169,7 +169,7 @@ void TabDiveNotes::updateDateTime(const struct dive *d) void TabDiveNotes::updateTripDate(const struct dive_trip *t) { - QDateTime localTime = timestampToDateTime(trip_date(*t)); + QDateTime localTime = timestampToDateTime(t->date()); ui.dateEdit->setDate(localTime.date()); } diff --git a/qt-models/divetripmodel.cpp b/qt-models/divetripmodel.cpp index c65d090b3..baf7d2937 100644 --- a/qt-models/divetripmodel.cpp +++ b/qt-models/divetripmodel.cpp @@ -69,7 +69,7 @@ QString DiveTripModelBase::tripShortDate(const dive_trip *trip) { if (!trip) return QString(); - QDateTime firstTime = timestampToDateTime(trip_date(*trip)); + QDateTime firstTime = timestampToDateTime(trip->date()); QString firstMonth = firstTime.toString("MMM"); return QStringLiteral("%1\n'%2").arg(firstMonth,firstTime.toString("yy")); } @@ -79,13 +79,13 @@ QString DiveTripModelBase::tripTitle(const dive_trip *trip) if (!trip) return QString(); QString numDives = tr("(%n dive(s))", "", static_cast(trip->dives.size())); - int shown = trip_shown_dives(trip); + int shown = trip->shown_dives(); QString shownDives = shown != !trip->dives.empty() ? QStringLiteral(" ") + tr("(%L1 shown)").arg(shown) : QString(); QString title = QString::fromStdString(trip->location); if (title.isEmpty()) { // so use the date range - QDateTime firstTime = timestampToDateTime(trip_date(*trip)); + QDateTime firstTime = timestampToDateTime(trip->date()); QString firstMonth = firstTime.toString("MMM"); QString firstYear = firstTime.toString("yyyy"); QDateTime lastTime = timestampToDateTime(trip->dives[0]->when); @@ -125,7 +125,7 @@ QVariant DiveTripModelBase::tripData(const dive_trip *trip, int column, int role switch (column) { case DiveTripModelBase::NR: QString shownText; - int countShown = trip_shown_dives(trip); + int countShown = trip->shown_dives(); if (countShown < static_cast(trip->dives.size())) shownText = tr("(%1 shown)").arg(countShown); return formatTripTitleWithDives(*trip) + " " + shownText; @@ -814,7 +814,7 @@ dive *DiveTripModelTree::Item::getDive() const timestamp_t DiveTripModelTree::Item::when() const { - return d_or_t.trip ? trip_date(*d_or_t.trip) : d_or_t.dive->when; + return d_or_t.trip ? d_or_t.trip->date() : d_or_t.dive->when; } dive_or_trip DiveTripModelTree::tripOrDive(const QModelIndex &index) const diff --git a/stats/statsvariables.cpp b/stats/statsvariables.cpp index e0fa377ea..8f31190bc 100644 --- a/stats/statsvariables.cpp +++ b/stats/statsvariables.cpp @@ -75,7 +75,7 @@ struct TripWrapper { timestamp_t date; TripWrapper(const dive_trip *t) : t(t), name(t ? formatTripTitle(*t) : QString()), - date(t ? trip_date(*t) : 0) + date(t ? t->date() : 0) { } bool operator<(const TripWrapper &t2) const {