Map: remove access to displayed_dive_site in GPS-filter model

The location information shows a list of dive sites at the
same location as the edited dive site. This was done by passing
a function to an "SsrfSortFilterProxyModel". Unfortunately,
the latter does only support function pointers without state
and therefore had to access the global "displayed_dive_site"
object.

Replace the SsrfSortFilterProxyModel by a proper subclass of
QSortFilterProxyModel that contains information on the position
and id of the currently edited dive site.

Update the filter model if the location of the dive site changes.
This introduces a behavioral change: editing the GPS location
will lead to an updated list.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2018-10-08 19:01:45 +02:00 committed by Dirk Hohndel
parent ac02854a8a
commit f39596df06
4 changed files with 51 additions and 25 deletions

View file

@ -6,7 +6,6 @@
#include "core/qthelper.h"
#include "desktop-widgets/mapwidget.h"
#include "qt-models/filtermodels.h"
#include "qt-models/divelocationmodel.h"
#include "core/divesitehelpers.h"
#include "desktop-widgets/modeldelegates.h"
@ -42,10 +41,7 @@ LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBo
connect(ui.diveSiteCoordinates, SIGNAL(returnPressed()), this, SLOT(updateLocationOnMap()));
ui.diveSiteCoordinates->installEventFilter(this);
SsrfSortFilterProxyModel *filter_model = new SsrfSortFilterProxyModel(this);
filter_model->setSourceModel(LocationInformationModel::instance());
filter_model->setFilterRow(filter_same_gps_cb);
ui.diveSiteListView->setModel(filter_model);
ui.diveSiteListView->setModel(&filter_model);
ui.diveSiteListView->setModelColumn(LocationInformationModel::NAME);
ui.diveSiteListView->installEventFilter(this);
// Map Management Code.
@ -217,6 +213,7 @@ void LocationInformationWidget::rejectChanges()
void LocationInformationWidget::showEvent(QShowEvent *ev)
{
if (displayed_dive_site.uuid) {
filter_model.set(displayed_dive_site.uuid, displayed_dive_site.latitude, displayed_dive_site.longitude);
updateLabels();
enableLocationButtons(dive_site_has_gps_location(&displayed_dive_site));
QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel *>(ui.diveSiteListView->model());
@ -224,6 +221,7 @@ void LocationInformationWidget::showEvent(QShowEvent *ev)
if (m)
m->invalidate();
} else {
filter_model.set(0, degrees_t{ 0 }, degrees_t{ 0 });
clearLabels();
}
MapWidget::instance()->prepareForGetDiveCoordinates(displayed_dive_site.uuid);
@ -324,9 +322,11 @@ void LocationInformationWidget::reverseGeocode()
void LocationInformationWidget::updateLocationOnMap()
{
if (displayed_dive_site.uuid)
MapWidget::instance()->updateDiveSiteCoordinates(displayed_dive_site.uuid, displayed_dive_site.latitude,
displayed_dive_site.longitude);
if (!displayed_dive_site.uuid)
return;
MapWidget::instance()->updateDiveSiteCoordinates(displayed_dive_site.uuid, displayed_dive_site.latitude,
displayed_dive_site.longitude);
filter_model.setCoordinates(displayed_dive_site.latitude, displayed_dive_site.longitude);
}
DiveLocationFilterProxyModel::DiveLocationFilterProxyModel(QObject*)

View file

@ -4,6 +4,7 @@
#include "core/units.h"
#include "ui_locationInformation.h"
#include "qt-models/divelocationmodel.h"
#include <stdint.h>
#include <QAbstractListModel>
#include <QSortFilterProxyModel>
@ -48,6 +49,7 @@ private:
Ui::LocationInformation ui;
bool modified;
QAction *acceptAction, *rejectAction;
GPSLocationInformationModel filter_model;
};
class DiveLocationFilterProxyModel : public QSortFilterProxyModel {

View file

@ -116,21 +116,35 @@ GeoReferencingOptionsModel::GeoReferencingOptionsModel(QObject *parent) : QStrin
setStringList(list);
}
bool filter_same_gps_cb (QAbstractItemModel *model, int sourceRow, const QModelIndex& parent)
bool GPSLocationInformationModel::filterAcceptsRow(int sourceRow, const QModelIndex &parent) const
{
int ref_lat = displayed_dive_site.latitude.udeg;
int ref_lon = displayed_dive_site.longitude.udeg;
uint32_t ref_uuid = displayed_dive_site.uuid;
QSortFilterProxyModel *self = (QSortFilterProxyModel*) model;
uint32_t ds_uuid = self->sourceModel()->index(sourceRow, LocationInformationModel::UUID, parent).data().toUInt();
struct dive_site *ds = get_dive_site_by_uuid(ds_uuid);
if (!ds)
uint32_t uuid = sourceModel()->index(sourceRow, LocationInformationModel::UUID, parent).data().toUInt();
if (uuid == ignoreUuid || uuid == RECENTLY_ADDED_DIVESITE)
return false;
struct dive_site *ds = get_dive_site_by_uuid(uuid);
if (ds->latitude.udeg == 0 || ds->longitude.udeg == 0)
return false;
return ds->latitude.udeg == ref_lat && ds->longitude.udeg == ref_lon && ds->uuid != ref_uuid;
return ds && ds->latitude.udeg == latitude.udeg && ds->longitude.udeg == longitude.udeg;
}
GPSLocationInformationModel::GPSLocationInformationModel(QObject *parent) : QSortFilterProxyModel(parent),
ignoreUuid(0),
latitude({ 0 }),
longitude({ 0 })
{
setSourceModel(LocationInformationModel::instance());
}
void GPSLocationInformationModel::set(uint32_t ignoreUuidIn, degrees_t latitudeIn, degrees_t longitudeIn)
{
ignoreUuid = ignoreUuidIn;
latitude = latitudeIn;
longitude = longitudeIn;
invalidate();
}
void GPSLocationInformationModel::setCoordinates(degrees_t latitudeIn, degrees_t longitudeIn)
{
latitude = latitudeIn;
longitude = longitudeIn;
invalidate();
}

View file

@ -10,9 +10,6 @@
#define RECENTLY_ADDED_DIVESITE 1
bool filter_same_gps_cb (QAbstractItemModel *m, int sourceRow, const QModelIndex& parent);
class LocationInformationModel : public QAbstractTableModel {
Q_OBJECT
public:
@ -36,6 +33,19 @@ private:
QStringList locationNames;
};
// To access only divesites at the given GPS coordinates with the exception of a given dive site
class GPSLocationInformationModel : public QSortFilterProxyModel {
Q_OBJECT
private:
uint32_t ignoreUuid;
degrees_t latitude, longitude;
bool filterAcceptsRow(int sourceRow, const QModelIndex &source_parent) const override;
public:
GPSLocationInformationModel(QObject *parent = nullptr);
void set(uint32_t ignoreUuid, degrees_t latitude, degrees_t longitude);
void setCoordinates(degrees_t latitude, degrees_t longitude);
};
class GeoReferencingOptionsModel : public QStringListModel {
Q_OBJECT
public: