This is a preferences setting, it should belong to the preferences
structure.
Signed-off-by: Tomaz Canabrava <tomaz.canabrava@intel.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This patch adds the current dive time and the adjusted time to the time
shift window. I added a function to dive.c to get the timestamp of the
first selected dive.
This will view the time of the first selected dive only even when multi
dives are selected but it does change the times for multiple dives
properly.
Signed-off-by: Gehad elrobey <gehadelrobey@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
So this is totally unrelated to the git repository format, except for
the fact that I noticed it while writing the git saving code.
The subsurface divetag list handling is being stupid, and has a
initial dummy entry at the head of the list for no good reason.
I say "no good reason", because there *is* a reason for it: it allows
code to avoid the special case of empty list and adding entries to
before the first entry etc etc. But that reason is a really *bad*
reason, because it's valid only because people don't understand basic
list manipulation and pointers to pointers.
So get rid of the dummy element, and do things right instead - by
passing a *pointer* to the list, instead of the list. And then when
traversing the list and looking for a place to insert things, don't go
to the next entry - just update the "pointer to pointer" to point to
the address of the next entry. Each entry in a C linked list is no
different than the list itself, so you can use the pointer to the
pointer to the next entry as a pointer to the list.
This is a pet peeve of mine. The real beauty of pointers can never be
understood unless you understand the indirection they allow. People
who grew up with Pascal and were corrupted by that mindset are
mentally stunted. Niklaus Wirth has a lot to answer for!
But never fear. You too can overcome that mental limitation, it just
needs some brain exercise. Reading this patch may help. In particular,
contemplate the new "taglist_add_divetag()".
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This saves the dive data into a git object repository instead of a
single XML file.
We create a git object tree with each dive as a separate file,
hierarchically by trip and date.
NOTE 1: This largely duplicates the XML saving code, because trying to
share it seemed just too painful: the logic is very similar, but the
details of the actual strings end up differing sufficiently that there
are tons of trivial differences.
The git save format is line-based with minimal quoting, while XML quotes
everything with either "<..\>" or using single quotes around attributes.
NOTE 2: You currently need a dummy "file" to save to, which points to
the real save location: the git repository and branch to be used. We
should make this a config thing, but for testing, do something like
this:
echo git /home/torvalds/scuba:linus > git-test
to create that git information file, and when you use "Save To" and
specify "git-test" as the file to save to, subsurface will use the new
git save logic to save to the branch "linus" in the repository found at
"/home/torvalds/scuba".
NOTE 3: The git save format uses just the git object directory, it does
*not* check out the result in any git working tree or index. So after
you do a save, you can do
git log -p linus
to see what actually happened in that branch, but it will not affect any
actual checked-out state in the repository.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
clang-format doesn't appear to reindent multi line #define statements
correctly - so this hopefully will clean those up.
The included whitespace corrections to the code should stay in place when
using the updated tool.
This includes cleaning up some multi-line comments that were messed up the
last time around as well as a few other minor changes.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Minor change to the perl postprocessing script and resulting changes to
the affected source files.
This deals with two issues:
- "foreach"-like structures were not always treated correctly
- some longer calculations that ended on "+ constant" were reformatted in
a rather unatractive manner
In one source file (divelist.c) I ended up adding braces to the sources...
trying to cascade the indentation further down without having the block
there seemed a lot more trouble than it's worth.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The get_depth_units function was expecting an unsigned int as a first parameter.
When it received a negative integer, the function made a cast to an unsigned int,
resulting in a very big number.
Signed-off-by: Nicu Badescu <badescunicu@yahoo.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
I know everyone will hate it.
Go ahead. Complain. Call me names.
At least now things are consistent and reproducible.
If you want changes, have your complaint come with a patch to
scripts/whitespace.pl so that we can automate it.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In commit 23baf20f56 (Use "rint()" instead of rounding manually with
"+ 0.5") I had missed this one remaining place where we rounded things
by adding "+0.5" and then truncated.
Fix that up.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
rint() is "round to nearest integer", and does a better job than +0.5
(followed by the implicit truncation inherent in integer casting). We
already used 'rint()' for values that could be negative (where +0.5 is
actively wrong), let's just make it consistent.
Of course, as is usual for the messy C math functions, it depends on the
current rounding mode. But the default round-to-nearest is what we want
and use, and the functions that explicitly always round to nearest
aren't standard enough to worry about.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Earlier we converted the C++ code to using true/false, and this converts
the C code to using the same style.
We already depended on stdbool.h in subsurfacestartup.[ch], and we build
with -std=gnu99 so nobody could build subsurface without a c99 compiler.
[Dirk Hohndel: small change suggested by Thiago Macieira: don't include
stdbool.h for C++]
Signed-off-by: Anton Lundin <glance@acc.umu.se>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Some dive computers will always download all tanks that they store, not
just the ones used in a dive. Most people only want to see the tanks that
they actually used during the dive (and for the others there's an option
to go back to the old behavior, just in case).
All this is only in memory / during runtime. If the dive computer provided
the extra data we will not throw it away.
Fixes#373
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When the user asks to merge dives in the divelist, we would always use
the "try tp find matching dive computers and merge at an offset" model.
That is incorrect if the intent is to actually merge two *identical*
dives (with different dive computers), as opposed to merging two short
dives into one longer one with a surface interval.
Normally this doesn't ever trigger (the "same dive" merging will have
been done automatically after downloading from the dive computer), but
if the dive computer times are off, and the user fixes them, and then
asks to merge dives, we should use the non-offset dive merging logic.
We already have that "likely_same_dive()" function that is used to
determine when downloaded dives get merged, so just use it for the user
merge case too.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This id is just held in memory. It's not supposed to be used for anything
but having a unique handle that represents a dive. Whenever you need to
remember a dive across an operation that might change the dive_table, this
is what you should hold on to, not a dive number, a dive pointer, or
anything like that.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
None of these are actual bugs. But none of the fixes are harmful, either.
And much as I hate adding the 'default' clauses, I'd rather not have the
build output cluttered by invalid warnings.
The exception is the fix in divelistview.cpp - while I don't think it is
possible for this function to be called with no dive selected,
initializing pd to NULL is cheap insurance in case that does happen for
some weird reason.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Use get_cylinder_index that handles SAMPLE_EVENT_GASCHANGE and
SAMPLE_EVENT_GASCHANGE2.
This also removes the need for a special case where get_gasidx returns
-1, because get_cylinder_index always returns the "closest" gas that it
finds.
Signed-off-by: Anton Lundin <glance@acc.umu.se>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In an inconsistant XML file (like our own dives/test20.xml) it is possible
that a gas change event refers to a non-existing gas. In that case
get_gasidx returns -1 - which we shouldn't use as index into the arrays.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This is a bit painful, but we basically walk the samples and pick the
valid tank from the events. And then we do a simple discrete integration
to figure out the mean depth per tank and duration per tank. And then we
assemble all that into per tank statistics.
Strangely the value calculated here seems slightly higher than one would
expect from the overall SAC rate. This inconsistency should be
investigated a bit further, but my guess it it's based on the assumption
that the DC provided mean depth is possibly more accurate than what we can
calculate from the profile.
Fixes#284
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We translate only tags we know since possible
translations of custom tags (provided by the user)
may be out of context and therefore wrong.
Signed-off-by: Maximilian Güntner <maximilian.guentner@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This patch adds the possibility to shift the times of all selected dives
by a fixed amount to correct for time zone problems or mis-set dive
computer clocks.
Select the dives and right click in the dive list.
[Dirk Hohndel: added .ui file to FORMS and fixed some whitespace damage]
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This patch removes a duplicated method: get_divenr and
get_index_for_dive. The two are exactly the same ( if my
c is not broken, but I may be broken since I'm working like
crazy for almost 30h nonstop. ), so please take a good look
before applying this one.
[Dirk Hohndel: Tomaz took the slightly broken of the two implementations,
so I switched that out for the correct one]
Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We need to make sure that the correct segment has the correct gas assigned
to it - and that those gases are correctly tracked when editing a manually
added dive as well.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The new implementation supports custom tags
which are provided by the user as well as
default tags which are provided by subsurface.
Default tags can be translated and will be written
to XML in their non-localized form.
Signed-off-by: Maximilian Güntner <maximilian.guentner@gmail.com>
The dive planner always showed the depth in our internal units, ie
millimeter, in the sidebar that showed the plan points.
That made little sense in metric mode, and none at all in imperial. The
_graph_ showed things in meter and feet.
So make the DivePlannerPointsModel always convert things to and from the
user units.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This may seem like a really odd change - but with this change the Qt tools
can correctly parse the C files (and qt-gui.cpp) and get the context for
the translatable strings right.
It's not super-pretty (I'll admit that _("string literal") is much easier
on the eye than translate("gettextFromC", "string literal") ) but I think
this will be the price of success.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
- remove the build flags and libraries from the Makefile / Configure.mk
- remove the glib types (gboolean, gchar, gint64, gint)
- comment out / hack around gettext
- replace the glib file helper functions
- replace g_ascii_strtod
- replace g_build_filename
- use environment variables instead of g_get_home_dir() & g_get_user_name()
- comment out GPS string parsing (uses glib utf8 macros)
This needs massive cleanup, but it's a snapshot of what I have right now, in
case people want to look at it.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Some people (free divers) are loving ft/s or m/s units for vertical speeds.
Now they can choose between /min or /s in the configuration (only Qt UI).
Signed-off-by: Patrick Valsecchi <patrick@thus.ch>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This gets things mostly right.
It creates a dive and uses the planner widget to create samples which are
copied into the dive. It fills in some reasonable defaults (DC model,
timestamp), but doesn't allow editing the timestamp (or the temperatures
and air pressure).
On accept the planner gets reset and the dive appears correctly in the
dive list.
Cancel still needs to be handled.
And I bet there are many subtle bugs lurking here and there. But it's a
start.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
11 is SAMPLE_EVENT_GASCHANGE, and thats the one that doesn't contain any
He-part. The type where He and O2 is packed togeather is 25,
SAMPLE_EVENT_GASCHANGE2.
Left to implement is to figure out the type of the event when we read
the xml, so we can create the right type there.
Signed-off-by: Anton Lundin <glance@acc.umu.se>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
.. otherwise the dive tags generally end up cleared when you download a
duplicate dive from another dive computer.
This uses MERGE_NONZERO, which means that if one of the dives has tags
set, we'll prefer those tags. If both dives have tags set, we take the
tags from the first ("preferred") dive.
We could do a "just or all the bits together" too. But this way we at
least take a set of tags that are consistent (ie we don't get both
"boat" and "shore" set unless one of the original dives already had that
inconsistency)
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This is a fun one.
We only want to mark the divelist changed if the user actually changed
something. So we try really hard to compare what was entered with what was
there and only if it is different do we overwrite existing values and
record this as a change to the divelist.
An additional challenge here is the fact that the user needs to enter a
working pressure before they can enter a size (when in cuft mode). That is
not really intuitive. We work around this by assuming working pressure is
3000psi if a size is given in cuft - but then if the user changes the
working pressure, that changes the volume. Now going back and changing the
volume again does the trick. Or enter the working pressure FIRST and then
the volume...
This also changes the incorrect MAXPRESSURE to WORKINGPRESSURE and uses
the text WorkPress in English (Gtk code used MaxPress which was simply
wrong - this is just the design pressure or working pressure, not some
hard maximum. In fact, people quite commonly "overfill" these tanks.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The events that had same time stamp were reversed in order on every new
load of the log file. This patch will keep the order static. (Changing
order is annoying when using version control to store the logs.)
Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
They do the "02=0 means air" thing autmatically, and make for less
typing. So use them more widely in places that looked up the o2 and he
permille values of a gasmix.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
.. so that different computers that have different ordering of the same
cylinders will see the end result the same way.
This also fixes up the sample sensor index and generates special initial
tank change events for the dive computers that had their cylinder
indexes renamed on them.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Create a little widget that lists all the gases / tanks we know about and
allow the user to pick one of them.
Turns out that add_event only added events at the end of the list - but we
treat that list as chronologically sorted. So I fixed that little
mis-feature as well.
This does raise the question whether we need the inverse operation
(removing a gas change). And if there are other things that we should be
able to manually edit, now that we have the infrastructure for this neat
little context menu...
See #60 -- this doesn't address all of the issues mentioned there, but at
least deals with the 'headline' of the feature request...
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
merge_text() could call strdup(NULL) if one pointer was "" and the other
NULL. This commit fixes that.
Reported-by: fhuberts
Analyzed-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
A couple of these could clearly cause a crash just like the one fixed by
commit 00865f5a1e1a ("equipment.c: Fix potential buffer overflow in
size_data_funct()").
One would append user input to fixed length buffer without checking.
We were hardcoding the (correct) max path length in macos.c - replaced by
the actual OS constant.
But the vast majority are just extremely generous guesses how long
localized strings could possibly be.
Yes, this commit is likely leaning towards overkill. But we have now been
bitten by buffer overflow crashes twice that were caused by localization,
so I tried to go through all of the code and identify every possible
buffer that could be affected by this.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This fixes two bugs:
- we overwrote the max depth that we read from an XML file with 0 if there
are no samples
- we didn't parse the DepthAvg tag in the DivingLog XML
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This creates a helper function called "gas_volume()" that takes the
cylinder and a particular pressure, and returns the estimated volume of
the gas at surface pressure, including proper approximation of the
incompressibility of gas.
It very much is an approximation, but it's closer to reality than
assuming a pure ideal gas. See for example compressibility at
http://en.wikipedia.org/wiki/Compressibility_factor
Suggested-by: Jukka Lind <jukka.lind@iki.fi>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The code was written to get the SAC rate correct, but we probably do
want to have the duration and mean depth of the dive always be shown for
the non-surface-time.
So move the code from the sac-rate calculation to the generic dive fixup
part. This makes the dive list and statistics all show the duration as
the under-water duration, which is not necessarily the same as
"difference between beginning and end of dive".
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We computed a made-up average depth based on the maximum depth, and used
that. That's questionable even if we didn't have any explicit average
depth to begin with, but it's particularly wrong if we did have an
explicit average depth to use.
Now, admittedly we have no way to actually create fake dives like this
with a particular average depth, so this really doesn't make any
difference in real life. But we should do this right.
Also, make the XML be in the format that subsurface actually saves
things in (mainly things like cylinder sizes having an extra decimal
place, but also ordering of XML elements).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We even documented that we did SAC in bar*l/min, but the "S" in SAC
stands for "Surface". So we should normalize SAC rate to surface
pressure, not one bar.
It's a tiny 1% difference, and doesn't actually matter in practice, but
it's noticeable when you want to explicitly test for SAC-rate by
creating a test-dive that averages exactly 10m. Suddenly you don't get
the round numbers you expect.
[ Side note: 10m is not _exactly_ one extra atmosphere according to our
calculations, but it's darn close in sea water: the standard salinity
of 1.03 kg/l together with the standard acceleration of 9.81m/s^2
gives an additional pressure of 1.01 bar, which is within a fraction
of a percent of one ATM.
Of course, divers have likely chosen that value exactly for the math
to come out that way, since the true average salinity of seawater is
actually slightly lower ]
So here's a few test-dives, along with the SAC rate fixup to make them
look right.
(There's also a one-liner to dive.c that makes the duration come out
right if the last sample has a non-zero depth, and the previous sample
did not: one of my original test-dives did the "average 10m depth" by
starting at 0 and ending at 20m, and dive.c got a tiny bit confused
about that ;)
[ The rationale for me testing our SAC rate calculations in the first
place was that on snorkkeli.net user "Poltsi" reported that our SAC rate
calculations differ from the ones that Suunto DM4 reports. So I wanted
to verify that we did things right.
Note that Poltsi reported differences larger than the difference of
BAR/ATM, so this is not the cause. I'll continue to look at this. ]
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We have this oddity in "fixup_dive()" that we fix up the dive water
temperates and durations by looking over all the dive computer data.
But we actually call that *before* we've fixed-up the dive computer data.
So the water temperature is there in the samples, but hasn't made it to
the generic dive computer water temperature yet, so then it doesn't make
it into the dive structure either.
Until the *second* time, when we have load the (partially fixed-up) data.
Acked-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Downloading dives from the dive computer attempts to merge same dives,
e.g. when multiple dive computers are used. If the mean depth is zero when
downloading from DC this comparison fails resulting in not merging the
multiple dive computers used on one dive. This patch skips the mean depth
comparison when this information is not available.
Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We now load and save this in the XML file, we do the right thing when
merging dives and show the edited air temperature in the Dive Info
notebook when a divecomputer doesn't have an air temperature.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Two separate bugs.
a) Air cylinders were created with o2=209 and no other value set.
sanitize_gasmix() turned that into o2=0 which meant that this cylinder was
now identified as "nodata", i.e., unset.
We now set a fake cylinder name to deal with that issue.
b) the gaschange event is inherited from libdivecomputer and therefore
only supports 1 percent granularity for o2 and h2. Since we didn't round
when assigning the value we ended up with air being stored as o2=20 he=0
which of course then didn't match air anymore (which we have defined as
208 <= o2 <= 210).
We now use o2=210 for air in the planner and carefully round the permille
values whenever we convert into percent - and compare gases with percent
granularity as well.
A better fix for b) would be to change the Subsurface event to not simply
copy the libdivecomputer behavior and use percent granularity but support
permille instead. But this closely before the 3.0 release that seemed like
a far too invasive change to make - the changes to the planner should have
no impact outside the planner module.
Reported-by: Chris Lewis <chrislewis915@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This showed up when suddenly some of the test dives no longer got merged
when loaded twice. As I moved maxdepth up into the dive structure and
added the code to fixup the data from what is in the divecomputer I missed
the part where the function is exited early if there are no samples. This
patch corrects that oversight.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This adds watertemp and airtemp to the dive, populates them in fixup and
uses them elsewhere in the code.
WARNING: as a sideeffect we now edit the airtemp in the dive, but we never
display this in the DIve Info notebook (as that always displays the data
from the specific selected divecomputer). This is likely to cause
confusion. It's consistent behavior, but... odd. This brings back the
desire to have a view of "best data available" for a dive, in addition to
the "per divecomputer" view. This would also allow us to consolidate the
different pressure graphs we may be getting from different divecomputers
(consider the case where you dive with multiple air integrated computers
that are connected to different tanks - now we could have one profile with
all the correct tank pressure plots overlayed - and the best available (or
edited) data in the corresponding Dive Info notebook.
This commit also fixes a few remaining accesses to the first divecomputer
that fell through the cracks earlier and does a couple of other related
cleanups.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When starting on this quest to stop using the first divecomputer instead
of data for the whole dive in commit eb73b5a528c8 ("Duration of a dive is
the maximum duration from all divecomputers") I introduced an accessor
function that calculates the dive duration on the fly as the maximum of
the durations in the divecomputers.
Since then Linus and I have added quite a few of the variables back to the
dive data structure and it makes perfect sense to do the same thing for
the duration as well and simply do the calculation once during fixup.
This commit also replaces accesses to the first divecomputer in
likely_same_dive to use the maxdepth and meandepth of the dive (those two
slipped through the cracks in the previous commits, it seems).
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This is currently only used in one place (in statistics.c), but it
certainly is consistent with the other recent changes to avoid using only
the first divecomputer when trying to make statements about a dive.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In commit 904aa0be0d0e ("Do more dive fixup for each dive computer") two
new helper functions were introduced that sadly both incremented variables
without initializing them, first.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Populate during dive fixup as the maximum depth shown by all the
divecomputers. Use this value (instead of the one in the first
divecomputer) in printing, statistics, etc.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The existing code only populated the maxtemp based on the samples of a
dive and then in statistics.c checked if there was no such temperature and
replaced it with the water temperature of the first divecomputer.
It makes much more sense to add the water temperature information in every
divecomputer to the min / max calculation during the dive fixup phase.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The fixup_dives() code used to only look at the first divecomputer,
which meant that minimun temperatures etc for the dive would only ever
come from the primary divecomputer.
This splits up the code that walks over the divecomputer into a function
of its own, and iterates over all computers in fixup_dive() calling into
it.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In commit b6c9301e58 ("Move more dive computer filled data to the
divecomputer structure") we moved the fields that get filled in by the
dive computers to be per-divecomputer data structures.
This patch re-creates some of those fields back in the "struct dive",
but now the fields are initialized to be a reasonable average from the
dive computer data. We already did some of this for the temperature
min/max fields for the statistics, so this just continues that trend.
The goal is to make it easy to look at "dive values" without having to
iterate over dive computers every time you do. Just do it once in
"fixup_dive()" instead.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Instead of maintaining a rolling average and re-calculating it at each
stage, just calculate the surface_pressure average the natural way: as
the sum divided by the number of entries.
This results in a single rounding, rather than doing rounding multiple
times and possibly rounding wrong as a result.
Not that we care all that deeply about the LSB of the mbar value, but
the code is simpler and more obvious this way too.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
There are two ways to look at surface pressure. One is to say "what was
the surface pressure during that dive?" - in that case we now return an
average over the pressure reported by the different divecomputers (or the
standard 1013mbar if none reported any).
Or you want to do specific calculations for a specific divecomputer - in
which case we access only the pressure reported by THAT divecomputer, if
present (and fall back to the previous case, otherwise).
We still have lots of places in Subsurface that only act on the first
divecomputer. As a side effect of this change we now make this more
obvious as we in those cases pass a pointer to the first divecomputer
explicitly to the calculations.
Either way, this commit should prevent us from ever mistakenly basing our
calculations on a surface pressure of 0 (which is the initial bug in
deco.c that triggered all this).
Similar changes need to be made for other elements that we currently only
use from the first divecomputer, i.e., salinity.
Reported-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Some days I'm just a f*cking moron. That code was so stupid that I'm
lacking words. I replaced using the first divecomputer with using the last
divecomputer. When what I wanted was to use the maximum duration.
This looks better.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
So far we always used the duration of the first divecomputer. The same fix
needs to be done for some of the other calculations that always use the
first divecomputer.
This commit also removes some obsolete code from the webservice merging.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Merging two different dives by interleaving dive computer data got
broken by the multi-dive-computer code in commit b6c9301e58 ("Move
more dive computer filled data to the divecomputer structure") which
added a lot more entries to the dive computer data structure, and then
copied the resulting structure incorrectly.
Make sure we don't copy the events and samples allocations when we copy
all the other fields of the divecomputer.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We had this special logic to not show the end of a dive when a dive
computer shows a series of very shallow samples (basically snorkeling
back to shore after the dive ended). However, that logic ended up being
global per dive, which is very annoying when you have two or more dive
computers, and it decides to cut off the second one because the first
one surfaces.
So get rid of this per-dive state, and just use the plot-info 'maxtime'
field for this (we never used the 'start' case anyway). That way we
will properly cut off boring surface entries only when they are past the
end of the interesting entries of *all* dive computers, and we won't be
cutting things short.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This no longer abuses the dive merging code (which would leave stray
"dives" behind if a gps fix couldn't be merged with any of the dives) and
instead parses the gps fixes into a second table and then walks that table
and tries to find matching dives.
The code tries to be reasonably smart about this. If we have
auto-generated GPS fixes at regular intervals, we look for a fix that is
during a dive (that's likely when the boat where the phone is staying dry
is more or less above the diver having fun). And if we have named entries
(so the user typed in a location name) we try to match them in order to
the dives that happened "that day" (where "that day" is about 6h before
and after the timestamp of the gps fix).
This commit also renames dive_has_location() to dive_has_gps_location() as
the difference between if(!dive->location) and if(dives_has_location) is a
bit too subtle...
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Mostly coding style and whitespace changes plus making lots of functions
static that have no need to be extern. This also helped find a bit of code
that is actually no longer used.
This should have absolutely no functional impact - all changes should be
purely cosmetic. But it removes a bunch of lines of code and makes the
rest easier to read.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The statistics page only used each dive's "watertemp" attribute,
regardless of actual higher/lower temperatures in the samples. By
finding the actual max/min temperatures, the statistics page utilize
more "real" data, and look better even on single dives.
Signed-off-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This moves the fields 'duration', 'surfacetime', 'maxdepth',
'meandepth', 'airtemp', 'watertemp', 'salinity' and 'surface_pressure'
to the per-divecomputer data structure. They are filled in by the dive
computer, and normally not edited.
NOTE! All actual *use* of this data was then changed from dive->field to
dive->dc.field programmatically with a shell-script and sed, and the
result then edited for details. So while the XML save and restore code
has been updated, all the displaying etc will currently always just show
the first dive computer entry.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Dive locations marked (and named) via the companion app are downloaded
from the webservice, parsed and merged with the existing dives.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
It used to be that when you checked the "Prefer downloaded" checkmark,
we'd throw away *any* old dive computer data. That was good, because it
allowed us to start from a clean slate when you had some old subsurface
data with questionable dive computer data.
However, it was a bit extreme, and it's really not what you want if you
already have (good) dive computer data from other dive computers.
So this modifies the logic a bit. Instead of throwing away all old dive
computer data, the "Prefer downloaded" checkmark now means:
- the newly downloaded data becomes the "primary" dive computer data
(ie the first in the list)
- if there was old dive computer data that *could* have been from this
new dive computer (ie it didn't have model information, or it had a
matching model but no device ID data), we throw that away
- but any existing dive computer data from other dive computers is left.
This seems to be much closer to what we really would want for a new
"preferred" download.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This patch centralizes the definition for surface pressure, oxygen in
air, (re)defines all such values as plain integers and adapts calculations.
It eliminates 11 (!) occurrences of definitions for surface pressure and
also a few for oxygen in air.
It also rewrites the calculation for EAD, END and EADD using the new
definitons, harmonizing it for OC and CC and fixes a bug for EADD OC
calculation.
And finally it removes the unneeded variable entry_ead in gtk-gui.c.
Jan
Signed-off-by: Jan Schubert <Jan.Schubert@GMX.li>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
.. and rename the badly named 'output_units/input_units' variables.
We used to have this confusing thing where we had two different units
(input vs output) that *look* like they are mirror images, but in fact
"output_units" was the user units, and "input_units" are the XML parsing
units.
So this renames them to be clearer. "output_units" is now just "units"
(it's the units a user would ever see), and "input_units" is now
"xml_parsing_units" and set by the XML file parsers to reflect the units
of the parsed file.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This clarifies/changes the meaning of our "cylinderindex" entry in our
samples. It has been rather confused, because different dive computers
have done things differently, and the naming really hasn't helped.
There are two totally different - and independent - cylinder "indexes":
- the pressure sensor index, which indicates which cylinder the sensor
data is from.
- the "active cylinder" index, which indicates which cylinder we actually
breathe from.
These two values really are totally independent, and have nothing
what-so-ever to do with each other. The sensor index may well be fixed:
many dive computers only support a single pressure sensor (whether
wireless or wired), and the sensor index is thus always zero.
Other dive computers may support multiple pressure sensors, and the gas
switch event may - or may not - indicate that the sensor changed too. A
dive computer might give the sensor data for *all* cylinders it can read,
regardless of which one is the one we're actively breathing. In fact, some
dive computers might give sensor data for not just *your* cylinder, but
your buddies.
This patch renames "cylinderindex" in the samples as "sensor", making it
quite clear that it's about which sensor index the pressure data in the
sample is about.
The way we figure out which is the currently active gas is with an
explicit has change event. If a computer (like the Uemis Zurich) joins the
two concepts together, then a sensor change should also create a gas
switch event. This patch also changes the Uemis importer to do that.
Finally, it should be noted that the plot info works totally separately
from the sample data, and is about what we actually *display*, not about
the sample pressures etc. In the plot info, the "cylinderindex" does in
fact mean the currently active cylinder, and while it is initially set to
match the sensor information from the samples, we then walk the gas change
events and fix it up - and if the active cylinder differs from the sensor
cylinder, we clear the sensor data.
[Dirk Hohndel: this conflicted with some of my recent changes - I think
I merged things correctly...]
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We used to have the rule that a dive trip has to have all dives in it in
sequential order, even though our XML file really is much more flexible,
and allows arbitrary nesting of dives within a dive trip.
Put another way, the old model had fairly inflexible rules:
- the dive array is sorted by time
- a dive trip is always a contiguous slice of this sorted array
which makes perfect sense when you think of the dive and trip list as a
physical activity by one person, but leads to various very subtle issues
in the general case when there are no guarantees that the user then uses
subsurface that way.
In particular, if you load the XML files of two divers that have
overlapping dive trips, the end result is incredibly messy, and does not
conform to the above model at all.
There's two ways to enforce such conformance:
- disallow that kind of behavior entirely.
This is actually hard. Our XML files aren't date-based, they are
based on XML nesting rules, and even a single XML file can have
nesting that violates the date ordering. With multiple XML files,
it's trivial to do in practice, and while we could just fail at
loading, the failure would have to be a hard failure that leaves the
user no way to use the data at all.
- try to "fix it up" by sorting, splitting, and combining dive trips
automatically.
Dirk had a patch to do this, but it really does destroy the actual
dive data: if you load both mine and Dirk's dive trips, you ended up
with a result that followed the above two technical rules, but that
didn't actually make any *sense*.
So this patch doesn't try to enforce the rules, and instead just changes
them to be more generic:
- the dive array is still sorted by dive time
- a dive trip is just an arbitrary collection of dives.
The relaxed rules means that mixing dives and dive trips for two people
is trivial, and we can easily handle any XML file. The dive trip is
defined by the XML nesting level, and is totally independent of any
date-based sorting.
It does require a few things:
- when we save our dive data, we have to do it hierarchically by dive
trip, not just by walking the dive array linearly.
- similarly, when we create the dive tree model, we can't just blindly
walk the array of dives one by one, we have to look up the correct
trip (parent)
- when we try to merge two dives that are adjacent (by date sorting),
we can't do it if they are in different trips.
but apart from that, nothing else really changes.
NOTE! Despite the new relaxed model, creating totally disjoing dive
trips is not all that easy (nor is there any *reason* for it to be
easty). Our GUI interfaces still are "add dive to trip above" etc, and
the automatic adding of dives to dive trips is obviously still based on
date.
So this does not really change the expected normal usage, the relaxed
data structure rules just mean that we don't need to worry about the odd
cases as much, because we can just let them be.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit makes deco handling in Subsurface more compatible with the way
libdivecomputer creates the data. Previously we assumed that having a
stopdepth or stoptime and no ndl meant that we were in deco. But
libdivecomputer supports many dive computers that provide the deco state
of the diver but with no information about the next stop or the time
needed there. In order to be able to model this in Subsurface this adds an
in_deco flag to the samples. This is only stored to the XML file when it
changes so it doesn't add much overhead but will allow us to display some
deco information on dive computers like the Atomic Aquatics Cobalt or many
of the Suuntos (among others).
The commit also removes the old event based deco code that was commented
out already. And fixes the code so that the deco / ndl information is
stored for the very last sample as well.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
dive.c:merge_text():
When "or" is translated into other languages it may be longer than 2 letters,
therefore there is a need for a slightly larger buffer to be reserved.
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
dive.c:
merge_cyclinder_type() can cause a small memory leak if two cylinder types
are about to be merged, but the redundant one has a "description" string
allocated.
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
dive.c:
A dive computer may have its model allocated in memory.
Let's clear that as well when calling free_dc().
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This patch makes a couple of modifications:
1) divelist.c:delete_single_dive() now tries to free all memory associated
with a dive, such as the string values for divemaster, location, notes &
etc.
2) dive.c:merge_text(), now always makes a copy in memory for the returned
string - either combined or one of the two which are passed
to the function.
The reason for the above two changes is that when (say) importing the same
data over and over, technically a merge will occur for the contained dives,
but mapped pointers can go out of scope.
main.c:report_dives() calls try_to_merge() and if succeeds the two dives
that were merged are deleted from the table. when we delete a dive,
we now make sure all string data is cleared with it, but also in the actual merge
itself, which precedes, copies of the merged texts are made (with merge_text()),
so that the new, resulted dive has his own text allocations.
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We had logic to remove duplicate dive computer information after merging
dives, but it didn't actually work.
Why? Because we had used the 'res' dive computer pointer to traverse the
list of dive computers, so it no longer actually pointed to the first
dive computer in the result list any more, and so the "remove redundant"
code only removed redundant dive computers from a limited and incomplete
list.
Oops.
Also, before checking the whole event and sample list, check if it's the
exact same dive computer using our new "match_one_dc()" helper function,
and don't even bother checking for sample details if it is.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
If we havd divecomputer model and dive ID information available, use
that to match existing dives when trying to merge them.
Otherwise fall back to the fuzzy time-based merging logic.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
I foolishly changed visible_columns in both the (ill-named) cns branch and
master...
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Conflicts:
divelist.c
gtk-gui.c
profile.c
We either pick the CNS reported by the dive computer at the end of the
dive, or the maximum of that and the CNS values in the samples, if any.
As usual, this column in the dive list defaults to off and it is
controlled by a setting in the tec page of the preferences.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Now we can simply remember the state of all the preferences at the
beginning of preferences_dialog() and restore them if the user presses
'Cancel'.
Fixes#21
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This adds the new members to the sample structure and fills them from
supported dive computers (Uemis SDA and OSTC / Shearwater Predator,
assuming you have libdivecomputer 0.3).
Save relvant values of this to the XML file and load it back. Handle the
new fields when merging dives.
At this stage we don't DO anything with this, all we do is extract them
from the dive computer, save them to the XML file and load them back.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
From 178a3f0d6d5112f76943fec5f8c1c1f3b173a7f4 Mon Sep 17 00:00:00 2001
From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Fri, 7 Dec 2012 09:34:18 -0800
Subject: [PATCH 2/2] Tune the dive joining surface event insert code
So this makes us do surface events only if the samples are more than one
minute apart, and are shallow enough (randomly selected at 5m).
We can add more heuristics. Maybe we should compare the 1-minute sample
time limit of the previous sample to the time to the sample before that:
if some computer (or manually entered dive) has a long time between
*all* samples, we'd make the cut-off time longer.
Baby steps.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This doesn't really change the logic of the merging, but it does mean
that the end result tends to be less unexpected: when downloading dives
that end up being merged with pre-existing dives (because you have
multiple dive computers, for example), the newly downloaded dive data
will tend to be appended to the old dive data, rather than showing up
first.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Handle the case where we have no divecomputer information.
Reported-by: Sergey Starosek <sergey.starosek@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This actually makes us internally use 'micro-degrees' for latitude and
longitude, and we never turn them into floating point either at parse
time or save time.
That said, the Uemis downloader internally does still use atof() when
converting things, which is likely a bug (locale issues and all that),
but I'll ask Dirk to check it out.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This tunes the heuristics for when to merge two dives together into a
single dive. We used to just look at the date, and say "if they're
within one minute of each other, try to merge". This looks at the
actual dive data, and tries to see just how much sense it makes to
merge the dive.
It also checks if the dives to be merged use different dive computers,
and if so relaxes the one minute to five, since most people aren't
quite as OCD as I am, and don't tend to set their dive computers quite
that exactly to the same time and date.
I'm sure people can come up with other heuristics, but this should
make that easier too.
NOTE! If you have things like wrong timezones etc, and the
divecomputer dates are thus off by hours rather than by a couple of
minutes, this will still not merge them. For that kind of situation,
we'd need some kind of manual merge option. Note that that is *not*
the same as the current "merge two adjacent dives" together, which
joins two separate dives into one *longer* dive with a surface
interval in between.
That kind of manual merge UI makes sense, but is independent of this
partical change.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When picking the "better" trip, we stupidly looked not at the trip
location, but at the _dive_ location.
Which obviously didn't actually pick the "better" trip information at
all, since it never actually looked at the trip itself.
Oops.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Commit bb6b6b49a6d4 "Start merging dives by keeping the dive computer data
from both dives" created a compile time warning. This simply adds an #if /
Yes, this might accelearate bit rod in the code, but I just dislike the
warning message when compiling Subsurface.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Now that we have dive computer device ID fields etc, we can do a much
better job of merging the dive computer data.
The rule is
- if we actually merge two disjoint dives (ie extended surface interval
causing the dive computer to think the dive ended and turning two of
those dives into one), find the *matching* dive computer from the
other dive to combine with.
- if we are merging dives at the same time, discard old-style data with
no dive computer info (ie act like a re-download)
- if we have new-style dive computers with identifiers, take them all.
which seems to work fairly well.
There's more tweaking to be done, but I think this is getting to the
point where it largely works.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Also, note that we do *not* do the "find_sample_offset()" any more when
we merge two dives that happen at the same time - since we just keep
both sets of dive computer data around.
But we keep the function to find the best offset around, because we may
well want to use it later when *showing* the dive, and trying to match
up the different sample data from the multiple dive computers associated
with the dive.
Because of that, this causes warnings about the now unused function.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When we have a preferred dive computer that overrides old information
when merging two dives, we just copy the dive computer data over.
However, we need to clear the source of the dive computer data so that
we then don't free the sample data when that old source of the newly
merged dive gets free'd.
This fixes a memory scribble (and likely SIGSEGV) for the "prefer
downloaded" case.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
For now we only have one fixed divecomputer associated with each dive,
so this doesn't really change any current semantics. But it will make
it easier for us to associate a dive with multiple dive computers.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We used to avoid some extra allocations by just allocating the dive
samples as part of the 'struct dive' allocation itself, but that ends up
complicating things, and will make it impossible to have multiple
different sets of samples (for multiple dive computers).
So stop doing it. Just allocate the dive samples array separately.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When this was first implemented the assumption was that a downloaded dive
that is to be merged with an existing dive would have the same time stamp.
But as Linus pointed out even back then, this does fail if a dive has been
merged with a download from a different dive computer before (think:
download from computer a, then download same dive from b, then improve
something in the parsing from computer a and try to redownload; the time
stamp could have changed).
This commit also fixes a silly omission in the merge_dives() function
(which ended up ALWAYS prefering the downloaded dive) and finally
implements the necessary changes to mark dives downloaded from a Uemis SDA
as well.
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>
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>
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>
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>
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>
We used to have very spotty logic for picking the dive trip when
merging two dives. It turns out that that spotty logic almost never
really matters, because in practice you'll never hit the situation of
merging two dives with different dive trips, but it *can* happen.
In particular, it happens when you use multiple dive computers, and
end up loading the dives from one computer on top of the dives of your
other computer. If the clocks of the dive computers was set
sufficiently close to each other, the dive merging logic will kick in
and you may now have slightly different times for the dives that get
merged, and the trip merging logic got *really* confused.
The trip management also depends on the trip dates being updated
correctly when the dives associated with a trip are updated (whether
added or removed), and the trip merging code did none of that.
This fixes it all up. Hopefully correctly.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
I just tried downloading some duplicate dives I had on my second dive
computer, and it all "just worked" and subsurface merged them for me.
Almost perfectly.
I say "almost", because in merging them, it threw my old weightsystem
data away, due to that not being merged.
Also, it was a perfect merge only because the computers are so similar
that they just line everything up - same water activation logic, same
sample interval, same pretty much everything. So while I know the
sample merging is not really the right thing to do (it was designed to
get the "merge the exact same dive from the same computer" case
right), it worked well enough for this particular case. I'll look at
something better later.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
get_pressure_units() and get_volume_units() should
return localized strings.
[Dirk Hohndel: updated to use the correct macro]
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This is just the first step - convert the string literals, try to catch
all the places where this isn't possible and the program needs to convert
string constants at runtime (those are the N_ macros).
Add a very rough first German localization so I can at least test what I
have done. Seriously, I have never used a localized OS, so I am certain
that I have many of the 'standard' translations wrong. Someone please take
over :-)
Major issues with this:
- right now it hardcodes the search path for the message catalog to be
./locale - that's of course bogus, but it works well while doing initial
testing. Once the tooling support is there we just should use the OS
default.
- even though de_DE defaults to ISO-8859-15 (or ISO-8859-1 - the internets
can't seem to agree) I went with UTF-8 as that is what Gtk appears to
want to use internally. ISO-8859-15 encoded .mo files create funny
looking artefacts instead of Umlaute.
- no support at all in the Makefile - I was hoping someone with more
experience in how to best set this up would contribute a good set of
Makefile rules - likely this will help fix the first issue in that it
will also install the .mo file(s) in the correct place(s)
For now simply run
msgfmt -c -o subsurface.mo deutsch.po
to create the subsurface.mo file and then move it to
./locale/de_DE.UTF-8/LC_MESSAGES/subsurface.mo
If you make changes to the sources and need to add new strings to be
translated, this is what seems to work (again, should be tooled through
the Makefile):
xgettext -o subsurface-new.pot -s -k_ -kN_ --add-comments="++GETTEXT" *.c
msgmerge -s -U po/deutsch.po subsurface-new.pot
If you do this PLEASE do one commit that just has the new msgid as
changes in line numbers create a TON of diff-noise. Do changes to
translations in a SEPARATE commit.
- no testing at all on Windows or Mac
It builds on Windows :-)
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In dive.c:fixup_dive() it would be better to call functions
like add_people() and add_location() before the possible return
in the "if (end < 0)" branch.
This prevents a partial auto-complete list in "Dive Info"
combo boxes.
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This introduces a new data structure for dive trips - reuseing the struct
dive just got way too messy.
The dive_trip_t datastructure now allows the code to remember if the trip
was auto generated or if its time stamp changed when dives where added to
the trip during auto generation.
The algorithm also distinguishes between dives that were intentionally
added to a trip (either in an XML file or by adding them to trip in the
UI) and dives that were added to trips via autogen. Saving dives that were
added to trips via autogen makes that assignment "intentional".
With this partial rewrite several of the oddities of the old code should
be resolved - especially turning autogen on and off again should get the
divelist back to the previous stage.
Also, when dives are merged during file open or import we now try to pick
the correct tripflag (instead of just ignoring the tripflag completely and
resetting it to TF_NONE by mistake).
Finally, the dive trip debugging code got more verbose and is trying
harder to detect issues at the earliest time possible.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Thanks to Christian for running the static code analysis tool against
subsurface...
There were some false positives, a few style issues that I'll ignore for
now, and two actual potential bugs.
First: Don't check unsigned variables for < 0
This has been around for a while and we are lucky that while technically a
bug it still works as expected. Passing a negative idx simply turns it
into a very large unsigned integer which then fails the > dive_table.nr
test. So it still gets a NULL returned. A bug? Yes. Critical? No.
Mismatched allocation and free
This is an actual bug that potentially could cause issues. We allocate
memory with malloc and free it with g_free. Not good.
Reported-by: Cristian Ionescu-Idbohrn <cristian.ionescu-idbohrn@axis.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Freedives can easily exceed the assumed ascent/descent rate, which
results in wacky dive profiles. Add a check to make the ascent and
descent fit within the duration of the dive.
This fixes the case of the dive duration being zero, or being shorter
than the assumed ascent/descent time.
Reported-by: Lutz Vieweg <lvml@5t9.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Pull miscellaneous fixes, mostly UI stuff from Mikko Rasa.
Both this and the pull from Pierre-Yves Chibon created a "Save As" menu
entry and logic. As a result, there were a fair number of conflicts,
but I tried to make the end result somewhat reasonable. I might have
missed some semantic conflict, though.
Series-acked-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
* 'misc-fixes' of git://github.com/DataBeaver/subsurface:
Add a separate "Save as" entry to the menu
Changes to menu icons
Improved depth info for dives without samples
Divide the panes evenly in view_three
For simplicity and shortness, throughout subsurface exposure protection is
simply referred to as "suit".
Add the fields to the data structures, add the column to the dive_list
and the preferences dialog (once again with it being turned invisible by
default). Support loading and saving of the suit information.
Display the suit information in the Dive Info pane (this may be a bit
controversial as people could argue this should be in the Equipment pane)
and allow editing of the suit info, with our usual support for completion
and drop down lists to pick from.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This adds the total weight carried on the dive in different weight systems
to the divelist. The column is by default not shown, which can be changed
in the preferences. The column is sortable.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This was simply an omission in the current implementation. All the
plumbing was there but never got hooked up with the fixup_dive function as
intended.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This calculates a mean depth for the dive with a fixed ascent/descent
rate and an assumption that all of the bottom time is at the maximum
depth. It's not much, but it allows some derived values such as SAC to
make more sense.
The depth profile for such dives is now also generated with the same
assumptions instead of putting the samples at fixed percentages of the
dive duration.
Signed-off-by: Mikko Rasa <tdb@tdb.fi>
Right now we do certain cylinder info operations only when importing
from an XML file, which is wrong. In particular, we do the "is the
gasmix air" or "what is the standard cylinder name" only at XML read
time, which means that if you import a dive directly from the dive
computer, it won't have the air sanitization or the proper default
cylinder names.
Of course, most dive computers don't actually save enough cylinder
information for us to do the cylinder name lookup anyway, but some do.
And all Nitrox-capable dive computers do have that O2 percentage that
needs cleanup too.
Reported-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This works ok-ish, but doesn't allow us to click on the stars and edit
them in the divelist, which a user might expect to be able to do - in
most "star rating UIs" you simply click on the n-th star to set that
rating. Here you need to edit the dive and pick the rating from a drop
down menu.
Minor oddity: you can actually (if you force it) write anything you want
into the star rating. But anything that isn't one of the predefined
strings simply results in a zero star rating.
Overall the UI feels a bit... forced. But I think this is quite useful
anyway.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
I've seen at least DivingLog do this. If you manually enter beginning and
end pressure for a tank it will either linearize the samples in between or
offer to simulate a dive (with constant SAC rate). At least the first case
is reasonably easy to detect. We throw out those samples and ensure that
we still have valid beginning and end pressure for that dive.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
At least the Suunto pressure transmitter seems to be pretty
"quantisized", and it will send identical samples for a while until the
pressure changes enough. Then subsurface gives this silly flat line
with a sudden jump downwards, which *could* be you suddenly taking a
deep breath after holding it for a while, but almost certainly it's a
sensor issue.
So just remove successive identical pressure readings. They aren't
interesting, and subsurface will actually do a good job of interpolating
it according to SAC rate instead. And they just make the XML look
worse.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This makes it consider them to be identical if they are within half a
bar of each other. If you edit the pressures by hand and set them to
the same bar pressure as the samples, they may not be identical to the
last milli-bar, but clearly the manually entered cylinder pressure isn't
significantly different from the sample data, so consider it redundant.
We do want manual overrides of cylinder pressures to take precedence
over sample data (as Dirk so eloquently puts it, some dive computers
really don't have very reliable sample data), but at the same time the
sample data is the one we are expecting to be fairly accurate. The
starting and ending pressure overrides are for when there is no sample
data, or when the sample data is totally wrong for some reason.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Keep the sample pressure start/end data separate from the overall
cylinder start/end data - and clean the overall cylinder start/end data
if it matches the samples exactly to avoid the redundancy.
This breaks all the SAC calculations etc, which expect the cylinder
pressures to always be in the cylinder data. I'll fix that up
separately.
The reason for this is that we really want to keep the manually entered
data separate: the pressure plotting doesn't need the confusion, and
considers end-point data (with interpolation) very different from sample
data. Also, we do not want to pollute the xml save-file with data that
is computed.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Finally getting more consistent overall in how we convert between the
different units and how we decide which units to display.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Treat SAC and OTU consistently:
- SAC is now a member of struct dive
- it's calculated / populated at the same time with a helper function with
consistent API
Create get_volume_units function that returns volumes (e.g. used in SAC
rates) based on preferred units - make sure we have these conversions just
once in the code.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Designed along the lines of get_depth_units - except we don't define a
specific number of digits to show.
Use this in the one spot we need it right now in profile.c
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
First step to being able to filter the events that we display in the
profile. We could (in theory) walk all the dives in the divelist when we
need this data, but it seems much more convenient to have them in an array
in one place.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This way you can just type the first few characters of a location you've
been to before, and it will show you a list of possible completions.
Same for buddies and divemasters (which take the completions from a list
of people you've used before).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This way the cylinder model list will contain all the different
cylinders that we have ever seen, rather than only containing the models
that we have *edited*.
That makes it much more practical to add new dives with the same
cylinders that we've used before, because now those cylinders will show
up as cylinder models even if we haven't looked and edited the old dives
first.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
If we have en explicit end pressure in the dive information, we should
not change it just because we also have some samples. The sample data
may not be complete (read: "Linus wireless connection dropped during the
dive again, and he fixed up the end pressure manually afterwards").
The beginning pressure already works correctly, because it will only use
the sample data for the first sample if no pressure existed before.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Depending on the tool used to import a dive from the uemis Zurich we end
up with different time stamps for the dive - just by a few seconds, but
the existing code insisted on an exact match.
We now allow for up to 60 seconds in difference and still consider two
dives as the same.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
At first glance it seems logical to make the ending pressure be the
lowest pressure observed during a dive. But if you do valve shut down
drills with a tech setup (where you have a fully redundant double
tank setup with two valves, two regulators and a manifold in between),
then you continue to breath from what is indeed the same "tank", but still
the valve on which your air pressure transmitter sits does get shut down
and de-pressurized. So your pressure goes down by quite a bit, and then
comes back up when the valve is turned back on.
And the ending pressure of the dive (which is used for things like the SAC
calculation) is indeed potentially higher than the lowest pressure
observed during a dive.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When merging two identical dives and one of them has lat/long data, pick
it up correctly for the merged dive.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Parse them, save them, take them from libdivecomputer.
This doesn't merge them or show them in the profile yet, though.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
The following are UI toolkit specific:
gtk-gui.c - overall layout, main window of the UI
divelist.c - list of dives subsurface maintains
equipment.c - equipment / tank information for each dive
info.c - detailed dive info
print.c - printing
The rest is independent of the UI:
main.c i - program frame
dive.c i - creates and maintaines the internal dive list structure
libdivecomputer.c
uemis.c
parse-xml.c
save-xml.c - interface with dive computers and the XML files
profile.c - creates the data for the profile and draws it using cairo
This commit should contain NO functional changes, just moving code around
and a couple of minor abstractions.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
.. without the actual text, because I'm a "random plots that cannot
actually be interpreted" kind of guy.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
We're going to start to want to allocate dives and samples for the
libdivecomputer import too, so let's clean things up a bit for that.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
libdivecomputer already uses 'gasmix_t' for its own gasmix thing. I
don't like th eway we step on each others name spaces, but hey, might as
well just use 'struct gasmix' and avoid the typedef.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Doing per-dive cylinder start/end pressures is insane, when we can have
up to eight cylinders. The cylinder start/end pressure cannot be per
dive, it needs to be per cylinder.
This makes the save format cleaner too, we have all the cylinder data in
just one place.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
We don't want to override potentially more exact values for water
temperature etc either. The sample save interval may be longer than
some internally kept state of key per-dive values like that.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
.. and sort based on the 'time_t' value itself.
This allows us to use a more compact date format that doesn't need to
sort alphabetically, because sorting by date is always based on the date
value. So we can use just a two-digit year, and skip the seconds, to
keep the column narrow, while still sorting correctly.
Also, "Depth" is a nice header string, but it is wider than the column
itself, which makes the whole column wider than necessary. So put the
units in the header instead of in the string, keeping things narrow.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* 'compiler-warning' of https://github.com/nathansamson/diveclog:
Removed the unused startemp and enttemp calculations. This fixes a compiler warning too.
Fix up trivial conflict in dive.c due to the temperature simplification
(commit 9961c7f89c: "Remove redundant temperature readings").
I'm aiming to really differentiate in dive log software by making my XML
export files be *clean*, dammit.
That means that we don't have random names, we don't have crazy random
units, and we don't have redundant information.
So when the temperature doesn't change, just don't report it. That's
already what "no sample" means, just clean things up.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Instead of just tracking gasmix, track the size and workng pressure of
the cylinder too.
And use "cylinder" instead of "tank" throughout.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
The computer may track "real" max depth more closely than it tracks
samples. So we trust the non-computed mean/max depths more than the
computed ones.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Now the dive profile plot *really* needs some units. The pressure is
just a random line otherwise.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>