Commit graph

2554 commits

Author SHA1 Message Date
Dirk Hohndel
44691dae10 dc-download: fingerprint details are debug info
In the normal use of the app this information is simply too verbose.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-10-29 15:14:59 -07:00
Dirk Hohndel
10e6519ad5 dc-download: give progress update for long downloads
Most divecomputers download data dive by dive - so we get reasonably
frequent updates during the download (as new dives are found and posted
in the progress text area). But some (like the G2) download all of the
new dives at once and only then start parsing them. As a result the
download can look like it is hung.

As a compromise this shows updates on the data received in 10kB
increments. Which for most cases should never be shown and therefore not
make the user experience any worse - but for cases like the G2 will make
a huge difference.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-10-29 15:14:59 -07:00
Dirk Hohndel
8e4b2d9b82 cleanup: replace QRegExp with QRegularExpression
Qt 6 will drop support for QRegExp.
Use QRegularExpression instead.

Much of this is a simple replacement of one class with the other, but
there are some changes to the way matches are tracked and captures are
created. Also, the exactMatch now needs to be implemented via anchors in
the regular expression itself.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-10-27 12:35:09 -07:00
Dirk Hohndel
4d0c863d61 cleanup: replace QRegExp with QRegularExpression
Qt 6 will drop support for QRegExp.
Use QRegularExpression instead.

This is a straight forward replacement without any other code changes.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-10-27 12:33:20 -07:00
Berthold Stoeger
540e4437d5 cleanup: fix conversion warning
Fix a pair of warnings, which annoyed me for a long time:
For some reasons prefs.bottompo2 is an integer (mbar)
whereas prefs.modpO2 is a float (bar). This results
in mixed integer/floating point arithmetics when
conditionally using either of them. And ultimately
a warning, when storing a mbar value as an integer.
Fix this by an explicit cast to int after converting
modpO2 to mbar.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-10-16 15:32:56 -07:00
Robert C. Helling
41258647d2 Don't access gasmix.o2.fraction
Air is a special gas that does not contain oxygen according
to gasmix.o2.fraction. If you want to use the fo2, you
need to use get_o2() to treat this special case correctly.

This fixes a bug when setting the MND of a gas containing
21% oxygen when o2 is considered not narcotic.

Reported-by: Christoph Gruen <gruen.christoph@gmail.com>
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2021-10-01 08:50:36 -07:00
Berthold Stoeger
a481cdc13d core: don't write pressure samples with "no sensor"
This has led to broken XML files, don't do it.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-09-22 09:11:00 -07:00
Berthold Stoeger
d9c77a27da core: properly clear pressure data of invalid sensors
When we found an invalid sensor (referring to a non
existing cylinder) in fixup_dive() the sensor-id was
set to NO_SENSOR.

This led to invalid XML files, because the code decides
to switch into legacy mode. However, there are two
pressure readings, which is invalid in legacy mode.

Therefore, also clear the pressure data.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-09-22 09:11:00 -07:00
Dirk Hohndel
8525b2e274 core: remove superfluous arguments
Fixes CID 373231

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-09-20 14:49:57 -07:00
Linus Torvalds
85392343fa Re-do the libdivecomputer fingerprint save/load code
This tries to make our fingerprinting code work better, by avoiding
using the "deviceid" field that has always been unreliable because we've
calculated it multiple different ways, and even for the same version of
subsurface, it ends up changing in the middle (ie we calculate one value
initially, then re-calculate it when we have a proper serial number
string).

So instead, the fingerprinting code will look up and save the
fingerprint file using purely "stable" information that is available
early during the download:

 - the device model name (which is a string with vendor and product name
   separated by a space)

 - the DC_EVENT_DEVINFO 32-bit 'serial' number (which is not necessarily
   a real serial number at all, but hopefully at least a unique number
   for the particular product)

but because the model name is not necessarily a good filename (think
slashes and other possibly invalid characters), we hash that model name
and use the resulting hex number in the fingerprint file name.

This way the fingerprint file is unambiguous at load and save time, and
depends purely on libdivecomputer data.

But because we also need to verify that we have the actual _dive_
associated with that fingerprint, we also need to save the final
deviceid and diveid when saving the fingerprint file, so that when we
load it again we can look up the dive and verify that we have it before
we use the fingerprint data.

To do that, the fingerprint file itself contains not just the
fingerprint data from libdivecomputer, but the last 8 bytes of the file
are the (subsurface) deviceid and the diveid of the dive that is
associated with the fingerprint.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2021-09-19 16:51:46 -07:00
Dirk Hohndel
2a0d14b100 core: remove location service preferences
Including the related tests.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-09-13 11:21:34 -07:00
Dirk Hohndel
6f813b9f8e mobile: remove GpsLocation
Only used in context of acquiring GPS locations with the mobile app, which
we no longer do.

Keep the DiveAndLocation structure around as that's needed by the
ApplyGpsFixes command.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-09-13 11:21:34 -07:00
Dirk Hohndel
bea552bf0d mobile: remove GpsListModel
This is only needed to show the list of GPS fixes obtained with
the now removed location service.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-09-13 11:21:34 -07:00
Josh Torres
7e6d9935f1 core: fix off-by-one causing incorrect profile display
In commit 4724c88 get_plot_details_new was updated to pass an index
instead of the entry into plot_string. This means we are passing "i" to
plot_string after the final increment of the for loop, instead of
getting the entry[i] within the loop before the final increment. This
means if we are mousing over the far right of the graph, where the time
based break is not hit, we will end up passing an index equal to nr-2
instead of nr-3, which is intended to shave off the final two rows
containing data not useful to the display.

There are a handful of ways to fix this. This commit intends to be
consistent with stylistic choices made elsewhere in the project.

Signed-off-by: Josh Torres <torres.josh.j@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-09-06 13:00:37 -07:00
Berthold Stoeger
28fe6a7b38 core: add a function to test for sensors of a given cylinder
We want to prevent the user from accidentally deleting a
cylinder with sensor readings. Therefore, we need such a
function.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-09-03 13:35:28 -07:00
Berthold Stoeger
5eda1c0e39 parser: XML_PARSE_RECOVER to xmlReadMemory()
Due to changes in the handling of sensor-ids, invalid XMLs were
generated. In particular, these contained duplicate attributes
in the sample tags.

Even though these files shouldn't exist, let's try to parse
them anyway. Some data will be lost, but that's better than
not opening the file.

libxml2 can be told to try to recover from such petty(?) errors
by passing the XML_PARSE_RECOVER flag.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-09-03 09:30:34 -07:00
Robert C. Helling
c634a07e38 Planner: Correctly compute CNS and OTU for bailout segments
For dives with mixed divemode, one needs to check sample.setpoint
to figure out if the segment is an OC segment and the po2 needs
to be computed from the gasmix and ambient pressure.

This fixes #3310

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2021-08-19 10:58:08 -07:00
Dirk Hohndel
e7a5ec46f5 undo/device: adjust device management infrastructure
We no longer need the remove infrastructure, and the edit nickname function
becomes much more intuitive to use by passing in the dive computer for
which we want to create a nickname instead of the internal index into
the array of devices.

This also removes / simplifies the device list update signals in the
DiveListNotifier.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-08-18 13:22:02 -07:00
Dirk Hohndel
fbe17e620e core: add get_or_add helper for dc table
This makes it much easier to manipulate dc nickname entries. In order
for that to work we can't simply remove entries with empty nickname (but
that isn't needed, anyway, as the code that saves XML or git already
handles that case correctly).

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-08-18 13:22:02 -07:00
Linus Torvalds
47b0a9ce65 Don't share dive computer data allocations
... it just causes problems later when we free them, since we don't do
any reference counting.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2021-08-18 13:22:02 -07:00
Linus Torvalds
d141bbf38f Update the serial number and deviceid in sync when loading
When we save the divecomputer data, we never actually save the serial
value as a field.  We used to rely on saving the very dodgy 'deviceid',
and then look up the serial number from there.  And that never really
worked reliably, but we didn't really notice, because we never really
_used_ the serial number anywhere.

The only place the serial number is actually reliably displayed is in
the "Extra data" tab, which contains the key value pairs, and that's
where the original dive download code got the serial number from.

So just parse that at load time too, the same way we parsed it at dive
download time.

In fact, do the firmware version the same way, and remove the code from
the downloader, since it too can rely on 'add_extra_data()' just picking
up the information directly.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2021-08-18 13:22:02 -07:00
Linus Torvalds
6c4e890960 Clean up divecomputer 'device' handling
We have this odd legacy notion of a divecomputer 'device', that was
originally just basically the libdivecomputer 'EVENT_DEVINFO' report
that was associated with each dive.  So it had firmware version,
deviceid, and serial number.

It had also gotten extended to do 'nickname' handling, and it was all
confusing, ugly and bad.  It was particularly bad because it wasn't
actually a 'per device' thing at all: due to the firmware field, a dive
computer that got a firmware update forced a new 'device'.

To make matters worse, the 'deviceid' was also almost random, because
we've calculated it a couple of different ways, and libdivecomputer
itself has changed how the legacy 32-bit 'serial number' is expressed.

Finally, because of all these issues, we didn't even try to make the
thing unique, so it really ended up being a random snapshot of the state
of the dive computer at the time of a dive, and sometimes we'd pick one,
and sometimes another, since they weren't really well-defined.

So get rid of all this confusion.

The new rules:

 - the actual random dive computer state at the time of a dive is kept
   in the dive data. So if you want to know the firmware version, it
   should be in the 'extra data'

 - the only serial number that matters is the string one in the extra
   data, because that's the one that actually matches what the dive
   computer reports, and isn't some random 32-bit integer with ambiguous
   formatting.

 - the 'device id' - the thing we match with (together with the model
   name, eg "Suunto EON Steel") is purely a hash of the real serial
   number.

   The device ID that libdivecomputer reports in EVENT_DEVINFO is
   ignored, as is the device ID we've saved in the XML or git files. If
   we have a serial number, the device ID will be uniquely associated
   with that serial number, and if we don't have one, the device ID will
   be zero (for 'match anything').

   So now 'deviceid' is literally just a shorthand for the serial number
   string, and the two are joined at the hip.

 - the 'device' managament is _only_ used to track devices that have
   serial numbers _and_ nicknames. So no more different device
   structures just because one had a nickname and the other didn't etc.

   Without a serial number, the device is 'anonymous' and fundamentally
   cannot be distinguished from other devices of the same model, so a
   nickname is meaningless. And without a nickname, there is no point in
   creating a device data structure, since all the data is in the dive
   itself and the device structure wouldn't add any value..

These rules mean that we no longer have ambiguous 'device' structures,
and we can never have duplicates that can confuse us.

This does mean that you can't give a nickname to a device that cannot be
uniquely identified with a serial number, but those are happily fairly
rare (and mostly older ones).  Dirk said he'd look at what it takes to
give more dive computers proper serial numbers, and I already did it for
the Garmin Descent family yesterday.

(Honesty in advertizing: right now you can't add a nickname to a dive
computer that doesn't already have one, because such a dive computer
will not have a device structure.  But that's a UI issue, and I'll sort
that out separately)

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2021-08-18 13:22:02 -07:00
Dirk Hohndel
75fdb8676b core: add downloaded GPS to existing dive site
If we download a first dive computer and add a dive site to the dive (by
setting a location name for example), and then download from another
dive computer that provides us with GPS data, we should keep the
existing dive site information, but add the GPS data from the freshly
downloaded dive computer.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-08-15 09:31:17 -07:00
Richard Fuchs
f308a6b57b export: clean up temp file after divelogs.de upload
This adds a cleanup function to be called after a divelogs.de upload
finishes (successful or not) to make sure the temporary zip file is
closed and removed.

Signed-off-by: Richard Fuchs <dfx@dfx.at>
2021-08-06 11:05:06 -07:00
Richard Fuchs
cf78e4cb20 export: use unique temporary file for divelogs.de upload
On multi-user systems with a shared directory for temporary files, using
a static file name can lead to permissions problems and subsequent
errors due to collisions. Use a random unique file name for each
generated file to avoid these problems.

Note: the temporary file generated from the divelogs.de upload is still
left behind after the upload finishes.

Signed-off-by: Richard Fuchs <dfx@dfx.at>
2021-08-03 08:34:18 -07:00
Dirk Hohndel
096de0efd0 core/import: fix string check logic
The intent of the code was to check that there is a string and it has at least
two characters. Since iter is the result of a strchr(iter, '|') call, we
know that if iter isn't NULL, iter[0] is '|', so we only need to check the next
character.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-07-23 11:30:17 -07:00
Dirk Hohndel
c90352008b core/csv-import: don't do pointer math after realloc
try_to_xslt_open_csv() re-allocates the memory passed in (not really great as
far as design goes, maybe something that should be reimplemented). Doing
pointer arithmatic with the returned base pointer results in garbage, unless
one gets super lucky and the realloc manages to not move the memory.

It's a wonder this ever worked.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-07-23 11:30:17 -07:00
Berthold Stoeger
846e1ba53e core: always create a fake profile if there are no samples
Before making the cylinder-table dynamic, dives always
had at least one cylinger. When such a dive is displayed,
the TabDiveInformation class calls per_cylinder_mean_depth().
If there are no samples, this function generates a "fake
profile" with fake_dc(). Thus, effectively dives always
had samples once the user was displaying them.

When the cylinder-table was made dynamic, dives without
cylinders were supported. This can notably happen, when
importing from CSV (this could actually be a bug).
per_cylinder_mean_depth() exits early in that case and
doesn't create a fake profile. This lead to crashes
of the profile-widget, which were fixed in 6b2e56e513.
Non-sample dives were now shown with the Subsurface-logo.

To restore the previous behavior, genarate a fake profile
for sample-less dives in fixup_dive(), which is called
anytime  a dive is loaded or imported. This seems to
have been the intention anyway and this worked only
"by chance". This will make a few fake_dc() calls obsolete,
but so be it.

Since fake profiles are now generated on loading,
the parse-tests need to be fixed to account for that.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-07-23 11:30:17 -07:00
Berthold Stoeger
63e1516579 core: recalculate CNS values on merge
When merging two dives, the higher CNS value was taken. This could
result in inconsistent CNS values if two dives were merged where
one dive's CNS was calculated from a "fake profile", i.e. a dive
without dive-computer profile. In that case, the most conservative
value (all time spent at the bottom) was assumed. The merged dive
then consisted of the dive-computer profile and the conservative
CNS estimate.

This is fixed by setting the CNS value to "0" after merging,
which means "unknown". The correct value will then be recalculated
in "fixup_dive" from the actual sample data.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-07-23 11:30:17 -07:00
Berthold Stoeger
b18b3119b5 cleanup: don't NUL-terminate membuffer in uploadDiveLogsDE
The data of the membuffer is passed as a data/length pair
to xmlReadMemory(). There is no point in NUL-terminating it.

Moreover, pass the data directly to xmlReadMemory()
instead of via variables. These variables are reused
later with a different meaning, making this super-confusing.

The membuf variable is turned from "const char *" to "char *"
to signal that we own the buffer.

Amazingly, zip_source_buffer() frees the buffer, even though
a "const void *" is passed in. This API is pure madness. Add
a comment.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-07-23 11:22:43 -07:00
Berthold Stoeger
16b31985c3 cleanup: replace membuffer by membufferpp in C-code
Thus, the membuffer data is automatically freed when going
out of scope - one thing less to worry about.

This fixes one use-after-free bug in uploadDiveLogsDE.cpp
and one extremely questionable practice in divetooltipitem.cpp:
The membuffer was a shared instance across all instances
of the DiveToolTipItem.

Remves unnecessary #include directives in files that didn't
even use membuffer.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-07-23 11:22:43 -07:00
Berthold Stoeger
f142e9a9c6 core: C++-ify membuffer
C-style memory management is a pain and nearly nobody seems to get
it right. Add a C++-version of membuffer that frees the buffer
when it gets out-of-scope. Originally, I was thinking about
conditionally adding a constructor/destructor pair when compiling
with C++. But then decided to create a derived class membufferpp,
because it would be extremely confusing to have behavioral change
when changing a source from from C to C++ or vice-versa.

Also add a comment about the dangers of returned pointer: They
become dangling on changes to the membuffer.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-07-23 11:22:43 -07:00
Berthold Stoeger
0c84f369c3 core: use int16_t for sensor-id
The sensor-id in the sample struct was a uint8_t, with all
the known problems of unsigned integers. In the rest of the
code cylinder ids are signed integers. To avoid confusion,
make it a signed int. int8_t should be enough (max. 127
cylinders). To allow for degenerate cases, use an int16_t.
16k cylinders should be enough for everyone.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-07-23 11:16:00 -07:00
Dirk Hohndel
2193f09006 core/ble: add auto detection for Aladin A2
This way it will be recognized as a dive computer when it is scanned via BLE.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-07-20 09:28:38 -07:00
Berthold Stoeger
82f967ddb3 core: sanitize pressure-sensor cylinder ids in fixup_dive()
The code will happily perform out-of-bound accesses if
pressure-sensors refer to non-existing cylinders. Therefore,
sanitize these values in fixup_dive(), which is called
everytime a dive is loaded or imported.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-07-19 10:13:51 -07:00
Berthold Stoeger
361678dcbe parser: don't create samples with invalid cylinder ids
By default, the parser would create samples with cylinder
ids 0 and 1. This creates out-of-bound accesses for the
common one-cylinder (or even no-cylinder) dives. These
were harmless when the cylinder-table was of a fixed size.
Since changing to a dynamic cylinder-table, these became
actual out-of-bound accesses. Don't create such samples
in the parser.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-07-19 10:13:51 -07:00
Berthold Stoeger
7e11a35371 core: add a special NO_SENSOR value for sample::sensor
The sensor member of sample refers to a cylinder from which
the pressure was read. However, some dives don't even have
a cylinder. Therefore, introduce a special NO_SENSOR value
for these dives. Since the cylinder is given as a uint8_t,
0xff seems to be a sensible choice.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-07-19 10:13:51 -07:00
Miika Turkia
48c2929f48 Fix coverity reported memory leaks
Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
2021-07-19 09:07:48 -07:00
Miika Turkia
63795a84f4 Export unused cylinders to divelogs.de
When user has selected to show unused cylinders in equipment tab,
respect this setting when exporting to divelogs.de.

Fixes #3277

Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
2021-07-18 13:43:54 +03:00
mikeller
2d734c529b desktop: Add the capability to copy / paste dive number and date / time.
This is adding the capability to select 'Dive number' and 'Date / Time'
in the 'Copy dive components' dialog, and then copy them into the
clipboard.
When using 'Paste dive components, these values will then be pasted into
the selected dive(s).
This is intended to help with workflows that import dive information
from two different sources, like general information from another
logging program, and CCR ppO2 sensor readings from a unit log, and then
stitch them together into one cohesive entry with all data per dive.
Copied data is also output into formatted text when pasting the
clipboard outside of the application:

```
Dive number: 401
Date / time: Sun 2 May 2021 12:00 AM
```

No translations have been added as of now - I could not find any
information on how strings are translated for this project.

Signed-off-by: Michael Keller <github@ike.ch>
2021-05-19 15:15:34 -07:00
Berthold Stoeger
dc645ce8c6 profile: rename GF_LINE color to DURATION_LINE
The color was misnamed, since it has only been used for the
duration line for quite some time (since 893bea700c to be
exact).

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-05-08 13:40:24 +02:00
Berthold Stoeger
a7002f4089 profile: remove DiveAmbPressureItem
This was replaced by the tissue map in 893bea700c.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-05-08 13:40:24 +02:00
Robert C. Helling
09bbd846da The planner should not always ascent from the depth of
the last manually entered waypoint but consider the
possibility that it should first top where we are
before the next stop depth has cleared.

Reported-by: David Carron

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2021-05-07 08:16:41 -07:00
Linus Torvalds
a0a631122a xml parsing: add XML_PARSE_HUGE flag to xmlReadMemory()
It looks like libxml2 has some internal limitations by default that
causes parse failures in some situations.  Avoid them with
XML_PARSE_HUGE.

Without this, you get errors like

    test.xml:349250: parser error : internal error: Huge input lookup
    όμουν τουλάχιστον αλλά +2kg και ενδεχομένως +4
                                                                                   ^
when something in the xml file grows too large.

I don't know libxml2 internals, so I have no idea what exactly goes
wrong, but the docs say:

    XML_PARSE_HUGE = 524288 : relax any hardcoded limit from the parser

and that makes us successfully parse the Greek file from Kostas.

Reported-by: Kostas Katsioulis <kostaskatsioulis@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2021-04-21 08:39:29 -07:00
Dirk Hohndel
194fe28d50 cleanup: don't hardcode array length
Move the ARRAY_SIZE macro into a header file and use it to determine the
number of cloud servers that we need to check.

Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-04-19 12:51:01 -07:00
Dirk Hohndel
9620d11828 cloudstorage: update remote if cloud server changes
If we can't reach the cloud server in the URL (which might come from the
settings or be passed in by the user), we try the alternative server(s).
If we end up changing servers, we need to update the remote that we have
already parsed from the URL.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-04-19 12:51:01 -07:00
Dirk Hohndel
766f297bc4 cloudstorage: try alternative server if first connection fails
If we can't reach our preferred server, try using a different one.
The diff makes more sense when ignoring white space.

With this we check the connection to the cloud server much earlier and
in case of failure to connect try a different cloud_base_url.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-04-19 12:51:01 -07:00
Dirk Hohndel
cfe20ee5f4 cloudstorage: create consistent local directory names
With the new names for the cloud server we'd get different local cache
directory names depending on which server gets used. In order to avoid
that, normalize the name before generating the hash that determines the
local directory name.

Additionally, the old code had an extra '/' in the URL, due to the way
the URL was assembled. Again, to match the existing hash for people
upgrading from older Subsurface versions, add that to our normalized
name as well.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-04-19 12:51:01 -07:00
Dirk Hohndel
7fa031b648 cloudstorage: try to pick between multiple cloud servers
The backend infrastructure will soon be able to support more than one
cloud server which automagically stay in sync with each other.

One critical requirement for that to work is that once a session was
started with one of the servers, the complete session happens with that
server - we must not switch from server to server while doing a git
transaction. To make sure that's the case, we aren't trying to use DNS
tricks to make this load balancing scheme work, but instead try to
determine at program start which server is the best one to use.

Right now this is super simplistic. Two servers, one in the US, one in
Europe. By default we use the European server (most of our users appear
to be in Europe), but if we can figure out that the client is actually
in the Americas, use the US server. We might improve that heuristic over
time, but as a first attempt it seems not entirely bogus.

The way this is implemented is a simple combination of two free
webservices that together appear to give us a very reliable estimate
which continent the user is located on.

api.ipify.org gives us our external IP address
ip-api.com gives us the continent that IP address is on

If any of this fails or takes too long to respond, we simply ignore it
since either server will work. One oddity is that if we decide to change
servers we only change the settings that are stored on disk, not the
runtime preferences. This goes back to the comment above that we have to
avoid changing servers in mid sync.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-04-19 12:51:01 -07:00
Dirk Hohndel
e22b33795b cloudstorage: add API to just update on-disk setting
This way we can change the host that we will use next time the app runs.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-04-19 12:51:01 -07:00
Dirk Hohndel
c5eb806adb cloudstorage: some cleanup of cloud url handling
We know the preference is never empty, so stop testing for this. But
don't maintain two different preferences with basically the same
content. Instead add the '/git' suffix where needed and keep this all in
one place.

Simplify the extraction of the branch name from the cloud URL.

Also a typo fix and a new comment.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-04-19 12:51:01 -07:00
Dirk Hohndel
da6395a4a8 cloudstorage: remove ancient SSL hack
This was a hack for a very early SSL certificate that was rejected on
some platforms. We haven't used that one in ages, so let's just remove
the whole hack - but always show in the console output when there was an
SSL error.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-04-19 12:51:01 -07:00
Berthold Stoeger
a988e3c135 core: initialize dive selection after resetting the data
The dive selection was initialized during data-reset. However,
this emitted a signal before all data-reset routines were run.
Ultimately, this led to access-after-free in the statistics code.

Instead, move the select_newest_visible_dive() signal from the
divelist-model to the process_loaded_dives() function. There
is no point in initializing the selection if the dive data
is cleared after all.

This change broke closing of the log, because the UI-selection
was not reset. Therefore, when clearing the data, clear the
selection before proceeding with clearing.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-03-31 13:54:23 +02:00
Berthold Stoeger
d0494beb5f planner: fix deco calculation
In 9bfc6d252, testing of the planner was changed to use the
planner_ds parameter instead of a global variable.

Unfortunately, two conditionals were inverted, leading to
an erroneous ceiling calculation when in the planner.

Restore the proper conditions. Moreover, instead of testing
the planner_ds parameter, use the already existing in_planner
flag, which is derived from said parameter.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-03-24 10:30:22 -07:00
Robert C. Helling
7c62f7541c Use PSCR gas when computing O2 toxicity
Both the calculations for CNS and OTU did not take
into account the pO2 drop when using a PSCR. Furthermore,
there was some unit confusion due to not using internal
units.

Reported-by: arosl
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2021-03-12 22:24:23 +01:00
Andreas Buhr
41fc822d56 Use QtBluetooth enums from their namespace
For increased type safety, some enums have been changed to
scoped enums in Qt 6.2, see
https://codereview.qt-project.org/c/qt/qtconnectivity/+/337069
https://codereview.qt-project.org/c/qt/qtconnectivity/+/336678
This patch adapts subsurface to this change.
Since C++11, enums inject their symbols in both their own
and their parent namespace, so this patch can be merged right
now.

Signed-off-by: Andreas Buhr <andreas.buhr@qt.io>
2021-03-12 08:41:31 -08:00
Berthold Stoeger
5ba6db80cc parser: initialize picture variable
When parsing "event 123" (?) a picture is added, without
initializing the picture structure. Thus, a picture with a
random gps location is added.

Use the "empty_picture" initializer to avoid that. Fixes a
Coverity warning.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-03-08 16:29:04 -08:00
Robert C. Helling
345959177f Max ceiling precision
We used to round the ceilings for the individual tissues with
%.1f but the maximal (and thus effective) ceiling only with
%.0f. This makes no sense or be rounded up (to the conservative
side).

This commit shows also the maximal ceiling with higher accuracy.

Reported-by: Peter Hübner
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2021-03-01 21:33:25 +01:00
Robert C. Helling
fdcfcb1b32 Get O2 right in bailout mode
When doing OC bailout from a CCR dive, there could still
be pO2 sensor readings but those are not valid.

This fixes a problem noticed by Justin Ashworth.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2021-02-26 08:42:30 -08:00
Robert C. Helling
2064ce06cc Fix pO2 for CCR at shallow depths
Even when diving a CCR, the pO2 cannot exceed ambient
pressure. This only makes a difference at shallow depths.

Fix this in the calculation of OTUs and CNS.

This affects some tests that now have slightly different CNS and OTU values.

Suggested-by: Justin Ashworth
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2021-02-26 08:42:30 -08:00
Robert C. Helling
6b8a07f0d9 Planner: Depth dependent setpoint changes in CCR mode
We had a user request to allow for setpoint changes
at certain depths for CCR deco.

You can now enter a cylinder with name like
"SP 1.4" ('S' and 'P' and ' ' and a float) with
a switch depth and that cylinder is interpreted as
a depth dependent setpoint switch.

This user interface is a hack. But I believe that such
setpoint changes are similar enough to gas switches during
deco and should thus be handled in a simiar manner.

I would be happy to hear ideas how this could be made
less easter eggish.

Suggested-by: Justin Ashworth
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2021-02-26 08:42:30 -08:00
Berthold Stoeger
5b3cb5898f desktop: fold ApplicationState into MainWindow
The application state is a desktop-only thing. The mobile UI
also has its application state, but that is something completely
different.

The last remaining user of the application state was to flag
whether the planner is active. Since this has all been
unglobalized, the ApplicationState structure can be moved
from core to the desktop UI. And there it can be made local
to the MainWindow class.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17 07:26:55 -08:00
Berthold Stoeger
42cff9b3a5 planner: pass in_planner down to TemplateLayout
The TemplateLayout prints different dives depending on
whether the planner is active. Instead of accessing a
global variable, pass the status down from the MainWindow.
That's all quite convoluted, since there are multiple
layers involved.

On the positive side, the in_planner() function has now
no users an can be removed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17 07:26:55 -08:00
Berthold Stoeger
642d9c80b3 planner: pass in_planner argument to decoMode()
To remove reliance on global state, pass an "in_planner" argument
to decoMode(). Thus, calls to in_planner() can be removed.

This is a more-or-less automated change. Ultimately it would
probably be better to pass the current deco-mode to the affected
functions instead of calling decoMode() with an in_planner
parameter.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17 07:26:55 -08:00
Berthold Stoeger
03a7e65cf0 planner: pass in_planner argument to clear_deco()
To remove reliance on global state, pass an "in_planner" argument
to clear_deco(). Thus, calls to in_planner() can be removed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17 07:26:55 -08:00
Berthold Stoeger
8103e947aa planner: pass in_planner argument to vpmb_next_gradient()
To remove reliance on global state, pass an "in_planner" argument
to vpmb_next_gradient(). Thus, calls to in_planner() can be removed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17 07:26:55 -08:00
Berthold Stoeger
93ecad1b04 planner: pass in_planner argument to add_segment()
To remove reliance on global state, pass an "in_planner" argument
to add_segment(). Thus, calls to in_planner() can be removed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17 07:26:55 -08:00
Berthold Stoeger
9fb37ea27f planner: remove print_mode parameter from calculate_deco_information()
Only 'false' was ever passed as value.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17 07:26:55 -08:00
Berthold Stoeger
b3e4c9c8da desktop: cache photo and geo icons
The icons shown in the dive list were rendered for every single
access. Render them only once. This supposes that the
defaultIconMetrics structure does not change once the icons are
rendered!

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-10 14:33:15 -08:00
Berthold Stoeger
1ed2f1681a desktop: remove the view-state
There was the "application state", which decided what to show
in the "quadrants" and the "view state" which decided which
quadrant to show. These interacted in a hard-to-grasp way.

The "view state" is used to show the map or dive list in
full screen.

I simply couldn't get these two orthogonal states to interact
properly. Moreover the thing was buggy: If a quadrant was hidden,
the user could still show it, by dragging from the side of the
window, at least under KDE.

To solve these woes, merge the two states into a single
application state. If the widget of a quadrant is set to null,
don't show it. So the four "view states" are now "application
states" where three of the four quadrants are not shown.

This also changes the memory management of the widgets:
widgets that are not shown are now removed from the QSplitter
objects. This makes it possible that the same widget is
shown in *different* quadrants.

While writing this, I stumbled upon a Qt bug, which is known
since 2014:
https://forum.qt.io/topic/43176/qsplitter-sizes-return-0

When restoring the quadrant sizes there was a test whether
the quadrant size is 0. If that was the case, a default size
was set. This seems not to work if the widgets were recently
added. Since this test now always fails, make the quadrants
non-collapsible and thus guarantee that 0 is never saved as
a size.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-06 10:00:39 -08:00
Dirk Hohndel
805a2388af core/BT: fix duplicate entries in BT detection
Somehow three identical lines snuck into commit 0a4e37ee8b ("core/BT: simplify
detection of bluetooth names").

Reported-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-28 12:51:19 -08:00
Dirk Hohndel
0a4e37ee8b core/BT: simplify detection of bluetooth names
Instead of that super long if-else if chain, have something more
structured using a table for the common case of prefix based names.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-23 14:35:32 -08:00
Dirk Hohndel
4a6ef023db core/BT: improve BT name detection for Pelagic dive computers
It would be so much nicer if we could just let libdivecomputer do this,
but the filter function there doesn't quite do things the way we need
them to be. Which is why we have our own function here.

This is a small attempt to rationalize the code that we have to make it
easier to maintain.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-23 14:35:32 -08:00
Dirk Hohndel
64dea827bd mobile/debugging: copy GPS fixes to clipboard
The goal is to enable a user experiencing crashes when applying GPS data
to their dive log to make all necessary data available to the
developers. Hopefully the clipboard is large enough to hold all the
data.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-23 13:19:11 -08:00
Berthold Stoeger
84f48b7290 cleanup: constify create_plot_info_new()
This only read accesses the dive and constructs a plot-info
structure. Make the dive parameter const.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-20 10:01:50 -08:00
Berthold Stoeger
8d423359a5 cleanup: constify populate_pressure_information()
This has only read access on the dive. Make the parameter const.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-20 10:01:50 -08:00
Berthold Stoeger
ad1e57dd67 cleanup: constify init_decompression()
This function initializes decompression data from a dive.
The dive is not modified, therefore make it const.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-20 10:01:50 -08:00
Dirk Hohndel
323e97c603 mobile/UI: remember the system default font size
We need to do this before the preferences are loaded, or the system
default size is lost. Given that our other sizes are all relative to
this value, that would be a problem.

With this we can now ensure that we always have the right font size for
smaller, regular, and larger theme settings.

Also removes some obsolete commented out code.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-19 12:35:29 -08:00
Dirk Hohndel
1472117541 cleanup: create separate UI entry points for desktop and mobile
This doesn't really change anything, but makes the code easier to read.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-19 12:35:29 -08:00
Doug Junkins
31e26fd144 mobile: add GF fields for ceiling calculation
Adds fields to the advanced preferences page to modify GFLow and GFHigh for
the Buhlmann decompression model for calculating ceilings. Updated preferences
code to set the Buhlmann parameters in core/deco.c when the GF prefs are
updated.

Signed-off-by: Doug Junkins <douglas.junkins@gmail.com>
2021-01-19 12:34:46 -08:00
Dirk Hohndel
bf556da81a core/bluetooth: make device discovery less noisy
This mainly combines reasonably redundant text to make the output easier
to read.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-13 16:16:31 -08:00
Dirk Hohndel
702d09df9f mobile/GPS: fix two errors in the GPS handling
First, the time zone adjustment was wrong - this as written could only
ever have worked in UTC or by pure chance.

Second, the order of alerting the UI of the availability of a GPS fix
was also incorrect creating a race between the UI and our data
structures.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-13 13:52:00 -08:00
Berthold Stoeger
1a0f6f53ed undo: set dive mode to CCR in undo command, not profile code
When setting a CCR setpoint, the profile code(!) would turn
the dive into a CCR dive. Not only should the display layer
not alter dives, this also means that the action is not
undoable.

Move that to the appropriate undo command, where it makes
more sense, but obviously also makes things more complicated.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-11 09:31:36 -08:00
Berthold Stoeger
cd32c280ae undo: remove invalidate_dive_cache() call from make_first_dc()
The make_first_dc() function clones a dive with a certain dive
computer moved to the front. This is used by the
MoveDiveComputerToFront undo command.

make_first_dc() calls invalidate_dive(). However, the undo
command does that by itself on every undo/redo. Thus,
remove the call in make_first_dc().

Aside from consistency, the goal is to move invalidate_dive()
to command/* so that we can be more aggressive about the whole
topic: Store only "const dive *" pointers and thus force any
writing access to explicitly invalidate the dive cache.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-11 08:42:17 -08:00
Dirk Hohndel
6add24fe3e mobile: enable deco information calculation on mobile
This simply allows us to calculate the information, it doesn't do
anything to actually display it, yet.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-10 15:57:39 -08:00
Berthold Stoeger
235146a95f profile: pass dive to DiveHandler
The DiveHandler shows a context menu where a cylinder can be
chosen. This indirectly accesses the global displayed_dive
variable.

Remove this in a step to make the profile reentrant.

The code was quite ominous: instead of simply generating the
list of cylinders, a global model was reset and then accessed
with Qt's cumbersome model/view API. All this trampling over
global state can be removed by simply making the function
that generates the list globally accessible.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-10 15:57:39 -08:00
Berthold Stoeger
88c6ce988d profile: pass dive to RulerItem
Instead of accessing the global displayed_dive variable
in RulerItem, pass the dive. This is a step in making the
profile reentrant.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-10 15:57:39 -08:00
Berthold Stoeger
54e8fe5d9e profile: pass dive to ToolTipItem::refresh()
Don't access the global displayed_dive variable in a step
to make the profile reentrant.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-10 15:57:39 -08:00
Berthold Stoeger
193513a61f profile: pass dive to plot function of profile-items
Instead of accessing the global displayed_dive variable,
pass the dive to the various profile items. This is a
step in making the profile code reentrant.

This removes the last user of the displayed_dc macro,
which can now be removed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-10 15:57:39 -08:00
Berthold Stoeger
be9f9efb0e profile: pass dive to EventItem
Don't access the global displayed_dive variable in an effort
to make the profile reentrant.

Note that this still accesses the global dc_number variable,
which will likely have to be removed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-10 15:57:39 -08:00
Berthold Stoeger
09287809eb profile: move adding of ceiling-violation-event
The profile item that shows the ceilings adds a warning event
if the ceiling is violated. This is very unfortunate.

Improve this situation by adding the event up to the function
that calculates the ceiling. This is still not how it should
be - the display layer should not modify the dive that it
displays.

To make this clear, add a comment that details that this
is a contract between planner and display layer: The planner
uses a dive that can be trampled upon by the profile.
Still, this should be solved differently.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-10 15:57:39 -08:00
Berthold Stoeger
9bfc6d2520 profile: use a parameter to determine planner state
The in_planner() function is incompatible with a reentrant
profile, since it accesses a global variable. In
create_plot_info_new() it is essentially redundant, because
there is a planner_ds (ds = deco_state) parameter that
is used only when in the planner. Therefore use that as
the in_planner indicator: when non-null, the profile is
showing a planned dive.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-10 15:57:39 -08:00
Berthold Stoeger
94a57d9a1d cleanup: make calculate_deco_information() of static linkage
This function was not used outside of profile.c

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-10 15:57:39 -08:00
Damian Zaremba
bd6c874be0 btdiscovery - Add second matcher for Ratio iX3M
New (late 2020) iX3M hardware (refered to as 'iX3m with Sequared Buttons'
in the Ratio support section) appears to identify as iX5M, both in the
Bluetooth name and reported revision e.g.

$ ./ratio-toolbox-x86_64.AppImage info | head -n2
Model: Ratio® iX5M GPS TECH+
Firmware version: 4.1.26/016 (English)

Add a second Bluetooth name matcher for this variation, returning the same
(generic) model as is currently used.

Signed-off-by: Damian Zaremba <damian@damianzaremba.co.uk>
2021-01-10 13:44:16 -08:00
Dirk Hohndel
76136010bf preferences: remove pointless member
This could never have worked the way it was used.

Some whitespace fixes snuck into this commit.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-06 10:18:23 -08:00
Berthold Stoeger
106f7a8e0e desktop: add statistics widget dummy and application state
Add a new "statistics" application state. In the statistics state
show the statistics widget and the filter in the top quadrants.
The idea is to allow filtering and doing statistics at the same
time.

Sadly, we can't use the filter-widget in different quadrants,
because Qt's ownership model is completely broken / inflexible.
It does not support a widget having different parents and
thus a widget can only belong to one QStackedWidget.

Hiding the map in the statistics view is quite hacky:
Since the view of the quadrants is not determined by the
"ApplicationState", we have to restore the original quadrant
visibility when exiting the stats mode. Therefore, set the
original visibility-state when changing application state.

The MainWindow-quadrant code really needs to be rewritten!

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-03 13:41:15 -08:00
Dirk Hohndel
5048a695aa mobile: turn GpsLocation into a regular singleton construct
Simply move the initialization of the logging function into its own method and
call that in the QMLManager constructor.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-02 12:47:15 -08:00
Berthold Stoeger
fdde4c23ea cleanup: move pref related structs and functions to pref.c
These were declared in pref.h and defined in subsurfacestartup.c.
pref.c didn't even exist. Create it and move preferences-related
structs and functions there.

setup_system_prefs() is left in subsurfacestartup.c, since it
works with environment variables.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-02 10:26:29 -08:00
Berthold Stoeger
91ffa5a59a cleanup: move definition of get_units() to core/unit.c
The function is declared in core/unit.h, therefore it seems logical
to define it in the corresponding source file.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-02 10:26:29 -08:00
Berthold Stoeger
966cd873c5 cleanup: remove support for PASCAL in get_pressure_units()
The user preferences can never end up with PASCAL pressure
units. The only place that uses these units is the XML parser.
Therefore, remove the PASCAL case in get_pressure_units().
This will remove an unused translation string.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-02 10:26:29 -08:00