Comits f427226b3b and 43c3885249 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>
Instead of the weirdly named "information" and the inconsistent
"dive_list" use the logical "mainTab" and the camel-cased
"diveList", respectively.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The keeps track of different sub widgets needed by other parts
of the code, notably:
MainTab
PlannerDetails
PlannerSettingsWidget
ProfileWidget2
DivePlannerWidget
DiveListView
Access to these widgets was provided with accessor functions.
Now these functions were very weird: instead of simply returning
pointers that were stored in the class, they accessed a data
structure which describes the different application states.
But this data structure was "duck-typed", so there was an
implicit agreement at which position the pointers to the
widgets were put inside. The widgets were then down-cast by
the accessor functions. This might make sense if the individual
widgets could for some reason be replaced by other widgets
[dynamic plugins?], but even then it would be strange, as one
would expect to get a pointer to some base class.
Therefore, directly store the properly typed pointers to the
widgets and simply remove the accessor functions. Why bother?
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In the dive-site-edit widget, a copy of the current dive site was
used to store the old (pre-edit) data. This is not necessary, since
we can simply access the data in the original dive site. Thus,
replace the subobject by a simple pointer.
This is part of a series to replace dive-site uuids by pointers.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The displayed_dive_site object is used in the dive-site-edit widget
to store the old (before-edit) data. But it was also used to store
the GPS data when changed on the map or the input box. Very confusing.
Instead, use the text field as only authoritative source of the
GPS data.
This introduces a small behavioral change: when changing the text
of the GPS text field, update the list of dive sites at the same
position.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
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>
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>
Remove a comment which is outdated in two ways:
1) The global variable "displayed_dive_site" was not used at all.
2) The location box cannot be used to rename dive sites.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
MainTab::refreshDisplayedDiveSite() was used after dive-site edit
to update the information of the location entry box. This should
always display the dive-site of the currently shown/edited dive,
therefore it makes no sense to use the displayed_dive_site here.
Simply use the dive site of displayed_dive.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The old code had a special case for dive-editing mode:
The dive site uuid of displayed_dive_site instead of displayed_dive
was used.
This makes no sense, because displayed_dive_site is only used by
the dive-site-edit widget, which firstly cannot be activated
during dive-edit and secondly doesn't change the dive site id
anyway.
Thus, use the dive site of the currently edited/displayed dive
in all cases.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When tabbing through the dive-info screen, a dive-master and a
dive-buddy would be added. The reason is that pressing tab would
be interpreted as a text-input. Disable this behavior by calling
setTabChangesFocus(true) in the TagWidget constructor.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
If we update the device with a shortcut button, this is the reliable way to get
the information we need.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
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>
Previously nothing was shown while we were trying to connect; now we show a busy
indication in the progress bar and ensure that the 'waiting to connect' text is
displayed. The progress bar switches back to showing actual progress once we have
connected and are downloading data.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
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>
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>
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>
There is no reason (any more?) to have a property defined
that basically renames the global pageStack into a local
pageView. Just cleanup.
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
Separated from the previous commit as I do not like big whitespace
changes in a small functional commit.
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
While trying to understand more of the big change from PR 1528,
I found that the divelist was marked changed while it was not
changed at all. Reason is simple. The MODIFY_DIVES code assumes
its called only for truly changed data. But in case of saving
tagged strings, it was not.
This fixes this. And I do not believe this has any visual effects.
Further, the now broken indentation is fixed seperately.
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
SsrfFilterSortProxyModel was a thin wrapper around QFilterSortProxyModel,
which was intended as a convenience class to avoid deriving from the
latter. The filter and sort functions were replaced by simple function
pointers.
Unfortunately, by using function-pointers, the whole thing was rather
weak as these functions do not have state. The last user was removed
in ac8dcd7f65b78958587ba025280ed4c529b0b519. Therefore, remove the
whole class.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The location information shows a list of dive sites at the
same location as the edited dive site. This was done by passing
a function to an "SsrfSortFilterProxyModel". Unfortunately,
the latter does only support function pointers without state
and therefore had to access the global "displayed_dive_site"
object.
Replace the SsrfSortFilterProxyModel by a proper subclass of
QSortFilterProxyModel that contains information on the position
and id of the currently edited dive site.
Update the filter model if the location of the dive site changes.
This introduces a behavioral change: editing the GPS location
will lead to an updated list.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
MapWidgetHelper::reloadMapLocations() reloads all dive flags
of the non-hidden dives plus the one of the currently edited
dive. Use the current_dive macro to determine whether this
is the current dive site instead of the global displayed_dive_site
object.
This is part of a series of commits, which makes the map-code
independent of the global displayed_dive_site object.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of reading out the global object "displayed_dive_site",
pass the dive site to be edited in arguments to
prepareForGetDiveCoordinates() and enter edit mode.
Simplify the code in LocationInformationWidget by not using
signals to call the prepareForGetDiveCoordinates() function.
While doing this, collect common code in accept() and reject()
in the already existing resetState() function.
This is another entry in a series of commits that makes
data-flow more clear by removing access to the global
"displayed_dive_site" object.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The setEditMode(bool) function behaves very differently, when
entering and exiting edit mode. Therefore, split it in two
versions. This will allow to pass arguments that make sense
only when entering the edit mode.
Since setEditMode() doesn't exist anymore, turn the editMode
Q_PROPERTY line to the MEMBER version. Accordingly, remove
the reader function. If QML wants to enter edit mode, it
should invoke the appropriate function and not simply set
the flag.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The coordinates of a "dragged flag" were passed out-of-bound via
the global "displayed_dive_site" object and then a signal was sent
to notify of the changed coordinates.
Instead, pass the coordinates directly via the signal. This makes
the data- and control-flow more clear.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This was used by LocationInformationWidget to instruct the map
that the coordinates of the current dive site has changed.
There is no reason why this couldn't be a function call, as no
other object ever connect()s to this signal. In fact, such a
function already exists viz. updateLocationOnMap.
Therefore, replace the signal by a simple function call.
Moreover, the uuid and coordinates of the dive site were transported
via the global "displayed_dive_site" object. Instead, pass this
information in the parameters of the function. This makes it
easier to reason about data- and control-flow.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
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>
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>
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>
When editing a dive, in the location box a list of dive sites is
shown containing the distance to the current dive site. This was
implemented via the global displayed_dive_site object, which is
set when switching between dives. This seems like an unnecessary
indirection. Instead, use the current_dive macro.
This is part of a series to refactor dive-site handling to use
pointers instead of UUIDs and a general push to reduce global state.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Planned dives were still added by directly calling core code.
This could confuse the undo-machinery, leading to crashes.
Instead, use the proper undo-command. The problem is that as
opposed to the other AddDive-commands, planned dives may
belong to a trip. Thus, the interface to the AddDive command
was changed to respect the divetrip field. Make sure that
the other callers reset that field (actually, it should never
be set). Add a comment describing the perhaps surprising
interface (the passed-in dive, usually displayed dive, is
reset).
Moreover, a dive cloned in the planner is not assigned a
new number. Thus, add an argument to the AddDive-command,
which expresses whether a new number should be generated
for the to-be-added dive.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Currently, the filter is recalculated if a filter-entry is changed.
This also happens if the counts of a filter-entry changes. This
is to be avoided, as it causes unnecessary churn.
Therefore, send the proper role with the dataChanged() signal
and add a new slot, which invalidates only if a field with the
Qt::CheckStateRole is changed.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of reloading all the filter, only increment / decrement the
count of the entries of added / removed dives.
Originally, this was planned to be done via the signals from the
divelist, but it turned out that this was suboptimal, because
if the filter decides that the new item is selected, this has to
be done *before* adding the dive. Otherwise, it wouldn't be shown.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When adding dives to the list, set the filter flag accordingly.
Thus, dives that are hidden by the filter are not shown on
redo/undo.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
The current code cheats when it comes to move dives inside
a trip or move dives between trips: Instead of using the
*MoveRows() functionality, the dives are removed from and
re-added to the respective trips. This loses the selection.
Therefore, remember which of the moved dives are selected
and select them manually after they are re-added.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>