If the name of a dive site is edited, it might wander somewhere
else in the table and thus out of view. Hook into the "dive site
changed" signal and scroll there.
The code is rather subtle as it depends on signals being called
in a certain order: First the item is moved in the model, only
then can we scroll to the correct place.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When adding a dive site, enter the name field of the new dive site.
Thus, when adding a new dive site, the user can immediately edit the
name.
The code is rather subtle: It hooks into the dive site added signal
before executing the command and unhooks afterwards. This only works,
because signals are executed in order of connect - thus the model
adds the index first and only *then* is the field edited.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Implement a dive site addition undo command and connect it to
the add dive site button. The added dive site has a default
name ("new dive site").
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
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>
This feature will be replaced by.
1) An explicit purge empty dive sites feature.
2) Not allocating dummy dive sites for GPS coordinates.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
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>
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>
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>
For consistency with remove_dive(). Moreover, swap parameter order
in remove_dive() so that both functions use the same parameter order.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
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>
1) The second parameter (selected_only) was always false. Therefore,
remove it.
2) Simplify the function by simply returning the reference count.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of setting dive->dive_site directly, call the
add_dive_to_dive_site() and unregister_dive_from_dive_site()
functions. In the parser this turned out to be a bit tricky.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
Move the declaration of these functions to "file.h" and "parse.h"
according to the translation unit they are defined in. Thus, not
all users of "dive.h" have to suck in "sqlite3.h".
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Since the UUID will be overwritten on save and is only used on save
and load, set it only on save or load. For other created dive sites,
leave the UUID field uninitialized.
This means that the UUID will change between saves. Let's see how
the git saver handles that.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When a new dive site is created in MainTab::updateDiveSite()
and there is no text, it gets a generic name. But: the function
exits early if there is no text, so this is dead code. Remove.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
To extend the undo system to dive sites, the importers and downloaders
must not parse directly into the global dive site table. Instead,
pass a dive_site_table argument to parse into.
For now, always pass the global dive_site_table so that this commit
should not cause any functional change.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
-return the result instead of storing in a parameter, we now know that the list
contains only those results that are generated in the function
-allocate the result with the correct length right from the start
-do not iterate over keys of a map and then do a map lookup to get the value but
use an iterator that gives us both right from the start
-remove one call alltogether as the results were not used there
Signed-off-by: Rolf Eike Beer <eike@sf-mail.de>
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>
This is only in Qt 5.7 and therefore can't be used in Qt 5.5 and 5.6
builds. Moreover, we can't simply reuse Qt's version owing to
licensing concerns.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Allow splitting out a dive computer into a distinct dive. This
is realized by generating a base class from SplitDive.
This turned out to be more cumbersome than expected: we don't
know a-priori which of the split dives will come first. Since
the undo-command saves the indices where the dives will be insert,
these have to be calculated. This is an premature optimization,
which makes more pain than necessary. Let's remove it and
simply determine the insertion index when executing the command.
Original code by Linus Torvalds <torvalds@linux-foundation.org>.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This introduces a csv file that contains the data from
the structs defined in profile.c, in particular all
deco information computed for the dive profle (including
NDL, TTS, ceilings, surface GFs etc).
Signed-off-by: Robert C. Helling <helling@atdotde.de>
It expands to nullptr anyway and is inconsitent with the rest of the
code. Let's remove this anachronism.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
printGPSCoords() returned a newly allocated C-style string. Most
callers simply made a QString out of it and freed the C-style string.
This is paradoxical, as printGPSCoords internally works with QStrings
and converts them to C-style on return.
Therefore, let printGPSCoords() return a QString and create a
printGPSCoordsC() wrapper for the two C-callers.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The printGPSCoords() function returns a copied C-style string. Since
the owndership is transferred to the caller, the correct return type
is "char *" instead of "const char *".
Thus a number of casts when calling free can be removed.
Moreover a number of callers didn't free the string and thus were
leaking memory. Fix them. Ultimately we might want two versions
of the function: one for QString, one for C-style strings.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Printing never worked, none of this was ever included in test builds. Also, now
that there are official releases of QtWebKit again, this just doesn't seem worth
carrying along anymore.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
All these aren't actually things that need fixing, they are observations about
the code.
Given that LGTM.com reports FIXME comments as Alerts, let's change the ones
that aren't about things that need fixing to something more harmless.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
ostcFirmwareCheck in DownloadFromDCWidget was neither freed
in the destructor, not freed if a new object was allocated.
Simply make it a unique_ptr<> to do all the work for us.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We already do that on mobile and I was certain we used to do this for
desktop as well, but apparently that got lost somewhere...
This should solve the problems we are seeing for people with mixed case
email addresses.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
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>
6bf4120dbb replaced the trip flag by
a notrip boolean. This was supposed to signal that the user removed
the dive from a trip and therefore it shouldn't be autogrouped again.
Sadly, the commit removed the feature. Reinstate it.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
That's redundant with the information that we show in the window title (and
only risks going out of sync, as it is right now).
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Since the filter numbers are now shown in the window titlebar, we can use this
space for an explanation of the two button (they already have tooltips, but
this is even easier for the user).
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Instead of using the filter widget itself to show the information how many
dives are displayed, put it in the window title where it's visible even if the
filter widget isn't shown.
If the filter is not active, simply show the total number of dives.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Only clear the filter when the user explicitly resets it. This way the user can
toggle between the map and the filter widget without losing the filter state.
Fixes#1952
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This is not perfect - if you open the filter, set some criterion and then
remove it again (without resetting the filter), this variable will give you a
false positive).
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
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>
The undo-work reversed the direction of the offset. This was apparently
only fixed when using the menu entry, but not when editing dives directly.
Invert the offset to get the correct time.
While doing so, remove a redundant if: First it checked whether the
dates are the same, then whether the offset is non-zero.
Fixes#1975.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
By default we'll only show devices that we believe to be dive computers,
but the user can override that with the recently introduced check box.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Which right now is of course what we do by default, the goal is to only show
what we think are dive computers, but allow to see all of them if the user
wants to.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
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>
With Facebook support gone, we should offer a way to export
the profile image. This has been part of the TeX support
but this makes it explicit.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
The info box can get longish. Offer the user to turn
off display of deco information (surface GF and
individual ceilings).
Signed-off-by: Robert C. Helling <helling@atdotde.de>
The .cpp and .h files are all lower-case, the .ui file is camel-case.
Unify to lower-case (which is much more common in the code base).
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The texts may not be perfect, but this is a start. Replace the buttons
by combo-boxes. This will allow potential extension to "any of".
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Use button text to indicate what the current state is (done in code) and use
tool tip to tell the user that pressing the button negates the filter's effect.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In MainTab::acceptChanges there was a "editMode != ADD" condition
inside a else block to "editMode == ADD", which is therefore
redundant. Remove.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
Implement the close & reset functionality, by reseting the
application state to "Default". This is currently the only
state from where the fiter can be called.
To make it consistent with CTRL^F, clear the filter in the
hide() slot, which is called in both cases.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
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>
This was missing in the export. We export separate hour and
minutes so the template can decide about the time format.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
This makes it more like the plain TeX export, the main change
is in the structure of the template file (not included here).
Signed-off-by: Robert C. Helling <helling@atdotde.de>
So far, the TeX export was intended to be used with plain TeX.
To make it compatible with LaTeX, we only need to make sure
there are no macro name clashes and remove plain TeX specific
calls.
So far, this works only for single dives as the export only
sets up macros to contain dive data and then read the actual
latex file (starting with \documentclass etc). Later, the
template should setup macros to be called from the export
file.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
When connecting to facebook, I get a warning that the connection
is not secure. It's a wild guess that this patch solves the
issue but I currenty cannot build with facebook support. So I cannot
check.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
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>
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>
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>
The alignment of the 2 first lines of the new filter widget looked badly
aligned. Fixed by this simple change.
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
In 891fcbf520 boolean parameters were
replaced by flags. Fix an error in this commit: IMPORT_IS_DOWNLOADED
should be IMPORT_PREFER_IMPORTED.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The "Rating label" had a superfluous space at the beginning.
Remove.
Reported-by: Jan Mulder <jlmulder@xs4all.nl>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Commit 8e81d3f100 changed a bunch
of Ui classes to be subobject of the widget. For consistency do
the same with the filter widget.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In commit b0556abdd35f96b816ba11e40bf5707abe0c3ebf, the filter-widget
and the filter were connected by a direct function call. This led
to a rather obscure crash on application-close with Qt 5.12. The
crash is due to the Ui::MainWindow class being a sub-object of MainWindow,
but the FilterWidget2 being *not* a subobject.
What happens is that after calling the MainWindow destructor, the
subobjects are destructed, notably the Ui class. Then the base-class
destructor is called (which makes sense, as destructors are called
in reverse order of constructors).
But: the QObject destructor calls hide() on all still existing child-objects
according to Qt's object hierarchy, notably the visible FilterWidget2.
Now the FilterWidget2, on hiding, updates the MainWindow, which has already
destructed all its subobjects. Crash.
Prevent this crash by making FilterWidget2 a subobject of MainWindow
and thus have it destructed before running the QObject destructor.
Alternative ways would be:
1) Use signal/slot() instead of function calls, as these are automatically
removed if an object is destroyed.
2) Make the FilterWidget2 subobject a smart-pointer. Thus, we probably
wouldn't have to include the corresponding header.
3) Make the FilterWidget2 subobject a plain pointer and delete it
explicitly in the constructor.
Reported-by: Jan Mulder <jlmulder@xs4all.nl>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
In the latest version of the new filter-widget the connection
between widget and filter was lost. Connect both - but use a
simple function call instead of a signal, since it is not
immediately obivous where the connection should be made.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
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>
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>
The logic in process_imported_dives() was faulty: Dives are merged
trip-wise in a loop. But if only autogenerated trips were supposed
to be merged, the trip would not be added.
Change the logic to always add the trip if it is not merged. To make
the loop easier to read, factor out the merge-trip-into-existing-trips
logic into a separate function.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This adds a checkbox for rebreather modes of the planner
that force the ascent to be in OC mode. Before, one had
to add a one minute last segment with the mode change but
this is not practical when manually searching for the
maximal bottom time given gas reserves.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
After the downloading finished, the mainwindow-display is reset
via a signal. This is probably an artifact of old times, when
downloading was done into the main dive-list. Nowadays, this seems
to make little sense, as the main dive-list is not changed by download.
Remove the signal.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
DiveListBase had an explicit constructor that initialized the
"firstExecution" member variable. The latter was a development-
artifact that was never used. Remove the member and the constructor.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
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>
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>
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>
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>
To allow parsing into arbitrary trip_tables, add the corresponding
parameter to the parsing functions and the parser state. Currently,
all callers pass the global trip_table so there should be no change
in functionality. These arguments will be replaced in subsequent commits.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Currently trips are added to the global trip table. If we want to
make dive-import undoable, we should be able to parse trips of a
log-file into a distinct table. Therefore, add a trip_table
parameter to
- insert_trip()
- create_and_hookup_trip_from_dive()
- autogroup_dives()
- unregister_trip()
- remove_dive_from_trip()
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Trips were added to the core with the first dive of that trip.
With the recent changes that keep trips ordered by first dive,
this became counter-productive. Keeping a consistent state at
all times would mean resorting the trip table for every dive
that is added.
Instead, add all dives to a trip and *then* add the trip to the
core. Change the data-structures to not register trips-to-be-added
with individual dives, but keep them in a separate vector for
each undo command.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Currently, all trips are kept in a linked list. Replace the list
by a table in analogy to dive_table. Use this to keep the trip_table
sorted as suggested by dump_trip_list(). When inserting a trip into
the table do that after adding the dives, to avoid warnings coming
out of dump_trip_list().
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Rename
- dive_get_insertion_index() -> dive_table_get_insertion_index()
- unregister_dive_from_table() -> remove_from_dive_table()
- get_idx_in_table() -> get_idx_in_dive_table()
- sort_table() -> sort_dive_table()
This will make it more straight-forward to generate these functions
from macros.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Currently autogroup_dives() groups all dives in the global dive
list. Add a table parameter so that dives in any table can be
grouped. Thus it will be possible to pre-group dives on import,
which will be used for undo of import.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
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>
In commit 6bf4120dbb the trip-flags
were replaced by a simple boolean. This made the was_autogen
parameter to the remove_dive_from_trip() and unregister_dive_from_trip()
functions unused. Remove these parameters.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Capitalize the first letter of error message sentences in this
file to be consistent with other error messages in this file
and across the project.
[Dirk Hohndel: edit to remove the changes to the .ts files]
Signed-off-by: John Plaxco <john@johnplaxco.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
If no dives are selected when trying to export a selection, a message
is shown that no dives were selected, but it's immediately hidden
behind a message saying that a temporary file could not be created.
In fact, the creation of the temporary file wasn't never attempted,
so the message that the user actually sees is misleading.
The solution chosen here is to duplicate the check that at least some
dives are selected, and abort early if that case is detected, rather
than continuing on to show the additional misleading message. Not
elegant, but it gets the job done.
Better solutions to this include refactoring prepare_dives_for_divelogs
to return something more descriptive than a bool, remove that check
from prepare_dives_for_divelogs entirely since it doesn't seem to be
a good fit there, or switch to exceptions for handling these problems
rather than return values. I don't have sufficient familiarity with
the codebase to attempt these more invasive changes, but they
should be considered in the future.
On a final note, some of the other error messages in this file start
with a capital letter, but the one relevant to this particular PR
does not. Again, I'm not familiar enough with the codebase (or
translations) to know if that's safe to change, so I'll leave that
for another time or another developer.
Reported-by: John Plaxco
Signed-off-by: John Plaxco <john@johnplaxco.com>
Unsure where this bug got introduced, but when asking for the dive
time to be shifted 1 hour later, the divelist and the dive details
showed 1 our earlier.
Fixes: #1893
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
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>
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>
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>
Register the new FilterDive widget on the mainwindow
so we can trigger a shortcut to display it.
The shortcut currently doesn't exists.
Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
The idea of this new widget is to be able to filter more
types of data, while keeping it simple and extending the
feature set to something that was impossible with the old
implementation.
While the old implementation had 4 panels that you could
use to filter specific tags / people / types of dives
the new one will let you filter by visibility, temperature
people, name, equipment, etc, in a more natural way
than the old one.
Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
In 302f6adb79 dive-splitting was made
undo-able. To this goal, the dive-splitting functions were split in
two types: Those that operate directly on the divelist and those that
only allocate the dives. The former are not in use anymore, therefore
remove them. Since only the latter remain, remove the "_dont_insert"
appendix of the name.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In f427226b3b a combine_trips_create()
function was introduced that combined trips without deleting the old
trips. This was necessary for making combine-trips function undo-able.
The old combine_trips() function is not used anymore. Therefore remove
it. Rename the combine_trips_create() function to combine_trips() as
no differentiation is needed anymore.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In moveDivesBetweenTrips() a the model is informed of dives
that are moved between trips. A flag tells the model to delete
empty trips. If dives were removed in batches [use case: split
a big trip into multiple smaller trips] the flag would be sent
for every batch. This was handled gracefully by the model code,
but it gave a warning message.
Set the flag only for the last batch, when the trip is *really*
empty.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Currently, when selecting "Load media files even if time does not
match the dive time", the media are added to *all* selected dives.
Instead add it to the closest dive.
This seems like the less surprising behavior. Of course now if the
user really wants to add a media file to multiple dives, they will
have to do it manually.
To avoid a messy interface, this is solved by moving the iterate-
over-selected-dives loop to the core. Thus, a helper-function can
be made local to its translation unit.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
dive_create_picture() is called from DiveListView::matchImagesToDives()
with a copy of the picture-filename. But:
- On error the filename is not freed
- On success the filename is strdup()ed
Thus, in all cases the memory is lost. Instead, pass in a temporary
buffer using qPrintable().
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
... otherwise this change is not saved when saving to git.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
The whole point of the undo-command system is that the divelist
doesn't have to be refreshed. Therefore, don't do it for autogrouping
/ deautogrouping.
Moreover, the divelist-changed flag is also set by the command and
doesn't have to be set explicitly.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
New gcc (v8.2) complains about memcpy()ing an object with non-POD
members. Even though this seems not to be an issue for template_options,
the warning has some merrit. The compiler will recognize when to do
a memcpy() anyway. Moreover, the assignment is easier to read and also
more secure, as a-priory we can't know if Qt's QColor copy-constructor
does some strange things (hopefully not).
Thus, replace memcpy() by simple assignment.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
On shift-times, the list of dives in a trip may become disordered.
Reestablish order with sort_table().
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
Up to now, dives were added to the global dive table with
add_single_dive(). Split out the funtionality to add a dive to
an arbitrary dive in the add_dive_to_table_function(). The
difference compared to record_dive_to_table is that dives
are added at a specific position or the sort-criterion given
by dive_less_than(). This will allow to use a dive tabe for trips
instead of a linked list.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
There were two versions of the insert_trip() function: one
would merge trips if a trip with the same date already existed,
the other wouldn't. The latter was introduced with the dive-list
undo work.
The problem is that the "date" of a trip (i.e. the first dive)
seems ill-defined as this is a volatile value. Moreover in
the context of making dive-import undoable this is a very
dangerous notion, as the caller needs control over when the dives
are added to a trip.
Therefore, unify these two functions and never merge trips.
The decision on merging dives now has to made by the caller.
This will be implemented in a future commit.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
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>