summaryrefslogtreecommitdiffstats
path: root/core
AgeCommit message (Collapse)Author
2018-10-15Bluetooth cleanup: remove pointless download_modeGravatar Dirk Hohndel
This was used to track whether we had selected the native BT mode in the download dialog. But the information is redundant as we can tell from the device name whether this is a BT/BLE download or not. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-15Dive import: reset current_dive in process_imported_dives()Gravatar Berthold Stoeger
process_imported_dives() might delete the currently selected dives. This could lead to use-after-free problems. Therefore, reset the currently selected dive to the last dive. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-15Dive import: remove dive-to-be added from trip before deletionGravatar Berthold Stoeger
On dive import, dives to be added may be merged into already existing dives. In such a case, the dive to be added is deleted. Before doing so, it must be removed from the trip is belongs to to avoid corruption of the trip-list. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-15Dive list: make deep copy of picture list on mergeGravatar Berthold Stoeger
On merging make a deep copy of the picture list, to avoid a use-after-free crash after the orginal dive is deleted. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-15Dive list: fix crash on dive importGravatar Berthold Stoeger
In commit 8c2383b4952fa22d41745d29484462ed6a67112b dive merging was changed to not modify the original dive. On import, dives were then merged and the original deleted. The merge_weightsystem_info() was not adapted accordingly (deep copy of string instead of pointer), leading to a use-after-free crash. Resolve this by doing a deep copy. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-14Cleanup: constify get_dive_gas() and get_dive_gas_string()Gravatar Berthold Stoeger
There's no reason for the dive input-parameter being non-const. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-14Cleanup: free all data in clear_table()Gravatar Berthold Stoeger
Instead of calling free() on all dives, call free_dive() which also frees additional allocated data, not only the dive struct. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-14Cleanup: move clear_table() to divesite.cGravatar Berthold Stoeger
There were two declaration of clear_table(), one in dive.h and one in parse.h. The definition was in parse.c. Since the parser doesn't even use the function, move the function and its declaration to divelist.[ch] and remove the redundant declaration in dive.h. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-14Parser: remove global variable dive_idGravatar Berthold Stoeger
This variable was only used in the divinglog_dive() function. There, it was initialized right at the beginning and therefore there seems to be no point in conserving its value across function-calls. Make the variable local and remove the global version. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-14Cleanup: remove rebasing artefactsGravatar Berthold Stoeger
Embarrassingly, the header-comment in divelist.c contained a rebasing artefact. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-14Autogroup only when selectedGravatar Jan Mulder
Comits f427226b3b and 43c3885249f of the undo series introduced 2 calls of autogroup_dives() without checking the autogroup global boolean. This is a bug. An import from DC (for example) then triggers an autogrouping, the divelist is autogrouped, and the UI button is off. This commit solves this. I've chosen for a guard in the autogroup_dives() that now is a no-op when called when the user did not select autogrouping. In additon, simplified the other calls to this function, as we do not need to check before calling any more. Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2018-10-13Dive site: use own copy of taxonomy in dive-site-edit widgetGravatar Berthold Stoeger
The dive-site-edit widget uses a copy of the to-be-edited site to compare with old values. Generally, this seems overkill (the original dive-site can be used for such a comparison). But one place where it can't simply be removed is the taxonomy, because the widget needs a place to store the unsaved data. Change the code to use an explicit taxonomy structure instead of the one provided in the copy. This should ultimately allow removal of the latter. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-13Dive site: un-globalize displayed_dive_siteGravatar Berthold Stoeger
The global object displayed_dive_site is used a a backing-store by the dive-site-edit widget. All external accesses were removed, therefore make the object local to the widget. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-13Dive site: explicitly init displayed_dive_site on show widgetGravatar Berthold Stoeger
The global object "displayed_dive_site" is used to store the old dive site data for the edit-dive-site widget. The fields of the widget were initialized from this object in the show event. Therefore the object was updated in numerous parts of the code to make sure that it was up-to-date. Instead, move the initialization of the object to the function that also initiatlizes the fields. Call this function explicitly before showing the widget. This makes the data-fow distinctly easier to understand. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-12core: recognize Aqualung i770R over BLEGravatar Dirk Hohndel
The name seems crazy until you realize that FQ is 0x4651 which is the model number of the i770R. And the six digits are the serial number of the device. Still crazy, but at least now you understand WHY. Thanks to Jef for decoding that. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12Bluetooth: add helper to separate BT name and addressGravatar Dirk Hohndel
And restructure the existing "isBtAddress()" function in the process. Also add more tests. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12Bluetooth: restart scan for different device on macOSGravatar Dirk Hohndel
This makes no sense, but apparently we need to start a fresh scan in order to be able to talk to a different BLE dive computer on the Mac. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12Bluetooth: wait until we actually have device infoGravatar Dirk Hohndel
On macOS, we cannot connect to a BT/BLE device until we have scanned it. Right now this just sits quietly and waits, which given how long this can take is rather unsatisfying and might look like Subsurface is hung. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12Bluetooth: start discovery if address isn't already knownGravatar Dirk Hohndel
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12Bluetooth: move declaration and make variable file scopedGravatar Dirk Hohndel
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12Bluetooth: remember all data during a scan on macOSGravatar Dirk Hohndel
Since we trigger a scan even without the dialog to pick the right device, we need to remember all devices that we find. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12Bluetooth: discovery should always scan on macOS as wellGravatar Dirk Hohndel
Instead of only starting the scan when explicitly asked to do so in the BT dialog, create the discovery agent when the download dialog opens, since on macOS we cannot connect to a device without having scanned for it first. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12core: helper function to recognize BT/BLE addressesGravatar Dirk Hohndel
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-11Geo lookup: don't pass arguments / result via global objectGravatar Berthold Stoeger
The reverseGeoLookup() fetches dive-site data via GPS coordinates. The coordinates and the result were passed via the global "displayed_dive_site" object. To make data-flow more clear, pass data as in and out parameters instead. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Geo lookup: make the reply a managed-pointerGravatar Berthold Stoeger
By making reply a std::unique_ptr<>, the function can be quit from any point and the reply will be freed. This is valid according to Qt's documentation as we're not deleting during signal processing. This commit fixes a leak: reply was overwritten with the address of a new object without freeing the old object. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Geo lookup: make the QNetworkAccessManager a static objectGravatar Berthold Stoeger
According to Qt's docs, the QNetworkAccessManager is supposed to be a long-living object. Therefore, don't create one on every geo-lookup, but a single object for all geo-lookups. By making the object function-local it is only initiaized on first use. Morover this limits the amount of concurrent geo lookups. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Cleanup: remove ReverseGeoLookupThreadGravatar Berthold Stoeger
Fetching the taxonomy from GPS coordinates was implemented in a QThread. But the only access to the main function was a direct call to run(). Thus, the thread was *never* started. The function call was always asynchronous [it was using an event loop though, so the UI doesn't hang]. Notably this means that the signals connected to the thread would never fire. And the spinner would never be activated. Thus: 1) Turn the thread into a simple function. 2) Remove the spinner. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Dive list: unify sorting in core and Qt-modelGravatar Berthold Stoeger
Ultimately, we want to use a single dive-list and not replicate it in the Qt-model code. To this goal, let's start with using the same sort function. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Undo: don't modify source-dives on mergeGravatar Berthold Stoeger
For undo, it is crucial that commands don't modify existing dives. Unfortunately, dive merging would write into the data-structures of the to-be-merged dives. To prevent it from doing so, make the input dives const-pointers. This led to a whole cascade of functions that had to take const and significant churn. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Undo: select dives after add, remove, merge, split dive commandsGravatar Berthold Stoeger
Select the proper dives after the add, remove, split and merge dives commands on undo *and* redo. Generally, select the added dives. For undo of add, remember the pre-addition selection. For redo of remove, select the closest dive to the first removed dive. The biggest part of the commit is the signal-interface between the dive commands and the dive-list model and dive-list view. This is done in two steps: 1) To the DiveTripModel in batches of trips. The dive trip model transforms the dives into indices. 2) To the DiveListView. The DiveListView has to translate the DiveTripModel indexes to actual indexes via its QSortFilterProxy- model. For code-reuse, derive all divelist-changing commands from a new base-class, which has a flag that describes whether the divelist changed. The helper functions which add and remove dives are made members of the base class and set the flag is a selected dive is added or removed. To properly detect when the current dive was deleted it became necessary to turn the current dive from an index to a pointer, because indices are not stable. Unfortunately, in some cases an index was expected and these places now have to transform the dive into an index. These should be converted in due course. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Dive list view: replace signal-magic by flagGravatar Berthold Stoeger
In DiveListView, we have a very fundamental problem: When On the one hand, we get informed of user-selection in the DiveListView::selectionChanged() slot. This has to set the correct flags in the C-backend. On the other hand, sometimes we have to set the selection programatically, e.g. when selecting a trip. This is done by calling QItemSelectionModel::select(). But: this will *also* call into the above slot, in which we can't tell whether it was a user interaction or an internal call. This can lead to either infinite loops or very inefficient behavior, because the current dive is set numerous times. The current code is aware of that and disconnects the corresponding signal. This is scary, as these signals are set internally by the model and view. Replace this by a global "command executing" flag in DiveListNotifier. The flag is set using a "marker" class, which resets the flag once it goes out of scope (cf. RAII pattern). In DiveListView, only process a selection if the flag is not set. Otherwise simply call the QTreeView base class, to reflect the new selection in the UI. To have a common point for notifications of selection changes, add such a signal to DiveListNotifier. This signal will be used by the DiveListView as well as the Command-objects. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Dive list: remember selected divesGravatar Berthold Stoeger
Don't delesect dives, when unregistering them from the backend. If a previously selected dive is added, select it in the dive-list. For this purpose introduce a SELECTED_ROLE to query the DiveTripModel for selected dives. Unfortunately, when adding multiple selected dives, current_dive_changed is called for each of them, making this very slow. This will have to be fixed in subsequent commits. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Undo: implement autogrouping of trips in DiveAddGravatar Berthold Stoeger
If the autogroup flag is set, search for appropriate trips in DiveAdd() and add the dive to this trip. If no trip exists, add a new trip. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Dive list: implement proper Qt-model semantics for DiveTripModelGravatar Berthold Stoeger
Previously, each dive-list modifying function would lead to a full model reset. Instead, implement proper Qt-model semantics using beginInsertRows()/endInsertRows(), beginRemoveRows()/ endRemoveRows(), dataChange(). To do so, a DiveListNotifer singleton is generatated, which broadcasts all changes to the dive-list. Signals are sent by the commands and received by the DiveTripModel. Signals are batched by dive-trip. This seems to be an adequate compromise for the two kinds of list-views (tree and list). In the common usecase mostly dives of a single trip are affected. Thus, batching of dives is performed in two positions: - At command-level to batch by trip - In DiveTripModel to feed batches of contiguous elements to Qt's begin*/end*-functions. This is conceptually simple, but rather complex code. To avoid repetition of complex loops, the batching is implemented in templated-functions, which are passed lambda-functions, which are called for each batch. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Core: introduce insert_trip_dont_merge() functionGravatar Berthold Stoeger
insert_trip() adds a trip to the backend, but merges trips if there exists a trip with the same date. This is a disaster for the MergeTrips command, because this command adds a new trip and removes the previous two. Of course if the added trip is merged, this cannot work. Therefore, add an insert_trip_dont_merge() function, which adds the trip, but doesn't merge. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Undo: make diverse trip-related operations undo-ableGravatar Berthold Stoeger
AddDivesToTrip, CreateTrip, AutogroupDives, RemoveAutogenTrips and MergeTrips basically all did the same thing as RemoveDivesFromTrip, which was already implemented. Thus, factor our the common functionality and hook it up to make all these functions undo-able. Don't do the autogroup-call everytime the dive-list is rebuilt (that would create innumberable undo-actions), but only on dive-load / import or if expressly asked by the user [by switching the autogroup flag]. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Undo: implement rudimentary support for undo of dive-mergingGravatar Berthold Stoeger
For this, an output-parameter was added to the backend merge_dives() function. When non-zero, instead of adding the merged dive to the preferred trip, the preferred trip is returned to the caller. Since the new UndoObject, just like the delete-dives UndoObject, needs to remove/readd a set of dives, the corresponding functionality was split-off in a helper function. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Undo: implement rudimentary support for undo of dive-splittingGravatar Berthold Stoeger
For this, the core functionality of the split_dive() and split_dive_at_time() functions were split out into new split_dive_dont_insert() and split_dive_at_time_dont_insert(), which do not add the new dives to the log. Thus, the undo-command can take ownership of these dives, without having to remove them first. The split-dive functionality is temporarily made desktop-only until mobile also supports "UndoObjects". Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Undo: implement undo of manual dive-creationGravatar Berthold Stoeger
Play manual addition of dives via an UndoCommand. Since this does in large parts the same thing as undo/redo of dive deletion (just the other way round and only a single instead of multiple dive), factor out the functions that add/delete dives and take care of trips. The UI-interaction is just mindless copy&paste and will have to be adapted. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Undo: fix multi-level undo of delete-dive and remove-dive-from-tripGravatar Berthold Stoeger
The original undo-code was fundamentally broken. Not only did it leak resources (copied trips were never freed), it also kept references to trips or dives that could be changed by other commands. Thus, anything more than a single undo could lead to crashes. Two ways of fixing this were considered 1) Don't store pointers, but unique dive-ids and trip-ids. Whereas such unique ids exist for dives, they would have to be implemented for trips. 2) Don't free objects in the backend. Instead, take ownership of deleted objects in the undo-object. Thus, all references in previous undo-objects are guaranteed to still exist (unless the objects are deleted elsewhere). After some contemplation, the second method was chosen, because it is significantly less intrusive. While touching the undo-objects, clearly separate backend from ui-code, such that they can ultimately be reused for mobile. Note that if other parts of the code delete dives, crashes can still be provoked. Notable examples are split/merge dives. These will have to be fixed later. Nevertheless, the new code is a significant improvement over the old state. While touching the code, implement proper translation string based on Qt's plural-feature (using %n). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-10QML UI: do not try to download from DC with empty vendor/productGravatar Jan Mulder
Disable the Download button when one of the fields vendor, product, connection is not filled in. The app will crash when trying. In addition, make the underlying core code to actual download more safe by checking this, and silently fail instead of crash. And, yes, this is a double fix in this scenario, but the core code is used in more places, so better safe than sorry. Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2018-10-09Substring match BT addressGravatar Jocke
Since a known DC will have the name prepended to the BT/BLE addresss we need to substring match the BT address. Signed-off-by: Joakim Bygdell <j.bygdell@gmail.com>
2018-10-09Mobile RememberDCs: save device addressGravatar Jocke
By saving the device address together with the vendor and product we fix the corner case where a user with two DCs would not get quick select buttons if they where the same vendor and model. Signed-off-by: Joakim Bygdell <j.bygdell@gmail.com>
2018-10-09BT OSTC 3 should be reported as OSTC PlusGravatar Jocke
Report BT/BLE capable OSTC 3/3+ as OSTC PLus as it is required to get a functional download. Signed-off-by: Joakim Bygdell <j.bygdell@gmail.com>
2018-10-09Dive sites: don't add dummy entries to LocationInformationModelGravatar Berthold Stoeger
The LocationInformationModel added two dummy sites to the front of the list (add new dive site). This was never used - desktop uses its own model, mobile only extracts the list of dive site names with a custom function. Remove this functionality. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-09Prefs: add bool preference cloud_auto_sync [1/3]Gravatar Jan Mulder
With removal of the git_local_only from the preferences (see ae653703a5d3f), the users choice, in the mobile app, was not stored any more in between sessions. This resulted in issue 1725. So, in order to store that user preference, we need a new preference. This is added here, but its not yet hooked up in the app yet. This deals only with the preference handling. And adapted tests are included. Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2018-10-08libdivecomputer: remove ifdefs for ancient versionsGravatar Dirk Hohndel
We bundle our version of libdivecomputer and don't expect Subsurface to work with a different version, certainly not with something older than 0.5. I kept the checks for SAMPLE_EVENT_STRING and DC_FIELD_STRING and DC_SAMPLE_TTS because maybe there's a situation where being able to compile with a current upstream version is useful. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-08Fix warning about unused variablesGravatar Linus Torvalds
Commit 810903bdb9db ("Import: pass a dive table to process_imported_dives()") introduced the variables struct dive *old_dive, *merged; into process_imported_dives(), but never used them. It seems to be an artifact of having split the function to use the try_to_merge_into() helper function (that has those same variable names and _does_ use them), but forgetting the original variables from the pre-split case. Gcc understandably warns about it: core/divelist.c: In function ‘process_imported_dives’: core/divelist.c:1351:26: warning: unused variable ‘merged’ [-Wunused-variable] struct dive *old_dive, *merged; ^~~~~~ core/divelist.c:1351:15: warning: unused variable ‘old_dive’ [-Wunused-variable] struct dive *old_dive, *merged; ^~~~~~~~ and the trivial fix is to just remove that line that declares the stale and unused variables. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-10-08ftdi: make the timeout be based on actual real timeGravatar Linus Torvalds
bperrybap reported on github that the ftdi timeouts can be excessive: "the timeout period while waiting for read data to be 10x or even 100x longer than it should be when there are read issues on the data cable particularly when using Android and USB OTG cables. i.e. a 5 second read timeout for not receiving data can be as long as 7 minutes" and the reason is that the code at one point tried to use the regular "gettimeofday()" to handle timeouts, but that doesn't exist in Windows. We already have Windows-specific code to sleep for a number of milliseconds in "ftdi_serial_sleep()", let's just extend that same concept and add a "ftdi_serial_get_msec()" that returns the number of msec's since some arbitrary point in time. On Windows, that's just "GetTickCount()", and in sane environments it's just a trivial wrapper around gettimeofday() to turn sec/usec into msec. NOTE! The actual msec value doesn't have any meaning. Only the difference between two calls to ftdi_serial_get_msec() is meaningful. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-10-08qt-ble: add 'get_name()' function to expose the BLE name to libdivecomputerGravatar Linus Torvalds
Some divecomputer backends (ok, right now really only the Aqualung i770R and i300C) want to know the bluetooth name of the dive computer they connect to, because the name contains identifying information like the serial number. This just adds the support for that to our Qt BLE code. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>