The goal here is to add general addition and scalar multiplication
functions to the unit types.
Thereto, we need a CRTP
(https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)
base class.
However, this breaks compound initialization, so we have to use
named initializers:
weight_t { 2000 } -> weight_t { .grams = 2000 }
The good thing is that this is exactly how these classes were
supposed to be used: make the unit explicit!
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Fix a bug introduced in #4245, causing an incorrect dive mode to be
selected when starting the dive planner from a CCR dive.
Signed-off-by: Michael Keller <github@ike.ch>
This has become a bit of a catch-all overhaul of a large portion of the
planner - I started out wanting to improve the CCR mode, but then as I
started pulling all the other threads that needed addressing started to
come with it.
Improve how the gas selection is handled when planning dives in CCR
mode, by making the type (OC / CCR) of segments dependent on the gas use
type that was set for the selected gas.
Add a preference to allow the user to chose to use OC gases as diluent,
in a similar fashion to the original implementation.
Hide gases that cannot be used in the currently selected dive mode in
all drop downs.
Include usage type in gas names if this is needed.
Hide columns and disable elements in the 'Dive planner points' table if
they can they can not be edited in the curently selected dive mode.
Visually identify gases and usage types that are not appropriate for the
currently selected dive mode.
Move the 'Dive mode' selection to the top of the planner view, to
accommodate the fact that this is a property of the dive and not a
planner setting.
Show a warning instead of the dive plan if the plan contains gases that
are not usable in the selected dive mode.
Fix the data entry for the setpoint in the 'Dive planner points' table.
Fix problems with enabling / disabling planner settings when switching
between dive modes.
Refactor some names to make them more appropriate for their current
usage.
One point that is still open is to hide gas usage graphs in the planner
profile if the gas isn't used for OC, as there is no way to meaningfully
interpolate such usage.
Signed-off-by: Michael Keller <github@ike.ch>
The copy/pasting of dive-sites was fundamentally broken in at least two
ways:
1) The dive-site pointer in struct dive was simply overwritten, which
breaks internal consistency. Also, no dive-site changed signals where
sent.
2) The copied dive-site was stored as a pointer in a struct dive. Thus,
the user could copy a dive, then delete the dive-site and paste.
This would lead to a dangling pointer and ultimately crash the
application.
Fix this by storing the UUID of the dive-site, not a pointer.
To do that, don't store a copy of the dive, but collect all
the data in a `dive_paste_data` structure.
If the dive site has been deleted on paste, do nothing.
Send the appropriate signals on pasting.
The mobile version had an additional bug: It kept a pointer to the
dive to be copied, which might become stale by undo.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Also, turn it to use std::string instead of writing into a
global(!) buffer. This was not reentrant.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Feels natural in a C++ code base.
This removes a nullptr-check so some care has to be taken.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This accesses the global dive_table, so make this explicit.
Since force_fixup_dive() and default_dive() use fixup_dive(),
also move them to struct dive_table.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Before, a non-owning pointer was passed and the dive moved
away from the dive. Instead, let the caller decide if they
still want to keep a copy of the dive, or give up ownership:
In MainWindow and QMLManager new dives are generated, so
one might just as well give up ownership. In contrast,
the planner works on a copy (originally the infamous
"displayed_dive") and now moves the data manually.
This commit also removes duplicate code, by moving the
"create default dive" code from MainWindow and QMLManager
to struct dive.
Finally, determination of the "time zone offset" is not done
in POSIX, since we want to avoid calls form the core into
Qt.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This implicitly accessed the global divelog. Most of the users were
in the test/ folder anyway. Replace by explicit accesses to the
global divelog.dives.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
These functions accessed the global divelog make this explicit.
I'm still not happy about the situation, because these functions
access global state, such as the selection. I think these
should be moved up the call-chain.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This function implicitely accessed the global divelog. To make
that explicit make it a member of dive_table, such that the
caller must access it via the global variable.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This is a messy commit, because the "qPref" system relies
heavily on QString, which means lots of conversions between
the two worlds. Ultimately, I plan to base the preferences
system on std::string and only convert to QString when
pushing through Qt's property system or when writing into
Qt's settings.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Since all code can now directly access C++ structures these
accessor functions were not necessary.
Split out the table from the filterconstraint source file
and include it directly into the divelog.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Having this as a pointer is an artifact from the C/C++ split.
The triptable header is small enough so that we can
include it directly
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Having this as a pointer is an artifact from the C/C++ split.
The divesitetable header is small enough so that we can
include it directly.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Not strictly necessary, but a "natural" thing to do in a classical
C++ code base.
Move the tiny trip-table into its own source file, since it also
has its own header.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
Nothing against free-standing functions, but in the case
of dc_watertemp(), dc_airtemp(), endtime() and totaltime(),
it seems natural to move this into the dive class and avoid
polution of the global name space.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The dive_table will be converted into a table of owning pointers.
Since the trip has only non-owning pointers to dives, turn
its dive_table into an std::vector<dive *>.
Add a helper functions to add/remove items in a sorted list.
These could be used elsewhere.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Since the sorted_owning_table depends on the fact that
different elements never compare as equal, make the
comparison function safer in that respect. If all failes,
compare the pointers.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This had to be done simultaneously, because the table macros
do not work properly with C++ objects.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Since struct divecomputer is now fully C++ (i.e. cleans up
after itself), we can simply turn the list of divecomputers
into an std::vector<>. This makes the code quite a bit simpler,
because the first divecomputer was actually a subobject.
Yes, this makes the common case of a single divecomputer a
little bit less efficient, but it really shouldn't matter.
If it does, we can still write a special std::vector<>-
like container that keeps the first element inline.
This change makes pointers-to-divecomputers not stable.
So always access the divecomputer via its index. As
far as I can tell, most of the code already does this.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This is a rather long commit, because it refactors lots of the event
code from pointer to value semantics: pointers to entries in an
std::vector<> are not stable, so better use indexes.
To step through the event-list at diven time stamps, add *_loop classes,
which encapsulate state that had to be manually handled before by
the caller. I'm not happy about the interface, but it tries to
mirror the one we had before.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This is a hairy one, because the sample code is rather tricky.
There was a pattern of looping through pairs of adjacent samples,
for interpolation purposes. Add an range adapter to generalize
such loops.
Removes the finish_sample() function: The code would call
prepare_sample() to start parsing of samples and then
finish_sample() to actuall add it. I.e. a kind of commit().
Since, with one exception, all users of prepare_sample()
called finish_sample() in all code paths, we might just add
the sample in the first place. The exception was sample_end()
in parse.cpp. This brings a small change: samples are now
added, even if they could only be parsed partially. I doubt
that this makes any difference, since it will only happen
for broken divelogs anyway.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This allows us to use non-C member variables. Convert a number
of pointers to unique_ptr<>s.
Code in uemis-downloader.cpp had to be refactored, because
it mixed owning and non-owning pointers. Mad.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The old code would construct and then initialize the object
in a separate function, which added lots of complication.
Just initialize the thing in the constructor, store a
reference, not a pointer to the table. And do a few other
code cleanups. The result is distinctly more pleasing.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
After all it doesn't access any dive_site structure.
Moreover, rename it, since we use mostly snake_case in core.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This gives the distance between to location_t objects. It is
unclear why this was in divesite.cpp.
Moreover pass by value, not raw pointer.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>