The DiveItem and TripItem classes were wrappers around dive * and
dive_trip * used to extract tabular data. With the rework of
DiveTripModel they lost all their state besides the pointer itself.
The usage was:
DiveItem item(d);
item.data(...);
This can now be simplified to the much more idiomatic
diveData(d, ...);
and analoguously for TripItem.
While adapting the data() function to be part of DiveTripModel, change
the
QVariant ret
switch(...) {
...
case ...:
ret = ...;
break;
...
}
return ret;
style to
switch(...) {
...
case ...:
return ...;
}
Not only is this shorter and easier to reason about, it generally also
improves the generated code. The compiler can directly construct the
return value in the buffer provided by the caller. Though modern
compilers start to be very good at avoiding unnecessary copies.
In total this cleanup results in a net-reduction of 190 lines of code.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Ultimately, we want to use a single dive-list and not replicate
it in the Qt-model code. To this goal, let's start with using
the same sort function.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The current code cheats when it comes to move dives inside
a trip or move dives between trips: Instead of using the
*MoveRows() functionality, the dives are removed from and
re-added to the respective trips. This loses the selection.
Therefore, remember which of the moved dives are selected
and select them manually after they are re-added.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The command-objects select a current item, but this selection
was not propagated to the front-end. The current item is the
base for keyboard-navigation through the dive-list and therefore
should be set correctly.
It took some experimentation to get the flags right:
QItemSelectionModel::Current
Hopefully, these are the correct flags across all supported
Qt versions!
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Select the proper dives after the add, remove, split and merge
dives commands on undo *and* redo. Generally, select the added
dives. For undo of add, remember the pre-addition selection.
For redo of remove, select the closest dive to the first removed
dive.
The biggest part of the commit is the signal-interface between
the dive commands and the dive-list model and dive-list view.
This is done in two steps:
1) To the DiveTripModel in batches of trips. The dive trip model
transforms the dives into indices.
2) To the DiveListView. The DiveListView has to translate the
DiveTripModel indexes to actual indexes via its QSortFilterProxy-
model.
For code-reuse, derive all divelist-changing commands from a new base-class,
which has a flag that describes whether the divelist changed. The helper
functions which add and remove dives are made members of the base class and
set the flag is a selected dive is added or removed.
To properly detect when the current dive was deleted it
became necessary to turn the current dive from an index
to a pointer, because indices are not stable.
Unfortunately, in some cases an index was expected and these
places now have to transform the dive into an index. These
should be converted in due course.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Don't delesect dives, when unregistering them from the backend.
If a previously selected dive is added, select it in the dive-list.
For this purpose introduce a SELECTED_ROLE to query the DiveTripModel
for selected dives.
Unfortunately, when adding multiple selected dives, current_dive_changed
is called for each of them, making this very slow. This will have
to be fixed in subsequent commits.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Previously, each dive-list modifying function would lead to a
full model reset. Instead, implement proper Qt-model semantics
using beginInsertRows()/endInsertRows(), beginRemoveRows()/
endRemoveRows(), dataChange().
To do so, a DiveListNotifer singleton is generatated, which
broadcasts all changes to the dive-list. Signals are sent by
the commands and received by the DiveTripModel. Signals are
batched by dive-trip. This seems to be an adequate compromise
for the two kinds of list-views (tree and list). In the common
usecase mostly dives of a single trip are affected.
Thus, batching of dives is performed in two positions:
- At command-level to batch by trip
- In DiveTripModel to feed batches of contiguous elements
to Qt's begin*/end*-functions.
This is conceptually simple, but rather complex code. To avoid
repetition of complex loops, the batching is implemented in
templated-functions, which are passed lambda-functions, which
are called for each batch.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
AddDivesToTrip, CreateTrip, AutogroupDives, RemoveAutogenTrips
and MergeTrips basically all did the same thing as RemoveDivesFromTrip,
which was already implemented. Thus, factor our the common functionality
and hook it up to make all these functions undo-able.
Don't do the autogroup-call everytime the dive-list is rebuilt
(that would create innumberable undo-actions), but only on dive-load /
import or if expressly asked by the user [by switching the autogroup
flag].
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The dive list is fed data by means of a sorted "DiveTripModel".
There are two modes: list and tree. This was implemented rather
elegantly with a general "TreeModel", which can represent trees
of arbitrary depths.
Nevertheless, we have at most two levels and on the second level
only dives can reside. Implementing proper model-semantics
(insert, delete, move) will be quite a challenge and implementing
it under the umbrella of a very general model will not make it
easier.
Therefore, for now, hardcode the model:
At the top-level there are items which may either be a trip
(can contain multiple dives) or a dive (contains exactly one dive).
Thus, we can completely de-virutalize the DiveItem and TripItem
classes, which are now trivial wrappers around dive * and dive_trip *.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The undo-system now guarantees that pointers to dives are stable
throughout their lifetime. Therefore, replace the unique index by
pointers. This is a small performance improvement, but much more
importantly, it will make it more natural to transport a pointer
to the dive inside QModelIndex's private pointer.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Dives are now in all cases imported via distinct dive_tables.
Therefore the "preexisting" marker is useless. Remove.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
DiveTripModel (the model describing the dive-list) was destroyed
and recreated on every reset of the list. This seems excessive.
Instead - in analogy to most other models - make it a single
global object.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The function DiveListView::fixMessyQtModelBehaviour() was used to
expand the first columns of dive-trips in the dive-list view.
This function was called everytime that the dive-list was modified.
It is kind of ludicrous that external callers would have to
tell the DiveListView, when it has to update its column headers.
Instead, place this functionality in the overriden reset() and
rowsInserted() functions, as these are the only ways that
rows can be added. Change the DiveTripModel to use the proper
beginResetModel()/endResetModel() pair instead of the previous
full deletion and full repopulation using the beginRemoveRows()/
endRemoveRows() and beginInsertRows()/endInsertRows().
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Conceptually, the width of the columns should probably reside in
the view not the model. But much more severly, the old code didn't
work: Columns were set in a DiveTripModel, which was deleted
right away.
Therefore, move the logic back to the DiveListView. Introduce
a QVector<int> of the initial column widths, so that they can be
erased from the setting if unchanged.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Each DiveItem (which is a wrapper around diveId with some virtual
functions), had a member icon_names, which is an array of
four QStrings. These were not used anywhere and must be an obscure
oversight and was probably planned as a static cons array?.
In any case, remove it.
There *was* a function-local analogous icon_names array in
DiveItem::data() though. This array would initialize four
QStrings from C-string literals on every invocation. Make
this array static, local to the translation unit and use
the QStringLiteral macro to construct the QString object at
compile-time.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This changes the above mentioned terms everywhere in the UI to
reflect the fact that Subsurface now also supports video files on top
of image files.
Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
helpers.h included qthelper.h and all functions declared in helpers.h
were defined in qthelper.h. Therefore fold the former into the latter,
since the split seems completely arbitrary.
While doing so, change the return-type of get_dc_nichname from
"const QString" to "QString".
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Previous taglist_get_tagstring signature/implementation did not allow
handling of cases where inputted buffer could not contain all tags.
New implementation allocates buffer based on pre-computed size allowing to
insert all tags in the returned string.
Added get_taglist_string in qthelper to handle conversion to QString
Added TestTagList with tests for taglist_get_tagstring
Signed-off-by: Jeremie Guichard <djebrest@gmail.com>
Add DiveItem::displayTags helper method to return Tags as a QString
New Tags column is
by default inserted before "Photos" column
by default disabled
Signed-off-by: Jeremie Guichard <djebrest@gmail.com>
This changes the numeric format of many values printed to the UI to
reflect the correct numeric format of the selected locale:
- dot or comma as decimal separator
- comma or dot as thousands separator
In the Qt domain the `L` flag is used case specific mostly
in qthelper.cpp.
Then the helper functions get_xxx_string() are used more consistently.
Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
Icon aliases were complete mess.
Some icons had alias some didn't.
Named with underscores vs. hyphens vs. camelCase.
Lower vs. upper case.
"ICON" prefix vs. suffix vs. nothing.
With vs. without filename suffix.
Some didn't make sence. Eg. mapwidget-marker-gray
(I can see, it's grey, but what does it represent?)
Some were duplicated, eg warning vs. warning-icon.
Some were name after widget, which is wrong.
Do not reinvent wheel. Use widely used naming scheme
close to Freedesktop Icon Naming Specification. This
will enable usage of common icons from current set in
the future. Thus Subsurface will fit nicely to GUI.
This changes icon aliases to one, easy grep-able style.
Signed-off-by: Martin Měřinský <mermar@centrum.cz>
Icon aliases were inconsistent mess. Underscores vs. hyphens vs. camelCase.
With vs. without filename suffix. Lower vs. upper case. "icon" suffix vs.
prefix vs. nothing. Some were duplicated, eg warning vs. warning-icon. Some
icons didn't have alias at all.
This changes all icon aliases to one, easy grep-able style which complies
to Freedesktop Icon Naming Specification (Guidelines).
Signed-off-by: Martin Měřinský <mermar@centrum.cz>
The `static int defaultWidth[]` definition in divelistview.cpp
could potentially end up missing an element which can later result
in out-of-bounds access when iterating through the list of
columns and updating their widths.
Add a couple of methods in DiveTripModel for setting and getting
the widths and use those. The default values are now pre-set in a
QVector in the DiveTripModel() constructor.
Throw warnings if out-of-bounds columns are requested.
Reported-by: Gaetan Bisson <bisson@archlinux.org>
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Calculating dive.when + dive.duration doesn't always give the correct
endtime of a dive especially when a dive has surface interval(s) in
the middle.
Using the helper function dive_endtime() fixes this issue.
Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
Update the function to create the dive duration string in a way that
it can be used also in info and stats tab and added some more flexibility.
Changed layout for <1h freedives to "0:05:35" (w/o units) or "5:35min"
(with units and :) or "5min 35sec" (with units with space).
Add a new function to create the surface interval string.
Completely remove old function get_time_string() and get_time_string_s().
Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
We now respect the settings in the preferences and also only show
the duration as minutes and seconds if the dive is a free dive.
Fixes#361Fixes#362
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The Qt model sorting for the dive date was using a unsigned number,
which doesn't work for dates before 1970.
Also, the dive date parsing got the year 1900 wrong. Not that we really
care, because other parts of date handling will screw up with any date
before the year 1904. So if you claim to be diving before 1904, you get
basically random behavior.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Please apply this patch on top of the previous patch with the same title.
1) Provide icons with white margin to look more like photos
2) Optimise code, following Robert's suggestions.
3) Column heading for photos column is now: Photos. This takes up extra
horizontal space but makes the user interface more understandable.
Signed-off-by: Willem Ferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
1) Add an extra column to dive list, just left of Locality field.
2) For each dive, give summary of photos as follows:
i) no photos: no icon in that column
ii) photos taken during dive: show icon of fish
iii) photos taken before/after dive: show icon of sun
iv) photos taken during as well as before/after dive: show
icon with both fish and sun
3) Provide information for the sort operation to work on
this column of the dive list.
Signed-off-by: Willem Ferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Having subsurface-core as a directory name really messes with
autocomplete and is obviously redundant. Simmilarly, qt-mobile caused an
autocomplete conflict and also was inconsistent with the desktop-widget
name for the directory containing the "other" UI.
And while cleaning up the resulting change in the path name for include
files, I decided to clean up those even more to make them consistent
overall.
This could have been handled in more commits, but since this requires a
make clean before the build, it seemed more sensible to do it all in one.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Apparently transifex drops the leading space in the translation string and
then at runtime the string no longer matches. So let's just code this
differently.
This of course creates a new string but that new string should be the
string that transifex already asks people to translate...
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>