Prior to this commit, gtk often decided to collapse the trip with the
selected dive after the user imported or downloaded additional dives.
Since Subsurface tracks dives as being selected even after gtk collapses a
trip (which clears all selection state as far as gtk is concerned) this
could lead to the strange situation that the user could click on a new
dive to select it without unselecting the already selected dive - and
suddenly edit or delete did things that were entirely unwanted.
With this change we explicitly save and then restore the tree state around
import and download operations. This ensures that the same dive(s) stay
selected and trips stay expanded and therefore avoids the issues described
here.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The code pretended to support this for libdivecomputer based downloads,
but it had never been hooked up when the native Uemis downloader was
implemented. When I finally decided to close that feature gap I realized
that the original code was, shall we say, "aspirational" or "completely
bogus" and therefore never worked.
So instead of just hooking up the code for the Uemis downloader I instead
implemented this correctly for the first time for both libdivecomputer and
the native Uemis downloader.
In order not to have to mess with multithreaded Gtk development I simply
opted for a helper function that fires on a 100ms timeout and have it end
the dialog without a response. This way we can run the dialog while
waiting for the download to finish, still update the progress bar and
respond in a useful manner to the user clicking cancel.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
- Create a grid for each dive printed.
- We change justify "center" to "left" wich contributes to diferentiate each component of the array.
Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The divecomputer download code will stop at a matching dive (unless
you check the "Download all dives" option when downloading).
However, the matching dive is an *exact* match, which works well when
you have a single dive computer, but is a big pain when you have
multiple. What happens is that the date of the dive will be determined
by whatever dive computer you used first, and then downloading from
other dive computers will not match exactly, but will merge (if the
computers are within a minute of each other).
And that will continue to happen every time you try to download from
that other dive computer.
So use the same logic as for the automatic dive merging: consider
"within one minute" to be a matching dive. So don't download dives
that will be merged - unless the user asks for it.
We do want to have some way of saying "force download of all dives
from today" or something like that, I suspect. Because while I don't
want to re-download *every* dive, I might want to force-merge the last
<N> dives.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
And again buffer_insert contained the blatant bug.
The code wasn't copying the trailing '\0' when extending the string, which
usually didn't end up blowing up the code (and therefore kept the bug
hidden until now) because of the way realloc reused memory - we just had
trailing garbage strings. But sometimes we weren't so lucky and the strlen
in a subsequent call of buffer_insert would run past the end of the
allocated buffer.
Oops.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We are accessing offset 24 in an array of length 24. To make things easier
for the base64 conversion we just treat this as an off by three error and
instead create an array large enough for 27 elements and convert a
sufficient number of base64 chars to initialize all of them.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Simply call "make LIBDCDEVEL=1" and the libdivecomputer includefiles are
expected in ../libdivecomputer/include and the actual library is linked
from ../libdivecomputer/src/.libs
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This may seem like an esoteric corner case, but it will actually happen
reliably when re-downloading dives from the Uemis SDA:
If the user selects "Force downloada of all dives" in the "Download from
divecomputer" dialog and if the SDA runs out of space and needs to be
unmounted and remounted, then for the 'Retry' the 'force' flag should be
cleared - or the user will once again start from the first dive which
almost certainly is not what they expect.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
If we ran out of space on the Uemis SDA during download and the user
unmounted, unplugged and replugged the SDA, we need to take care to
correctly reset the file number we use for finding the correct ANS file.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Start every step with much longer timeouts (until we get the first
response back), but then use shorter timeouts once we have started
receiving data.
This uses up fewer of the ANS files and allows us to get more dives
downloaded before the SDA has to be unplugged to reset communications,
yet at the same time it still improves the overall download time.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This mirrors commit 59929fdb5d2a "Mark divelist changed as we download
dives from a dive computer" which only fixed things for the
libdivecomputer case.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The GPS parsing and saving was using sscanf and sprintf respecively, and
since it is using floating point values (boo!) that affects both of
them. In a C/US locale, we use a period for decimal values, while most
European locales use a comma.
We really should probably just fix things to use integer values (degrees
and nanodegrees?) but this is the simplest fix/workaround for the issue.
Probably nobody ever really noticed until I tested the Swedish locale
for grins, since we don't have a good way to actually set the GPS
coordinates yet. I've got a few dives with GPS information that I
entered manually.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Most of the dive computers I have access to don't do the whole surface
event thing at the beginning or the end of the dive, so when you merge
two consecutive dives, you got this odd merged dive where the diver
spent the time in between at a depth of 1.2m or so (whatever the dive
computer "I'm now under water" depth limit happens to be).
Don't do that. Add surface events at the end of the first dive to be
merged, and the beginning of the second one, so that the time in between
dives is properly marked as being at the surface.
The logic for "time in between dives" is a bit iffy - it's "more than 60
seconds with no samples". If somebody has dive computers with samples
more than 60 seconds apart, this will break and we may have to revisit
the logic. But dang, that's some seriously broken sample rate.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Commit 38c79d149d ("Simplify and clean up dive trip management")
simplified the code a bit *too* much, and removed the check for
"dive->selected".
As a result, trying to delete a dive resulted in *all* dives being
deleted.
Oops.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
"record_dive()" won't do that, since otherwise we'd mark the dive list
changed when we load it from an XML file.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This allows zooming in with the scroll-wheel if you have one (or the
two-finger scrolling on a touchpad).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Prervent tiny temperature changes from being exaggerated in the plot.
Also, shift pressure plot around a bit (if necessary) to prevent it from
ending in the same space as the temperature plato on the profile graph.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
THe Uemis SDA allows the user to set it up for salt water and fresh water
use. We should take this into consideration for the water pressure to
depth conversion.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In my excitement about extracting these from libdivecomputer I forgot to
actually store them and then parse them again. Oops.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We generate the average temperature statistics by adding up the
(converted to user unites - not in millikelvin) temperatures and then
dividing by the number of dives we've added up over.
HOWEVER.
We did that summing of the temperatures into an integer variable, even
though the converted temperatures are floating point. So things got
rounded down to integers and the average temperature was just bogus
(although reasonably close).
We could do the summing of the temperatures in millikelvin and only
doing the conversion to the user at the very end. But the smaller patch
is to just change the accumulator to a double value.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The code in commit f99e1b476b18 "Trim the dive to exclude surface time at
beginning and end" failed rather badly if a dive has no samples at all -
which is true for many of our test dives.
This makes sure that we don't exclude data points if we never set up start
and end times.
Reported-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Commit 6c52e8a2e5 ("Add plotting of the deco ceiling") for some
totally unexplained reason deleted one "else" statement, resulting in
some plot events not having a time at all. Which causes various really
odd issues if you hit that situation, including divide-by-zero etc due
to the difference in times between events being nonsensical.
It's just some odd mistake that was entirely unrelated to the other
changes in that commit.
Add the missing line back in.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
I think I prefer the 2.5x zoom over the pure doubling.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This shows the values for all the graphs that are shown (depth,
temperature, tank pressure, pO2, pN2m pHe), but also correctly doesn't
display them when they are turned off or no data is available (prior to
this commit, tank pressure was always shown, even if no pressure samples
were available for the dive).
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
If the surface interval between two dives is more than half an hour,
don't try to call it a single dive. Just the dive profile will be
looking ridiculous.
Things like tank refills etc could also be a good thing to check (again,
the dive profile would look ridiculous), but the cylinder pressure going
up a small amount is actually normal (ie cylinder warming up in warmer
water on the surface). So I don't know what the proper limit for that
would be.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When we calculate the interval for the tick-marks for the dive, we need
to limit 'i' to be within the size of the array. The code does that
with a "i < 8" check, but the fact is, we must never increment past the
last entry, which is 7 (the size of the array is 8, but the last valid
index is 7).
This only happens for unrealistically long dives. Which you can trigger
either by inputting insane values for a manually created dive, or by
merging two dives that are consecutive, but not close to each other
time-wise (eg on different days ;)
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Linus convinced me that I was wrong to modify his commit 24690ce35f81
"Initial not-so-pretty profile zoom support" and so this changes it back
to use the left mouse button for zooming. It turns out that on some
touchpads there's a very nice way to hold down the click with one finger
and then pan with another finger, but that does not work if you do a two
finger click (and use one of those or a third to pan).
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This extends on our current tooltip logic (which shows events when you
mouse over them) to show tooltips for the whole profile area.
If you mouse over an event, that is still shown in the tooltip, but
even in the absense of events, the tooltip will be active, and mousing
over the profile area will show the time, depth and pressure.
This can certainly be improved upon further, but even in this form it is
useful.
Fixes#9
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This will hopefully not be something we need often, but if we improve
support for a divecomputer (either in libdivecomputer or in our native
Uemis code or even in the way we handle (and potentially discard) events),
then it is extremely useful to be able to say "re-download things
from the divecomputer and for things that were not edited in Subsurface,
don't try to merge the data (which gives BAD results if for example you
fixed a bug in the depth calculation in libdivecomputer) but instead
simply take the samples, the events and some of the other unedited data
straight from the download".
This commit implements just that - a "force download" checkbox in the
download dialog that makes us reimport all dives from the dive computer,
even the ones we already have, and an "always prefer downloaded dive"
checkbox that then tells Subsurface not to merge but simply to take the
data from the downloaded dive - without overwriting the things we have
already edited in Subsurface (like location, buddy, equipment, etc).
This, as a precaution, refuses to merge dives that don't have identical
start times. So if you have edited the date / time of a dive or if you
have previously merged your dive with a different dive computer (and
therefore modified samples and events) you are out of luck.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
You can press the left mouse-button on the profile and drag the mouse
around to zoom in on a specific area. Releasing the mouse button unzooms.
Yeah, everybody wants rubber-banding, but I have reached the end of my
willingness to fight gtk for more details. Some day.
[Dirk Hohndel: changed this to use the right mouse button instead of the
left which seemed just terribly unnatural]
References ticket 9
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This just makes sure that the merged dive is properly selected, and
that we've saved the trip tree state so that the dive list repaints
nicely and with the newly merged dive selected after the merge.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Simply add a dive option on bigger surface, whith bigger fonts.
The size isn't A4 nor A5, but the size used by some popular paper
divelogs.
The modification performs better if we transpose the profile and
the text of the dive, because, if the notes are very brief,we get
an excess of white space at the bottom of the print.
Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This introduces the notion of merging two disjoint dives: you can select
two dives from the dive list, and if the selection is exactly two dives,
and they are adjacent (and share the same dive trip), we support the
notion of merging the dives into one dive.
The most common reason for this is an extended surface event, which made
the dive computer decide that the dive was ended, but maybe you were
just waiting for a buddy or a student at the surface, and you want to
stitch together two dives into one.
There are still details to be sorted out: my Suunto dive computers don't
actually do surface samples at the beginning or end of the dive, so when
you stitch two dives together, the profile ends up being this odd "a
couple of feet under water between the two parts of the dive" thing.
But that's an independent thing from the actual merging logic, and I'll
work on that separately.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This just re-organizes the dive merging code so that we expose a new
"merge_dives(a, b, offset)" function that merges two dives together into
one with the samples (and events) of 'b' at the specified offset after
'a'.
We'll want to use this if a dive computer has decided that the dive
ended (due to a pause at the surface), but we really want to just turn
the two computer dives into one long one with an extended surface swim.
No functional changes, but some independent cleanups due to the trip
simplifications.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We don't change any of the samples, we just don't plot (or consider for
dive time / mean calculations) the samples at the beginning or end of the
dive that are less than a certain threshold under water. Right now that's
an arbitrary 75cm which seems to Do The Right Thing(tm) for the dives I
tried this with - but I'm happy to look at other values if this causes
problems for people with dive computers I do not have access to.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Add the bookmark and heading events to the list of events not to be
simplified just because they are redundant - in both cases they are
about the user doing something explicit (like the gaschange), so even
if the data is otherwise identical, they should likely be saved.
That said, both events are kind of pointless (we don't actually seem
to save the heading value for the heading events, and bookmarks are
universally just due to user error in at least my case). But still..
This overly aggressive filtering was introduced in commit 6ad73a8f04
("Improve logic handling events").
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This adds a couple of helper functions to manage dive trips
("add_dive_to_trip()" and "remove_dive_from_trip()") and makes those
functions do the trip statistics maintenance (trip beginning times,
number of dives, etc).
This was needed because the dive merge cases for multiple dive
computers showed some rather nasty special cases: especially if the
new dive information has been loaded into an XML file with trips
auto-generated, merging several of these kinds of xml files with
multiple dives in several overlapping trips would completely confuse
our previous code.
In particular, auto-generated trips that had the exact same date as
previous trips (because they were generated from the same dive
computer) really confused the code that used the trip timestamp to
manage the trips.
Adding the helper functions allows us to get the general case right
without having to have each piece of code that handles trip
information having to bother about all the odd rules. It will
eventually also allow us to make the dive trip data structures more
logical: right now the dive trip list is largely designed around the
odd gtk model handling, rather than some more higher-level conceptual
relationship with the actual dives.
But for now, this keeps all the data structures unchanged, and just
modifies them using the new helper functions.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This requires a patched libdivecomputer that can return salinity of the
water the dive was conducted in. Experimental patches exist that implement
this for the OSTC. The code is designed so that it simply defaults to salt
water if libdivecomputer doesn't include the feature.
The patch also fixes the dive merge code to merge two other recent
additions to the dive structure (surface_pressure and visibility).
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The tec diving preference pane now allows us to set a partial pressure
threshold for each of the three gases. When the partial pressure surpasses
that value, the graph becomes red.
Fixes#12
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The default filename handling is broken in two different ways:
(a) if we start subsurface with a non-existing file, we warn about
the inability to read that file, and then we exit without setting the
default filename.
This is broken because it means that if the user (perhaps by mistake,
by pressing ^S) now saves the file, he will overwrite the default
filename, even though that was *not* the file we read, and *not* the
file that subsurface was started with.
So just set the default filename even for a failed file open.
The exact same logic is true of a failed parse of an XML file that we
successfully opened. We do *not* want to leave the old default
filename in place just because the XML parsing failed, and possibly
then overwriting some file that was never involved with that failure
in the first place. So just get rid of all the logic to push the
filename saving into the XML parsing layer, it has zero relevance at
that point.
(b) if we do replace the default filename with a NULL file, we need
to set that even if we cannot do a strdup() on the NULL.
This fixes both errors.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When we fill the cylinder information in an imperial unit world, a
working pressure of zero is a special case, and forces us to use the
actual physical size of the cylinder in liter, despite the fact that
we normally would use cuft.
However, we compare that value against zero in a 'double', and in
between going through the gtk spinbutton logic, the zero we have
filled in then gets read out as some very tiny epsilon value from the
gtk spinbuttons (typically in the 10**-317 range). This causes us to
think that the zero isn't actually a zero, because gtk has done odd
things with it.
Fix this by calculating the millibar value (as an integer) first, and
check that *integer* against zero. Any crazy epsilon values will have
been rounded away, and our logic works again.
There's a good reason why subsurface does everything using integers
(ie the afore-mentioned "convert to integer millibar" etc) and doesn't
use floating point for any core data structures, only for conversion.
FP rounding and inexact behavior can be really subtle.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When we merge dives where the samples have come from different dive
computers, the samples may be offset from each other due to the dive
computers not having decided that the dive starts at quite the same
time.
For example, some dive computers may take a while to wake up when
submerged, or there may be differences in exactly when the dive
computer decides that a dive has started. Different computers tend to
have different depths that they consider the start of a real dive.
So when we merge two dives, look for differences in the sample data,
and search for the sample time offset that minimizes the differences
(logic: minimize the sum-of-square of the depth differences over a
two-minute window at the start of the dive).
This still doesn't really result in perfect merges, since different
computers will give slightly different values anyway, but it improves
the dive merging noticeably. To the point that this seems to have
found a bug in our Uemis data import (it looks like the Uemis importer
does an incorrect saltwater pressure conversion, and the data is
actually in centimeter, not in pressure).
So there is room for improvement, but this is at least a reasonable
approximation and starting point.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This enables plotting the ceiling in deco dives and also adds the
necessary code to the uemis importer. The only other dive computer this
has been tested with the OSTC and that needs a libdivecomputer patch in
order to provide the deco/ceiling information to Subsurface.
Fixes#5
We now throw away redundant events, just as we throw away other redundant
data coming from the dive computer. Events are considered redundant if
they are less than 61 seconds apart and identical.
This also improves the display of the remaining events in the profile as
we now show the value of the event, if it is present (for example for a
deco event we show the duration of the deepest stop).
Finally, for events that define a range (so they set the beginning flag
and assume and end flag some time later) we no loger show the triangle but
assume that some other code handles visualizing them (as happens for the
ceiling events).
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>