Commit graph

20 commits

Author SHA1 Message Date
Berthold Stoeger
236f0512be Filter: sort filter items in FilterModelBase::updateList()
All callers of FilterModelBase::updateList() sorted the items
(except the last one). Thus we can do the sorting inside the
function.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-31 07:48:23 -07:00
Berthold Stoeger
9b90c461a2 Filter: Make FilterModelBase a proper Qt model (mostly)
Since FilterModelBase now contains complex data (counts and checked),
we might just as well make it a full model and keep track of
the name as well. I.e. do not derive from QStringListModel but from
QAbstractListModel and add the name to the item structure.

Implement proper reset / add / rename semantics. This is overkill at the
moment, as after all any modification the model will be reset, but
ultimately it will allow us to be smarter and only update rows when
needed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-31 07:48:23 -07:00
Berthold Stoeger
66aeaddd0f Filter: cache number of dives fulfilling filter rules
Currently, in FilterModelBase::data() the number of dives is recalculated.
This happens for every mouse-over event!

Calculate the number of dives only on recalculation and store the count
in the items-struct.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-28 05:03:59 -07:00
Berthold Stoeger
ec586d0e0a Filter: replace checked-state by struct
In the future, we might be smarter about the dive-counts and calculate
them only once and incrementally (if e.g. new dives are added).
Prepare for more complex caching by turning the checked boolean into
a struct, which can then be extended by a count and other things
(e.g. the name).

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-28 05:03:59 -07:00
Berthold Stoeger
979f81f409 Filter: separate backend from frontend logic
The filter code was an unholy intermixture of backend and frontend
logic, which made it hard to access it from outside of the UI.
Notably, it expected that Qt would call filterAcceptsRow on all rows.
For trip-view, apparently the filter functions were called twice
(once for filtering the trip, then for filtering the individual dives).

Make the filtering explicit, by calling showDive() for all dives in
MultiFilterSortModel::myInvalidate(), setting the hidden_by_filter
flags accordingly and ultimately invalidating the filter.

The UI code only accesses the hidden_by_filter flag set previously.

The "justCleared" flag can then be removed, since accessing the filter
does not have side effects. Moreover, there is no noticeable performance
gain by returning out early.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-16 08:07:25 +02:00
Berthold Stoeger
13fbca3f55 Filter: break out showDive() function from filterAcceptsRow()
To make dive-filtering accessible from other parts of the code,
break out the actual dive-filtering code into a function that
takes a pointer-to-dive instead of QModelIndex.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-14 14:16:25 -04:00
Berthold Stoeger
8a394b9db4 Filter: constify doFilter() argument
Conceptually, the doFilter() functions shouldn't modify the dive
they test. Therefore, make the argument const. To do this, constify
the parameter of get_dive_location(), which likewise seems to be
the right thing to do.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-14 14:09:30 -04:00
Berthold Stoeger
fb47c15cd8 Filter: remove unused parameters from doFilter functions
Change the signature from of the virtual doFilter() functions from
 bool doFilter(struct dive *d, QModelIndex&, QAbstractItemModel*) const;
to
 bool LocationFilterModel::doFilter(struct dive *d) const;
as the QModelIndex and QAbstractItemModel parameters were not used.

This makes this functions independent from Qt's model/view
framework. This is in preparation for making the undo-machinery
compatible with the filtering.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-14 13:03:33 -04:00
Berthold Stoeger
1c4a859c8d Cleanup: remove all override modifiers
Commit df156a56c0 replaced "virtual"
by "override" where appropriate. Unfortunately, this had the
unintended consequence of producing numerous clang warnings. If
clang finds a override-modified function in a class definition,
it warns for *all* overriden virtual functions without the override
modifier.

To solve this, go the easy route and remove all overrides. At least
it is consistent.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-08-01 06:30:00 -07:00
Berthold Stoeger
df156a56c0 Cleanup: replace virtual by override where appropriate
The keyword "virtual" signalizes that the function is virtual,
i.e. the function of the derived class is called, even if the
call is on the parent class.

It is not necessary to repeat the "virtual" keyword in derived
classes. To highlight derived virtual functions, the keyword
"override" should be used instead. It results in a hard compile-
error, if no function is overridden, thus avoiding subtle bugs.

Replace "virtual" by "override" where appropriate. Moreover,
replace Q_DECL_OVERRIDE by override, since we require reasonably
recent compilers anyway. Likewise, replace /* reimp */ by
"override" for consistency and compiler support.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-07-31 11:02:34 +02:00
Berthold Stoeger
b6bf57a13b Introduce negate-toggle buttons to filter lists
Introduce toggle buttons which mean "filter all dives except
those fulfilling the selected criteria".

The old code used to check for rowCount() == 0. This should never happen,
because there is always a row "empty field". This check was moved into
the preamble of the functions to seperate it from the actual logic.

Fixes #435

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2017-12-26 13:08:49 -08:00
Berthold Stoeger
7451517e4a Add select-all, deselect-all and invert-selection options to filters
To every filter list add a menu button that allows selection of all,
selection of none or inversion of selection.

Implements #435.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2017-12-24 08:24:11 -08:00
Berthold Stoeger
668635e98e Move *FilterModel functions into base class
The *FilterModels had a number of of virtual functions, which only
accessed members of the base class. Moreover, these functions were
identical and generated with macros. Therefore, move these functions
to the base class.

The one excption is data(), which uses different count functions
(passed as a macro parameter). Thus, introduce a virtual countDives()
function and likewise move data() to the base class. A function pointer
might be even more clear, but since the rest of the code/Qt relies
heavily on runtime polymorphism, let's do the same here.

The only macros left are those creating the singleton accessors.
This could be more clearly realized by templates, but let's
likewise keep it the way is.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2017-12-24 08:24:11 -08:00
Berthold Stoeger
7eed752ba1 Fold MultiFilterInterface into FilterModelBase
There were two classes, MultiFilterInterface and FiterModelBase.
The latter derives from the former and from QStringListModel.
The former was not used anywhere else. Moreover, in contradiction
to its name, MultiFilterInterface is not an interface (in the Java
sense), because it actually has (non-virtual) data members. All in
all, the data model is very weird.

Merge these two classes, since there seems to be no gain whatsoever
from keeping MultiFilterInterface separate.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2017-12-24 08:24:11 -08:00
Berthold Stoeger
24c72cb359 Inform LocationFilterModel of added dive site name
If the user implicitly adds a dive site by editing a dive, and
a location filter is active, check the new dive site in the
location filter.

This is done by informing the LocationFilterModel of the new
dive site name prior to repopulation. The LocationFilterModel
then adds a corresponding entry and marks it as checked.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2017-11-26 18:50:40 -08:00
Berthold Stoeger
f4bcdf46aa Inform LocationFilterModel of changed dive site name
Since commit 01d961086c, the location filter
list is updated if a dive site is edited. The problem is that if the
name of a selected dive site is changed, the selection is lost.

Therefore, before repopulating, inform the location filter that a dive
site changed its name. The location filter then internally changes the
name and can properly transfer the old selection on repopulate. This is
performed via the new LocationInformationWidget::nameChanged signal,
which is connected to the new LocationFilterModel::changeName slot.

A special case to be handled is the following:
 [ ] Site 1
 [x] Site 2
and "Site 2" being renamed to "Site 1", i.e. both sites being merged.
Here, the merging is detected and "Site 1" will likewise be checked:
 [x] Site 1
 [x] Site 1
No merging is performed, as the list will be repopulated anyway.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2017-11-26 18:50:40 -08:00
Berthold Stoeger
dd2466f518 Update filters on refreshDisplay and remember old selecttions
Update the filters if the list of dives is updated by calling
MultiFilterSortModel::instance()->myInvalidate();
This had the side effect of clearing all selections. Thus, in
the repopulate() methods of the FilterModels, check those
entries that were checked previously. Since all the filter
models use the same code, introduce a base class FilterModelBase.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2017-11-25 08:24:36 -08:00
Berthold Stoeger
4da6a0a732 Replace bool * array by std::vector<char> in MultiFilterInterface
This replaces a dynamically allocated array of bool by std::vector<char>.
1) This makes the code shorter and less error prone, because memory
   management has not to be done by hand.
2) It fixes a bug in the old code:
   memset(checkState, false, list.count()) is wrong, because bool is
   not guaranteed to be the same size as char!

Two notes:
1) QMap<>, QVector<>, etc. are used numerous times in the code, so
   this doesn't introduce a new C++ concept. Here, the std:: version
   is used, because there is no need for reference counting, COW
   semantics, etc.
2) std::vector<char> is used instead of std::vector<bool>, because
   the latter does a pessimization where a bitfield is used!

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2017-11-25 08:24:36 -08:00
Dirk Hohndel
5372f12d8b Add SPDX header to Qt models
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-04-29 13:32:55 -07:00
Tomaz Canabrava
338c0f22aa Move the models to its own folder
This is an attempt to help share code between the desktop version of
Subsurface and the mobile version.
More code will be moved around and the models will be split in a way that
will help recompile times and also creation of different interfaces for
different form-factors.

Signed-off-by: Tomaz Canabrava <tomaz.canabrava@intel.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2015-05-29 14:07:54 -07:00
Renamed from qt-ui/filtermodels.h (Browse further)