Commit graph

2697 commits

Author SHA1 Message Date
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
Berthold Stoeger
18acb85a01 cleanup: don't save PASCAL pressure units to git
The way I understand, the PASCAL pressure unit is used to parse
obscure dive logs. However, there is no support in the UI for
using Pa as pressure unit. Therefore remove reading / writing
this unit to git divelogs.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-02 10:26:29 -08:00
Dirk Hohndel
b79114c5d0 cleanup: ensure DiveFilter is consistent when created
Otherwise we might access an uninitialized member.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2021-01-01 12:38:50 -08:00
Berthold Stoeger
b02847de53 core: add get_*_unit functions with explicit unit system
The get_*_unit() functions return the unit-name as set in
the preferences. Add versions with a "metric" parameter.

This will be used by the statistics code, which may in
the future allow for binning with alternative units.

All the unit-formatting functions should probably be moved
away from qthelper to their own source file.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-01 21:10:10 +01:00
Berthold Stoeger
e23d103c5d core: move formatting of day-of-week to string-format.cpp
This was only used by the filter, but will also be used
by the statistics module. To avoid duplicate translation
strings, move to a common place.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-01 21:10:10 +01:00
Berthold Stoeger
b0b52d51bd core: add "transparent" parameter to renderSVGIcon
The start-selection widget will need icons with a transparent
background so that the icons don't stick out like a sore thumb.

So far the icons rendered by this function were only used by
the images on the profile and were perfectly rectangular.
Therefore there was no need for this.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-01 21:10:10 +01:00
Berthold Stoeger
60999e3a39 core: make gasmix_is_invalid globally accessible
The statistics module will use that to bin dives by gasmix.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-01 21:10:10 +01:00
Berthold Stoeger
1270d94701 core: add notion of gas-type to core/gas.c
Create a gastype enum, which describes the type of a gas.
For now: air, nitrox, normoxic, trimix and oxygen.

This probably should be made configurable.

The gas types will be used to bin gasses in the statistics
module.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-01 21:10:10 +01:00
Berthold Stoeger
1d93926700 core: move renderSVGIcon() to qthelper.cpp
The renderIcon() function was used by the thumbnailer to
render SVG-based icons. Move it to the global qthelper.cpp
so that it can also be used by the statistics module.
Add "SVG" to the name to emphasize what it is used for.

For consistency also move the renderSVGIconWidth() function,
which renders to a fixed width, to qthelper.cpp

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-01 21:10:10 +01:00
Berthold Stoeger
6b46e8ae57 cleanup: const-ify utc_mktime()
To make it clear that the struct tm is only used as an input
parameter.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-29 08:34:09 -08:00
Berthold Stoeger
4c85357dcc cleanup: move monthname to time.c
Weirdly, this function was declared in dive.h and defined in
subsurface-startup.c. Let's move declaration and definition to
more appropriate places, viz. subsurface-time.h and time.c.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-29 08:34:09 -08:00
Berthold Stoeger
bbbd4c8818 cleanup: remove getDivesInTrip() in qthelper.cpp
This function was not used anywhere. Moreover, remove a few
unused includes from qthelper.h. Surprisingly, a number of users
of qthelper.h depend on these, so readd them at the appropriate
places.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-29 08:34:09 -08:00
Berthold Stoeger
8758b95881 filter: provide function that returns all shown dives
This will be used by the statistics widget.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-29 08:34:09 -08:00
Berthold Stoeger
c53bab8965 filter: internalize shown_dives in DiveFilter class
one piece of global state removed!

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-29 08:34:09 -08:00
Berthold Stoeger
51d0c42a5c filter: move shown_dive from divelist.c to divefilter.cpp
Arguably, the number of filtered dives is a matter of the divefilter.
Let's move it there.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-29 08:34:09 -08:00
Berthold Stoeger
9e84fd935b filter: keep track on shown_dive on dive removal in DiveFilter
When removing dives, the UndoCommands would keep track of the
shown dives. When adding, they were calling into the filter
instead. Let's remove this asymmetry.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-29 08:34:09 -08:00
Berthold Stoeger
e80c0d2c60 filter: reset shown_dives in filter
The shown_dives variable was reset by the dive_list code. Arguably,
the filter should keep track of the number of shown dives, so move
the resetting there. This means adding a new "reset()" member function
to the filter and call that instead of "updateAll()" when the core
data is reset.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-29 08:34:09 -08:00
Berthold Stoeger
79f95b7f7d core: remove DiveObjectHelper
Since switching to the mobile-models and removing grantlee,
DiveObjectHelper was demoted to a thin wrapper around string
formatting functions. The last user was removed in a previous
commit.

It was never a good idea, given QML's strange memory-management.
Let's remove it.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17 13:03:56 -08:00
Berthold Stoeger
1037c15b98 mobile: remove DiveObjectHelper code
When editing a dive, a DiveObjectHelper of the unmodified dive
was created to compare the edited with the old values. Since
the DiveObjectHelper is used here only as a pointless wrapper
around the formatting functions, call these functions directly.

However, note that the code is in principle wrong since the
change to the mobile-models, which do not use the DiveObjectHelper.
The real fix would be to reload the data from the model to prevent
going out-of-sync with respect to the formatting routines!

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17 13:03:56 -08:00
Berthold Stoeger
cc5ebd7414 printing: remove CylinderObjectHelper
With the removal of grantlee, this became pointless glue
code. Call the formatting functions directly.

Since the printing code was the only user of CylinderObjectHelper,
remove the whole thing.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17 13:03:56 -08:00
Berthold Stoeger
ae182c386b printing: remove DiveObjectHelper from printing code
At this point (post grantlee), DiveObjectHelper is just pointless
glue code. Let's remove it from the printing code and call the
formatting functions directly. If necessary, move these functions
to core/string-format.cpp.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17 13:03:56 -08:00
Berthold Stoeger
d9942269a9 printing: remove DiveObjectHelperGrantlee
This was a weird helper object, needed for grantlee. Instead
of storing this object, loop over cylinders and dives directly.

The actual accessor function is unchanged and now generates
a DiveObjectHelper or DiveCylinderHelper for every variable
access. Obviously, this is very inefficient. However, this
will be replaced in future commits by direct calls to formatting
functions.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17 13:03:56 -08:00
Berthold Stoeger
bf8261c001 core: create string-format.cpp source file
The mobile version of the list used string formatting functions
defined in DiveObjectHelper and declared in mobilelistmodels.h.
Very confusing. Move them to a separate source file where - in
the long run - all the string-formatting functions, which
are scattered all over the place, can be collected.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-12-17 13:03:56 -08:00
Berthold Stoeger
daebd0ad0e core: correct AL* tankinfo sizes.
Recently (d16a9f118a) the tankinfo table was made dynamic, which
means that the default tankinfos are added programatically.
Thereby, the wrong function was used for AL* type of cylinders:
metric instead of imperial. Fix those.

Reported-by: Michael Andreen <harv@ruin.nu>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-17 08:10:56 -08:00
Berthold Stoeger
296a391faa prefs: add option to display only actually used tanks
A user complained about the default cylinders list. Provide
a preferences option to turn this off.

When changing the preferences, the tank-info model will be
completely rebuilt. Currently, this is a bit crude as this
will be done for any preferences change.

Suggested-by: Adolph Weidanz <weidanz.adolph@gmail.com>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-13 11:49:59 -08:00
Berthold Stoeger
11e576ffbf core: remove the "no-name" tank info
There was a tank info with an empty name. According to a comment,
this is needed for the "no cylinder" case. However, we now support
empty cylinder tables, so this is not needed anymore. Therefore,
remove it.

Make sure that the user can still enter the empty name, just in
case. But don't save the size and pressure in that case.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-13 11:49:59 -08:00
Berthold Stoeger
d16a9f118a core: free tank info table on exit
This is obviously a pure code-hygiene thing. But with the new
dynamic tank info table, this becomes trivial, so let's do it.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-13 11:49:59 -08:00
Berthold Stoeger
50b11024d6 core: keep tank infos in a dynamic table
The list of known tank types were kept in a fixed size table.
Instead, use a dynamic table with our horrendous table macros.
This is more flexible and sensible.

While doing this, clean up the TankInfoModel, which was leaking
memory.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-13 11:49:59 -08:00
Berthold Stoeger
2d7be7a0e3 preferences: create global settingsChanged signal
So far, the PreferencesDialog emitted a settingsChanged signal.
This meant that models that listened to that signal had to
conditionally compile out the code for mobile or the connection
had to be made in MainWindow.

Instead, introduce a global signal that does this and move
the connects to the listeners to remove inter-dependencies.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-12 15:52:40 -08:00
Robert C. Helling
e7a18456c9 Add surge etc to printing template variables
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2020-12-12 16:37:29 +01:00
Robert C. Helling
df9a52d857 downloader: filter possible devices and add mounts, remember last choices
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2020-12-03 13:26:55 -08:00
Dirk Hohndel
eac59a79d8 build-system/downloader: cli-downloader isn't part of the core
It's part of the main excutable / helper and needs to be linked before
all of our support libraries.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-12-03 13:26:55 -08:00
Robert C. Helling
faf4736675 downloader: turn off bluetooth mode for now
Eventually, this should also be set from the command line.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2020-12-03 13:26:55 -08:00
Robert C. Helling
b39e77071e downloader: small improvements
Provide supported dive computer list on the command line
and actually call the cli download. Still not functional.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2020-12-03 13:26:55 -08:00
Dirk Hohndel
31f0741ecc downloader: first outline of downloading dives from a device
This is of course not functional at all, but it gives a first idea of
what we will need to do in this code.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-12-03 13:26:55 -08:00
Dirk Hohndel
25d7c58c07 downloader: first step to get instructions via CLI
This still doesn't do a thing, but at least it seems to get the
information closer to where we want it.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-12-03 13:26:55 -08:00
Dirk Hohndel
057c151fe8 build-system: start adding a headless build
Right now this doesn't do a thing, but it gives us a nice target that
has far fewer dependencies and should contain enough parts to download
stuff from a divecomputer and then sync that with cloud storage.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-12-03 13:26:55 -08:00
Berthold Stoeger
b36178a00a cylindermodel: remove in_planner() use
in_planner() is problematic, since it is uses desktop-only
application state. Since the cylinder-model already has
an appropriate inPlanner flag, use this instead.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-11-24 10:54:10 +01:00
Dirk Hohndel
f4ef9565a7 android: find the translations
As we switched to the qmake based build we now bundle the translations
via the Qt resource system instead of explicitly as Android assets. This
adjusts the code that opens the translations accordingly.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-11-23 08:30:57 -08:00
Dirk Hohndel
47c837cc42 core/picture: don't compile all on mobile
We don't support adding pictures and videos on mobile, so let's not
referernce the infrastrutcture that's needed for that.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-11-19 17:18:33 -08:00
Dirk Hohndel
d6d3c9a02f core: fix incorrect QString::asprintf/vasprintf usage
These are static functions, they cannot be used as a method on an object to
construct that object.

commit aa5f2e7c73 ("cleanup: replace deprecated sprintf()/vsprintf() calls")
introduced this bug in an ill-advised attempt to deal with a deprecation
warning.

This caused us to not print GPS coordinates in the UI.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-11-17 12:56:40 -08:00
Berthold Stoeger
52d5125926 undo: add a general dives-imported signal
Add a general dives-imported signal for those cases where we
want to fully rebuild models, notably, the completion models.
The divesAdded signals are too fine, because they are sent
per trip and we don't want to reload these models multiple
times per import.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-11-14 10:01:50 -08:00
Robert C. Helling
10bedf02d0 Gracefully handle infinite MND for oxygen
When breathing pure oxygen and considering it not
narcotic, there is not maximal narcotic depth and
the formula divides by zero. So better, handle this
case separately.

Fixes #3080

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2020-11-13 11:10:48 -08:00
Dirk Hohndel
10a026b2ff filter: avoid Windows crash
The scope confusion between s (the for loop variable) and s (the function
argument) caused a crash in the s.split() on Windows.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-11-12 07:46:52 -08:00
Berthold Stoeger
04149623c1 core: don't construct std::string from null in device.cpp
Recently the QStrings were replaced by std::strings in device.cpp
so that they can be accessed from C-code. However, libstd being
modelled after C, constructing a std::string from a NULL pointer
leads to a crash.

Fix one case where this was overlooked.

Moreover, replace a null-pointer check by empty_string(), to
treat NULL and "" equally.

Reported-by: Salvador Cuñat <salvador.cunat@gmail.com>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-11-04 15:53:15 -08:00
Dirk Hohndel
be3190db8a revert preference settings for title color
Because of subsequent changes there is no clean way to just revert the changes
introduced in commit 8b36cf1051 ("desktop: offer different colors for info tab
titles"), so this manually removes the parts we don't need anymore.

This also restores a tooltip value that was inadvertantly removed in that
commit.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-11-04 14:51:55 -08:00
Dirk Hohndel
00dd98163f cleanup: random small whitespace cleanup
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-11-03 23:08:39 -08:00
willemferguson
8b36cf1051 desktop: offer different colors for info tab titles
Add a preference option to set the color of the text on the information tab to
either MediumBlue, LightBlue or Black. The last two of these colors are meant
to enable areadable font contrast on displays with dark mode.
The choice is saved with the other preferences.

[Dirk Hohndel: this isn't really about dark mode, so changed many of the types
	       and variable names, changed the user visible texts, and
               addressed some whitespace issues]

Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-11-03 23:08:39 -08:00
Berthold Stoeger
386e08b69c parser: don't crash when parsing <weight> tags
When encountering a <weight> tag, we would parse into the last
weightsystem. However, we only create weightsystems when
encountering <weightsystem> tag. Therefore, this code would
either crash or overwrite the previous weightsystem.

Instead, create a new weightsystem for each <weight> tag.

Moreover, make sure that inside a <weightsystem> tag a
weightsystem actually exists. This should be the case,
but who knows...?

Reported-by: Nihal Gabr <gabr.nihal@gmail.com>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-11-01 10:59:39 -08:00
Berthold Stoeger
b2b3544f3f core: on import remove merged dives from trip/divesite
When dives were merged on import, they were not unregistered
from their dive site and trip before being deleted. Thus, these
tables had stale pointers, which would ultimate lead to crashes.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-31 23:20:59 -07:00
Berthold Stoeger
d747d76762 cleanup: refactor subsurfacesysinfo.cpp
This used to be a copy of QSysInfo. However, once the requirement
was raised to Qt5.4, this was replaced by a subclass of the original
QSysInfo - which made the whole file mostly obsolete.

Just use QSysInfo directly where needed.

Only for windows.c, which can't call directly into Qt, keep the
isWin7Or8() helper function.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-27 16:18:09 -07:00
Dirk Hohndel
369baa5b74 cleanup: move variable declaration closer to use
This way we avoid an unused variable warning on mobile builds.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-10-26 19:27:03 -07:00
Dirk Hohndel
7fb4dd7a03 cleanup: remove unused function argument
Also, only compile the static function where it is used.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-10-26 19:27:03 -07:00
Dirk Hohndel
ffecc00f42 cleanup: SkipEmptyParts syntax has changed
Sadly, the new enum has only been available since Qt 5.14, so this is a rather
ugly replacement.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-10-26 19:27:03 -07:00
Dirk Hohndel
aa5f2e7c73 cleanup: replace deprecated sprintf()/vsprintf() calls
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-10-26 19:27:03 -07:00
Dirk Hohndel
484a50b6a8 cleanup: initialize all members of weightsystem
The auto_filled member was recently added and not initialized in the UEMIS
downloader.

Fixes CID 362080

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-10-26 19:27:03 -07:00
Dirk Hohndel
0d733747d1 cleanup: fix resource leak
Fixes CID 362078
Fixes CID 362081

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-10-26 19:27:03 -07:00
Dirk Hohndel
77195ccb88 cleanup: fix resource leak
And address typo in comment.

Fixes CID 362915

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-10-26 19:27:03 -07:00
Berthold Stoeger
e7b56c2d31 filter: use 64-bit integer literal for generating bit fields
For multiple-choice constraints we use a bit field of type
uint64_t. This means we theoretically support up to 64 items.
Currently use at most seven.

Coverity complained (correctly) that we use the expression
"1 << x" to generate the bitfields. However 1 is a 32-bit
literal on most platforms, which makes this undefined
behavior for x >= 32. Change the integer literal to 64-bit
1ULL.

Moreover, when detecting items with an index >= 64, don't
even attempt to set the according bit, since this is
undefined behavior and the compiler is free to do as it
pleases in such a case.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 16:23:46 -07:00
Berthold Stoeger
b984839836 cleanup: remove pref.h include in dive.h
If source files want to access preferences functions, they should
include pref.h themselves.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:52 -07:00
Berthold Stoeger
a719bfbeaf cleanup: move git-pref declarations into core/pref.h
These seem to be an artifact.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:52 -07:00
Berthold Stoeger
975ef65913 cleanup: move sort_dive_table declaration to divetable.h
Apparently this was forgotten in a previous include-reshuffling.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:52 -07:00
Berthold Stoeger
f2494931e9 cleanup: move cylinder_use_text declaration to equipment.h
This is unrelated to struct dive and also wasn't defined in
dive.c

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:52 -07:00
Berthold Stoeger
df4c0ed403 cleanup: remove unused macros / declarations from dive.h
Nobody was using these return-code macros and the functions
do not exist since a long time.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:52 -07:00
Berthold Stoeger
f728923c79 cleanup: move interpolate inline function to its own header file
This is not really related to struct dive, so let's move it.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:52 -07:00
Berthold Stoeger
f9c3227975 cleanup: remove system includes from dive.c
Let the various source files include the system headers they need
themselves.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:52 -07:00
Berthold Stoeger
2b86fe84f9 cleanup: move application flags to core/subsurfacehelper.h
These flags are not dive-related, therefore move their declaration
to the appropriate header file. Likewise, move their definition
from parse-xml.c to subsurfacehelper.c

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:52 -07:00
Berthold Stoeger
17d21dbf40 cleanup: move function declarations to divelist.h
unregister_dive() and delete_single_dive are defined in
divelist.c, as they take an "index" argument into the global
divelist. Therefore, move their declarations to divelist.h.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:52 -07:00
Berthold Stoeger
0e196310f9 cleanup: split out divecomputer functions from dive.c
Since dive.c is so huge, split out divecomputer-related functions
into divecomputer.[c|h], sample.[c|h] and extradata.[c|h].

This does not give huge compile time improvements, since
struct dive contains a struct divecomputer and therefore
dive.h has to include divecomputer.h. However, it make things
distinctly more clear.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:52 -07:00
Berthold Stoeger
4aa571d5a0 cleanup: remove get_times() functions
The function
1) was misnamed: it determined the time of the first selcted dive.
2) had only one caller.
3) would crash if there was no selected dive.

Let's just fold the functionality into the caller. It's a one-liner
anyway.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:52 -07:00
Berthold Stoeger
464dd93fe8 cleanup: move fill_pressures from dive.c to gas.c
This function does not access a dive structure.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:52 -07:00
Berthold Stoeger
8212acc992 cleanup: break out event-related code into event.[c|h]
In an effort to reduce the size of dive.h and dive.c, break out
the event related functions. Moreover event-names were handled
by the profile-code, collect that also in the new source files.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:52 -07:00
Berthold Stoeger
3358bff432 cleanup: move mark_divelist_changed() to qmlmanager.cpp
Desktop does not use mark_divelist_changed() anymore - all is done
via the undo machinery. Therefore move this function (and its
counterpart unsaved_changes()) to qmlmanager.cpp.

Ultimately, it probably should be removed from there as well, but
currently I don't dare to touch all the cloud-logic!

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:04 -07:00
Berthold Stoeger
3a2f1b17b6 devices: add index based device removal function
The undo machinery will need a method to remove devices based
on their index instead of their name. Add it.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:04 -07:00
Berthold Stoeger
faebb53909 undo: add device related undo commands
Add commands for deleting devices and editing device nicknames
to include the device-handling in the undo system.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:04 -07:00
Dirk Hohndel
572e2678a0 cleanup: initialize all fields
This doesn't appear likely to cause an issue, but also doesn't
seem wrong.

Fixes CID 350734

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-10-25 13:58:03 -07:00
Dirk Hohndel
8e330f297e cleanup: fix over-eager Coverity warnings
Technically get_dive() could return a nullptr. The existing code made sure the
argument passed to get_dive() was one that always would result in a valid dive
pointer being returned. The new code is only slightly less efficient but allows
a static code analysis to easily see that we don't derefence NULL pointers here.

On some level this change is unnecessary. But it's also not wrong.

Fixes CID 354762

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-10-25 13:58:03 -07:00
Berthold Stoeger
272b7b3e27 cleanup: remove double const qualifier
The redundant qualifier was introduced in an erroneous rebase.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 09:59:36 +01:00
Berthold Stoeger
b7a586a5b4 core: remove create_device_node() from fixup_dive()
The device nodes are created for all DCs, when importing the
dives. There is no point in creating only the device node for
the first DC in fixup_dive().

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-24 09:51:37 -07:00
Berthold Stoeger
74d84a959a divecomputer: add device to provided table instead of global table
In the specuial case of suunto, where we may add a device directly
instead of via dive->dc, add the device to the provided table.
The caller will then pass on the new device to the undo system.
This makes downloading finally really undoable (at least I
hope so). So far, the dives and dive sites were removed, but any
new device remained.

However, when setting the device-id via serial, we now have
to check both, the global and the downloaded list of devices.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-24 09:51:37 -07:00
Berthold Stoeger
2bcb3d88a0 divecomputer: add device_table pointer to device_data_t
In one weird case (suunto), the code in libdivecomputer.c
generates a device node directly instead of going the usual
way (setting the data in the dc-structure of the imported
dive). It is unclear to me whether that has to be that way,
as it depends on the chronological order of callbacks to
event_cb() and dive_cb().

Therefore add a device_table pointer to device_data_t
so that the downloader can add the device to this table. This
only adds the pointer, but does not yet use it in the
downloading code.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-24 09:51:37 -07:00
Berthold Stoeger
5a19437311 cleanup: remove dc_user_device_t
The same structure was defined as "struct dc_user_device_t"
and typedefed as "device_data_t". Unify this. Since there
are much more of the latter, remove the former.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-24 09:51:37 -07:00
Berthold Stoeger
8c65558b5c devices: create device nodes in parsers
So far, we added a non-global device table to the parser states.
Now, create device nodes in that table instead of in the global
table. Thus, on undo of dive-import, the new device nodes will
be removed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-24 09:51:37 -07:00
Berthold Stoeger
255f561aff git: add device-table to git-parser-state
In analogy to the xml-parser add a device-table to git's parser-state.
Currently this is unused. In upcoming commits the git parser will
then be changed to add device nodes in this table instead of the
global device table. The long-term goal being to detach the
parsers from global state and to make dive-import fully undoable.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-24 09:51:37 -07:00
Berthold Stoeger
694776eed1 cleanup: rename set_dc_nickname() to add_devices_of_dive()
The function was misnamed in that it doesn't set the nickname
of a device. Instead, it adds all (unknown) devices of a
dive to the/a device-table. Let's call it appropriately.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-24 09:51:37 -07:00
Berthold Stoeger
39a4090c0a devices: add devices in Command::importTable()
Add a device_table parameters to Command::importTable() and
add_imported_dives(). The content of this table will be added
to the global device list (respectively removed on undo).

This is currently a no-op, as the parser doesn't yet fill
out the device table, but adds devices directly to the global
device table.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-24 09:51:37 -07:00
Berthold Stoeger
fadea413cd devices: return index from function adding / removing devices
This will be used to keep the model representing the device-list
up to date.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-24 09:51:37 -07:00
Berthold Stoeger
53118be1f9 devices: add functions to add / remove / check for devices
To include the device code in the undo system, we need functions
to check for the existence of devices and to add or remove them.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-24 09:51:37 -07:00
Berthold Stoeger
a261466594 parser: add device_table to parser state
If we want to avoid the parsers to directly modify global data,
we have to provide a device_table to parse into. This adds such
a state and the corresponding function parameters. However,
for now this is unused.

Adding new parameters is very painful and this commit shows that
we urgently need a "struct divelog" collecting all those tables!

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-24 09:51:37 -07:00
Berthold Stoeger
ad59f100ae cleanup: remove unused function intdup()
That was used by the old xml-params code, which was recently
replaced.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-23 18:17:02 -07:00
Berthold Stoeger
d508a16aca parser: replace params[] code by new xml_params struct
This fixes a load of memory holes, and makes the code
(hopefully) more readable.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-23 18:17:02 -07:00
Berthold Stoeger
b9b51ffd4e core: add a small helper-struct that keeps track of xml-parameters
The XML-parameter code is a mess. Ownership is unclear. Allocation
and freeing of strings is in different functions. Sometimes
only every second string is free()d, because keys are not copied.
But this is done inconsistently. The caller has to know how
many parameters the callee may add.

Instead, let's add a small helper-struct that uses C++ memory
management, but exports a C-API. The array for the XML-library
is generated on the fly.

This is only the implementation, the old code is not yet replaced.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-23 18:17:02 -07:00
Berthold Stoeger
ac3042b48b libdc: free value strings given by libdc's dc_parser_get_field()
Apparently libdc gives us copies of strings. The API is very
scary, because (at least according to my reading of the code),
the key/value pair may be stored in a cache. Thus on free()ing
the string in the cache becomes invalid and we must not access
it twice. Very obscure.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-23 18:13:44 -07:00
Berthold Stoeger
6b1be8c4f6 devices: use case-insensitive comparison for model
Recently, the sorting of the devices was changed to be
case-insensitive for models for consistency reasons. However,
then the equality-comparison should also be case-insensitive.

Break it out into its own function, to avoid that mistake
in the future.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-17 09:04:20 -07:00
Berthold Stoeger
c046742288 cleanup: rename clear_device_nodes() to clear_device_table()
For consistency with all the other clear_*_table functions
(dive, trip, dive_site, ...)

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-17 09:04:20 -07:00
Berthold Stoeger
a7bbb6c1cc filter: remove filter_preset_table_t
We used a typedef "filter_preset_table_t" for the filter preset table,
because it is a "std::vector<filter_preset>". However, that is in
contrast to all the other global tables (dives, trips, sites) that we
have.

Therefore, turn this into a standard struct, which simply inherits
from "std::vector<filter_preset>". Note that while inheriting from
std::vector<> is generally not recommended, it is not a problem
here, because we don't modify it in any shape or form.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-17 09:04:20 -07:00
Berthold Stoeger
67aec56f8c filter: make filter_preset_table an opaque struct for C code
filter_preset_table_t was defined as "void" for C code.
However, that meant that any pointer could be passed as
such a table and such a table could be passed as any pointer,
without generating compiler warnings.

Indeed, we had a parameter-mixup that went unnoticed.

Therefore, make filter_preset_t an anonymous structure with
the name filter_preset instead.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-17 09:04:20 -07:00
Dirk Hohndel
3d7b2a2d7c cleanup: use correct printf format
This fixes a warning from the CodeQL scan.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-10-16 21:32:43 -07:00
Berthold Stoeger
1d6c1db4a5 core: use case-insensitive comparison for device models
The code in core/libdivecomputer.c used string insensitive
comparison for device models, before being merged into core/device.c.

Let's reinstate that behavior, since it appears to be more logical.
On would assume that two different vendors will not use the same
model with different casing (and the same device-ids), so that
should be safe.

This uses strcoll to correctly sort unicode, which will hopefully
never be needed!

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16 14:26:37 -07:00
Berthold Stoeger
0c769b04b7 cleanup: replace std::find_if by std::any_of
To search for devices with the same model, we used find_if().
However, that was only to check whether such a thing exists,
not to actually do something with said device.

Therefore, change this to std::any_of() to make it clear what
the purpose of the statement is.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16 14:26:37 -07:00
Berthold Stoeger
8549f24c91 core: add device_table parameter to device table functions
Instead of accessing the global device table directly, add a parameter
to all device-table accessing functions. This makes all places in
the code that access the global device table grep-able, which is
necessary to include the device-table code in the undo system.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16 14:26:37 -07:00
Berthold Stoeger
7b06349be5 core: remove call_for_each_dc()
The core now loops over the devices directly - no need for this
callback.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16 14:26:37 -07:00
Berthold Stoeger
1e34e19c6d core: use C accessors in core/save-xml.c instead of callback
We now can loop over devices from C and check for selection.
So let's get rid of the last user of the call_for_all_devices()
callback.

Code readability improvement is not stellar, but one less
place where we shoe-horn user data through a void-pointer.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16 14:26:37 -07:00
Berthold Stoeger
d93b261e89 core: factor out device_is_used_by_selected_dive() function
We have a callback for all devices with a twist: it can loop
over those devices that are used by a selected dive. This is
used for exporting a subset of the dive log.

Factor out the "is device used by selected dive" part of the
function and make it available to C. The goal is to make
the whole callback thing unnecessary and let C code loop
directly over the device list.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16 14:26:37 -07:00
Berthold Stoeger
e8d3f75541 core: use C accessors in core/save-git.c instead of callback
Now we can simply loop over the list of devices. In this case,
it's not much more readable, but at least we don't have that
nasty pass user-data through "void *" pattern.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16 14:26:37 -07:00
Berthold Stoeger
7aca64bfca cleanup: remove device::operator!=()
This was not used. Moreover, mark device::operator==() for removal.
This is used for detecting changes in the DiveComputerModel. This
can be removed once that is integrated into the undo system.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16 14:26:37 -07:00
Berthold Stoeger
7415824a8c core: use C accessors in core/libdivecomputer.c instead of callback
Searching the proper device for the divecomputer was done via a
callback. Very hard to follow code. Since we can now access
"struct device" from C, obtain it directly via get_device_for_dc().

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16 14:26:37 -07:00
Berthold Stoeger
74b8d13672 core: make get_device_for_dc() accessible from C
The function getDCExact() was used to search for a device structure
matching a divecomputer. Since C code can now access struct device,
we can export that function to C. Rename it to get_device_for_dc()
for consistency with naming of the core functions.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16 14:26:37 -07:00
Berthold Stoeger
c4bfecce1b core: add C struct device and struct device_table accessors
Up to now, "struct device" and "struct device_table" were C++
only, because they used C++ strings for convenience. Since we
switched from QString to std::string, we can create accessors
for these structs. For the C code, we simply declare them as
opaque structs and give the full definition only for C++.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16 14:26:37 -07:00
Berthold Stoeger
4a50badb57 cleanup: use std::vector in struct device_table
Since we converted from QString to std::string, let's also use
std::vector instead of QVector. We don't need COW semantics
and all the rigmarole. Let's try to keep Qt data structures
out of the core.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16 14:26:37 -07:00
Berthold Stoeger
fd8bd9d5c7 cleanup: use std::string in struct device
struct device is a core data structure and therefore shouldn't use QString.
QString stores as UTF-16 (which is a very questionable choice in itself).
However, the real problem is that this puts us in lifetime-management
hell when interfacing with C code: The UTF-16 has to be converted to
UTF-8, but when returning such a string, this puts burden on the caller
who has to free it. In fact, instead of looping over devices from C-code
we had a callback that sent down temporary C-strings with qPrintable.

In contrast, std::string is guaranteed to store its data as
contiguous null-terminated and C-compatible strings. Therefore,
replace the QString by std::string. Keep the QString just in
one place that formats a hexadecimal number to avoid any
potential change.

The disadvantage of using std::string is that it will crash
when constructed with a NULL argument, consistent with C-style
functions such as strcmp, etc. Arguably, NULL is different
from the empty string even though we treat both as the same.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16 14:26:37 -07:00
Berthold Stoeger
4e479677a0 cleanup: fix tiny memory hole in device.cpp
empty_string() returns true for "". Thus, we can't simply overwrite
the pointer if empyt_string() returns true, but must free the string
regardless. The joys of C memory management!

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16 14:26:37 -07:00
Miika Turkia
1a646a2e5c Duration is in seconds
The dive duration is given in seconds in the Shearwater cloud database.
(At least nowadays.)

Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
2020-10-16 14:15:50 -07:00
Berthold Stoeger
23dc56e9cc parser: fix parsing of DAN files
The last two parameters of the parse_dan_format() function were
mixed up: sites should come before filter_presets.

This should have caused crashes, for DAN files with dive sites.
I don't understand why this didn't cause compiler warnings.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16 13:57:00 -07:00
Berthold Stoeger
2e5913d2ba core: fix detection of duplicate device names
Recently (c9b8584bd2) the sort criteria of the device-table
was changed from  (model/id) to (id/model). However, that
messed with the detection of duplicate device names: there,
the code searched for the first element greater or equal
to (model / 0).

With the reversal of the sort criteria, this would now
always give the first element.

Therefore, do a simple non-binary search, which is much
more robust. The binary search was a silly and pointless
premature optimization anyway - don't do such things
if not necessary!

Since only one place in the code search for existence
for a model-name, fold the corresponding function into
that place.

Moreover, change the code to do a case-insensitive compare.
This is consistent with the dc_match_serial() code in
core/libdivecomputer.c, where matching models is
case-insensitive!

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-13 16:26:42 -07:00
Berthold Stoeger
ff6c1a34ad cleanup: remove unused function is_default_dive_computer()
The last actual user was apparently removed back in 2013(!):
34db6dc2be

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-13 20:15:41 +02:00
Berthold Stoeger
c9b8584bd2 core: sort device-table by id/model instead of model/id
The device table is accessed by core via a callback using
call_for_each_dc(). This sorts the table by device-id. It
is unclear whether this is needed - since currently all it
does is make sure that the devices have a fixed order in XML
and git log files.

In any case, this means that the table had to be copied and
sorted in call_for_each_dc(). Since the frontend now does
its own sorting, we can just keep the core table sorted
as it needs it. This in turn will ultimately make it possible
to replace the callback by a simple loop.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-11 08:35:20 -07:00
Berthold Stoeger
8af40025b0 cleanup: use pointer-to-function connect() in ConfigureDiveComputer
This version is compile-time checked and therefore less risky with
respect to refactoring.

Since the same three signals were connect()ed for three different
threads-objects, do this in a new function.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-06 10:38:45 -07:00
Berthold Stoeger
b3f5473b66 core: don't merge sample-derived pressures in merge_one_cylinder()
These will be recalculated from the pressures in fixup_dive()
anyway.

Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-05 12:59:02 -07:00
Berthold Stoeger
6729428b6a core: improve merging of cylinders pressures
When merging cylinders pressures derived from samples were taken
as maximum of the start and minimum of the end pressure, which
makes sense, since we believe that this is the same cylinder.

However, for manually entered pressures, this was not done.

Moreover, when one dive had manual pressures and the other only
pressure from samples, the manual pressure was taken. However,
that could have been the wrong one, for example if the end
pressure was manually set for the cylinder of the first part of
the dive, but not the last.

Therefore, improve merging of manuall set pressures in two ways:
1) use maximum/minimum for start/end pressure
2) if the pressure of one cylinder was manually set, but not for
   the other, complete with the sample pressure (if that exists).

Fixes #2884.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-05 12:59:02 -07:00
Berthold Stoeger
6f8837eca3 cleanup: remove libdc_serial field in device_data_t
This was only set but never read. Therefore, remove it. Divecomputer
serial numbers are now handled via a string-based interface.

We can't remove the integer-based firmware number, because that is
still used by the OSTC firmware check in ConfigureDiveComputerDialog.
Let's not risk breaking that.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-05 12:44:30 -07:00
Berthold Stoeger
426a7f5442 cleanup: remove DC_FIELD_STRING conditional compilation
This dates from 2014 - this should be obsolete: we certainly don't
support such old libdivecomputer versions. Moreover, we bundle our
own anyway.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-05 12:44:30 -07:00
Dirk Hohndel
f775ec2e69 download from dive computer: correctly list transports tried
Instead of just 'BT' or 'device name' (which is wrong in cases where we don't
use a device name in the first place, like USBHID), try to list the actual
transports that we will consider.

A big part of this patch is just moving code around so we don't need a forward
declaration of the static helper function.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-10-05 12:42:40 -07:00
Dirk Hohndel
1065a52635 libdc/debug: provide better info regarding libdc interaction
Instead of just sending this to the user through the progress bar text, also
send things to stderr in verbose mode. That should make it easier to debug
situations where we fail to download from a dive computer.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-10-05 12:42:40 -07:00
Robert C. Helling
4b4a117f96 Use get_n2 helper function
Now, that we have this helper function that should have been
introduced long ago, we can make some more expressions
more idiomatic.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2020-10-05 10:17:29 +02:00
Berthold Stoeger
5bc6f5d36c cleanup: make device code more consistent with core
We keep track of device, i.e. distinct dive computers with id in the core.
The corresponding code stuck out like a sore thumb. Firstly, because it
is C++. But more importantly, because it used inconsistent nameing conventions.

Notably it defined a "DiveComputerNode" when this is something very different
from "struct dive_computer", the latter being the dive-computer related
data of a single dive.

Since the whole thing is defined in "device.h" and the function to create
such an entry is called "create_device_node", call the structure "device".
Use snake_case for consistency with the other core structures.

Moreover, call the collection of devices "device_table" in analogy
with "dive_table", etc.

Overall, this should make the core code more consistent style-wise.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-03 10:53:26 -07:00
Berthold Stoeger
90ca635316 cleanup: use getDCExact() instead of callback in set_dc_deviceid()
core/device.c used to be a C file, which couldn't access the C++
divecomputer list directly. Therefore, instead of a simple loop,
searching for a matching DC was implemented via a callback with
void * user data parameter. Wild. Since the file is now C++, let's
just use direct access to the C++ data structures to make this
readable by mere humans.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-03 10:53:26 -07:00
Berthold Stoeger
ce7e74f62f cleanup: pass divecomputer to getDC() and getDCExact() helpers
These are used to search for device nodes and were passed model
and device id (for the exact version). However, all callers used
them to search for the node corresponding to a specific struct
divecomputer, so let's just pass that instead to make the caller
site less complex.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-03 10:53:26 -07:00
Berthold Stoeger
2b557f567a cleanup: hide DiveComputerList implementation details
Remove the declaration of helper functions needed only in
core/device.cpp. To this goal, turn the member functions
into free functions.

Cosmetics: turn the DiveComputer[Node|List] "class"es into
"struct"s, since all members were public anyway.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-03 10:53:26 -07:00
Berthold Stoeger
4ec0c6508e filter: add tank size filter constraint
This is an actual user request.

Fixes #1787.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-03 10:29:15 -07:00
Berthold Stoeger
ec431155a9 filter: implement filtering for gas mixes
This adds filter constraints for numerical filtering for gas-mixes.
Currently, this does a "match any" kind of search, which means that
a dive is filtered if any of its cylinders matches.

We should also implement "all-of" and "none-of" modes for cylinder
filtering.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-03 10:29:15 -07:00
Berthold Stoeger
23da23a534 core: add N2 and general gas component accessors
There were helper functions to access O2 and He component fractions.
Add another one for N2. Indeed, this can be used in three cases, where
N2 was deduced indirectly.

Moreover, add a general accessor with a gas_component argument.
This will be used by the filter code to filter for gas components.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-03 10:29:15 -07:00
Berthold Stoeger
34730b898b core: make gas type enum globally available
The deco-routines used an enum to pass around the inert gas
type. Make that globally available and make it include O2.
This will be used in a future commit to generalize access
of gas fractions.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-03 10:29:15 -07:00
Berthold Stoeger
00abc04913 cleanup: use getDiveSelection() to loop over selected dives
getDiveSelection() returns a vector of the selected dives.
Use that instead of looping over the dive table and checking
manually.

This removes a few lines of code.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-03 10:01:13 -07:00
Berthold Stoeger
f4ee893424 cleanup: replace get_trip_date_string() by get_trip_string()
The get_trip_date_string() formatted, as the name implies, the date
of a trip. It was passed a number of parameters and had only one
caller, which would also add the location if it existed.
Therefore, move all that logic into the helper function and
name it get_trip_string().

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-03 10:01:13 -07:00
Linus Torvalds
d8f35711ff membuffer: be defensive about bad C library vsnprintf implementations
Dirk reports that some Windows users have had odd corruption in the
commit messages in the cloud storage.  They make no sense at all unless
there is some very weird Windows library bug.

The prime suspect is 'vsnprintf()' returning a negative error when the
target buffer is too small (rather than the proper "this is how much
space it would need").  That is a very traditional C library bug that I
thougth had been fixed everywhere, but there doesn't really seem to be a
lot of other likely causes.

So let's make our membuffer code be defensive against bad libraries that
return negative error numbers from vsnprintf.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2020-10-01 13:43:21 -07:00
Dirk Hohndel
4608beaee4 Android BLE discovery: use discovery agent
Android can't scan for classic BT devices, so when BT support was first
added, we simply didn't use the discovery agent at all and relied on the
list of paired BT devices provided by Android.

This still worked fine for a lot of BLE devices that allowed 'bonding'
with the Android device - similar to pairing. But some BLE devices (like
the Shearwater Peregrine) don't support bonding and so our Android code
didn't see them at all.

With this commit we start a BLE only scan on Android to add to the list
of already paired devices.

Fixes: #2974

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-09-30 16:40:41 -07:00
Dirk Hohndel
5b48585092 bluetooth discovery: report more information about progress
We certainly should log errors and the complete list of discovered
devices.

Also, it's good practice to set a specific search time (I picked three
minutes). This way we won't constantly scan and drain resources.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-09-30 16:40:41 -07:00
Dirk Hohndel
ca23147228 bluetooth discovery: differentiate discovered and paired devices
We call the same helper from two spots. Once when we report the already
paired BT devices on Android, and once from the deviceDescovered signal
for the discovery agent. Let's make sure we can tell where the info came
from.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-09-30 16:40:41 -07:00
Berthold Stoeger
e1c44a0a4d filter: save timestamps in user-readable format
So far we saved timestamps by their 64-bit value as decimal strings.
Change this to a user readable format. The parsing routine still
supports decimal numbers.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
8f898477cb core: add helper functions to format / parse timestamps
To save datetime-based filter constraints to git or XML,
it is preferrable to use human-readable representations.
Therefore, add helper functions to format / parse timestamp_t
64-bit values in the "YYYY-MM-DD hh:mm:ss" format.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
f9721fce4b filter: implement importing of filter presets
When importing a divelog, import filter presets. If there are
equal names, import only if the presets differ. In that case,
disambiguate the name. This made things a bit more complicated,
as comparison of filter presets had to be implemented.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
38b686687f cleanup: move shown-text calculation from filter widget to core
The filter widget was caching whether the filter was active and
used that flag to calculate the "# dives shown" string. Move this
directly to the DiveFilter class to remove interdependencies and
to unify with mobile.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
1fcf4f891d filter: implement loading of filter presets from git repositories
This is mostly copy and paste of other git loading code. Sadly,
it adds a lot of state to the parser-state. I wish we could pass
different parser states to the parser_* functions.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
3bfd448b59 filter: implement saving of filter presets to git repositories
On the mailing list it was decided that users might want to
move their filter presets across computers via the cloud.
Notably, in the future one might access statistics on mobile and
these might by controlled by filter presets.

The git save routines use the same string formatting as the
XML save routines. The string formatting is found in
core/filterconstraint.cpp. Thus, duplication of code and
inconsistencies should be minimized.

Each filter preset is saved into a file in the "02-Filterpresets"
folder in the root of the git repository.

Each file consists of one "name" line, zero or one "fulltext" line
and zero or more "constraint" lines.

The modes, types and the actual payload is controlled via attributes.
Thus, a preset file might look like this:

name "test"
fulltext mode="substring" query="clown"
constraint type="location" stringmode="starstwith" data="mafia"
constraint type="sac" rangemode="range" negate data="5000,10000"

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
41cf83583d filter: load filter presets from XML files
This is a bit painful: since we don't want to modify the filter
presets when the user imports (as opposed to opens) a log,
we have to provide a table where the parser stores the presets.
Calling the parser is getting quite unwieldy, since many tables
are passed. We probably should introduce a structure representing
a full log-book at one point, which collects all the things that
are saved to the log.

Apart from that, this is simply the counterpart to saving to XML.
The interpretation of the string data is performed by core
functions, not the parser itself to avoid code duplication with
the git parser.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
cef15c978d cleanup: move function declarations from dive.h to parse.h
The parse_* functions should probably be declared in parse.h.
Arguably, parse_xml_init() and parse_xml_exit() should be moved
to an init.h file, however that doesn't yet exist.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
4a78f5798a includes: move declaration of set_filename() from dive.h to qthelper.h
Declare the function in the header file corresponding to the source
file where the function is defined.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
448bc5600b filter: implement saving of presets to XML file
Users might want to move their presets with there log-file. Therefore,
save the presets to the log. The alternative would be to save them
to the preferences. However, on the mailinglist it was decided that
moving the presets to a mobile device is a wanted feature.

The XML saving code has a rather reasonable interface, therefore
this turned out to be pretty easy to implement.

The filter presets are saved into a
<filterpresets>
 ...
</filterpresets>
block

Each individual preset is saved into a
 <filterpreset name='...'>
    ...
 </filterpreset>
Block with a unique name attribute.

Each preset contains zero or one fulltext and zero or more constraint entries.
The type and mode(s) are controlled by attributes, the "payload" is saved in
the block. Note that all the formatting is done by functions in core/filterconstraint.c
and not the parser itself.

A preset in the XML file might look like this:

 <filterpreset name='test1'>
  <fulltext mode='startswith'>Train</fulltext>
  <constraint type='planned'>0,0</constraint>
  <constraint type='sac' range_mode='range' negate='1'>5000,10000</constraint>
 </filterpreset>

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
2f5223035a filter: add filter preset undo commands
Add undo commands to add / edit / delete filter presets.
These are styled after the other undo commands: On changes,
the UI is informed by DiveListNotifier signals. Editing is
a simple std::swap of values.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
937fdb500b filter: add primitive filter presets
Add a rudimentary list of filter presets to the core. The list
is sorted by name. Access is provided via a C interface so that
the presets can be written to the git and XML logs. Internally,
the list is realized by a C++ vector for convenience (euphemism for
laziness).

Morover, a C++ interface is provided for the UI. Currently names of
the presets cannot be edited, since this would mean that the order
of the list changes. This may be implemented later if required.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
634e26cbce filter: unify desktop and mobile filters
Switch the mobile code to use the constraint-based filter. The one
thing that is still commented out is dive-site mode, since mobile
doesn't (yet) have a dive-site edit feature. And even if it had,
the dive list probably wouldn't be shown at the same time.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
6c443ba841 filter: connect new filtercode to filterwidget2
Replace the static filterwidget with a list of filterconstraints.
The first attempt of using a table widget failed, because Qt's
table delegates are dysfunctional. It's not that they are bad, they
just don't work at all.

Therefore, this code "simulates" a table in that on addition / deletion
of constraints it keeps track of the rows of all constraints so
that each constraint-widget can be associated with a row of the
constraint model.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
af9d379a41 filter: add filter constraint model
Add a model that keeps track of a list of filter constraint and makes
them accessible from Qt. Sadly, this is mostly repetitive boiler-plate
code, but this is due to Qt's model/view-API, which is a perfect example
of how *not* to design a reasonable modern API.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
634152ae43 filter: add filter constraint object to the core
Adds a filter constraint object to the core, which represents one
constraint the user can filter dives with. The plan is to write these
constraints to the XML and git logs. Therefore, this code is written
in C-style except when it comes to handling strings and dates, which
is just too painful in plain C.

There is one pointer to QStringList in the class, though when compiled
with C, this is simply transformed into a pointer to void. Granted,
that smells of an ugly hack. However it's more pragmatic than
self-flaggelation with C string and list handling.

A filter constraint is supposed to be a very general thing, which can
filter for strings, multiple-choice lists, numerical ranges and date
ranges.

Range constraints have a range mode: less-or-equal, greater-or-equal
or in-range. Text constraints have a string mode: startswith, substring
or exact.

All the data are accessed via setter and getter functions for
at least basic levels of isolation, despite being written with
a C-interface in mind.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
0b7ba19775 fulltext: remember original query
So far, the fulltext-query structure only saves an canonicalized
upper-cased version of the query. However, if we want to save the
fulltext query to the log (filter presets) or want to restore an old
fulltext query, we have to store the original query. We don't want
to confront the user with the mangled upper-cased version.
Therefore, also save the original version.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
0f4154bacc core: add functions to core/time.c
To support the new filter code, add helper functions that turn timestamps
into year and day-of-week to core/time.c.

Internally, these functions simply call utc_mktime() to break down the
timestamp and then extract the wanted value. This may appear inefficient,
but testing shows that modern compilers are quite effective in throwing
away the unneeded calculations. FWIW in this respect clang10 outperformed
gcc10.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Robert C. Helling
efdc875aa3 Use correct pO2 when computing MOD in equipment tab
The cylinder model is used both in the planner and the
equipment tab. We have three preferences for the pO2 that
is used to compute MOD: In the planner, there is one for
the bottom part of the dive and another one for deco.
Those are set in the planenr UI. There is another value,
controlled in the Tec Prefernces. That one should be
used in the equipment tab rather than the one from
the planner.

Fixes #2984

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2020-09-29 15:46:55 -07:00