Commit graph

644 commits

Author SHA1 Message Date
Berthold Stoeger
22fe0c14e8 Dive sites: add fulltext filter
In the dive site tab, add a fulltext filter. The UI is only a mock up.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
9afea37e15 Undo: update filter flag when dives change
The filter code is strange: it actually only checks the
dive->hidden_by_filter flag. Thus, before propagating the dive
changed signal, this flag has to be updated. Do this in the
DiveTripModel. Ultimately, this should be refactored.

Moreover, if the filter-flag changed notify the frontend
of a changed trip so that the trip is hidden / unhidden.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
e7063b6b08 Undo: update dive list if trip changed
In tree-mode, the trip locations are displayed. Update the corresponding
entries if the trip changed, by hooking into the tripChanged() signal.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
9fd87fa080 Undo: update cylinder and weight models on paste
When pasting (or undoing paste) the cylinders or weights may change.
Send the appropriate signals and update the models accordingly.
Currently, this means copying from current dive to displayed dive,
but hopefully we can get rid of "displayed_dive" in the not so
distant future.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
6f574c53a3 Undo: implement undo of dive site editing
This one is a bit more tricky. There are two modes: set dive site
and set newly created dive site. This is realized using an OO model
with derived classed. Quite convoluted - but it seems to work.

Moreover, editing a dive site is not simply setting a value,
but the list of dives in a dive site has to be kept up to date.

Finally, we have to inform the dive site list of the changed
number of dives. Therefore add a new signal diveSiteDivesChanged.
To send only one signal per dive site, hook into the undo() and
redo() functions and call the functions of the base class there.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
cd3a8ba354 Dive site: add edit field to dive site table
Add an edit column that calls the new editDiveSite() function
of MainWindow. The calling code is in DiveSiteSortedModel.
Quite illogical, but that's how TableView works, for now.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
d4282e2689 Icons: cache small edit icon
In analogy to the trash-icons, cache a small rendered version of
the edit icon. This will be used in the dive-site table. Rename
the icon alias from "duplicate-edit-icon" to "edit-icon", as
it actually is not a duplicated. The other "edit" icon is an
"undo" icon!

Move the accessor functions to cleanertablemode.cpp. This is not
the ideal place, but since the functions are declared in
cleanertablemodel.h it's certainly better than the old place
(models.cpp)!

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
fa4fedbb48 Undo: implement undo of dive site location editing
Simply copy the code of note editing. It's a bit more complex,
since we have to parse the Gps coordinates. For consitency,
rename the COORD field to LOCATION (the field in the dive_site
struct is called LOCATION).

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
1deded7874 Cleanup: remove LATITUDE and LONGITUDE columns in DiveLocationModel
These were never used and it's hard to imagine when one of these
would be used. Typically users are more interested in the coordinates
than just one component, no?

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
021aa4bd57 Undo: implement undo of dive site country editing
Simply copy the code of notes editing, but use the taxonomy_* functions
to read and set the value. Moreover, replace the three TAXONOMY_n field
ids by a single TAXONOMY id. We will probably never show one column per
taxonomy field, but rather a single column with a string derived from all
taxonomy fields.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
2dcc0a7d1e Undo: implement undo of dive site description editing
Simply duplicate the code of dive site name editing. Split out
the common functionality that swaps a C and a Qt string.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
0fd85832b7 Dive site: remove implicit deletion of empty dive sites
There was a way of deleting dive sites by clearing all fields.
This is not necessary anymore, as now the user can delete a
dive site in the dive site list.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
0e1b0cf1da Undo: Implement undo of dive site name editing
Implement an undo command that edits the name of a dive site.
Connect it to the dive site table, so that names can be edited
directly in the table.

Send signals on undo / redo so that the dive site table and
the dive site edit widget can be updated.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
8e1f736d2b Undo: make dive site removal undoable
Create a new undo-command for deleting dive sites. If there are dives
associated with that site, the dives will be removed. The frontend
is not yet updated in such a case, as that infrastructure is in a
different PR.

Connect the trashcan icon of the dive site table to the undo command.
Currently, this code is in the dive site model, which makes little
sense, but is how the TableView class works. We might want to change
that when cylinder and weight editing are made undoable.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
e99c4c9059 Dive site: introduce proxy model DiveSiteSortedModel
The LocationInformationModel used to sort its entries and was completely
rebuilt after every change. This makes it rather complex to support
incremental changes.

Instead, keep LocationInformationModel sorted by UUID so that indexes
are consistent with indices in the core dive site table.

Implement sorting by other columns than name and enable sorting in the
dive site view.

Finally, don't cache the list of dive site names for the mobile app,
since that would also need some rather convoluted methods of keeping
the list up to date. Calculate it on the fly.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
59f1191d0c Coding style: add tab before Q_OBJECT
In virtually all cases we use a tab before Q_OBJECT. Fix the four
exceptions.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
59e602447b Dive site: inform model of dive site addition / deletion
Introduce two DiveListNotifier signals which are sent by
the undo commands if dives are added to / removed from the
core.

The signal has the dive site and the index in the global
dive site table as payload. Thus, the model has only to
remove the appropriate rows.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
8dcc33d8ab Undo: keep frontend informed of changes to dive site count
Add a new signal to DiveListNotifier. Send signal if dives are
added or removed and therefore the dive count of a dive site
changes. The dive sites are collected and the signal is sent
at the end of the command.

Add code to update the table view.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
dd12bdaf94 Dive site: add dive site list tab
Add a very simple tab-widget presenting the list of known dive sites.
The table is rendered using our custom "TableView".
The (mis)uses the "LocationInformationModel". It moves the items
to be displayed (delete, name, description, number of dives) to the
front and makes the others hidden.

Moreover, it was necessary to limit the geo-tag decoration role to
the name to avoid having the icon next to each column.

Make the trash-can icon active and the name and description editable.
This is modelled after the cylinders-table code.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
c22fd9f4fd Dive sites: prepare for dive site ref-counting
Add a dive site table to each dive site to keep track of dives
that have been added to a dive site. Add two functions to add
dives to / remove dives from dive sites.

Since dive sites now contain a dive table, the order of includes
had to be changed: "divesite.h" now includes "dive.h" and not
vice-versa. This caused some include churn.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
a2be015a43 Undo: consider dive site in AddDive()
If a dive site was added for a new dive, remove it on undo.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
82af1b2377 Undo: make undo-system dive site-aware
As opposed to dive trips, dive sites were always directly added
to the global table, even on import. Instead, parse the divesites
into a distinct table and merge them on import.

Currently, this does not do any merging of dive sites, i.e. dive
sites are considered as either equal or different. Nevertheless,
merging of data should be rather easy to implement and simply
follow the code of the dive merging.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Berthold Stoeger
f6e7bdc5ef Dive site: add dive site table parameter to dive site functions
To enable undo of dive site functions, it is crucial to work
with different dive site tables. Therefore add a dive site table
parameter to dive site functions. For now, always pass the global
dive site table. Thus, this commit shouldn't alter any functionality.

After this change, a simple search for dive_site_table reveals all
places where the global dive site table is accessed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12 18:19:07 +03:00
Rolf Eike Beer
e3d43b5696 replace deprecated qSort() with std::sort()
Signed-off-by: Rolf Eike Beer <eike@sf-mail.de>
2019-04-12 12:59:17 +03:00
Rolf Eike Beer
c4c8094e32 get rid of some foreach and Q_FOREACH constructs
See https://www.kdab.com/goodbye-q_foreach/

This is reduced to the places where the container is const or can be made const
without the need to always introduce an extra variable. Sadly qAsConst (Qt 5.7)
and std::as_const (C++17) are not available in all supported setups.

Also do some minor cleanups along the way.

Signed-off-by: Rolf Eike Beer <eike@sf-mail.de>
2019-04-12 12:59:17 +03:00
Robert C. Helling
30746e5d3f Make sure surface air is not considered a deco gas
it creapt in through the gaschange events.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2019-03-29 06:51:12 -07:00
Robert C. Helling
178eaa9a67 Add UI element for final surface segment in planner
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2019-03-29 06:51:12 -07:00
Rolf Eike Beer
7635ee3e77 CMake: add headers to targets
Signed-off-by: Rolf Eike Beer <eike@sf-mail.de>
2019-03-27 14:07:32 -07:00
Berthold Stoeger
b6c7abc1a7 Cleanup: make argument to YearStatisticsItem constructor a reference
The LGTM checker complained about passing large objects. Instead of
passing pointers, keep the old semantics and pass a reference. This
is more idiomatic C++.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-03-19 16:06:14 -07:00
Robert C. Helling
c7bb67c5be Profile: pass by reference rather than by value for large struct
Addresses LGTM.com suggestion.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-03-18 19:40:32 -07:00
Berthold Stoeger
5cd64d42e4 Map: create correct index in updateMapLocationCoordinates()
When updating the coordinates of a dive site, the MapLocationModel
is updated. The code created a (col, row) index with col = 0.
[The idea of course being col = x, row = y]. Alas, that's not
how Qt works - its models want (row, col) indices. The code
worked, because the only time when the dive site locations were
updated was in dive site edit mode, when only one site is visible,
i.e. there is only one row leading to the correct (0, 0) index.

Fix this so that we can also change dive site positions if more
than one site is displayed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-03-15 07:40:13 -07:00
Doug Junkins
a0f9957bce Display statistics by depth and temperature in Yearly statistics
Create a label for each line added for the depth and temperature
statistics buckets

Add line to statistics widget for each bucket to be displayed

Signed-off-by: Doug Junkins <junkins@foghead.com>
2019-03-12 00:53:51 +01:00
Rolf Eike Beer
47e9a771ba CMake: do not expand variables in if-expressions
CMake will do the expansion internally itself. Not doing it here is not only
less code, it also makes sure one does not accidentially get a double expansion.

Signed-off-by: Rolf Eike Beer <eike@sf-mail.de>
2019-03-05 13:27:54 -08:00
Willem Ferguson
10e7835290 Filter panel: add suit and notes search fields
All the field in the Notes Panel of the main window are now supported.
This needs some testing especially for the Notes field that may contain
markup. It appears ok to me for single term searches. One would like
to think about the default search option for the Notes.
There is a vertical spacer in the Filter panel that I moved downwards
and whose function I am not quite sure of.

[Dirk Hohndel: small adjustments]

Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-02-28 15:45:42 -08:00
willemferguson
2cda456282 Append the dive mode as a tag that is seen by the filter tool.
This allows one to filter dives by divemode, e.g. by typing
"CCR" or "Open circuit" in the tags textbox of the filter tool.
Quite useful if one dives using more than one dive mode. For the
purpose of the filter tool only the dive mode attribute is added
to the list of tags for the specific dive being considered. The
tag list for the same dive (in the XML dive log) is not affected
in any way.

Provide for translation in alternative languages (Response to
bstoeger's suggestion).

Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>
2019-02-28 07:29:15 -08:00
Berthold Stoeger
5033c02a11 Filter: change default mode for location to any-of
Since a dive has only one location all-of makes little sense. It
*can* make sense if the user enters two substrings (e.g. Tofo and Reef),
but generally it won't. Therefore change the default to any-of.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-02-20 09:04:56 -08:00
Berthold Stoeger
e550a788f0 Filter: implement any-of mode
Add an additional mode to the tags, people and location filters: any_of.
Replace the original invert-bool by an enum.
Move the common code into a distinct function.

Reported-by: Willem Ferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-02-19 12:02:15 -08:00
Berthold Stoeger
8a8063c1cd Profile: add "synchronous" mode for picture plotting
The thumbnails were fetched in the background to achieve a
snappier UI. The problem with that is that on LaTeX etc.
export only placeholder thumbnails were shown.

Therefore, implement a synchronous mode. This only tries
to fetch cached thumbnails or calculate thumbnails for
images. Videos and remote files are not supported.

Fixes #1963

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-02-07 16:06:43 +01:00
Berthold Stoeger
de4e6792c6 Filter: quick implementation of negation
Add negate buttons to the Tags, People, Location and Equipment
filters. Currently, if nothing is entered the filter is ignored
whether negate is on or off. One might think about filtering all
dives without tags, etc. instead.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-26 11:13:01 -08:00
Berthold Stoeger
a455b32e02 Filter: implement reset filter
Move initialization to a separate function and connect that to the
reset button.

Two points of note:

1) Reseting the text-fields causes signals. Thus, signals have to
   be ignored during reset. Do this with a new flag.
2) To make reset of the from-date work, the from-date has to be
   initialized to a distinct value. Setting a default-constructed
   QDateTime leaves the widget unchanged.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-26 08:05:39 -08:00
Berthold Stoeger
c210bfc0e0 Filter: update counts if dives added / removed
Update the filter counts if dives were added removed by the
undo commands. The undo commands call into the filter model
at the right time so that hidden_by_filter is already set.
The filter model keeps track of the counts and emits a signal,
which is caught by the widget.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-26 08:05:39 -08:00
Berthold Stoeger
1470048773 Filter: extend range of allowed temperatures
The temperature range 0-100 was inadequate in both supported
scales (Celsius and Fahrenheit). Extend the range to encompass
all physically meaningful values in both scales.

Use the default-values to set the minimum and maximum of the
UI-fields. Thus, these values are configurable in a single place.

In the future we should use a scale-independent representation
(e.g. mkelvin as in the rest of the code base). But this would
mean implementing a custom widget with a conversion function.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-22 10:01:22 +12:00
Berthold Stoeger
b28e0bf0b9 Filter: support imperial units
1) Choose the correct conversion function for comparison.
2) Add a unit suffix to the fields.
3) Update the suffixes on change of preferences.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-22 10:01:22 +12:00
Jan Mulder
e8b0d165a7 Desktop, Filter UI: make date/time consistent
On all (most?) places we use separate date/time fields for the time of a
dive, and we follow the setting from the preferences to format those.

Make the new filter widget consistent, with respect to the to and from
interval.

Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2019-01-21 17:22:24 +12:00
Berthold Stoeger
8fa156eb0d Filter: make tags, people and location filter logically-and
If the user provides multiple tags, they probably want to search for
dive with *all* of these tags. Replace the convoluted loops by
std::all_of(). This makes it trivial to change logically-and to
logically-or: Replace std::all_of() by std::any_of().

Reported-by: Jan Mulder <jlmulder@xs4all.nl>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-19 13:59:24 -08:00
Berthold Stoeger
b3010df14c Filter: reinstate dive-site filter functionality
Commit 201f0c8f89 removed the dive-site
filtering. This is needed for dive-site editing: The list should only
show dives at the corresponding dive-site.

As opposed to the original code, only compare for the actual dive-site,
not for the name of the dive-site. The reason for comparing dive-site
names is unknown.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-19 13:59:24 -08:00
Berthold Stoeger
37a521eb5d Filter: ignore unset temperatures
The filter treated unset air and water temperatures as 0 K, leading
to many dives not being shown. Don't filter on unset temperatures.

Reported-by: Jan Mulder <jlmulder@xs4all.nl>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-19 13:59:24 -08:00
Berthold Stoeger
36fa27050c Filter: update filterData directly without copying
In FilterWidget2::updateFilter() a new FilterData object is generated
and then copied onto the filterData member variable. Instead, modify
filterData directly. This seems also more logical from a semantic
point of view: Do we want to reset fields that were not set by the
user?

Contains trivial whitespace fix.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-19 13:59:24 -08:00
Berthold Stoeger
891fcbf520 Import: control process_imported_dives() by flags
process_imported_dives() takes four boolean parameters. Replace these
by flags. This makes the function calls much more descriptive. Morover,
it becomes easier to add or remove flags.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-19 13:48:17 -08:00
Berthold Stoeger
ff9506b21b Import: don't add to new trip while downloading
Since process_imported_dives() can add dives to a newly generated
trip, this need not be done in the downloading code. This makes
data flow distinctly simpler, as no trip table and no add-new-trip
flag has to be passed down to the libdivecomputer glue code.

Moreover, since now the trip creation is done at the import step
rather than the download step, the latest status of the "add to
new trip" checkbox will be considered.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-19 13:48:17 -08:00
Berthold Stoeger
1cd0863cca Import: add add_to_new_trip flag to process_imported_dives()
If this flag is set, dives that are not assigned to a trip will
be assigned to a new trip. This flag is set if the user checked
"add to new trip" in the download dialog of the desktop version.

Currently this is a no-op as the dives will already have been
added to a new trip by the downloading code. This will be removed
in a subsequent commit.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-19 13:48:17 -08:00
Berthold Stoeger
82c47bdd79 Undo: make dive-import undoable
On desktop, replace all add_imported_dives() calls by a new undo-command.
This was rather straight forward, as all the preparation work was done
in previous commits.

By using an undo-command, a full UI-reset can be avoided, making the UI
react smoother.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-09 20:58:04 -08:00
Berthold Stoeger
0249e12589 Import: split process_imported_dives() function
Split the process_imported_dives() function in two:
1) process_imported_dives() processes the dives and generates
   a list of dives and trips to be added and removed.
2) add_imported_dives() calls process_imported_dives() and
   does the actual removal / addition of dives and trips.

The goal is to split preparation and actual work, to
make dive import undo-able.

The code adds extra checks to never merge into the same
dive twice, as this would lead to a double-free() bug.
This should in principle never happen, as dives that
compare equal according to is_same_dive() are merged
in the imported-dives list, but perhaps in some pathologival
corner-cases is_same_dive() turns out to be non-transitive.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-09 20:58:04 -08:00
Berthold Stoeger
0dfc59f38c Import: add merge_all_trips parameter to process_imported_dives()
When importing log-files we generally want to merge trips. But
when downloading and the user chose "generate new trip", that
new trip should not be merged into existing trips.

Therefore, add a "merge_all_trips" parameter to process_imported_dives().
If false only autogenerated trips [via autogroup] will be merged.
In the future we might want to let the user choose if trips
should be merged when importing log-files.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-09 20:58:04 -08:00
Berthold Stoeger
1593f2ebad Import: merge dives trip-wise
The old way of merging log-files was not well defined: Trips
were recognized as the same if and only if the first dives
started at the same instant. Later dives did not matter.

Change this to merge dives if they are overlapping.
Moreover, on parsing and download generate trips in a separate
trip-table.

This will be fundamental for undo of dive-import: Firstly, we
don't want to mix trips of imported and not-yet imported dives.
Secondly, by merging trip-wise, we can autogroup the dives
in the import-data to trips and merge these at once. This will
simplify the code to decide to which trip dives should be
autogrouped.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-09 20:58:04 -08:00
Berthold Stoeger
f542dc4030 Import: add trip_table argument to DiveImportedModel::repopulate()
In the future we want to download trips into a distinct trip-table
instead of the global trip-table to allow for undo of import.

Therefore add a trip_table argument to DiveImportedModel::repopulate()
and a trip_table member to DiveImportedModel. To correctly set these,
add a DownloadThread::trips() function, which currently simply returns
the global trip table.

Finally, make "struct trip_table *" a Q_METATYPE, so that the corresponding
arguments can be passed from QML.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-09 20:58:04 -08:00
Berthold Stoeger
2802d42969 Cleanup: Make add_dive_to_table local to divelist.c
This function was not used outside of divelist.c, therefore make it
local. Moreover rename it to add_to_divetable so that the name
is generic and can be generated by a macro.

Moreover, remove the special case idx = -1, which would determine
the insertion index. Instead let the single caller who used this
feature do this.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-09 20:58:04 -08:00
Berthold Stoeger
f8327ed51b Core: move autogroup() into divelist.c
After loading or importing, the caller usually called autogroup()
to autogroup dives if so wished by the user. This has already led
to bugs, when autogroup() was forgotten.

Instead, call autogroup() directly in the process_loaded_dives()
and process_imported_dives() functions. Not only does this prevent
forgetting the call - it also means that autogrouping can be
changed without changing every caller.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-09 20:58:04 -08:00
Robert C. Helling
123f3ef7ec Filter for logged/planned dives
Add filter for dives having a planned dive computer or
a logged dive computer.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2019-01-08 10:39:06 +01:00
Berthold Stoeger
f1fc89b978 Dive list: split DiveTripModel into distinct models (tree and list)
The DiveTripModel was used to represent both, trip and list views.
Thus many functions had conditionals checking for the current mode
and both modes had to be represented by the same data structure.

Instead, split the model in two and derive them from a base class,
which implements common functions and defines an interface.

The model can be switched by a call to resetModel(), which invalidates
any pointer obtained by instance(). This is quite surprising
behavior. To handle it, straighten out the control flow:

DiveListView --> MultiFilterSortModel --> DiveTripModelBase

Before, DiveListView accessed DiveTripModelBase directly.

A goal of this commit is to enable usage of the same model by mobile
and desktop.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-07 09:33:52 -08:00
Berthold Stoeger
b5704ddb57 Cleanup: Remove MultiFilterSortModel::model
The source-model was cached in MultiFilterSortModel. For simplicity,
remove that and simply access via DiveTripModel::instance(). There
is only one instance where the cached model was used: when comparing
items for sorting. Thus, in indirection is added in a "hot" path.
Nevertheless, this will dwarf against the cost of string comparison.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-07 09:33:52 -08:00
Berthold Stoeger
2dd0187fe8 Cleanup: remove getDiveId() functions
These functions in DiveListSortModel and DiveListModel had no
users. Remove them.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-27 15:19:50 -08:00
Berthold Stoeger
bfe69239df Import: unglobalize downloadTable
To make data flow more clear, unglobalize the downloadTable object.
Make it a subobject of DownloadThread. The difficult part was making
this compatible with QML, because somehow the pointer to the
download-table has to be passed to the DiveImportedModel. Desktop would
simply pass it to the constructor. But with objects generated in QML
this is not possible. Instead, pass the table in the repopulate()
function. This seems to make sense, but for this to work, we have to
declare pointer-to-dive-table as a Q_METATYPE. And this only works
if we use a typedef, because MOC removes the "struct" from "struct
dive_table". This leads to compilation errors, because dive_table is
the symbol-name of the global dive table! Sigh.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-17 07:37:32 -08:00
Berthold Stoeger
a6a5cf61e2 Cleanup: make DiveImportedModel::checkStates a std::vector
To not have to bother with memory-management. Moreover, the
old code was in principle wrong, since it assumed that
sizeof(bool) == 1. Of course, this is true for all supported
platforms, but let's not depend on such implementation-defined
behavior anyway.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-17 07:37:32 -08:00
Berthold Stoeger
6febe22b6b Cleanup: remove DiveImportedModel::setImportedDivesIndexes()
This function resets the DiveImportedModel. It takes two
arguments: first and last index. All callers passed in 0
and number-of dives anyway, so remove the arguments.
Since this now does the same as repopulate(), merge the
two functions.

Moreover, implement Qt-model semantics by using a
beginResetModel()/endResetModel() pair. This simplifies the
code.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-17 07:37:32 -08:00
Robert C. Helling
ac8db01873 Show average max depth in yearly statistics
this was requested in #1854 and I think this suggestion makes sense

Fixes #1854

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2018-12-17 12:18:26 +01:00
Tomaz Canabrava
705e61b62c Hide unimplemented components from search
Those fields are not ready yet, hide them.

Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
2018-12-14 01:05:18 +08:00
Tomaz Canabrava
201f0c8f89 Filter the data
Wire up the needed code to filter the data in the myInvalidate
call. The data comes from the Struct FilterData and if any
of the test conditions on the filter function are false, the
filter will assume that the specific dive shouldn't be shown

Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
2018-12-14 01:05:18 +08:00
Tomaz Canabrava
e0f473fcb4 Drop old filter code
Drop tons of now-unused-code.

Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
2018-12-14 01:05:18 +08:00
Tomaz Canabrava
81bb6086c0 Struct FilterData
The idea is that this struct will have all the needed data
that will be passed to the filter model. Everything that happens
on the filterwidget will fill out this struct, then forward it
to the model, that in turn will activate the filter hiding
some of the dives that matches on your divelist.

Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
2018-12-14 01:05:18 +08:00
Berthold Stoeger
99b2de85b5 Dive list: fix off-by-two bug in DiveTripModel
Commit 911edfca71 changed the dive list
on desktop to update positions of trips when adding/removing dives.
A very unlikely case, but necessary for consistency.

For a trip to be moveable down, its index has to be one-less than
the maximum index, which is "items - 1". The code was doubly wrong:
it forget the "1" and checked for less-or-equal instead less-than.
Thus this was effectively an off-by-two error. Fix it.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-06 21:56:35 +01:00
Berthold Stoeger
1ebf5a99ed Filter: use hidden_by_filter also on mobile
Desktop used the hidden_in_filter flag in struct dive, mobile
used its own vector plus a new showndives member in struct dive_trip.

Unifiy these to use the same core-facility, viz. hidden_by_filter.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-23 13:22:24 -08:00
Berthold Stoeger
70897dd1b7 Core: move is-single-day-trip and count-shown functions into core
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>
2018-11-23 13:22:24 -08:00
Berthold Stoeger
68414531ad Mobile: don't format trip heading for all dives
QML's ListView uses the "section" property to test if items belong to the
same section. Apparently, this must be a string and therefore we can't
pass e.g. a dive-trip object. Therefore a specially formatted string
was passed in, which was guaranteed to be unique (contained the dive-trip
pointer value) and the fully formatted trip-title and short-date.

The disadvantage of that approach is that the formatting is performed for
every dive and not every trip. Perhaps not a problem now, but it makes
it for example necessary to cache the number of filtered dives.

To be more flexible, pass in only the pointer value formatted as
hexadecimal string and provide a function to convert that string
back to a trip-pointer (in the form of a QVariant, so that it can
be passed to QML). Moreover provide two functions for formatting the
title and the short-date.

The three new functions are members of DiveListSortModel. This might not
be the perfect place, but it is easy to reach from the DiveListView.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-23 13:22:24 -08:00
Berthold Stoeger
9e565e3552 Cleanup: make "struct dive *" and "struct dive_trip *" Qt metatypes
Just as we did for pointer to struct dive_site, make pointers to
struct dive and struct dive_trip "Qt metatypes". This means that
they can be passed through QVariants without taking a detour via
void *.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-23 13:22:24 -08:00
Berthold Stoeger
911edfca71 Dive list: update position of trip if data changed
If the date of a dive changed, it might be necessary to reorder
the trips, as the date of the trip changed. Although this seems
like an odd usecase, move the trip if necessary, for consistency's
sake.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-18 16:50:09 -08:00
Berthold Stoeger
64e6e435f8 Core: remove "when" field of struct dive_trip
The when field gives the time of the first dive. Instead of keeping
this field in sync, replace it by a function that determines the time
of the first dive.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-18 16:50:09 -08:00
Berthold Stoeger
431b2bb845 Coding style: fix indentation in addDivesToTrip()
addDivesToTrip() had one level of indentation too much owing
to a copy-and-paste error. Remove.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-18 16:50:09 -08:00
Berthold Stoeger
243962a67a Dive list: move sort-functionality into core
To make sorting more controlled, move all sorting functions into
the core. For this, introduce a "dive_or_trip" structure, which
represents a top-level item. Adapt the DiveTripModel accordingly.
There are now three sorting functions:
	1) dive_less_than
	2) trip_less_than
	3) dive_or_trip_less_than
These should be used by all sorting code. By moving them to a
single place, the mess can hopefully be cleaned up.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-18 16:50:09 -08:00
Berthold Stoeger
6b283e598a Dive list: replace dive-list of trips by a table
The dives of each trip were kept in a list. Replace this by a
struct dive_table. This will make it significantly easier to
keep the dives of a trip in sorted state.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-18 16:50:09 -08:00
Berthold Stoeger
7046c8b342 Dive list: invert sort-direction to reflect core
Traditionally, the DiveTripModel has its data sorted in opposite
direction to the core-data (chronologically descending vs. ascending).
This bring a number of subtle problems. For example, when filling
the model, trips are filled according to the *last* dive, whereas
later insertion points are according to the ->when value from the
core, which depends on the *first* dive.

As a start of fixing these subtleties, change the sort direction
to reflect the core-data. Ideally, this should lead to a removal
of the redundant data-representation.

Since the model is now sorted in ascending order, sorting has to
be enabled in the DiveListView constructor to reflect the
default-descending order.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-16 16:57:14 -08:00
Berthold Stoeger
da3ea59a25 Dive list: let sort arrows reflect sort order for NR and DATE
The old code always sorted by "ascending" by default. But
because users typically want their new dives top, "ascending"
was defined for NR and DATE, such that it is actually descending.
Turn these around and intitialize these two fields as
default-descending.

This is possible using the Qt::InitialSortOrderRole role
in DiveTripModel::headerData().

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-05 07:55:53 -08:00
Berthold Stoeger
83ed75f4ab Dive list: use proper comparison when comparing dive to trip
The DiveTripModels are sorted in *reverse* chronological order.
Therefore, when comparing a dive against a trip, the dive has
to be inserted if the dive has a *later* date. Change the
comparison accordingly.

Reported-by: Jan Mulder <jlmulder@xs4all.nl>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-04 08:04:27 -08:00
Berthold Stoeger
a2b3d0ff06 Undo: fix addition of multiple dives
The generic addInBatches() function is used to add batches of
contiguous sets of dives to the dive-list models. The loop
searching for the end of the batch used the wrong index and
would therefore not properly cut the batches.

Fix this.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-04 08:04:27 -08:00
Berthold Stoeger
ab894c9b64 Dive list: implement custom lessThan function
The dive list was sorted using the default-sorter of
QSortFilterProxy model. This is mighty inflexible as it
considers only one column. This has the funky effect that
for rows with identical elements, the sort order depends
on the previous sorting.

Implement a lessThan() function in the MultiFilterSortModel,
which simply hands the sorting down to the actual model.
This might be considered a layering violation, but it makes
things so much easier.

Sadly, it seems like the column-to-be-sorted is transported
in the provided indices. Therefore, the comparison is chosen
using a switch for *every* comparison. It would seem much
more logical to set a function pointer once and use that.
Further investigations are necessary.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-01 07:28:15 -07:00
Berthold Stoeger
803111ef02 Dive list: make filter model aware of its source
The data-flow from C-core to list-view is as follows:

C-core --> DiveTripModel --> MultiSortFilterModel --> DiveListView

The control-flow, on the other hand, differs as DiveListView
accesses both MultiSortFilterModel and DiveTripModel, whereas
MultiSortFilterModel is mostly unaware of its source model.

This is in principle legitimate, as the MultiSortFilterModel might
be used for different sources. In our particular case, this is
not so. MultiSortFilterModel is written for a particular use case.

Therefore, model control-flow follow after data-flow: Let MultiSortFilterModel
set its own source model and DiveListView access the MultiSortFilterModel,
which then manages its source model.

This is not bike-shedding, but will enable a more flexible and
higher-performance sorting.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-01 07:28:15 -07:00
Berthold Stoeger
a0cc02dfe8 Dive list: don't pass dive_site via uintptr_t through QML
Now that struct dive_site * is a proper Q_METATYPE it is not
necessary anymore to pass dive-sites as opaque uintptr_t types.
Simply pass a QVariants or directly via dive_site *.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
920eb7576f Dive site: pass pointer-to-dive_site via QVariant
There was this ugly pattern of passing pointers-to-dive_site via
a QVariant of void * type. This is of course inherently unsafe.

Pass these pointers using their proper types instead. This makes
it necessary to register them in Qt's meta-type system. Doing so,
fixes a bug: QML couldn't call into updateDiveSiteCoordinates()
because it didn't know the type and thus the coordinates of
the moved flag were not reflected in the divesite-dialog.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
e8b3fdb4a6 Dive site: compare pointers in MultiFilterSortModel::showDive()
To test whether to show a dive, the UUIDs of the filtered-by
location and the dive-site of a dive were compared. Since UUIDs
are unique (as the name implies), directly compare pointers.
Note: this code comes from a time when the filtered-by location
was not a pointer, but a copy.

Moreover, the if tested first for the same name, then (logical-or)
for the same uuid. This makes no sense, as the same dive-site
implies the same name. This code likewise can be explained by
historic reasons: the filtered-by location may have contained
a different name. Swap the order of the conditions: first test
for the same object and only of the objects differ, test for
the same same.

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
acd44467c1 Dive site: remove [start|stop]FilterDiveSite signals
This is another case of a weird pattern where an object would
connect it's own signal to the slot of a different object.
There seems to be no reason why the former couldn't simply
call the latter.

Remove the [start|stop]FilterDiveSite signals of LocationInformationWidget
and call the corresponding functions of MultiFilterSortModel directly.
While doing so, replace the UUID argument by a pointer-to-divesite.
It will be converted anyway right at the beginning of the function.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
b9b1b3146b Dive site: remove UUIDs from LocationInformationModel
Replace UUIDs from LocationInformationModel and fix the fallout.
Notably, replace the UUID "column" by a DIVESITE "column".
Getting pointers through Qt's QVariant is horrible, we'll have
to think about a better solution.

RECENTLY_ADDED_DIVESITE now defines to a special pointer to
struct dive_site (defined as ~0).

This fixes an interesting logic bug:
The old code checked the uuid of the LocationInformationModel (currUuid)
for the value "1", which corresponded to RECENTLY_ADDED_DIVESITE.
If equal, currType would be set to NEW_DIVE_SITE. Later, _currType_
was compared against _RECENTLY_ADDED_DIVESITE_. This would only work
because NEW_DIVE_SITE and RECENTLY_ADDED_DIVESITE both were defined
as 1.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
ab29f6416b Dive site: replace UUID_ROLE by DIVESITE_ROLE
Access to dive-sites in the LocationInformationModel was via UUID.
Replace this by a direct access to the struct dive_site pointer.
Accordingly, rename the UUID_ROLE to DIVESITE_ROLE.

This is a small step in replacing dive-site UUIDs by pointers
throughout the code base.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
f527a70831 Dive site: pass dive-site pointer to delete_dive_site()
Instead of passing a uuid, pass a pointer to the dive site.
This is small step in an effort to remove uuids.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
7f2026ded8 Cleanup: remove DiveTripModel::layout() function
This accessor was never used. This is a small step in splitting
the DiveTripModel in two (list & tree), which means that the
layout is moved up to the view.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-28 15:10:57 +00:00
Dirk Hohndel
c5fb66e775 Mobile/filtering: update nr of dives shown in a trip when filtering
Whenever the filter changes, simply walk the filtered dive list and ensure
that we have the correct count for dives that match this filter.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-25 23:24:22 +01:00
Dirk Hohndel
6248ddf529 Mobile/filtering: roll our own filtering for performance reasons
The regular expression based generic filtering made things very slow on a cell
phone or other, slower device. With this the results seem more reasonable.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-23 22:45:30 +01:00
Dirk Hohndel
52ec544c3b Mobile/filtering: finally implement the new settings in the actual filter
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-23 22:45:30 +01:00
Dirk Hohndel
17347f5110 Mobile/filtering: add fullTextNoNotes role to the dive list model
This way we can filter with and without the notes.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-23 22:45:30 +01:00
Dirk Hohndel
90d321f0ff Mobile/filtering: add count of filtered dives to search bar
The count in the trip headers is still that for the complete trip and therefore
misleading.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-23 22:45:29 +01:00