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>
Since the QHeaderView of DiveListView is now the authority
over sort-column and sort-order, it makes little sense
to keep these as member variables. That would only risk
inconsistencies. Remove them and query the QHeaderView
instead.
We still need to keep track of currentLayout, as we
have to detect if it changes to change the underlying
model from tree to list or vice-versa.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The DiveListView code had a very fundamental problem with its
header: Each had its own idea of who is responsible for sorting.
Since we can't easily change QHeaderView, accept QHeaderView
as the authority on sort-column and order.
To make this possible, split the reload() function in two
distinct functions:
- reload() reloads the model and sorts according to the
current sort criterion.
- setSortOrder() tells the header to display a certain
sort criterion. If this is a new criterion, it will then
emit a signal. In this signal, resort according to that
criterion.
Thus, the actual sorting code has to be moved from the
headerClicked() to a new sortIndicatorChanged() slot.
Morover, the sorting of the QHeaderView has to be used.
Reported-by: Stefan Fuchs <sfuchs@gmx.de>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Commit 6dc1d239f8 introduced a
well-defined sort order in the case of equal contents. It changed
the code for sorting by date to simply use the order of the
source model.
BUT: The source-model was already sorted in descending order
on date. Thus setting the default order on descening by date,
the data was then presented as *ascending* by date.
Change this back to descending by always using default-ascending
in the filter model.
Ultimately, the source model should simply reflect the ordering
of the core-data (ascending on date), but such a change is
too invasive shortly before release.
Reported-by: Jan Mulder <jlmulder@xs4all.nl>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
DiveListView::reload() was called for full reset of the dive list
and for changing the view (tree vs. lis) in DiveListView::headerClicked().
Since the latter does sorting by itself, a parameter "forceSort" was
introduced, which defaulted to true, but was set to false by
DiveListView::headerClicked().
To remove complexity, simply let DiveListView::headerClicked() set
the view by itself and remove tha parameter.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The QHeaderView::sectionPressed() signal was connected everytime
the list-view was reset. Likewise, setSectionsClickable() was
set to true everythime the list-view was reset.
Once in the constructor is enough.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
Import dives from a DC, and have ssrf started in verbose mode. After
downloading dives, hit ok, to add them to the dive list. This crashes
as we cannot get the uuid from the null dive site.
Added a simple guard to fix this.
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
In commit 920eb7576f "dive_site *"
was included in Qt's "metatype" system to be able to pass it
through QVariants. One instance was forgotten and a "void *"
was passed in. On readout NULL was returned, which made it
impossible to add new dive-sites under certain circumstances.
Convert this one instance to a proper "dive_site *" QVariant.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
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>
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>
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>
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>
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>
The diveSiteSelected signal of DiveLocationLineEdit had the dive-site
UUID as argument. But the receiving slot would not use that argument.
Remove this as a tiny step to remove the UUIDs alltogether.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
Instead of passing uuids, 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>
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>
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>