Dive site: add proximity field to dive site list

Merging dive sites is currently only possible if dive sites are at
the exact same position.

Introduce a field where the user can enter a distance up to which all
dive sites should be listed. These can then be merged.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2019-03-25 22:18:32 +01:00 committed by Dirk Hohndel
parent 22fe0c14e8
commit 8287d86d2b
5 changed files with 63 additions and 5 deletions

View file

@ -11,6 +11,7 @@
#include "core/subsurface-qt/DiveListNotifier.h"
#include "command.h"
#include "core/taxonomy.h"
#include "core/settings/qPrefUnit.h"
#include <QDebug>
#include <QShowEvent>
@ -20,7 +21,7 @@
#include <QDesktopWidget>
#include <QScrollBar>
LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBox(parent), diveSite(nullptr)
LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBox(parent), diveSite(nullptr), closeDistance(0)
{
ui.setupUi(this);
ui.diveSiteMessage->setCloseButtonVisible(false);
@ -35,6 +36,8 @@ LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBo
ui.diveSiteCoordinates->installEventFilter(this);
connect(&diveListNotifier, &DiveListNotifier::diveSiteChanged, this, &LocationInformationWidget::diveSiteChanged);
connect(qPrefUnits::instance(), &qPrefUnits::unit_systemChanged, this, &LocationInformationWidget::unitsChanged);
unitsChanged();
ui.diveSiteListView->setModel(&filter_model);
ui.diveSiteListView->setModelColumn(LocationInformationModel::NAME);
@ -112,6 +115,17 @@ void LocationInformationWidget::updateLabels()
ui.locationTags->setText(constructLocationTags(&diveSite->taxonomy, false));
}
void LocationInformationWidget::unitsChanged()
{
if (prefs.units.length == units::METERS) {
ui.diveSiteDistanceUnits->setText("m");
ui.diveSiteDistance->setText(QString::number(lrint(closeDistance / 1000.0)));
} else {
ui.diveSiteDistanceUnits->setText("ft");
ui.diveSiteDistance->setText(QString::number(lrint(mm_to_feet(closeDistance))));
}
}
void LocationInformationWidget::diveSiteChanged(struct dive_site *ds, int field)
{
if (diveSite != ds)
@ -222,6 +236,16 @@ void LocationInformationWidget::on_diveSiteNotes_editingFinished()
Command::editDiveSiteNotes(diveSite, ui.diveSiteNotes->toPlainText());
}
void LocationInformationWidget::on_diveSiteDistance_textChanged(const QString &s)
{
bool ok;
uint64_t d = s.toLongLong(&ok);
if (!ok)
d = 0;
closeDistance = prefs.units.length == units::METERS ? d * 1000 : feet_to_mm(d);
filter_model.setDistance(closeDistance);
}
void LocationInformationWidget::reverseGeocode()
{
location_t location = parseGpsText(ui.diveSiteCoordinates->text());

View file

@ -27,17 +27,20 @@ public slots:
void on_diveSiteDescription_editingFinished();
void on_diveSiteName_editingFinished();
void on_diveSiteNotes_editingFinished();
void on_diveSiteDistance_textChanged(const QString &s);
void reverseGeocode();
void mergeSelectedDiveSites();
private slots:
void updateLabels();
void diveSiteChanged(struct dive_site *ds, int field);
void unitsChanged();
private:
void keyPressEvent(QKeyEvent *e) override;
void clearLabels();
Ui::LocationInformation ui;
GPSLocationInformationModel filter_model;
dive_site *diveSite;
int64_t closeDistance; // Distance of "close" dive sites in mm
};
class DiveLocationFilterProxyModel : public QSortFilterProxyModel {

View file

@ -94,9 +94,30 @@
<item row="9" column="0" colspan="5">
<widget class="QGroupBox" name="diveSiteGroupBox">
<property name="title">
<string>Dive sites on same coordinates</string>
<string>Near dive sites</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>Show dive sites in the range of:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="diveSiteDistance"/>
</item>
<item>
<widget class="QLabel" name="diveSiteDistanceUnits">
<property name="text">
<string></string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QListView" name="diveSiteListView">
<property name="sizePolicy">

View file

@ -302,15 +302,17 @@ GeoReferencingOptionsModel::GeoReferencingOptionsModel(QObject *parent) : QStrin
bool GPSLocationInformationModel::filterAcceptsRow(int sourceRow, const QModelIndex &parent) const
{
struct dive_site *ds = sourceModel()->index(sourceRow, LocationInformationModel::DIVESITE, parent).data().value<dive_site *>();
if (ds == ignoreDs || ds == RECENTLY_ADDED_DIVESITE)
if (!ds || ds == ignoreDs || ds == RECENTLY_ADDED_DIVESITE)
return false;
return ds && same_location(&ds->location, &location);
return distance <= 0 ? same_location(&ds->location, &location)
: (int64_t)get_distance(&ds->location, &location) * 1000 <= distance; // We need 64 bit to represent distances in mm
}
GPSLocationInformationModel::GPSLocationInformationModel(QObject *parent) : QSortFilterProxyModel(parent),
ignoreDs(nullptr),
location({{0},{0}})
location({{0},{0}}),
distance(0)
{
setSourceModel(LocationInformationModel::instance());
}
@ -327,3 +329,9 @@ void GPSLocationInformationModel::setCoordinates(const location_t &locationIn)
location = locationIn;
invalidate();
}
void GPSLocationInformationModel::setDistance(int64_t dist)
{
distance = dist;
invalidate();
}

View file

@ -62,11 +62,13 @@ class GPSLocationInformationModel : public QSortFilterProxyModel {
private:
const struct dive_site *ignoreDs;
location_t location;
int64_t distance;
bool filterAcceptsRow(int sourceRow, const QModelIndex &source_parent) const override;
public:
GPSLocationInformationModel(QObject *parent = nullptr);
void set(const struct dive_site *ignoreDs, const location_t &);
void setCoordinates(const location_t &);
void setDistance(int64_t dist); // Distance from coordinates in mm
};
class GeoReferencingOptionsModel : public QStringListModel {