Commit graph

56 commits

Author SHA1 Message Date
Berthold Stoeger
6b835710bc map: use value semantics for MapLocation
This makes memory management more simple, as not explicit deletion
is necessary.

A rather large commit, because changing QVector<> to std::vector<>
is propagated up the call chain.

Adds a new range_contains() helper function for collection
types such as std::vector<>. I didn't want to call it
contains(), since we already have a contains function
for strings and let's keep argument overloading simple.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2024-08-13 19:28:30 +02:00
Berthold Stoeger
de2c4d93e0 map: fold selectionChanged() into setSelection()
This was very weird: a setSelection() call was always followed
by a selectionChanged() call, though sometimes in convoluted
ways. Notably, the formed was called by the DiveListView, the
lattern then by the MainWindow.

Let's just merge these two functions.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2023-04-16 20:23:59 +02:00
Berthold Stoeger
eb55ffde16 cleanup: split uiLanguage() in two functions
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>
2020-03-22 12:01:09 -07:00
Robert C. Helling
285fa8acbc Grammar: replaces 'indexes' by 'indices'
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>
2020-03-11 08:26:30 -07:00
Berthold Stoeger
b76f207158 Filter: split out filter from model
Split out the actual filtering from the MultiFilterSortModel.
Create a DiveFilter class that does the actual filtering.
Currently, mobile and desktop have their own version of this
class, though ultimately we may want to merge them.

The idea here is that the trip-model and undo-commands have
direct access to the filter-function and thus can take care
of keeping track of the number of shown dives, etc.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-11-19 21:13:40 -08:00
Berthold Stoeger
4eaf6b20be Cleanup: remove accessor functions from MapLocation
Let's face it: this is a value type. No point in having Java-style
getters and setters. Replace by plain old and boring member variables.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-06 11:48:47 -07:00
Berthold Stoeger
488eb15423 Desktop: show all selected dive sites on click
When clicking a dive site on the map, the QML code would set
the selected dive site, but then all dives of dive sites in
the vicinity were set. But still only the clicked-on dive site
was shown.

Therefore, don't set the list of selected dive sites in QML,
but later in DiveListView::selectDives(), where we know all
the dives that were selected.

This, again, gives nasty entanglement of diverse widgets and
models.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-06 11:48:47 -07:00
Berthold Stoeger
b39f2406c6 Map: don't fully reset model on selection change
When changing the selection the MapLocationModel was reset.
This lead to crashes on Qt-5.9 which are due to QML accessing
data that was freed during model reset. This putative Qt bug
doesn't happen on newer Qt versions. At least Qt-5.12 is known
to work.

Instead of fighting the bug, let's simply not reset the model
but send a dataChanged() for every element of the MapLocationModel.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-06 11:48:47 -07:00
Berthold Stoeger
bce31ab862 Map: generate pixmap name in model
Experimentation has shown that the image of a flag will
only be changed after dataChanged() if it is a simple
property. The old code had a complex QML expression and
then - for some reason - it didn't work.

To give us better control over the flags and avoid full
reloads of the map therefore introduce a model-property
pixmap name. The name depends on whether the site is
selected and if not, whether we are in divesite-edit mode.
This makes the code rather convoluted. Firstly, we have
to save whether the site is selected in the map-item.
Secondly we have to access the global map-widget, which
in turn has to go to the map-widget helper (layering
violation!).

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-06 11:48:47 -07:00
Berthold Stoeger
28cb75b73d Map: explicitly reload selected map on click
When clicking on a flag
 1) The QML would call MapLocationModel::setSelected() with
    fromClick = true
 2) MapLocationModel::setSelected() would emit a signal
    selectedLocationChanged()
 3) MapWidgetHelper would catch that signal and do the actual
    processing.
Other functions would call MapLocationModel::setSelected() with
fromClick = false, which would not emit the selectedLocationChanged()
signal.

Detangle this a bit by calling the selectedLocationChanged() function
directly from QML and remove the fromClick parameter.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-06 11:48:47 -07:00
Berthold Stoeger
f818ac3352 Map: replace enterEditMode()/exitEditMode() by updateEditMode()
There weree two functions in MapWidgetHelper: one to enter and
one to exit edit mode. Both functions set the flag and emitted
a signal if the flag had changed.

Since the edit mode only depends on a flag of the filter this
can be simplified to a simple function that updates the flag
and raises the signal if the flag changed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-09-06 11:48:47 -07:00
Berthold Stoeger
ae6f17af0c Cleanup: construct MapWidgetHelper::pluginObject()
Instead of multiple string-concatenations, create the string object
from a single string literal.

Yes, this is a mostly pointless "optimization". But it saves a few
bytes.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-05-11 12:06:19 -07:00
Berthold Stoeger
44c65fec88 Map: automatically update names on the map
Currently, dive site names are only updated on full reload.
Instead hook directly into the corresponding signal in the
MapLocationModel to set the name. Also to the coordinates
directly there instead of going via the MapWidgetHelper.

In the MapWidgetHelper, just center on the changed dive site.
Hook into the signal directly there and remove the slot
from the MapWidget. This makes the whole call-chain at least
one call shorter.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-05-11 12:06:19 -07:00
Berthold Stoeger
30d96d3704 Map: ignore dive sites without location in centerOnSelectedDiveSite()
Don't zoom onto (0,0) for selected dive sites that have no location.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-05-11 12:06:19 -07:00
Berthold Stoeger
0da86dfd86 Map: in edit mode place no-gps dive sites at center of map
Move the code to add the first selected dive site from
MapWidgetHelper::enterEditMode() to MapLocationModel::reload().

Thus, the list of sites is built only at one place. For this
it is necessary to pass a pointer to the map, so that new
dive sites can be added at the center of the map.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-05-11 12:06:19 -07:00
Berthold Stoeger
15cb7e4e92 Map: don't recalculate selected dive sites
In MapWidgetHelper::centerOnSelectedDiveSite() the selected dive
sites were recalculated. Simply use the ones we already know are
selected.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-05-11 12:06:19 -07:00
Berthold Stoeger
d29f82c52d Map: make edit mode depend on dive-site-filtering
Since the dive-site-filter is active either on the dive-site-edit
page or the dive-site-list page, use that as the flag for dive-site-edit
mode. Moreover, when the filter is reset, the
MapWidgetHelper::reloadMapLocations() function is called, so we
can use that place to enter/exit edit mode.

This makes it easier to keep everything consistent.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-05-11 12:06:19 -07:00
Berthold Stoeger
b6d830f004 Map: remove dead code
When entering map-edit mode and the dive site existed, its
coordinates were extracted but never used. Remove that useless
if-branch.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-05-11 12:06:19 -07:00
Berthold Stoeger
48b8129137 Cleanup: remove MapWidgetHelper::m_selectedDiveIds member
This member variable was only used locally in functions.
Accordingly, make it a function-local variable.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-05-11 12:06:19 -07:00
Berthold Stoeger
79f3000630 Map: don't set map selection in selectVisibleLocations()
MapWidgetHelper::selectVisibleLocations() calls setSelection()
on a single dive. Firstly, this make no sense anymore, as
we now support multiple highlithed flags. Secondly, the
highlted dives are now derived from the selected dives.
Therefore, remove the call.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-05-11 12:06:19 -07:00
Berthold Stoeger
7c99b3a76f Map: don't update map-selection in centerOnSelectedDiveSite()
To detangle this code a little bit, let centerOnSelectedDiveSite()
just do what is says: center on the selected dive sites.
Don't update the selected dive site by calling
MapLocationModel::setSelected().

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-05-11 12:06:19 -07:00
Berthold Stoeger
446dfed6e7 Map: move calculation of list from map-helper to map-model
The map model keeps track of the dive site positions on the
map. Therefore, it seems more logical to have the code calculating
the map position in the model, not in the helper-class.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-05-11 12:06:19 -07:00
Berthold Stoeger
3e05d61eb9 Map: show all dive sites when in dive-site filter mode
When on the dive site tab or editing a dive site, we want
to show all dive sites so that the user can related different
dive sites. Therefore export a "in dive site mode" flag from
the filter model and don't filter in that case in MapWidgetHelper.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-05-11 12:06:19 -07:00
Berthold Stoeger
779c4eb5d0 Cleanup: remove redundant checks for null dive site
The dive_site_has_gps_location() function already checks for the null
dive site. Remove redundant checks.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
53c9d524ca Map: Use proper location for flag when editing dive site
When the dive site was not on the map because it had no dives,
entering dive site edit mode would place the map at the center
of the map, not at the location of the dive site.

Use the location of the dive site unless it has no location.
In that case use the map center.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
b5d4d88fe5 Dive site: remove edit mode from dive location widget
Since no dive site field editing enters edit mode anymore,
the whole edit mode state and code can be removed from the
widget.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
40a3e562b0 Cleanup: provide printGPSCoords in C and C++ versions
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>
2019-03-27 13:58:15 +01:00
Berthold Stoeger
04593e8ec4 Cleanup: fix printGPSCoords signature and leaks
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>
2019-03-24 21:57:13 -07:00
Berthold Stoeger
c980216dc0 Dive list: take pointer-to-dive_site instead of QVariant
Since "struct dive_site *" is now a Q_METATYPE, the functions
MapWidgetHelper::centerOnDiveSite() and ::getCoordinates()
can directly get such a pointer instead of a QVariant. This
makes the code nicer to read.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
724055f0af Dive site: replace dive->dive_site_uuid by dive_site
Replace the UUID reference of struct dive by a pointer to dive_site.
This commit is rather large in lines, but nevertheless quite simple
since most of the UUID->pointer work was done in previous commits.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
f41bb32428 Dive site: use an array of pointers in reloadMapLocations()
MapWidgetHelper::reloadMapLocations() used an array of uuids to
add dive sites to the map only once. Replace this by an array
of pointers. This is a small piece of a larger effort to remove
dive site UUIDs.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
75b5d61522 Dive site: replace UUID by pointer in mobile code
Replace UUIDs by pointers to dive-site in mobile code. In both
cases, the value is transported via a QVariant. The function
getCoordinatesForUUID(), which was only used from mobile, can
be replaced by a getCoordinatesFor() function taking a variant
supposed to contain a dive-site pointer. Likewise, the variant
of the centerOnDiveSite function is now supposed to wrap a
pointer-to-divesite.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
872d56de01 Dive site: pass pointer to updateDiveSiteCoordinates()
There are two updateDiveSiteCoordinates() member-functions, viz.
in MapWidget and MapWidgetHelper. Adapt them to take a pointer
to dive_site instead of a UUID. This is part of an effort to
replace UUIDs by pointers.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
cedc23f487 Dive site: Pass dive-site pointer to MapWidgetHelper::enterEditMode()
Replace the uuid argument to MapWidgetHelper::enterEditMode() by a
pointer. Likewise, adapt the only caller prepareForGetDiveCoordinates().
This is a small step in a bigger effort to replace dive-site UUIDs
by pointers.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Linus Torvalds
28e3413ff6 Add 'location_t' data structure
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>
2018-10-21 19:55:09 +03:00
Berthold Stoeger
0416e54049 Dive site: select dive site when entering edit mode
Commit 0aef04352a made it impossible
to move new dive sites on the map. When entering dive-site-edit mode,
the filter would be instructed to show only dives of the corresponding
dive site [which didn't yet exist] and therefore all dive sites
on the map were deselected.

Fix this by explicitly centering on the dive site to be edited in
MapWidgetHelper::enterEditMode().

Fixes #1809

Reported-by: Jan Mulder <jlmulder@xs4all.nl>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-19 06:20:07 -04:00
Berthold Stoeger
ac02854a8a Map: don't access displayed_dive_site in reloadMapLocations()
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>
2018-10-11 16:25:32 -07:00
Berthold Stoeger
dd44dc4ab8 Map: pass down dive site in prepareForGetDiveCoordinates()
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>
2018-10-11 16:25:32 -07:00
Berthold Stoeger
8091497745 Map: split void MapWidget::setEditMode()
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>
2018-10-11 16:25:32 -07:00
Berthold Stoeger
754160d625 Map: pass changed coordinates via signal
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>
2018-10-11 16:25:32 -07:00
Berthold Stoeger
66c5c5f72b Map: remove LocationInformationWidget::coordinatesChanged signal
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>
2018-10-11 16:25:32 -07:00
Berthold Stoeger
0aef04352a Map: zoom on dive sites when flipping through dive site list
The dive site list was connected to centerOnDiveSite(). Apparently,
the currently selected dive site should have been shown in the map.
Yet, this never worked, because the actual dive site of the selected
dive had precedence in centerOnDiveSite().

It seems that centerOnDiveSite() had actually to purposes:
1) center on the passed in dive site
2) center on the dive sites of the selected dives

Therefore, split this function in two separate functions for
each of these use-cases. This allows us to remove some pre-processor
magic (mobile vs. desktop) and to remove a parameter from the
MainTab::diveSiteChanged() signal.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-08 13:29:51 -07:00
Lubomir I. Ivanov
b4f10553cc map-widget: add support for filtering of map locations
If the dive list is filtered the map should hide dive locations
that do not match the dive list filter.

To achieve that, loop over dives instead of dive sites in
MapWidgetHelper::reloadMapLocations() and discard
dives that are hidden by the filter. Then check if a dive
has a dive site attached to it and re-use the old functionality.

Suggested-by: Willem Ferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
2018-08-18 18:50:26 +02:00
Berthold Stoeger
36b9e5e31e Cleanup: fold core/helpers.h into core/qthelper.h
helpers.h included qthelper.h and all functions declared in helpers.h
were defined in qthelper.h. Therefore fold the former into the latter,
since the split seems completely arbitrary.

While doing so, change the return-type of get_dc_nichname from
"const QString" to "QString".

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-06-04 08:50:10 -07:00
Dirk Hohndel
ea83b5ed37 Core: remove dive.h from files that don't need it
Of course, quite a few of them indirectly get it through other header
files.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-05-14 10:13:39 -07:00
Lubomir I. Ivanov
48c032bb8e mapwidget-mobile: do not animate the first selection
centerOnLocationHard() is added in MapPage.qml so that
on `firstRun` the map is hard panned to the desired location
without animation.

This affects the selection of a new "Dive details" -> "Map it" or
when opening a GPS location in the map.

The idea behind this change is to avoid starting the map animation
from an arbitrary location such as [0,0] or London. Also, to not
start the map zoomed out completely and then zoom in on a selected
dive.

For this change to work, add the helper getCoordinatesForUUID()
to qmlmapwidgethelper.cpp/.h and use it to obtain the
QGeoCoordinates for a dive site UUID.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
2018-04-02 13:47:43 -07:00
Lubomir I. Ivanov
fbbb6ba4fb qmapwidgethelper: make adjustmets for the mobile version
The mobile version is limited as it does not support dive list
selection of multiple dives and editing multiple dives.

Also the dive list on mobile does not follow the same indexing as
the desktop version dive list.

Use the SUBSURFACE_MOBILE macro and for:
- centerOnDiveSite() either deselect map markers or center on
a single one (never on a rectangle like the desktop version)
- selectedLocationChanged() and selectVisibleLocations() return
a list of single dive ID

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
2018-03-11 11:40:12 -07:00
Lubomir I. Ivanov
8fa2295a61 qmapwidgethelper: add centerOnDiveSiteUUID()
centerOnDiveSiteUUID() is a helper to center the map on a dive_site
UUID instead of a dive_site pointer.
Make it call centerOnDiveSite().

Make both this function and reloadMapLocations() Q_INVOKABLE
as these are going to be called from QML.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
2018-03-11 11:40:12 -07:00
Lubomir I. Ivanov
eb8772d967 qmapwidgethelper: move includes to the header
Add the following includes in the header -
<QVariant> and <QGeoCoordinate> otherwise the
mobile build fails.

It is unclear how the desktop build does not complain
about this.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
2018-03-11 11:40:12 -07:00
Jan Mulder
92a5e0644e cleanup: Uninitialized pointer field
CID: 208335

Mainly to silence Coverity, as I do not believe this caused
any problem.

Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2017-12-28 17:30:25 +01:00