The get_*_unit() functions return the unit-name as set in
the preferences. Add versions with a "metric" parameter.
This will be used by the statistics code, which may in
the future allow for binning with alternative units.
All the unit-formatting functions should probably be moved
away from qthelper to their own source file.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The start-selection widget will need icons with a transparent
background so that the icons don't stick out like a sore thumb.
So far the icons rendered by this function were only used by
the images on the profile and were perfectly rectangular.
Therefore there was no need for this.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The renderIcon() function was used by the thumbnailer to
render SVG-based icons. Move it to the global qthelper.cpp
so that it can also be used by the statistics module.
Add "SVG" to the name to emphasize what it is used for.
For consistency also move the renderSVGIconWidth() function,
which renders to a fixed width, to qthelper.cpp
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This function was not used anywhere. Moreover, remove a few
unused includes from qthelper.h. Surprisingly, a number of users
of qthelper.h depend on these, so readd them at the appropriate
places.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The get_trip_date_string() formatted, as the name implies, the date
of a trip. It was passed a number of parameters and had only one
caller, which would also add the location if it existed.
Therefore, move all that logic into the helper function and
name it get_trip_string().
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Declare the function in the header file corresponding to the source
file where the function is defined.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The water type strings were static and therefore passed through
gettextFromC::tr() before main(). One would hope to get a warning
in such a case, but this is not the case.
Therefore, use the QT_TRANSLATE_NOOP macro to register the strings
in Qt's translation system and translate the list when needed.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Dives for the seac action computer are imported by the seacsync
program into two tables in an sqlite3 database.
The dive information is read from the headers_dive table.
The dive_data table is then queried for each dive to get samples.
The seac action computer is the only current supported computer
by the seacsync program. It only supports two gas mixes, so the
parser will toggle between two cylinders whenever it detects a
change in the active O2 mix.
Dive start time is stored in UTC with a timezone offset.
A helper function to read this was added to qthelper.
Default cases have been added to some switch statements
to assist in future development for other dive types and
salinity.
Example database has been added to ./dives/TestDiveSeacSync.db
Signed-off-by: James Wobser <james.wobser@gmail.com>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
1) The full text search was looping over the DiveListModel when
it could simply loop over the core model. Do that instead.
2) Don't generate a DiveObjectHelper to do a full text search.
Currently this is harmless as the DiveObjectHelper is only
a disguised "dive *". But from a conceptual point of view,
it represents the full representation of a dive and we don't
want to generate that in a tight loop.
This will help in
1) Making the DiveObjectHelper a non-reference object.
2) Moving fulltext search to the core and thus making it available
to desktop and more performant.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The string_to_*() functions were declared in dive.h and qthelper.h.
Moreover in one file they were declared with C in the other with
C++ linkage. This only works because qthelper.h includes dive.h
first.
Fix this anomaly by declaring the functions only in qthelper.h,
but moving them from the C++ to the C part.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
These functions were spread out over dive.c and divelist.c.
Move them into their own file to make all this a bit less monolithic.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The application state was encoded in a QByteArray. Thus, there was
no compile-time checking. Typos would lead to silent failures.
Turn the application state into an enum. Use the enum-class construct,
so that the values don't polute the global namespace. Moreover,
this makes them strongly typed, i.e. they don't auto-convert to
integers.
A disadvantage is that the enums now have to be cast to int
explicitly when used to index an array.
Replace two hash-maps in MainWindow to arrays of fixed sizes.
Move the application-state details into their own files.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The function is defined in qthelper.c and thus not all users
of dive.h have to suck in the xslt headers.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-return the result instead of storing in a parameter, we now know that the list
contains only those results that are generated in the function
-allocate the result with the correct length right from the start
-do not iterate over keys of a map and then do a map lookup to get the value but
use an iterator that gives us both right from the start
-remove one call alltogether as the results were not used there
Signed-off-by: Rolf Eike Beer <eike@sf-mail.de>
This is only in Qt 5.7 and therefore can't be used in Qt 5.5 and 5.6
builds. Moreover, we can't simply reuse Qt's version owing to
licensing concerns.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
printGPSCoords() returned a newly allocated C-style string. Most
callers simply made a QString out of it and freed the C-style string.
This is paradoxical, as printGPSCoords internally works with QStrings
and converts them to C-style on return.
Therefore, let printGPSCoords() return a QString and create a
printGPSCoordsC() wrapper for the two C-callers.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The printGPSCoords() function returns a copied C-style string. Since
the owndership is transferred to the caller, the correct return type
is "char *" instead of "const char *".
Thus a number of casts when calling free can be removed.
Moreover a number of callers didn't free the string and thus were
leaking memory. Fix them. Ultimately we might want two versions
of the function: one for QString, one for C-style strings.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
These functionality was used by the desktop filter. To unify desktop
and mobile, move it into two new functions in divelist.c
Since one of them is the only caller of is_same_day() move that
likewise into divelist.c and make it of static linkage.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of having people treat latitude and longitude as separate
things, just add a 'location_t' data structure that contains both.
Almost all cases want to always act on them together.
This is really just prep-work for adding a few more locations that we
track: I want to add a entry/exit location to each dive (independent of
the dive site) because of how the Garmin Descent gives us the
information (and hopefully, some day, other dive computers too).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
On top of the file filter for all media files add a file filter
for images only, one for videos only and one for all files.
Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
Gracefully handle drag & drop to the profile, which changes the
offset of the pictures. To do this, keep the pictures in the
DivePictureModel and the ProfileWidget2 sorted by offset and
re-arrange if needed to keep the list sorted. This needs some
code reshuffling.
Introduce a helper-function that moves ranges in arrays.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When generating thumbnails, test for video files. If it is, use
a dummy-thumbnail. Write only the type (video), but no image to
the thumbnail cache, for forward-compatibility.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
There were two catch-all classes for translations outside of class
context. gettextFromC was used exclusively from C, but C++ used
both, gettextFromC and QObject. Some of the string were even present
in both. Therefore, unify to gettextFromC throughout the code base.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Move the find-moved-images functions into a new translation unit
and present the user with the identified matches before applying
them.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In the last commits, the canonical-to-local filename map was made
independent from the image hashes and the location of moved images
was based on filename not hashes. The hashes are now in principle
unused (except for conversion of old-style local filename lookups).
Therefore, remove the hashes in this commit. This makes addition
of images distinctly faster.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Users might have edited their pictures. Therefore, instead of identifying
pictures by the hash of the file-content, use the file path. The match
between original and new filename is graded by a score. Currently, this
is the number of path components that match, starting from the filename.
Camparison is case-insensitive.
After having identified the matching images, write the caches so that they
are saved even if the user doesn't cleanly quit the application.
Since the new code uses significantly less resources, it can be run in a
single background thread. Thus, the multi-threading can be simplified.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The connection canonical filename to local filename was done via
two maps:
1) canonical filename -> hash
2) hash -> local filename
But the local filename was always queried from the canonical filename.
Therefore, directly index the former with the latter.
On startup, convert the old map to the new one.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When adding a picture to a dive, cache_picture() was called, which
calculated the hash of the picture in a background-thread.
This made tests occasionally fail, because the tests depended on
the filename-to-localfilename being overwritten in a call running
in a different thread. Depending on which thread finished first,
the test succeeded or failed.
The easiest way to circumvent this problem is to remove the cache_picture()
call. The hash will be calculated anyway with the thumbnails. And
the only function of the hash is the "find moved images" function. Which
is not an issue here, because the user just loaded the images from
disk.
Reported-by: Jan Iversen <jani@apache.org>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>