We don't really expect to get Nº of dives greater than the biggest
integer value.
Signed-off-by: Salvador Cuñat <salvador,cunat@gmail.com>
Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
WLog is a Win32 based ancient shareware program whose target was:
1) fully support divelogs coming from DataTrak (DOS or Win)
2) fill some meaningful data which wasn't supported by Uwatec software
3) have a more user-friendly GUI than Datatrak had
The problem achieving goals 1) and 2) at the same time was solved by
adding a complementary file with .add extension and - mandatory - same
base name than .log file (including directory tree).
This .add file has a fixed structure composed of a 12 bytes header,
including file type check and Nº of dives following; then a fixed 850
bytes size for each dive in the log file. Data fields size and position
are fixed inside these blocks and heavily zero padded, so they are easy
to parse.
A serious restriction imposed to the WLog user was *Do not edit the logs
with other software than Wlog*; this was due the order of dives in .log
file being the same than the order of dives in .add file. Thought you
could show a WLog divelog in Datatrak, editing it resulted in mixing all
extended data for dives following the edited one.
Thus, we have to trust files are correct and is to the user ensure this
is so. If extended data are mangled, they are mangled in WLog too and we
are not trying to fix the mess, just importing.
On the technical side, we try to be smart about tank names as neither
DataTrak nor WLog record them. So we just take the first tank in users
list matching the volume recorded in WLog.
For weights we add a translatable "unknown" string as an empty string
results in weight not being shown in subsurface-mobile (which could be a
reportable issue, BTW).
Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
When the dive has no explicity salinity, our conversion
between pressure and depth assumed salt water. Make this
explicity by using the corresponding macro.
When the planner starts and no salinity is set explicity,
set the water type chooser to salt water to reflect
our default assumption.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
While this code was added as I was trying to work through issues with a BLE
stack that turned out to be broken, the failure behavior of that device showed
that Qt doesn't like it when we start discovering the details of
characteristics while it is still busy discovering services.
So instead of handling the services as we find them, let's instead wait until
we are done discovering services and then discover the details for all those
services.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
There is no need to continue to look, and at least with the Shearwater
Peregrine having the scan run while we are trying to discover characteristics
appeared to cause issues.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
I can no longer reproduce the case where this rescan was necessary.
So let's remove it as it causes additional wait time for BT/BLE users on macOS.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
get_cylinder(d, i) is more readable than d->cylinders.cylinders[i].
Moreover, it does bound checking and is more flexible with respect to
changing the core data structures. Most places already used this accessor,
but some still accessed the cylinders directly.
This patch unifies the accesses by consistently switching to get_cylinder().
The affected code is in C++ and accesses the cylinder as reference or
object, whereas the get_cylinder() function is C and returns a pointer.
This results in funky looking "*get_cylinder(d, i)" expressions.
Arguably still better than the original.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The libdivecomputer internals changed for USB devices, and now we need
to scan the USB devices before calling libdivecomputer. That's the same
pattern as for USBHID and IRDA, so let's just regularize this all.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
getFormattedCylinder() is a helper function to format a list
of cylinders. It had that weird logic that it would skip
cylinders without description unless it is the first, which
would instead be written as "unkown".
The reason was the old statically sized cylinder array,
where it wasn't clear if a cylinder was actually in use.
This became obsolete when switching to a variable size
cylinder array. Firstly, all cylinders in the array were added
by the user. Secondly, we now also support dives without
cylinders, i.e. the first cylinder is not any different from
the rest.
Thus, remove the logic and format any cylinder without
description as being of type "unknown".
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This adds the Oceanic Veo 4.0 & Pro Plus 4, the Sherwood Wisdom 4 and the
Tecdiving DiveComputer.eu to our list of known names.
The Oceanic Pro Plus X detection is simply moved to have the other names
in a more logical order.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
0249e12 split up the dive import logic in multiple steps. Thereby,
the one of the conditions for renumbering the imported dives (is
the last old dive numbered) got messed up: The first number of the
new dive was compared to the total number of old dives, which makes
no sense.
- Simply check for the number of the last existing dive (if any).
- Don't remember the number of old dives - the original table is
not modified anyway.
Fixes#2731
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We are usually showing pressures with localized group separator. And we made a
total mess out of things when then re-parsing those values. This caused us to
ignore start and end pressures in Subsurface-mobile when those were entered in
psi and included a group separator:
2,900psi was turned into 2.900psi which we then rounded to 0 mbar.
This fixes the problem by asking Qt to do the right thing instead of doing
stupid separator magic.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The merge_events() function was subtly and not-so-subtly broken in a
couple of ways:
- in commit 8c2383b49 ("Undo: don't modify source-dives on merge"), we
stopped walking the event list after we merged the first event from a
dive when the other dive computer had run out of events.
In particular, this meant that when merging consecutive dives, the
second dive only had the first event copied over to the merged dive.
This happened because the original code just moved the whole old list
over when there was nothing left from the other dive, so the old code
didn't need to iterate over the event list. The new code didn't
realize that the pointer movement used to copy the whole rest of the
list, and also stopped iterating.
In all fairness, the new code did get the time offset right, which
the old code didn't. So this was always buggy.
- similarly, the "avoid redundant gas changes" case was not handled for
the "we ran out of events for the other dive computer" case.
This fixes both issues.
Cc: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
gettimezoneoffset() returns incorrect values when called with a time_t.
Since we only accept the value here if it is within 5 minutes of 'now',
using the current timezone offset is a fair approximation.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
For some reason we suddenly started logging the GPS fixes in UTC instead
of local time. Which caused the matching algorithm to fail (unless you
happened to be diving in UTC). Unclear what broke this, but this seems
like an easy enough fix, since the GPS fix being reported is by
definition "right around now". So using gettimezoneoffset() with the
current time seems "good enough".
I don't know when gettimezoneoffset() with an argument got broken, TBH.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
A while ago, we introduced a preference whether O2 should
be considered narcotic. We used this when computing
best mix or when entering the He content via MND. But
we forgot to make the displayed MND depend on this
preference. This patch add this.
Fixes#2895
Signed-off-by: Robert C. Helling <helling@atdotde.de>
When removing the MAX_CYLINDERS restriction, the layout of the
pressure readings was changed from a (cylinder,sample) to a
(sample,cylinder) scheme. I.e. previously there were one cylinder
block for each sample, then one sample block for one cylinder.
However, after populating the samples, the array size was reduced
to the actual number of used samples. With the new layout this
breaks indexing. Therefore, restore the old layout.
Fixes#2887
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We did something really horribly wrong when merging cylinders. It's
been broken since commit 7c9f46a ("Core: remove MAX_CYLINDERS
restriction"), and used some really strange logic.
This rewrites the logic to be (I think) a bit more easy to understand.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This updates libdivecomputer to support the Oceans S1 and McLean Extreme
divecomputers.
It also adds the Oceans S1 to the list of dive computers we reconize by
bluetooth name.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Having the full list of all members in the exact order should be enough to get
g++ to accept the named initializers.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The last time those changed, we forgot to update serial_ftdi. In that change
set_latency had been removed from libdivecomputer and poll and ioctl had been
added. This caused the callbacks to no longer be aligned correctly and the
functions were called with the wrong arguments through the wrong function
pointers, leading to crashes.
Instead of the fragile assumptions about order and type of function pointers,
use named initializers. And while we are at it, fix that for the bluetooth
implementation as well.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
For unknown reasons, the dive site and trip to be parsed into were
passed as pointers to pointers. A simple pointer seems to be enough,
since the object is not allocated by the function.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This may seem like a bit heavy handed as it adds more global state, but given
the number of ways in which attempts to sync with the cloud can fail it seems
much more reliable to claim success in the spots where we actually know that we
have successfully synced with the remote server. Transporting that information
back through the various call chains turned out to be very disruptive and ugly,
so I went with global state instead.
Whenever we access cloud storage (or any git repo), we always first check if it
actually is a git repo by calling is_git_repository() - so this is the perfect
spot to initialize the variable to false.
And there are only two spots where we either clone the remote repo
(create_local_repo()) or update the remote with the (potentially merged) local
changes (check_remote_status()). So those are the two places where we set the
variable to true.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In many cases we did not log the issues the code ran into to stderr which made
remote debugging user problems much harder. This hopefully will help with that.
Since I was looking at the code, I also made the existing messages more
consistent.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Apparently libdivecomputer can return DC_GASMIX_UNKNOWN when
fetching tank info with
dc_parser_get_field(parser, DC_FIELD_TANK, i, &tank);
This caused emission of a warning, which was annoying users.
Disable the warning in that case.
Fixes#2866
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The last caller was removed in 7eb422d988.
Since this is the only caller of dive_within_time_range(), remove that
function as well.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In analogy to the timestamp -> QDateTime conversion, create a
common function.
1) For symmetry with the opposite conversion.
2) To remove numerous inconsistencies.
3) To remove use of the deprecated QDateTime::toTime_t() function.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Move this function from maintab.cpp to qthelper.cpp. Since the
functionality was used in numerous places, use the helper function
there as well. This removes a number of inconsistencies. For example,
sometime setTimeSpec(Qt::UTC) was called, even though the
QDateTime object was already created with that time spec.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The short and long date formats where initialized in a common if-branch.
However, inside the if-branch the code rechecked which of the two should
be initialized. This could make sense if there was some common code between
the two, but there wasn't. Therefore, make this two independent branches
to avoid one nesting-level.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Add a couple of known services (Scubapro G2 and Shearwater), and update
the names of others that turn out to be used for multiple dive
computers. Also add another Broadcom upgrade service UUID.
While at it, sort the services numerically to make it easier to see that
a UUID already exists, since these service numbers do get used across
multiple different devices.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
We've tried to do this "automagic" service discovery, and it mostly
works, but then occasionally it doesn't.
Making things worse, I think different platforms end up enumerating
services differently, so our "pick the first service that looks like it
might be a serial service" ends up working on some platforms, but not
necessarily on others. Because "first" might be different.
So start a list of known good/bad services - and fall back to the old
logic when you can't decide reliably.
This fills in juat a few cases that I can easily check myself, and the
"details" field for them may be incomplete. For example, I know Nordic
Semiconductor has their vendor-specific UUIDs, and they can be found in
different devices, so calling them "Nordic UART" and "Nordic Flash"
services makes sense.
But the "Scubapro i770R" service? It might indeed be specific to the
Scubapro i770R. Or it might be a general service UUID that Pelagic
uses. Or it might be the service UUID of a particular chip, and found
in dive computers from other designs too (and not necessarily in all
i770R's either).
So this is a preliminary first stab at this, and I'm sure we'll extend
the list and possibly improve on the explanations.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
The old code used get_taglist_string() and split the resulting
string at commas to get the list of tags. This was wrong for two
reasons:
1) It was buggy. Every tag but the first would start with a leading
space and thus not be found.
2) It was inefficient. The tag list was concatenated, just to be split
again.
Turn the tag list directly into a QStringList and remove whitespace
for good measure.
Fixes#2842.
Reported-by: Hartley Horwitz <hhrwtz@gmail.com>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We don't order the list of addresses alphabetically, but we want to ensure
that devices that offer us a name are listed before those that don't. This
should only be relevant if the user selects the option to show all BT/BLE
devices, not just recognized dive computer, because if we recognize a computer
we always have the product name prepended to the address.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
If the user asks to have all BT/BLE devices shown, we should behave
consistently to the case of a recognized dive computer and always show the
device name. In almost all cases the BT/BLE address (and even worse on
iOS/macOS the weird uuids) are completely meaningless.
If there isn't a name, don't add a leading space in order to make it easy to
detect if we have an address without a name (which almost certainly isn't a
dive computer, so it should be towards the end of the list of addresses - which
will be handled in a later commit).
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This fixes a rather subtle bug.
In btdiscovery.cpp we are detecting dive computers based on their BT name and
are setting up product+vendor as the key for that lookup. QMap always uses case
sensitive comparisons and a tiny inconsistency snuck into our code.
libdivecomputer names for the Aqualung dive computers i200C / i300C / i550C end
in an upper case C (as matches the official branding), but in btdiscovery.cpp
we have those names with lower case c. And therefore didn't recognize these
dive computers.
Obviously this is easy to fix by fixing those three strings, but I decided that
it was silly to set ourselves up for similar oversights in the future. So
instead I switched the matching of the descriptor to simply be allways all
lower case.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We do _not_ read them back, since they are calculated values, although I
guess we could aim to do that too at some point in case we have an
import from somewhere else that has these values but not the profile (or
gas use) to actually calculate them.
Fix test-cases that are checked by TestParse (but nothing else) to match.
Requested-by: Miika Turkia <miika.turkia@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This warning is unnecessarily scary - we had a problem with parsing
multiple strings on the same line, but it should be all solved, and
while it does mean that people may have old incorrect git save files
with empty strings, scaring users about it isn't going to help.
And with the warning removed, we can just remove the whole test for an
empty string, because the normal code sequence handles that case just
fine.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
To reset the core data structures, the mobile and desktop UIs
were calling into the dive-list models, which then reset the
core data structures, themselves and the unrelated
locationinformation model. The UI code then reset various other
things, such as the TankInformation model or the map. . This was
unsatisfying from a control-flow perspective, as the models should
display the core data, not act on it. Moreover, this meant lots
of intricate intermodule-dependencies.
Thus, straighten up the control flow: give the C core the
possibility to send a "all data reset" event. And do that
in those functions that reset the core data structures.
Let each module react to this event by itself. This removes
inter-module dependencies. For example, the MainWindow now
doesn't have to reset the TankInfoModel or the MapWidget.
Then, to reset the core data structures, let the UI code
simply directly call the respective core functions.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This one is a bit hairy, because two things might happen if the
picture has a geo location:
- A dive gets a newly generated dive site set.
- The dive site of a dive is edited.
Therefore the undo command has to store keep track of that.
Oh my.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Move the two functions create_picture() and picture_check_valid_time()
from dive.c to picture.c.
This might be somewhat questionable, as these functions are not purely
picture related, but check the nearest selected dives, etc. However,
dive.c is so huge, that slimming it down can't hurt. Moreover,
getting the nearest selected dive is more divelist- than dive
functionality anyway.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
If we want to make addition of pictures undoable, then create_picture()
must not add directly to the dive. Instead, return the dive to which the
picture should be added and let the caller perform the addition.
This means that the picture-test has to be adapted.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We can do the same with get_picture_idx(). Yes, it is a bit more
unwieldy. However a full reimplementation seems not worth it.
We could make this a one-liner helper function though.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The code is rather complex. Firstly, we have different representations
of pictures throughout the code. Secondly, this tries to do add the
pictures in batches to the divepicture model and that is always rather
tricky.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
By using a std::string instead of a C-string, memory management
becomes so much simpler! This class will be used for keeping track
of deleted/added pictures in the undo system.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Even though the functionality is seemingly trivial, this is a bit
invasive, as the code has to be split into two distinct parts:
1) Post undo command
2) React to changes to the divelist
Don't compile that code on mobile.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This needs a slight change to the macro, because here we sort by
value type. Yes, from a C-programming point of view this is horrible,
however a decent compiler should just inline everything and not
pass around value types.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
A function that gets the index of a picture in a picture table
given its filename. Since we are going to identify pictures by
their filename, we will need this function in the undo code.
Use the function in the remove_picture() function.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
For consistency with equipment, use our table macros for pictures.
Generally tables (arrays) are preferred over linked lists, because
they allow random access.
This is mostly copy & paste of the equipment code.
Sadly, our table macros are quite messy and need some revamping.
Therefore, the resulting code is likewise somewhat messy.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Since this doesn't touch struct dive, dive.c is not an appropriate
place for this function.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The Bühlmann factors were cached in a thread-safe hashmap. It seemed
somewhat dubious that entering a critical section and doing a hash-lookup
would be significantly faster than a simple exp() call.
Indeed, in a very cache friendly test (16 entries, tight loop) calling the
factor() function 32 000 000 times from a different translation units we get:
- with cache: 604 ms
- without cache: 266 ms
Therefore, remove the cache. Given that 32 000 000 calls take only 266 ms,
it appears not sensible to try to optimize this function anyway.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
It was suggested in a review of a previous patchset that we should
capitalize the use of "use dc" to "Use DC" - but if we were going
to do that we should do it everywhere, not just in the one place.
This is the followup to do that.
Signed-off-by: Monty Taylor <mordred@inaugust.com>
In the code, the difference between SALTYWATER and SALTWATER is hard
to see. More importantly, in the UI - Brackish is the word for water
that has more salt that freshwater but less salt that seawater. The
docs already use the word to clarify what is meant.
These can be useful in a printed divelog, especially if the
log entry is also showing weight and exposure suit.
Signed-off-by: Monty Taylor <mordred@inaugust.com>
The DiveListView had a singleSelectedTrip function that
returns the selected trip if exactly one trip is selected.
This could be very slow if numerous non-trip items were
selected, because all the selection indices were back-
translated by the proxy model.
This could make selection changes very slow, because the
MainTab used said function to determine whether it should
show trip or dive data.. Indeed, with a 3500 dive test log,
when selecting all dives in tree mode, the updating of the
TabWidgets is sped up from 130 ms to 5 ms this commit.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The DiveListView would touch the selection-innards directly.
Let's encapsulate that. Moreover, take care to reset the trip
selection when resetting the core data.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In analogy to dives add a selection flag for trips. The reason
being that search for a selected trip can be painfully slow when
we do it through Qt's proxy model.
Make sure to deselect trips when they are removed from the core.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
No point in slurping in all of dive.h for translation units that only
want to do some time manipulation without ever touching a dive.
Don't call the header "time.h", because we don't want to end up in a
confusion with the system header of the same name.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This included QFile, which is fatter and not needed here. Include
QFile only in the actual translation unit.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
There appears to be no reason to slurp in all dive.h when compiling
membuffer.c. units.h might not seem like the perfect place, but it
is the most fitting I found.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
For consistency: declare enumerate_dives as extern, since we do that
for all other C-functions.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
No external caller of this function exists. Moreover, turn the return
type to void, as it only returned the passed-in plot_info and no
caller used that.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
It make debugging much easier if the function signature tells you
that a parameter is not altered.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When plotting profiles with surface segments, there were strange
artifacts. As we found out with Robert, these were due to the fact
that the calculated maxtime was set to the last event which is just one
second inside the surface segment. This terribly confused the profile
code. For example, it didn't properly allocate samples for the surface
segment.
Thus, when calculating maxtime, consider the last sample beyond the
last event.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When we had fixed-sized cylinder arrays, the planner used the last
empty cylinder for "surface air". This was not recognized by the UI
as a separate cylinder, because "empty cylinder" was the sentinel for
the end of the table. The conversion to dynamically sized cylinder
tables broke this code: everytime the surface segment is changed,
a new dummy cylinder is added, which is visible in the UI.
As a very temporary stop-gap fix, emulate the old code by creating
a cylinder and then setting the end-of-table to before that cylinder.
This means that we have to loosen the out-of-bound checks.
That's all very scary and should be removed as soon as possible.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This will be temporarilly used by the planner to mark consumption of
air at the surface. Do this by creating a new function add_cylinder,
which replaces add_to_cylinder_table() and takes care of always adding
a dummy cylinder at the end of the table. Make the original
add_to_cylinder_table() local, so that it cannot be accessed anymore.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This was used by the divelist to check wether a selection change is
programmatical or user-initiated. However, since there is only one
entry point for programmatical selection changes, this is not needed
anymore. Remove it - this removes an inter-module dependency.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We no longer use libusb to access USB devices on Android, therefore
there's no point including libusb in our build. Also, we have never even
attempted to run the tests on Android, so let's not even pretend to
support building them.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Move this to the core so that desktop and mobile don't have
to call this explicitly. Matter of fact, mobile didn't call
this. It is unclear, whether that was even used on mobile,
though.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
It makes no sense to keep the device nodes if all the other data
is cleared. Let's do this automatically and not explicitly.
This ensures that the function is also called on mobile.
Currently it was only called on desktop.
Weirdly, the parser-tests were expecting that the device nodes
were not reset by clear_dive_file_data() and therefore divecomputers
were accumulating in the test results. Thus, the additional
computers had to be removed from the expected test results.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The filter sets the maximum date to now. This is so confusing when
you manually add a dive and it isn't shown, because it is slightly
in the future. Add seven days, that should help.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This only checks the first divecomputer as the semantics for
multiple dive computers with different dive modes are not
clear. Should we check them all?
The implementation is a bit hackish: the indexes [0...n] of the
combobox are mapped onto [-1...n-1], where -1 means don't filter
and n-1 is the last valid dive mode.
Implements #2329
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Arguably, returning 0 for a dive with no cylinders is wrong, since the
0 is a valid cylinder id, however that cylinder doesn't exist. Instead,
return -1. All callers of explicit_first_cylinder() return early anyway
for dives with no cylinders.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Since we removed MAX_CYLINDERS, we have the possibility of dives
with no cylinders. In such a case, setup_gas_sensor_pressure()
would do invalid read- and write-accesses. Therefore, return
early in such a case.
Reported-by: Chirana Gheorghita Eugeniu Theodor <office@adaptcom.ro>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Turns out that at least on Android libgit2 sometimes rejects valid
certificates. And I cannot quite figure out when and why. But since we
actually already checked the validity of the certificate when we called
canReachCloudServer() (and the Qt code handles certificates correctly),
we'll simply ignore this here and override the check to always return
true for our cloud server.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
I would have bet money that Android used to send stderr to the logcat
log, but apparently it doesn't (anymore?). So in order to be able to
have a chance to debug weird cloud storage issues on Android, let's do
some wholesale replacement of fprintf(stderr,...) with our own version
of the INFO macro that we long ago borrowed from libdivecomputer (and
rename it to ensure we don't have a conflict there).
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
free_plot_info_data() freed the pressure-data, but didn't set the
value to NULL. Thus, when the plot_info was reused, a double-free()
could ensue.
Crash condition: export the profiles of multiple dives with pressure
data.
Reported-by: Willem Ferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This will be used by the test to clean up test branches that are created
on the server. Since we aren't testing that functionality (it's not
something that Subsurface itself ever does) the helper prints out errors
it encounters, but doesn't report them back to the caller.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
If you had one of the unfortunate local git caches with a local HEAD
just pointing to 'master', this will make note of that and then fix it
up to use the proper branch name in the cache repository.
[Dirk Hohndel: demoted from error to fprintf as most users won't care]
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In create_and_push_remote(), we set up the remote tracking etc to use
the proper branch name, but never actually set up the initial local
branch for the new cache repository at all. So the repository would end
up with the default 'master' branch, instead of the branch name it
should have.
This went unnoticed, because most setups start by initializing the git
caches by cloning from the cloud, and that worked fine.
Debugged-by: Dirk Hohndel <dirk@hohndel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This fixes a crash: when the undo commands removed a dive from
the list, the fulltext cache was not cleared. If now the divelist
is reset and then the undo-command deleted, deletion of the owned
dive tries to remove it's fulltext cache, which doesn't exist
anymore.
For reasons of symmetry, when readding the dive, its fulltext
has to be registered.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When initializing the fulltext-cache and the dive-list, every
100 dives a notification was shown. I had a feeling that this
made startup significantly slower, but that could have been
purely psychological.
Therefore I measured and indeed, removing the fine-grained
notification, it becomes *significantly* faster. For a 3500
dives test log with mobile-on-desktop:
Initialization of the fulltext: 1350 ms -> 730 ms (-46%)
Initialization of the divelistmodel: 689 ms -> 113 ms (-83%)
Let's remove the fine-grained notification. There *is* a visual
indication of work-in-progress anyway.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The compiler complained about this and it seems the
function does not need it.
Additional-test-suggested-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Robert C. Helling <helling@atdotde.de>
The planner does not know about events except gas
changes. But if the dive comes from the log, we
should preserve the dive computer events. At least
those that happend before we started to delete
waypoints to let the planner take over.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
This fixes a bug: when deleting a picture when multiple dives
were selected, possibly the wrong dive was invalidated.
Thus, the dive wouldn't have been saved to the git repository.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This isn't really a useful performance improvement, but it's still better,
IMHO, because we don't have a less specific match later on potentially change
an already executed match.
Because of our coding style the comment covering multiple cases of Pelagic dive
computers now is associated just with the first of those entries. I don't see a
way to do this differently without being in violation of our coding style, so
I'll just keep it like this.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Both Shearwater Petrel and Petrel 2 identify as 'Petrel' as their BT and BLE
names. But only the Petrel 2 supports BLE, thus only the Petrel 2 shows up in
the list of known dive computers on iOS (which supports only BLE but not
BT-only). By switching this around to always pick Petrel 2 we now correctly
detect such a dive computer on iOS.
Fixes#2739
Reported-by: Rick Holcombe <wrh@nc.rr.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Qt hates empty ranges, and even for a non-empty range, this is better
implemented as a reset than a remove.
This fixes a crash that I have been able to create on iOS by rescanning
for devices on the download page.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
There is the free_picture() function with the same functionality.
The compiler/linker should recognize that and remove the duplicate
code, but still...
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This never made sense and I think I just forgot to complete this code
when I first worked on it. Now we can see which version of Subsurface or
Subsurface-mobile created a merge.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
While having the local user information in the repo on Linux seemed
clever when we implemented it, it's inconsistent with all the other
platforms. Let's just not do that unless the user has indeed set
a global name/email pair for git.
Instead indicate if this was Subsurface or Subsurface-mobile.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This function was not meant to be called with already existing data.
However, if it was, it cleared the words without clearing the fulltext
caches of the dives. This lead to crashes.
Be more resilient by not clearing the words: Already existing dives
are unregistered during the process of populating anyway. So this
now *should* work if new dives are added to the dive list and then
this function is called.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This function was named improperly: it was only used on freshly
loaded data. Indeed, attempts to use it to actually reload lead
to crashes.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
parse_file() refused to load from a git repository if we already
had that repository and there were no changes. However, this only
checked the global divelist_changed flag, which does not track
undo-commands. Thus, after editing dives the user couldn't reload
from git.
Remove this check. It is somewhat questionable that the io layer
refuses to load from a repository anyway. Let the caller decide.
There appears to be a check_git_sha function for that purpose(?).
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Don't overwrite the full cylinder when editing a single field.
Implement three "modes": editing of type, pressure and gasmix.
Don't consider individual fields, because some of them are
related. E.g. you can change the gasmix by setting the MOD.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Use the user-editable MOD-pO2 preferences value when creating
a default cylinder. It is not clear to me, when that even has
a consequence, but it looks like the right thing to do.
Reported-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Apparently this was used to hide events in pre-Qt times. However,
that has already been reimplemented in different ways. Let's remove
that commented-out code.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
For undo, we want to create gas change events without adding them
immediately to the dive computer.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Since all the other event-functions are also defined there.
Ultimately, we should probably move them to their own
event.c translation unit.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
There is a slight complexity here owing to the fact that the profile
works on a copy of the current dive: We get a copy of the event and
have to search for the original event in the current dive. This
could be done in the undo command. Nevertheless, here we do it in
the profile so that when in the future the profile can work on a
non-copied dive we can simply remove this function.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Add a DiveListNotifer::eventsChanged signal, which is emitted when
the events changed. This is very coarse, at it doesn't differentiate
between signal addition / editing / deletion. We might want to
be finer in the future.
Catch the signal in the profile-widget to replot the dive if this
is the currently displayed dive. Reuse the cylindersChanged() slot,
but rename it to the now more appropriate profileChanged().
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We have a remove_event() function that
1) frees the event
2) works on the current divecomputer
3) compares the events because the profile has copies of events
However, for undo commands
1) we want to keep the event so that we can readd it later
2) we have to work on arbitrary divecomputers
3) we don't work with copies of events
Therefore, create a new remove_event_from_dc() function that
does all that. Moreover, make the event argument to remove_event()
const to (slightly) point out the difference in the API.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
add_event() creates and adds an event from the given parameters.
For undo, we want to do these separately, therefore split this
function in two parts: create_event() and add_event_to_dc().
Keep the add_event() function for convenience. Moreover, keep
the remember_event() call in there, so that undo-commands can
call remember_event() once, not on every undo/redo action.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In two cases we were passing the magic value 8 instead of the
symbolic SAMPLE_EVENT_BOOKMARK. Use the symbolic version instead.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The cylinders in the events must be reordered if we remove
a cylinder. To avoid duplication of code, move the reordering
function into qthelper.cpp, though it might not be ideal
there.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Do a simple copy & paste followed by a simple search & replace
to generate cylinder undo commands from weight undo commands.
Obviously, this is still missing the necessary code to keep
the dive-data consistent after cylinder editing.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Moreover, move the declaration from dive.h to equipment.h.
The result is a) more consistent and b) more logical.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Turn the code in CylindersModel that creates a new cylinder for
addition into its own function to avoid code duplication. This
will be used from the undo commands.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We have a set_weightsystem() function. For symmetry, introduce
a set_cylinder() function so that we can more-or-less copy&paste
the weightsystem undo code for cylinder undo.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The cylinder undo commands will keep a copy of a cylinder
and therefore need the ability to free a cylinder object.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We have a clone_weightsystem function. For symmetry, introduce
a clone_cylinder() function so that we can more-or-less copy&paste
the weightsystem undo code for cylinder undo.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Especially on slower devices with a large dive list the startup time has
become really long. This callback allows us to give the user an idea of
what the app is doing during that time.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In an attempt to reduce the number of global variables, don't use
a local buffer to store the currently loaded git-id. The git-id
itself is still a global variable, which in the future can hopefully
be encapsulated in a "struct File" or similar.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This is pointless bike-shedding: instead of allocating the QTranslators
on the heap an assigning them to a variable at translation-unit scope,
we can simply generate them as static objects.
That makes
1) two fewer lines of code
2) the translator-resources are properly released when the application
closes.
Not that either of these points would make *any* difference.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The prefs.locale.lang_locale field was overwritten without
free()ing the old value. Not that the function would be called
numerous times, but as a matter of principle...
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The uiLanguage() function was used for two purposes: to initialize
the language related preferences and to read the current language.
To make things more easy to follow, split this function in two:
one for initializing, one for getting the current language.
Moreover, don't return the current locale in an out-parameter
as there is already a function to do that [getLocale()].
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In uiLanguage() the preferences fields are initialized and there
is fixup for a MacOS indiosyncrasy. For some reason the uncorrected
value is written to the preferences. Let's store the corrected
value instead.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
uiLanguage() initializes the language fields from the preferences
values. It is unclear why this function is called in qPref::loadSync()
*before* the fields are loaded from disk. It can only initialize to
the default values anyway. After qPref::loadSync() uiLanguage()
is called again so that everything can be initialized with the
correct perferences values.
Remove the first call. If things break, let's fix them in a sensible
way.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This reverts commit 573a4a5e2d.
The commit broke setting the language in the desktop preferences:
Instead of setting the locale in the prefs struct, the locale
is set via qPrefLanguage. However, that saves the default language
(extracted from the system) to disk. Now when the language is
read from the preferences, we get that default value.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Adding dives uses the number of the last dive to create a new
dive number. Ignore invalid dives.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The git parser loads into the global dive table, even if it
is called indirectly via parse_file(). However, parse_file()
may be given a different table. Fix this by extending the
git parser state.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When editing a dive on mobile we might have to create a new
dive site. That site is added to the global dive site table
in the undo command. However, the code in QMLManager created
the dive site with create_dive_site*() functions, which already
adds it to the table. The undo command then added the dive
site again leading to a hang of the application.
To solve this problem, create new alloc_dive_site*()
functions that do the same as create_dive_site*()
but do not add it to the table.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The pop_cstring() function is used by the git parser to
duplicate a quoted string. On error, it returns an empty
string literal. Since the caller expects a copied string
and takes ownership of that string, it will ultimately
be freed.
Concrete example: a log with erroneous cylinder data was opened
getting such an empty string literal as description. On closing or
syncing with the cloud, the dive is freed, leading to a free
of the string literal -> crash.
Return a copy of the empty string instead.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of relying on the std::vector staying unchanged and not freeing
its members, instead keep a copy of the object in our DCDeviceData class.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
If the user tries to download from a device that he hasn't given the app
permission to read from, Android will pop up a dialogue asking for that
permission. With this after giving the permission we continue (well,
technically, restart) the download which is likely the expected behavior.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This finally allows us to download from not just the first device, but specifically
the device that the user picks.
Passing the object through a void pointer is not nice - but since this traverses
C code other solutions (like passing an index into the list) seemed even worse.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Instead of creating a string with all the object information, simply pass
the actual object to the C++ code.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We now always create a list of usb devices that doesn't list a driver
for known devices, and adds multiple entries with each of the drivers
for devices that are unknown to us.
This removes some debugging output in the ..._open() function as well.
This could be combined with Christof's earlier commit.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
For a small number of dive computers we can actually figure out the
real information which we can then later show to the user.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
As discussed in issue #2657, there are now more fields about the usb
device information in android_usb_serial_device_descriptor.
Additionally, the user-facing string now makes more sense:
"vendor [<bus# as integer>:<dev# as integer>]"
Where vendor is as reported by android, but shortened to 16 characters.
Examples:
FTDI [1:2]
Silicon Labs [1:4]
Signed-off-by: Christof Arnosti <charno@charno.ch>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit contains the serial_android_usb part of the changes proposed
in issue #2657.
What's implemented:
- A data structure that contains all the data that can be used to
describe an usb device (including user-facing string).
- A function to get a list of all attached usb devices (optionally with
selectable driver class).
- Changes in the serial_android_usb_open-function and in the Java part
to use the information about the usb device and optionally selected
driver when connecting.
This commit keeps compatibility with the current UI-Code in the case
that only one USB-Device is connected. If two devices are connected,
only the first one is tried.
There are still some small things to do:
- Change the user-facing string to something more descriptive.
- Parts which aren't uesd anymore when the UI-Part is implemented are
simply marked as obsolete (to keep compatibility for now).
But generally it seems to work.
[Dirk Hohndel: some white space / coding style adjustments]
Signed-off-by: Christof Arnosti <charno@charno.ch>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This is the exact same case as the previous commit, just for the writing
side.
Once again, it's the subsurface rfcomm iostream code that can return
DC_STATUS_SUCCESS with a byte count of zero when something goes wrong
with the write.
And once again, our libdivecomputer iostream code didn't try to be
robust and protect itself from that case.
The fix is equivalent, although slightly simpler, since the write side
doesn't have the whole timeout issue.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
We had two independent bugs here, both of which needed to fire for this
to cause a problem. This fixes both of them.
The first bug was that our rfcomm code would return DC_STATUS_SUCCESS
with a zero-sized read when a timeout happened, or when the rfcomm
socket had disconnected. That makes absolutely no sense. We should
return DC_STATUS_TIMEOUT on timeout, and DC_STATUS_IO if the socket has
disconnected without any data.
The fix to this is to make the whole rfcomm iostream read logic much
simpler: there's no need to loop at all for partial results, because the
libdivecomputer iostream side will do the loop for us (and handle
partial results much better: it knows if the target backend can handle
those partial results or not).
The second bug was in our libdivecomputer iostream read() function,
which reacted very badly to this bad return value. This updates our
libdivecomputer branch to one that is more careful about things.
Reported-by: linuxcrash <albin@mrty.ch>
Debugged-by: Jef Driesen <jef@libdivecomputer.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
The diveListNotifier.divesSelected() signal is used to inform the
models of a selection change. It sent the current dive as a second
parameter. This is redundant, because the only sender of the signal
sets current_dive just before sending the signal. Remove the
parameter, which appears to be an artifact.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Grammar-nazi ran
git grep -l 'indexes' | xargs sed -i '' -e 's/indexes/indices/g'
to prevent future wincing when reading the source code.
Unfortunatly, Qt itself is infected as in
QModelIndexList QItemSelection::indexes() const
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Since I learned while trying to implement this that getting sub-second
resolution time in portable C99 is hard (especially for someone who is
used to the comfort of std::chrono and Howard Hinnants date library) the
timer-implemetation from libdivecomputer is now copied to the subsurface
source.
Signed-off-by: Christof Arnosti <charno@charno.ch>
Thanks to the new USB serial implementation also that complex special-casing
is no longer needed. This should do the right thing now.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Create a C string (which the caller needs to free) with the executed commands
in this session.
The detour via the callback allows us to not make the corelib depend on the
commands, which is nice for tests, export-html, and smtk2ssrf.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In the QML code we pass ids around. I had assumed that there already was a reverse
lookup function, but I wasn't able to find it. So I added it.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Use the undo-command for importing dives also on mobile. This should make the
whole disconnect-model shenigans unnecessary.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The goal is to send the signal for the correct dives / divesites
and thus not having to reload the whole model.
Right now the mobile UI does not yet catch the diveSiteChanged signals.
[Dirk Hohndel: small fix to ensure that we trigger a save to storage]
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This finishes the spliting of the GPS fix application:
One function for collecting the fixes, one for application.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Not that this would make any noticeable difference, but out of
principle, let's use Qt's string-literal macro for string-literals.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Make the application of the GPS fixes in two runs: first
collect dives and fixes, then apply the fixes. This will
simplify turning the application of GPS fixes into an
undo-command.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We know that we cannot support native USB, USB HID, IRDA, and USB
storage on Android.
On the flip side, don't try to force the long broken FTDI download.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Since the Android USB stack and subsequently the usb-serial-for-android
driver have problems with read-timeouts, the read-timeout is now
implemented in AndroidSerial.java. Also, DC_STATUS_TIMEOUT is returned
if there are less bytes returned than expected.
Different chipsets seem to behave differently with
usb-serial-for-android. On CP210x the read blocks until there is some
data here, but on FTDI the chip seems to return whatever is currently in
the buffer (so 0 bytes if the buffer is empty). This different behaviour
should be mitigated by the changes by this commit.
Signed-off-by: Christof Arnosti <charno@charno.ch>
Implement the libdivecomputer API in Java and create C/JNI translation
layer.
[Dirk Hohndel: whitespace harmonization - yes, some of this is Java,
this still makes it much easier to read for me;
also changed the FTDI conditional compilation to make
sure we can still use that for mobile-on-desktop if
necessary]
Signed-off-by: Christof Arnosti <charno@charno.ch>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This is a quick hack to reduce the noise in the log file when chasing other
bugs. Maybe this should not be enabled on release builds, but right now I don't
think the harm that having this in would do.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
For reasons which I don't yet understand, when plotting a dive
whose first cylinder is not cylinder 0 and then plotting a dive
with only one cylinder, it can happen that for the latter
explicit_first_cylinder() returns an erroneous value.
This is due to the way in which we copy the dive to be plotted
to displayed_dive.
For now, make sure that no invalid cylinder is returned to avoid
crashes. This will have to be changed anyway, since this is very
fundamentally not thread-safe and inefficient.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The version_printed variable is used to print version information
only once. It was a global variable, but never used outside of
its function. Therefore, move it into the function and make it
static. Since this is a plain old datatype (POD), it makes no
no difference whatsoever whether the static variable is in block
scope or not. Indeed, it is initialized in the data segment). Well,
we are in C mode and therefore everything has to be POD by definition.
I tested this on gcc and clang.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Implement tag- and people-filtering in the mobile version of
DiveFilter. As opposed to the desktop version, this has no
different modes: it always searches "startswith" and "all of".
I.e. all of the search strings must match and a tag / person
is considered as matching if it starts with the search term.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This function checked a dive for a search string. Its functionality
was replaced by a fulltext index.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In analogy to the desktop version, use the fulltext index in
DiveFilter. This code is not yet executed.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This function did not access any class members and was not used
outside the tranlation unit. Let's make it local (i.e. static)
to the translation unit.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
There are now three filter modes:
1) Dive site
2) Fulltext
3) Normal
When doing a fulltext search, get the dives that match the
fulltext filter and then apply the other filters on that list.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When loading dive data, populate the fulltext index. When clearing
dive data, free the fulltext index. When deleting a dive, remove it
from the fulltext index.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Add code that indexes all words of a dive and provides searching
for words.
A query is represented by the FullTextQuery class, which can be
initialized by assigning a string to it. It is basically a list
of words.
The result of a search is stored in the FullTextResult class,
which is a list of dives.
The actual indexing and searching is implemented in the FullText
class. However, this class is not exported because the interface
is partially accessible to C. Notably, the reloading of the
fulltext index is done from the C core.
Currently, the indexing and searching is totally unoptimized.
In a ~4000 dives test-log searches typically took single-digit
ms times. There is ample room for optimization (e.g. when
searching for multiple words, chose the words with few dives
first and when down to a few dives, check them individually).
The words of each dive are tokenized and uppercased and
cached with the dive. A pointer to these words is stashed
in the dive structure.
For now, compile only on desktop.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The FilterData struct has the enum StringMode, which describes how
strings are searched (substring, startswith, exact). To make it
more generally accessible, remove it from the class. Since it is
an "enum class", the values don't pollute the global namespace anyway.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The DiveFilter class defined the showDive() function to test
whether a dive should be filtered or not. This was used in
DiveTripModel to loop over all dives or all dives affected by
an editing action.
This restricts us in how we do filtering: We can't use indexes
that give us directly the result. To make the filtering more
flexible, move the actual loops that do the filtering to
the DiveFilter class.
The undo-commands likewise called directly the showDive()
function to check whether newly added dives are shown.
Use the new interface here as well.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Because of the multiple string confusion, we'd get the names wrong for
modechange events. If we then made other changes to the dive and saved
the end result back, they'd now be wrong in the git cloud storage too.
Fix it up manually by just noticing that there's a 'divemode' string on
the event line, which can only happen with modechange events.
Maybe we should report the fixup? This just silently fixes it (but only
for the git save format).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
We had some fairly obscure rules for how strings were parsed, and it
actually caused bugs when the same line had multiple strings in it.
That normally doesn't happen, and the cases where it was _supposed_ to
happen had special cases for it (divecomputer ID lines, and tag lines).
But by mistake, we had introduced a case of that for the event line
handling in commit b9174332d ("Read and write divemode changes (xml and
git)"), and nobody realized that the divemode string addition meant that
"oops, now it's corrupting the event name". An event line could look
like this:
event 40:00 type=8 divemode="OC" name="modechange"
where we now had both that "OC" and "modechange" strings, and the code
to pick the name just picked the first string. So we'd end up
effectively mis-parsing the above line as
event 40:00 type=8 divemode="OC" name="OC"
which is obviously wrong.
The dive mode didn't really need to be a string in the first place
(there is nothing to quote, and no spaces in it), but hey, here we are.
We can't just magially fix the existing broken saves.
So make it more straightforward to handle strings in the git format line
parser. We still stash the different decoded strings together in one
special memory buffer, but now the parser helpers automatically untangle
it as they traverse the key value pairs.
This is still overly subtle code, and it doesn't fix the cases where
we've saved the wrong data back. That comes later.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
If we change the gps location of a dive that didn't have a dive site associated
before (which is the normal case when a dive was just downloaded from a dive
computer), a new dive site is created with that GPS fix and added to the dive.
We need to mark that dive as changed in order for the changes to be saved to
storage.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Currently, we do substring search. Implement starts-with and
exact mode (for example when search for "Cave vs. Cavern" tags).
For each textual search criterion add a combo-box.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Corrected typo of the word celsius in three files:
core/import-csv.c
core/divefileter.h
mobile-widgets/qml/Settings.qml
These were spelled as celcius but corrected these to celsius.
The 'core files were just comments but the mobile-widgets file would be
'active' code.
Reported by: tormento <turment@gmail.com>
Signed-off-by: Jason Bramwell <jb2cool@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
These just make no sense. Since the value is copied, it
has no meaning to the caller whether the function can
change the value (and vice versa for return types).
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Remove two erroneous comments stating that a function-local
QSettings variable should not be static because it is initialized
too early. Scoped static variables are initialized when execution
first hits the statement.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The idea is that in portrait mode we can force the display to be single column (which
makes sure that the profile in dive display mode is nice and big).
This commit only implements the preference variable that we need for that.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Instead of transporting the global first and last dive date
in the dive summary, calculate it in an external function.
Since we already have time and date functions in qthelper.cpp
implement those functions there. Provide a stub in QMLInterface
so that QML can access these standalone functions.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Some Wikipedia pages use special (non-ASCII) unicode symbols for
representing the " and ' separators. Before parsing, replace these
by the ASCII symbols to enable copy & paste from Wikipedia (and
other sources?).
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
As we do XSLT parsing for the CSV import, ampersand characters need to
be encoded with & for the parsing to succeed.
Fixes#2037
Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
When starting / changing the dive-site filter, inform the map of
the changed dive site selection by calling
MapWidget::instance()->selectionChanged();
This fixes a bug, where on clicking dive sites in the dive site
tab the dive sites from the *previous* click were highlighted.
Perhaps the selectionChanged() call should be put into the
setSelected() call. But the data flow between the different
parts of the dive-site and map code are so convoluted that I
don't want to risk anything!
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We tend to use lower-case filenames. Let's do it for these files
as well. Simple search & replace.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Windows had it's own direct socket implementation for rfcomm (ie legacy
BT), while all the other platforms used QtBluetooth.
This makes Windows do the same thing. Hopefully modern Qt libraries now
work well enough on the Windows platform for this to work, but I can't
test it.
We can make a test build that Windows people can try, though.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Jef has changed the libdivecomputer iostream layer and extended it in
two different ways:
- iostram's now have a 'poll()' method, which does what the name
implies: waits for data to be available with a timeout.
- iostreams now have a 'ioctl()' method, which can be used to implement
miscellaneous operations. Right now the two ones that you can do are
"set latency" (this replaces the old 'set_latency()' method) and "get
BLE name" (this replaces our 'get_name()' method that was never part
of the upstream libdivecomputer interfaces)
Neither of these is all that complicated, and the transition is fairly
obvious.
HOWEVER.
I have absolutely no idea how to do 'poll()' on Windows sockets, and I
have no intention of figuring it out. We use a direct socket interface
to implement the (non-BLE) RFCOMM bluetooth serial protocol, and I'm not
sure why Windows is so special here. I suspect - but cannot test - that
we should just switch the Windows RFCOMM implementation over to the use
the same QtBluetooth code that we use on other platforms.
I assume that the Windows Bluetooth support was originally not
sufficiently good for that, but these days we depend on Qt doing BLE for
us even on Windows, so presumably FRCOMM works too.
That would be a nice cleanup, and would make 'poll()' work on RFCOMM
under Windows too. However, since I can't test it, I've not done that,
but instead just made the Windows RFCOMM 'poll()' method always return
success. That may or may not get the thing limping along.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Simply replace it with QLatin1String. There is a tiny performance penalty,
but none of that code would care.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This replaces the C-code XML parsing with a Qt infrastructure.
QXmlStreamReader is used to parse the GPX file.
It also takes into account comments by @neolit123
Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>
This shouldn't be part of the desktop UI code; there's still the issue that we
really shouldn't hand code XML parsing, but I'll leave that for later.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
prefs.unit_system is set at the top, so no need to set it again.
Signed-off-by: jan Iversen <jan@casacondor.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
prefs.unit = x needs to be after the setters are called, otherwise the setter
will not do anything, and result in an inconsistency between the values stored
on disk and in prefs.units.
Signed-off-by: jan Iversen <jan@casacondor.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Remove string version of unit_system, duration_units, length, pressure,
temperature, vertical_speed_time, and volume, including tests and make signals
strongly typed in C++
Signed-off-by: jan Iversen <jan@casacondor.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Register enums to allow them to be used in signal handlers instead of int.
Signed-off-by: jan Iversen <jan@casacondor.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Add CLOUD_STATUS enum to interface.
Add cloud_verifification_status variable to interface, and make
it strongly typed in QML.
using backend.cloud_verification_status = 1 will fail but
backend.cloud_verification_status = backend.CS_UNKNOWN is correct.
Added note to the original definitions of the enums that they have been
duplicated.
Signed-off-by: jan Iversen <jan@casacondor.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Add a header file that contains a duplicate of the enums,
that are needed in QML in one class.
the unit enums are added imidiatly, since they are needed
or will be neede shortly in Settings and DivePlannerSettings
This class will also contain Q_PROPERTY and signal/slot for
variables used in QML. This is done to allow e.g.
deco_mode qPrefUnits::planner_deco_mode()
void qPrefUnits::set_planner_deco_mode(deco_mode)
as strongly typed in C++
and
DECO_MODE planner_deco_mode()
void set_planner_deco_mode(DECO_MODE)
as strongly typed in QML
Remark: wrong assignments gives errors in QML
The advantage over using strings or the value directly is that
QML detects typos and flags them as errors/warnings.
It is important to note that the class may only contain
a) a function call to the implementation
b) a reference to a global variable e.g. prefs.
Added note to the original definitions of the enums that they
have been duplicated.
Signed-off-by: jan Iversen <jan@casacondor.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The user may modify the salinity by selecting a water type from the combobox.
The new datum does not replace the existing salinity value but is stored in a
separate variable within the dive structure. If the dc-based salinity is
overwritten, there is an exclamation mark next to the modified salinity value
to indicate that the salinity has been overwritten. The dc-derived salinity can
always be recovered by selecting the "use dc" option in the combobox.
Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Create a checkbox in the Preferences: General screen that enables or disables
editing of the salinity data. This preference is saved with all the other
preferences.
Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Commit dbb504 tried to prevent an uninitialized dc pointer
from being dereferenced. But I screwed up the logic always
setting the event pointer to NULL. This fixes this error.
Reported-by: willemferguson@zoology.up.ac.za
Signed-off-by: Robert C. Helling <helling@atdotde.de>
When using the string setters, the original signal should still be emitted.
Change to call original setter in string setter.
Signed-off-by: Jan Iversen <jan@casacondor.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When changing between METRICS <-> IMPERIAL, all type signals are emitted.
This may cause double sending of some signals, but all signals will be emitted
at least once.
Signed-off-by: jan Iversen <jan@casacondor.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When switching between imperial/metric it is important to change the single
measurements as well (e.g. METER <-> FEET).
Signed-off-by: Jan Iversen <jan@casacondor.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
All unit functions have a string version and a normal version, except
unit_system.
Make a non string version of unit_system.
Signed-off-by: Jan Iversen <jan@casacondor.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
There were several issues with these tests, including checking
the value argument against bool values even if the underlying
preference isn't bool.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Use string literals to communicate with QML.
Instead of passing arounds enum/int value, it seems easier to pass string literals to QML and have that code respond to those
Signed-off-by: Jan Iversen <jani@apache.org>
Do not set prefs.locale_lang_locale directly, but do it
indirectly through qPrefLanguage::set_lang_locale(),
to ensure the file plist is consistent with prefs.
the difference (prefs. contra plist) cause surprises
when restarting mobile (and playing with language).
Signed-off-by: Jan Iversen <jani@apache.org>
This commit does some final cleaning up to the code, mostly deleting
white space and comments.
Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This adds a tab for dive log - related preferences.
A suitable test programs is still required.
Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Add a preferences tab for dive download, allowing resetting the
buttons representing download connections in the Download panel.
Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Remove the preference settings dealing with thumbnails (currently under
General preferences and Profile preferences) and put them in a newly-created
Media preference tab.
Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Remove the "Show unused cylinders" checkbox (Profile tab) and the
"Set default cylinder" qTextEdit box (General tab) and put them in a
separate and new Equipment tab. This sounds like a simple task but,
as can be seen from the files changed, was actually a complex matter.
Adapt the existing test programs (General and TechDetails) for creating
a test program that tests parts of the Equipment tab.
Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
WARNING: multi directory commit, needed to secure it builds.
move the core/plannerShared.* to backend-shared.
update CMakeLists.txt to include backend-shared lib in link process.
update ios project to reflect new directory
Signed-off-by: Jan Iversen <jan@casacondor.com>
WARNING: multi directory commit, needed to secure it builds.
move the core/exportfuncs.* to backend-shared.
update backend-shared/CMakeLists.txt to generate backend-shared lib
update CMakeLists.txt to include backend-shared lib in link process.
update ios project to reflect new directory
Signed-off-by: Jan Iversen <jan@casacondor.com>
qPrefDiveplanner contains settings for ascent and descent in a neutral format.
diveplanner desktop uses a macro UNIT_FACTOR to convert between UI values and
qPref values.
In order not to dublicate these calculation (in C++ and QML) a set of shared
functions are made. The functions are identical to the calculations in diveplanner
desktop.
Signed-off-by: Jan Iversen <jan@casacondor.com>
Add a plannerShared class, whose purpose is to contain shared
functions between mobile and desktop
This class is the inner workings of the diveplanner not the UI
Signed-off-by: Jan Iversen <jan@casacondor.com>
LOG_STP is on longer providing the data needed, since a lot of the startup
is indirectly in QML, furthermore using the xcode project and running profiler
gives much more detailed information
Signed-off-by: Jan Iversen <jani@apache.org>
Do reply->readAll() before reply-deleteLater()
With UI deleteLater() seems to happen after the function exist,
but with QML it causes problems.
Signed-off-by: Jan Iversen <jan@casacondor.com>
The uploadStatus signal can be used to inform the user about
the process e.g.
- preparing zip file
- starting actual upload
It is a suplement to uploadProgress, that only informs about
the network part.
Signed-off-by: Jan Iversen <jan@casacondor.com>
Secure that the slots/signals in uploadDiveLogsDE, which are without
UI, can be used in DivelogsDeWebServices (to add the UI part).
Signed-off-by: Jan Iversen <jan@casacondor.com>
The difference between slot names and signal names was to insignificant
e.g. uploadFinish (signal) uploadFinished (slot).
Change slot names to slot_<name> should clear any confusion.
Signed-off-by: Jan Iversen <jan@casacondor.com>
prepareDives needs to be public, in order to be used in
subsurfacewebservices.
"friend" is another option, but that gives subsurfacewebservices
too much freedom.
Signed-off-by: Jan Iversen <jan@casacondor.com>
In order to replace DivelogsDeWebServices::prepare_dives_for_divelogs with
uploadDiveLogsDE::prepareDives, first step is to make the functions identical.
amount_selected is not maintained for mobile, add #ifdef SUBSURFACE_MOBILE
Add comment, to make code more readable
add white line to make code more readable
change to use variable ds (created a couple of lines earlier
Avoid "goto" by adding close code
Remove label and close code (it was only called in 1 place)
Signed-off-by: Jan Iversen <jan@casacondor.com>
use report_error directly, instead of making a QString first,
argument syntax are different (%s vs. %1)
Signed-off-by: Jan Iversen <jan@casacondor.com>
The implementation is based on class DivelogsDeWebServices in
desktop-widgets but without the UI entanglement
Signed-off-by: Jan Iversen <jan@casacondor.com>
Add divelogsde_userid and divelogsde_password to
qPrefCloudStorage to be used in Export.qml
Extending qPrefCloudStorage is more logical than adding QSettings
(and securing the same behaviour) outside qPref.
Signed-off-by: Jan Iversen <jan@casacondor.com>
diveshareexport wants to show the HTML received
in a positive response, so signal cannot be
compatible with diveLogsDE
Signed-off-by: Jan Iversen <jan@casacondor.com>
Add DiveShareExportDialog::do_upload() to
uploadDiveShare::do_upload(), while cleaning it from
UI.
Add signal connections as used in uploadDiveLogsDE
Signed-off-by: Jan Iversen <jan@casacondor.com>
Add diveshare/uid and diveshare/private to qPrefCloudStorage
to be used in Export.qml as well as diveshareexportdialog
Extending qPrefCloudStorage is more logical than adding QSettings
(and securing the same behaviour) outside qPref.
Signed-off-by: Jan Iversen <jan@casacondor.com>
This is the framework that mobileExecutable needs, all
prepared to move functionality from desktop-widgets
(current implementation) into a shared version.
Signed-off-by: Jan Iversen <jan@casacondor.com>
The old code called directly into the DiveListModel. Instead,
send a signal and hook into the signal from the model. This
will allow us to remove the DiveListModel::instance() function.
This, in turn, is a step towards supporting multiple models
at the same time. However, currently the model manually
sets the hidden_by_filter flag in the core and therefore
only one active model is supported at a time.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Currently, selecting a single dive or deselecting all dives was
quite awkward: One had to pass in a single-dive vector and the
dive itself (as current dive). Provide a convenience function
that selects a single dive or deselects all dives if null is
passed in.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Q_PROPERTY contains an internal ";", making clang produce a warning
when ending the line with a ;
Remove ; at the end of Q_PROPERTY lines.
Signed-off-by: Jan Iversen <jani@apache.org>
Currently, the caller is responsible for not reusing a freed
weightsystem / cylinder or resetting the description field to
null. This is very unfriendly. Set the description field to null,
because that allows us to call free_* repeatedly on the same
object. Use the new behavior to make the weightsystem model code
a bit cleaner.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Implement the EditWeight undo command. Since there is common code
(storage of the old weight), this creates a common base class for
RemoveWeight and EditWeight. The model calls directly into the undo
command, which is somewhat unfortunate as it feels like a layering
violation. It's the easy thing to do for now.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>