2017-04-27 18:25:32 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2016-04-05 05:02:03 +00:00
|
|
|
#include "qt-models/filtermodels.h"
|
|
|
|
#include "core/display.h"
|
2018-08-28 18:44:11 +00:00
|
|
|
#include "core/qthelper.h"
|
2019-05-31 14:09:14 +00:00
|
|
|
#include "core/trip.h"
|
2018-05-11 15:25:41 +00:00
|
|
|
#include "core/subsurface-string.h"
|
2018-09-06 07:52:02 +00:00
|
|
|
#include "core/subsurface-qt/DiveListNotifier.h"
|
2016-04-05 05:02:03 +00:00
|
|
|
#include "qt-models/divetripmodel.h"
|
2016-07-09 19:45:55 +00:00
|
|
|
|
2018-10-21 16:00:02 +00:00
|
|
|
MultiFilterSortModel *MultiFilterSortModel::instance()
|
2018-09-06 07:52:02 +00:00
|
|
|
{
|
2018-10-21 16:00:02 +00:00
|
|
|
static MultiFilterSortModel self;
|
|
|
|
return &self;
|
2017-11-26 21:21:58 +00:00
|
|
|
}
|
|
|
|
|
2019-11-17 17:13:55 +00:00
|
|
|
MultiFilterSortModel::MultiFilterSortModel(QObject *parent) : QSortFilterProxyModel(parent)
|
2014-11-13 18:31:03 +00:00
|
|
|
{
|
2018-10-29 13:56:48 +00:00
|
|
|
setFilterKeyColumn(-1); // filter all columns
|
2019-11-24 10:17:06 +00:00
|
|
|
setFilterRole(DiveTripModelBase::SHOWN_ROLE); // Let the proxy-model known that is has to react to change events involving SHOWN_ROLE
|
2018-10-29 13:56:48 +00:00
|
|
|
setFilterCaseSensitivity(Qt::CaseInsensitive);
|
|
|
|
}
|
|
|
|
|
2018-12-27 09:06:11 +00:00
|
|
|
void MultiFilterSortModel::resetModel(DiveTripModelBase::Layout layout)
|
2018-10-29 13:56:48 +00:00
|
|
|
{
|
2018-12-27 09:06:11 +00:00
|
|
|
DiveTripModelBase::resetModel(layout);
|
|
|
|
// DiveTripModelBase::resetModel() generates a new instance.
|
2019-11-27 20:55:37 +00:00
|
|
|
// Thus, the source model must be reset and the connections must be reset.
|
|
|
|
DiveTripModelBase *m = DiveTripModelBase::instance();
|
|
|
|
setSourceModel(m);
|
|
|
|
connect(m, &DiveTripModelBase::selectionChanged, this, &MultiFilterSortModel::selectionChangedSlot);
|
|
|
|
connect(m, &DiveTripModelBase::currentDiveChanged, this, &MultiFilterSortModel::currentDiveChangedSlot);
|
|
|
|
m->initSelection();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Translate selection into local indexes and re-emit signal
|
|
|
|
void MultiFilterSortModel::selectionChangedSlot(const QVector<QModelIndex> &indexes)
|
|
|
|
{
|
|
|
|
QVector<QModelIndex> indexesLocal;
|
|
|
|
indexesLocal.reserve(indexes.size());
|
|
|
|
for (const QModelIndex &index: indexes) {
|
|
|
|
QModelIndex local = mapFromSource(index);
|
|
|
|
if (local.isValid())
|
|
|
|
indexesLocal.push_back(local);
|
|
|
|
}
|
|
|
|
emit selectionChanged(indexesLocal);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Translate current dive into local indexes and re-emit signal
|
|
|
|
void MultiFilterSortModel::currentDiveChangedSlot(QModelIndex index)
|
|
|
|
{
|
|
|
|
QModelIndex local = mapFromSource(index);
|
|
|
|
if (local.isValid())
|
|
|
|
emit currentDiveChanged(mapFromSource(index));
|
2014-11-13 18:31:03 +00:00
|
|
|
}
|
|
|
|
|
2018-08-14 18:16:25 +00:00
|
|
|
bool MultiFilterSortModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
|
|
|
{
|
Dive list: cache shown flag in model (quick-fix for undo-crash)
We have a very fundamental problem with data-duplication in
core and qt-models. In a particular case, this led to an easily
reproducible crash:
1) An undo command moved the last dive of a trip to another.
2) When an undo-command removed the last dive of
a trip to a different trip, the dive was removed from the
trip in the core. Then, the model was updated.
3) That lead at first to a rearrangement of the trips, because
the trip with the added dive is moved before the trip with
the removed dive.
4) In such a case, the filter-model checks the visibility of
the trip.
5) Since the trip with the removed dive has no dives in the core,
visibility was determined as false.
6) From this point on the mappings of the QSortFilterProxyModel
were messed up. Accesses led to crashes. It is unclear
whether this is a Qt bug or only a QOI issue.
As a quick-fix, cache the visibility flag of trips directly
in the Qt-models. Don't set the visibility directly in the
core, but go via the Qt-models. Thus, a more clear layering
is achieved.
In the long run, we can hopefully get rid of the data-duplication
in the models.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-06-22 18:48:59 +00:00
|
|
|
QAbstractItemModel *m = sourceModel();
|
|
|
|
QModelIndex index0 = m->index(source_row, 0, source_parent);
|
|
|
|
return m->data(index0, DiveTripModelBase::SHOWN_ROLE).value<bool>();
|
2014-11-13 18:31:03 +00:00
|
|
|
}
|
|
|
|
|
2018-10-29 19:17:53 +00:00
|
|
|
bool MultiFilterSortModel::lessThan(const QModelIndex &i1, const QModelIndex &i2) const
|
|
|
|
{
|
|
|
|
// Hand sorting down to the source model.
|
2018-12-27 09:06:11 +00:00
|
|
|
return DiveTripModelBase::instance()->lessThan(i1, i2);
|
2018-10-29 19:17:53 +00:00
|
|
|
}
|