| 
									
										
										
										
											2017-04-27 20:26:05 +02:00
										 |  |  | // SPDX-License-Identifier: GPL-2.0
 | 
					
						
							| 
									
										
										
										
											2016-04-04 22:02:03 -07:00
										 |  |  | #include "desktop-widgets/locationinformation.h"
 | 
					
						
							| 
									
										
										
										
											2018-05-11 08:25:41 -07:00
										 |  |  | #include "core/subsurface-string.h"
 | 
					
						
							| 
									
										
										
										
											2016-04-04 22:02:03 -07:00
										 |  |  | #include "desktop-widgets/mainwindow.h"
 | 
					
						
							|  |  |  | #include "desktop-widgets/divelistview.h"
 | 
					
						
							|  |  |  | #include "core/qthelper.h"
 | 
					
						
							| 
									
										
										
										
											2017-07-15 23:52:59 +03:00
										 |  |  | #include "desktop-widgets/mapwidget.h"
 | 
					
						
							| 
									
										
										
										
											2019-11-17 18:13:55 +01:00
										 |  |  | #include "core/divefilter.h"
 | 
					
						
							| 
									
										
										
										
											2016-04-04 22:02:03 -07:00
										 |  |  | #include "core/divesitehelpers.h"
 | 
					
						
							|  |  |  | #include "desktop-widgets/modeldelegates.h"
 | 
					
						
							| 
									
										
										
										
											2019-03-12 23:51:39 +01:00
										 |  |  | #include "core/subsurface-qt/DiveListNotifier.h"
 | 
					
						
							| 
									
										
										
										
											2019-03-15 14:32:55 +01:00
										 |  |  | #include "core/taxonomy.h"
 | 
					
						
							| 
									
										
										
										
											2019-03-25 22:18:32 +01:00
										 |  |  | #include "core/settings/qPrefUnit.h"
 | 
					
						
							| 
									
										
										
										
											2019-11-13 15:08:40 +01:00
										 |  |  | #include "commands/command.h"
 | 
					
						
							| 
									
										
										
										
											2015-08-25 18:45:29 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | #include <QDebug>
 | 
					
						
							|  |  |  | #include <QShowEvent>
 | 
					
						
							| 
									
										
										
										
											2015-08-31 21:11:28 -03:00
										 |  |  | #include <QItemSelectionModel>
 | 
					
						
							| 
									
										
										
										
											2015-08-31 22:01:25 -03:00
										 |  |  | #include <qmessagebox.h>
 | 
					
						
							| 
									
										
										
										
											2015-08-31 21:35:17 -03:00
										 |  |  | #include <cstdlib>
 | 
					
						
							| 
									
										
										
										
											2015-09-21 16:08:58 -03:00
										 |  |  | #include <QDesktopWidget>
 | 
					
						
							|  |  |  | #include <QScrollBar>
 | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-25 22:18:32 +01:00
										 |  |  | LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBox(parent), diveSite(nullptr), closeDistance(0) | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | { | 
					
						
							|  |  |  | 	ui.setupUi(this); | 
					
						
							|  |  |  | 	ui.diveSiteMessage->setCloseButtonVisible(false); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-14 23:28:45 +01:00
										 |  |  | 	QAction *acceptAction = new QAction(tr("Done"), this); | 
					
						
							|  |  |  | 	connect(acceptAction, &QAction::triggered, this, &LocationInformationWidget::acceptChanges); | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ui.diveSiteMessage->setText(tr("Dive site management")); | 
					
						
							| 
									
										
										
										
											2015-06-04 00:18:25 -03:00
										 |  |  | 	ui.diveSiteMessage->addAction(acceptAction); | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 18:45:29 -03:00
										 |  |  | 	connect(ui.geoCodeButton, SIGNAL(clicked()), this, SLOT(reverseGeocode())); | 
					
						
							| 
									
										
										
										
											2017-11-27 00:26:46 +02:00
										 |  |  | 	ui.diveSiteCoordinates->installEventFilter(this); | 
					
						
							| 
									
										
										
										
											2015-07-30 22:10:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-12 23:51:39 +01:00
										 |  |  | 	connect(&diveListNotifier, &DiveListNotifier::diveSiteChanged, this, &LocationInformationWidget::diveSiteChanged); | 
					
						
							| 
									
										
										
										
											2019-09-06 22:01:59 +02:00
										 |  |  | 	connect(&diveListNotifier, &DiveListNotifier::diveSiteDeleted, this, &LocationInformationWidget::diveSiteDeleted); | 
					
						
							| 
									
										
										
										
											2019-03-25 22:18:32 +01:00
										 |  |  | 	connect(qPrefUnits::instance(), &qPrefUnits::unit_systemChanged, this, &LocationInformationWidget::unitsChanged); | 
					
						
							|  |  |  | 	unitsChanged(); | 
					
						
							| 
									
										
										
										
											2019-03-12 23:51:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-08 19:01:45 +02:00
										 |  |  | 	ui.diveSiteListView->setModel(&filter_model); | 
					
						
							| 
									
										
										
										
											2015-08-31 21:03:31 -03:00
										 |  |  | 	ui.diveSiteListView->setModelColumn(LocationInformationModel::NAME); | 
					
						
							| 
									
										
										
										
											2015-08-31 21:11:28 -03:00
										 |  |  | 	ui.diveSiteListView->installEventFilter(this); | 
					
						
							| 
									
										
										
										
											2015-05-17 17:14:23 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-16 10:44:39 +01:00
										 |  |  | void LocationInformationWidget::keyPressEvent(QKeyEvent *e) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (e->key() == Qt::Key_Escape) | 
					
						
							|  |  |  | 		MainWindow::instance()->setFocus(); | 
					
						
							|  |  |  | 	return QGroupBox::keyPressEvent(e); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-27 00:26:46 +02:00
										 |  |  | bool LocationInformationWidget::eventFilter(QObject *object, QEvent *ev) | 
					
						
							| 
									
										
										
										
											2015-08-31 21:11:28 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | 	if (ev->type() == QEvent::ContextMenu) { | 
					
						
							|  |  |  | 		QContextMenuEvent *ctx = (QContextMenuEvent *)ev; | 
					
						
							| 
									
										
										
										
											2015-09-04 12:23:19 +02:00
										 |  |  | 		QMenu contextMenu; | 
					
						
							| 
									
										
										
										
											2019-10-14 20:57:13 +02:00
										 |  |  | 		contextMenu.addAction(tr("Merge into current site"), this, &LocationInformationWidget::mergeSelectedDiveSites); | 
					
						
							| 
									
										
										
										
											2015-09-04 12:23:19 +02:00
										 |  |  | 		contextMenu.exec(ctx->globalPos()); | 
					
						
							|  |  |  | 		return true; | 
					
						
							| 
									
										
										
										
											2015-08-31 21:11:28 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-31 19:24:36 -07:00
										 |  |  | 	return false; | 
					
						
							| 
									
										
										
										
											2015-08-31 21:11:28 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-27 00:26:46 +02:00
										 |  |  | void LocationInformationWidget::enableLocationButtons(bool enable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ui.geoCodeButton->setEnabled(enable); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | void LocationInformationWidget::mergeSelectedDiveSites() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-10-13 13:14:48 +02:00
										 |  |  | 	if (!diveSite) | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2015-08-31 22:01:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-01 22:15:19 +02:00
										 |  |  | 	const QModelIndexList selection = ui.diveSiteListView->selectionModel()->selectedIndexes(); | 
					
						
							| 
									
										
										
										
											2019-03-15 17:41:31 +01:00
										 |  |  | 	QVector<dive_site *> selected_dive_sites; | 
					
						
							| 
									
										
										
										
											2018-10-23 19:40:41 +02:00
										 |  |  | 	selected_dive_sites.reserve(selection.count()); | 
					
						
							| 
									
										
										
										
											2019-04-01 22:15:19 +02:00
										 |  |  | 	for (const QModelIndex &idx: selection) { | 
					
						
							| 
									
										
										
										
											2018-10-28 21:16:42 +01:00
										 |  |  | 		dive_site *ds = idx.data(LocationInformationModel::DIVESITE_ROLE).value<dive_site *>(); | 
					
						
							| 
									
										
										
										
											2018-10-23 19:40:41 +02:00
										 |  |  | 		if (ds) | 
					
						
							|  |  |  | 			selected_dive_sites.push_back(ds); | 
					
						
							| 
									
										
										
										
											2015-08-31 21:35:17 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-03-15 17:41:31 +01:00
										 |  |  | 	Command::mergeDiveSites(diveSite, selected_dive_sites); | 
					
						
							| 
									
										
										
										
											2015-08-31 21:35:17 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-25 13:03:14 -03:00
										 |  |  | void LocationInformationWidget::updateLabels() | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-10-13 13:14:48 +02:00
										 |  |  | 	if (!diveSite) { | 
					
						
							|  |  |  | 		clearLabels(); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (diveSite->name) | 
					
						
							|  |  |  | 		ui.diveSiteName->setText(diveSite->name); | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		ui.diveSiteName->clear(); | 
					
						
							| 
									
										
										
										
											2019-03-15 14:32:55 +01:00
										 |  |  | 	const char *country = taxonomy_get_country(&diveSite->taxonomy); | 
					
						
							| 
									
										
										
										
											2017-10-02 23:03:44 -07:00
										 |  |  | 	if (country) | 
					
						
							|  |  |  | 		ui.diveSiteCountry->setText(country); | 
					
						
							| 
									
										
										
										
											2017-10-02 17:51:20 +02:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		ui.diveSiteCountry->clear(); | 
					
						
							| 
									
										
										
										
											2018-10-13 13:14:48 +02:00
										 |  |  | 	if (diveSite->description) | 
					
						
							|  |  |  | 		ui.diveSiteDescription->setText(diveSite->description); | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		ui.diveSiteDescription->clear(); | 
					
						
							| 
									
										
										
										
											2018-10-13 13:14:48 +02:00
										 |  |  | 	if (diveSite->notes) | 
					
						
							|  |  |  | 		ui.diveSiteNotes->setPlainText(diveSite->notes); | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		ui.diveSiteNotes->clear(); | 
					
						
							| 
									
										
										
										
											2019-03-25 09:05:47 +01:00
										 |  |  | 	if (has_location(&diveSite->location)) | 
					
						
							|  |  |  | 		ui.diveSiteCoordinates->setText(printGPSCoords(&diveSite->location)); | 
					
						
							|  |  |  | 	else | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | 		ui.diveSiteCoordinates->clear(); | 
					
						
							| 
									
										
										
										
											2015-10-07 20:00:22 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 14:32:55 +01:00
										 |  |  | 	ui.locationTags->setText(constructLocationTags(&diveSite->taxonomy, false)); | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-25 22:18:32 +01:00
										 |  |  | 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)))); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-12 23:51:39 +01:00
										 |  |  | void LocationInformationWidget::diveSiteChanged(struct dive_site *ds, int field) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (diveSite != ds) | 
					
						
							|  |  |  | 		return; // A different dive site was changed -> do nothing.
 | 
					
						
							|  |  |  | 	switch (field) { | 
					
						
							|  |  |  | 	case LocationInformationModel::NAME: | 
					
						
							|  |  |  | 		ui.diveSiteName->setText(diveSite->name); | 
					
						
							| 
									
										
										
										
											2019-03-13 20:10:22 +01:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	case LocationInformationModel::DESCRIPTION: | 
					
						
							|  |  |  | 		ui.diveSiteDescription->setText(diveSite->description); | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2019-03-14 00:00:54 +01:00
										 |  |  | 	case LocationInformationModel::NOTES: | 
					
						
							|  |  |  | 		ui.diveSiteNotes->setText(diveSite->notes); | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2019-03-14 08:26:50 +01:00
										 |  |  | 	case LocationInformationModel::TAXONOMY: | 
					
						
							|  |  |  | 		ui.diveSiteCountry->setText(taxonomy_get_country(&diveSite->taxonomy)); | 
					
						
							| 
									
										
										
										
											2019-03-15 14:32:55 +01:00
										 |  |  | 		ui.locationTags->setText(constructLocationTags(&diveSite->taxonomy, false)); | 
					
						
							| 
									
										
										
										
											2019-03-14 08:26:50 +01:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2019-03-14 22:07:48 +01:00
										 |  |  | 	case LocationInformationModel::LOCATION: | 
					
						
							|  |  |  | 		filter_model.setCoordinates(diveSite->location); | 
					
						
							|  |  |  | 		if (has_location(&diveSite->location)) { | 
					
						
							|  |  |  | 			enableLocationButtons(true); | 
					
						
							|  |  |  | 			ui.diveSiteCoordinates->setText(printGPSCoords(&diveSite->location)); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			enableLocationButtons(false); | 
					
						
							|  |  |  | 			ui.diveSiteCoordinates->clear(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-09-03 07:11:43 +02:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2019-03-12 23:51:39 +01:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-06 12:06:13 -07:00
										 |  |  | void LocationInformationWidget::clearLabels() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ui.diveSiteName->clear(); | 
					
						
							|  |  |  | 	ui.diveSiteCountry->clear(); | 
					
						
							|  |  |  | 	ui.diveSiteDescription->clear(); | 
					
						
							|  |  |  | 	ui.diveSiteNotes->clear(); | 
					
						
							|  |  |  | 	ui.diveSiteCoordinates->clear(); | 
					
						
							|  |  |  | 	ui.locationTags->clear(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-14 23:28:45 +01:00
										 |  |  | // Parse GPS text into location_t
 | 
					
						
							|  |  |  | static location_t parseGpsText(const QString &text) | 
					
						
							| 
									
										
										
										
											2018-10-13 12:30:32 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	double lat, lon; | 
					
						
							| 
									
										
										
										
											2019-03-14 23:28:45 +01:00
										 |  |  | 	if (parseGpsText(text, &lat, &lon)) | 
					
						
							|  |  |  | 		return create_location(lat, lon); | 
					
						
							|  |  |  | 	return { {0}, {0} }; | 
					
						
							| 
									
										
										
										
											2018-10-13 12:30:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-06 22:01:59 +02:00
										 |  |  | void LocationInformationWidget::diveSiteDeleted(struct dive_site *ds, int) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	// If the currently edited dive site was removed under our feet, close the widget.
 | 
					
						
							|  |  |  | 	// This will reset the dangling pointer.
 | 
					
						
							|  |  |  | 	if (ds && ds == diveSite) | 
					
						
							|  |  |  | 		acceptChanges(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | void LocationInformationWidget::acceptChanges() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-09-06 22:01:59 +02:00
										 |  |  | 	closeDistance = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-14 23:28:45 +01:00
										 |  |  | 	MainWindow::instance()->diveList->setEnabled(true); | 
					
						
							|  |  |  | 	MainWindow::instance()->setEnabledToolbar(true); | 
					
						
							| 
									
										
										
										
											2019-05-10 19:51:43 +02:00
										 |  |  | 	MainWindow::instance()->setApplicationState(ApplicationState::Default); | 
					
						
							| 
									
										
										
										
											2019-11-17 18:13:55 +01:00
										 |  |  | 	DiveFilter::instance()->stopFilterDiveSites(); | 
					
						
							| 
									
										
										
										
											2019-10-28 06:57:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Subtlety alert: diveSite must be cleared *after* exiting the dive-site mode.
 | 
					
						
							|  |  |  | 	// Exiting dive-site mode removes the focus from the active widget and
 | 
					
						
							|  |  |  | 	// thus fires the corresponding editingFinished signal, which in turn creates
 | 
					
						
							|  |  |  | 	// an undo-command. To set an undo-command, the widget has to know the
 | 
					
						
							|  |  |  | 	// currently edited dive-site.
 | 
					
						
							|  |  |  | 	diveSite = nullptr; | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-13 08:57:46 +02:00
										 |  |  | void LocationInformationWidget::initFields(dive_site *ds) | 
					
						
							| 
									
										
										
										
											2015-05-17 17:14:23 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-10-13 13:14:48 +02:00
										 |  |  | 	diveSite = ds; | 
					
						
							| 
									
										
										
										
											2018-10-13 08:57:46 +02:00
										 |  |  | 	if (ds) { | 
					
						
							| 
									
										
										
										
											2018-10-25 08:02:06 +02:00
										 |  |  | 		filter_model.set(ds, ds->location); | 
					
						
							| 
									
										
										
										
											2015-07-25 13:03:14 -03:00
										 |  |  | 		updateLabels(); | 
					
						
							| 
									
										
										
										
											2018-10-13 13:14:48 +02:00
										 |  |  | 		enableLocationButtons(dive_site_has_gps_location(ds)); | 
					
						
							| 
									
										
										
										
											2019-11-17 18:13:55 +01:00
										 |  |  | 		DiveFilter::instance()->startFilterDiveSites(QVector<dive_site *>{ ds }); | 
					
						
							| 
									
										
										
										
											2019-04-15 21:47:08 +02:00
										 |  |  | 		filter_model.invalidate(); | 
					
						
							| 
									
										
										
										
											2017-10-06 12:06:13 -07:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2018-10-20 14:12:15 -04:00
										 |  |  | 		filter_model.set(0, location_t { degrees_t{ 0 }, degrees_t{ 0 } }); | 
					
						
							| 
									
										
										
										
											2017-10-06 12:06:13 -07:00
										 |  |  | 		clearLabels(); | 
					
						
							| 
									
										
										
										
											2015-07-30 22:10:01 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-14 22:07:48 +01:00
										 |  |  | void LocationInformationWidget::on_diveSiteCoordinates_editingFinished() | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-24 13:02:05 +08:00
										 |  |  | 	if (diveSite) | 
					
						
							|  |  |  | 		Command::editDiveSiteLocation(diveSite, parseGpsText(ui.diveSiteCoordinates->text())); | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-14 08:26:50 +01:00
										 |  |  | void LocationInformationWidget::on_diveSiteCountry_editingFinished() | 
					
						
							| 
									
										
										
										
											2017-10-02 17:51:20 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-14 08:26:50 +01:00
										 |  |  | 	if (diveSite) | 
					
						
							|  |  |  | 		Command::editDiveSiteCountry(diveSite, ui.diveSiteCountry->text()); | 
					
						
							| 
									
										
										
										
											2017-10-02 17:51:20 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-13 22:49:34 +01:00
										 |  |  | void LocationInformationWidget::on_diveSiteDescription_editingFinished() | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-13 22:49:34 +01:00
										 |  |  | 	if (diveSite) | 
					
						
							|  |  |  | 		Command::editDiveSiteDescription(diveSite, ui.diveSiteDescription->text()); | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-13 22:49:34 +01:00
										 |  |  | void LocationInformationWidget::on_diveSiteName_editingFinished() | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-13 22:49:34 +01:00
										 |  |  | 	if (diveSite) | 
					
						
							|  |  |  | 		Command::editDiveSiteName(diveSite, ui.diveSiteName->text()); | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-14 00:00:54 +01:00
										 |  |  | void LocationInformationWidget::on_diveSiteNotes_editingFinished() | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-14 00:00:54 +01:00
										 |  |  | 	if (diveSite) | 
					
						
							|  |  |  | 		Command::editDiveSiteNotes(diveSite, ui.diveSiteNotes->toPlainText()); | 
					
						
							| 
									
										
										
										
											2015-05-17 16:13:41 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-25 22:18:32 +01:00
										 |  |  | 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); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 18:45:29 -03:00
										 |  |  | void LocationInformationWidget::reverseGeocode() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-14 23:28:45 +01:00
										 |  |  | 	location_t location = parseGpsText(ui.diveSiteCoordinates->text()); | 
					
						
							| 
									
										
										
										
											2019-03-15 14:32:55 +01:00
										 |  |  | 	if (!diveSite || !has_location(&location)) | 
					
						
							| 
									
										
										
										
											2018-10-13 12:30:32 +02:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2019-03-15 14:32:55 +01:00
										 |  |  | 	taxonomy_data taxonomy = { 0 }; | 
					
						
							| 
									
										
										
										
											2018-10-20 14:12:15 -04:00
										 |  |  | 	reverseGeoLookup(location.lat, location.lon, &taxonomy); | 
					
						
							| 
									
										
										
										
											2019-03-15 14:32:55 +01:00
										 |  |  | 	Command::editDiveSiteTaxonomy(diveSite, taxonomy); | 
					
						
							| 
									
										
										
										
											2015-08-25 18:45:29 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-25 00:26:48 +02:00
										 |  |  | DiveLocationFilterProxyModel::DiveLocationFilterProxyModel(QObject *) : currentLocation({0, 0}) | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-15 20:15:40 +02:00
										 |  |  | void DiveLocationFilterProxyModel::setFilter(const QString &filterIn) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	filter = filterIn; | 
					
						
							|  |  |  | 	invalidate(); | 
					
						
							| 
									
										
										
										
											2019-04-15 22:16:33 +02:00
										 |  |  | 	sort(LocationInformationModel::NAME); | 
					
						
							| 
									
										
										
										
											2019-04-15 20:15:40 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-25 00:26:48 +02:00
										 |  |  | void DiveLocationFilterProxyModel::setCurrentLocation(location_t loc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	currentLocation = loc; | 
					
						
							|  |  |  | 	sort(LocationInformationModel::NAME); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-21 18:09:09 +02:00
										 |  |  | bool DiveLocationFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex&) const | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-15 22:26:11 +02:00
										 |  |  | 	// We don't want to show the first two entries (add dive site with that name)
 | 
					
						
							|  |  |  | 	// if there is no filter text.
 | 
					
						
							|  |  |  | 	if (filter.isEmpty() && source_row <= 1) | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | 	if (source_row == 0) | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-09 12:26:58 +02:00
										 |  |  | 	QString sourceString = sourceModel()->index(source_row, LocationInformationModel::NAME).data(Qt::DisplayRole).toString(); | 
					
						
							| 
									
										
										
										
											2019-04-15 20:15:40 +02:00
										 |  |  | 	return sourceString.contains(filter, Qt::CaseInsensitive); | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | bool DiveLocationFilterProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const | 
					
						
							| 
									
										
										
										
											2015-09-21 15:04:52 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-15 22:16:33 +02:00
										 |  |  | 	// The first two entries are special - we never want to change their order
 | 
					
						
							|  |  |  | 	if (source_left.row() <= 1 || source_right.row() <= 1) | 
					
						
							|  |  |  | 		return source_left.row() < source_right.row(); | 
					
						
							| 
									
										
										
										
											2019-04-25 00:26:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// If there is a current location, sort by that - otherwise use the provided column
 | 
					
						
							|  |  |  | 	if (has_location(¤tLocation)) { | 
					
						
							|  |  |  | 		// The dive sites are -2 because of the first two items.
 | 
					
						
							|  |  |  | 		struct dive_site *ds1 = get_dive_site(source_left.row() - 2, &dive_site_table); | 
					
						
							|  |  |  | 		struct dive_site *ds2 = get_dive_site(source_right.row() - 2, &dive_site_table); | 
					
						
							|  |  |  | 		return get_distance(&ds1->location, ¤tLocation) < get_distance(&ds2->location, ¤tLocation); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-04-15 22:16:33 +02:00
										 |  |  | 	return source_left.data().toString().compare(source_right.data().toString(), Qt::CaseInsensitive) < 0; | 
					
						
							| 
									
										
										
										
											2015-09-21 15:04:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-15 20:15:40 +02:00
										 |  |  | DiveLocationModel::DiveLocationModel(QObject *) | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | { | 
					
						
							|  |  |  | 	resetModel(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DiveLocationModel::resetModel() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	beginResetModel(); | 
					
						
							|  |  |  | 	endResetModel(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | QVariant DiveLocationModel::data(const QModelIndex &index, int role) const | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-11-29 10:57:08 +01:00
										 |  |  | 	static const QIcon plusIcon(":list-add-icon"); | 
					
						
							|  |  |  | 	static const QIcon geoCode(":geotag-icon"); | 
					
						
							| 
									
										
										
										
											2015-09-25 12:19:41 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | 	if (index.row() <= 1) { // two special cases.
 | 
					
						
							| 
									
										
										
										
											2018-10-25 08:02:06 +02:00
										 |  |  | 		if (index.column() == LocationInformationModel::DIVESITE) | 
					
						
							| 
									
										
										
										
											2018-10-30 18:34:36 +01:00
										 |  |  | 			return QVariant::fromValue<dive_site *>(RECENTLY_ADDED_DIVESITE); | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | 		switch (role) { | 
					
						
							|  |  |  | 		case Qt::DisplayRole: | 
					
						
							|  |  |  | 			return new_ds_value[index.row()]; | 
					
						
							|  |  |  | 		case Qt::ToolTipRole: | 
					
						
							| 
									
										
										
										
											2019-04-13 18:54:41 +02:00
										 |  |  | 			return current_dive && current_dive->dive_site ? | 
					
						
							| 
									
										
										
										
											2015-09-30 19:33:33 -03:00
										 |  |  | 				tr("Create a new dive site, copying relevant information from the current dive.") : | 
					
						
							|  |  |  | 				tr("Create a new dive site with this name"); | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | 		case Qt::DecorationRole: | 
					
						
							|  |  |  | 			return plusIcon; | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-04-13 18:54:41 +02:00
										 |  |  | 		return QVariant(); | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// The dive sites are -2 because of the first two items.
 | 
					
						
							| 
									
										
										
										
											2019-02-26 22:26:11 +01:00
										 |  |  | 	struct dive_site *ds = get_dive_site(index.row() - 2, &dive_site_table); | 
					
						
							| 
									
										
										
										
											2018-10-09 12:26:58 +02:00
										 |  |  | 	return LocationInformationModel::getDiveSiteData(ds, index.column(), role); | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-21 18:09:09 +02:00
										 |  |  | int DiveLocationModel::columnCount(const QModelIndex&) const | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-10-09 12:26:58 +02:00
										 |  |  | 	return LocationInformationModel::COLUMNS; | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-21 18:09:09 +02:00
										 |  |  | int DiveLocationModel::rowCount(const QModelIndex&) const | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | { | 
					
						
							|  |  |  | 	return dive_site_table.nr + 2; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-21 18:09:09 +02:00
										 |  |  | bool DiveLocationModel::setData(const QModelIndex &index, const QVariant &value, int) | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | 	if (!index.isValid()) | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | 		return false; | 
					
						
							|  |  |  | 	if (index.row() > 1) | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	new_ds_value[index.row()] = value.toString(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dataChanged(index, index); | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-22 14:31:56 -03:00
										 |  |  | DiveLocationLineEdit::DiveLocationLineEdit(QWidget *parent) : QLineEdit(parent), | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | 							      proxy(new DiveLocationFilterProxyModel()), | 
					
						
							|  |  |  | 							      model(new DiveLocationModel()), | 
					
						
							| 
									
										
										
										
											2015-10-02 15:22:55 -04:00
										 |  |  | 							      view(new DiveLocationListView()), | 
					
						
							| 
									
										
										
										
											2018-10-25 08:02:06 +02:00
										 |  |  | 							      currDs(nullptr) | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | { | 
					
						
							|  |  |  | 	proxy->setSourceModel(model); | 
					
						
							| 
									
										
										
										
											2018-10-09 12:26:58 +02:00
										 |  |  | 	proxy->setFilterKeyColumn(LocationInformationModel::NAME); | 
					
						
							| 
									
										
										
										
											2015-09-21 16:51:39 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 15:04:52 -03:00
										 |  |  | 	view->setModel(proxy); | 
					
						
							| 
									
										
										
										
											2018-10-09 12:26:58 +02:00
										 |  |  | 	view->setModelColumn(LocationInformationModel::NAME); | 
					
						
							| 
									
										
										
										
											2019-04-25 09:35:46 +02:00
										 |  |  | 	view->setItemDelegate(&delegate); | 
					
						
							| 
									
										
										
										
											2015-09-21 16:51:39 -03:00
										 |  |  | 	view->setEditTriggers(QAbstractItemView::NoEditTriggers); | 
					
						
							|  |  |  | 	view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); | 
					
						
							|  |  |  | 	view->setSelectionBehavior(QAbstractItemView::SelectRows); | 
					
						
							|  |  |  | 	view->setSelectionMode(QAbstractItemView::SingleSelection); | 
					
						
							|  |  |  | 	view->setParent(0, Qt::Popup); | 
					
						
							|  |  |  | 	view->installEventFilter(this); | 
					
						
							| 
									
										
										
										
											2015-09-22 14:31:56 -03:00
										 |  |  | 	view->setFocusPolicy(Qt::NoFocus); | 
					
						
							|  |  |  | 	view->setFocusProxy(this); | 
					
						
							| 
									
										
										
										
											2015-09-25 13:11:44 -03:00
										 |  |  | 	view->setMouseTracking(true); | 
					
						
							| 
									
										
										
										
											2015-09-21 16:51:39 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | 	connect(this, &QLineEdit::textEdited, this, &DiveLocationLineEdit::setTemporaryDiveSiteName); | 
					
						
							| 
									
										
										
										
											2015-09-21 17:18:52 -03:00
										 |  |  | 	connect(view, &QAbstractItemView::activated, this, &DiveLocationLineEdit::itemActivated); | 
					
						
							| 
									
										
										
										
											2015-09-25 13:11:44 -03:00
										 |  |  | 	connect(view, &QAbstractItemView::entered, this, &DiveLocationLineEdit::entered); | 
					
						
							| 
									
										
										
										
											2015-09-25 13:21:23 -03:00
										 |  |  | 	connect(view, &DiveLocationListView::currentIndexChanged, this, &DiveLocationLineEdit::currentChanged); | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-15 22:16:33 +02:00
										 |  |  | bool DiveLocationLineEdit::eventFilter(QObject *, QEvent *e) | 
					
						
							| 
									
										
										
										
											2015-09-21 16:51:39 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | 	if (e->type() == QEvent::KeyPress) { | 
					
						
							|  |  |  | 		QKeyEvent *keyEv = (QKeyEvent *)e; | 
					
						
							| 
									
										
										
										
											2015-09-21 16:51:39 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (keyEv->key() == Qt::Key_Escape) { | 
					
						
							|  |  |  | 			view->hide(); | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | 		if (keyEv->key() == Qt::Key_Return || | 
					
						
							|  |  |  | 		    keyEv->key() == Qt::Key_Enter) { | 
					
						
							| 
									
										
										
										
											2015-10-25 10:38:16 +09:00
										 |  |  | #if __APPLE__
 | 
					
						
							|  |  |  | 			// for some reason it seems like on a Mac hitting return/enter
 | 
					
						
							|  |  |  | 			// doesn't call 'activated' for that index. so let's do it manually
 | 
					
						
							|  |  |  | 			if (view->currentIndex().isValid()) | 
					
						
							|  |  |  | 				itemActivated(view->currentIndex()); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-09-21 16:51:39 -03:00
										 |  |  | 			view->hide(); | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-09-22 16:27:07 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | 		if (keyEv->key() == Qt::Key_Tab) { | 
					
						
							|  |  |  | 			itemActivated(view->currentIndex()); | 
					
						
							|  |  |  | 			view->hide(); | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-09-21 17:11:59 -03:00
										 |  |  | 		event(e); | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | 	} else if (e->type() == QEvent::MouseButtonPress) { | 
					
						
							| 
									
										
										
										
											2015-09-22 14:31:56 -03:00
										 |  |  | 		if (!view->underMouse()) { | 
					
						
							|  |  |  | 			view->hide(); | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-09-21 16:51:39 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-26 06:17:00 +02:00
										 |  |  | 	else if (e->type() == QEvent::InputMethod) { | 
					
						
							|  |  |  | 		this->inputMethodEvent(static_cast<QInputMethodEvent *>(e)); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-09-21 17:11:59 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 16:51:39 -03:00
										 |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | void DiveLocationLineEdit::focusOutEvent(QFocusEvent *ev) | 
					
						
							| 
									
										
										
										
											2015-09-22 15:23:38 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-30 23:08:02 +02:00
										 |  |  | 	if (!view->isVisible()) | 
					
						
							| 
									
										
										
										
											2015-09-22 15:23:38 -03:00
										 |  |  | 		QLineEdit::focusOutEvent(ev); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | void DiveLocationLineEdit::itemActivated(const QModelIndex &index) | 
					
						
							| 
									
										
										
										
											2015-09-21 17:18:52 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-10-05 18:01:28 -03:00
										 |  |  | 	QModelIndex idx = index; | 
					
						
							| 
									
										
										
										
											2018-10-25 08:02:06 +02:00
										 |  |  | 	if (index.column() == LocationInformationModel::DIVESITE) | 
					
						
							| 
									
										
										
										
											2018-10-09 12:26:58 +02:00
										 |  |  | 		idx = index.model()->index(index.row(), LocationInformationModel::NAME); | 
					
						
							| 
									
										
										
										
											2015-10-05 18:01:28 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-28 21:16:42 +01:00
										 |  |  | 	dive_site *ds = index.model()->index(index.row(), LocationInformationModel::DIVESITE).data().value<dive_site *>(); | 
					
						
							| 
									
										
										
										
											2018-10-25 08:02:06 +02:00
										 |  |  | 	currDs = ds; | 
					
						
							| 
									
										
										
										
											2015-10-05 18:01:28 -03:00
										 |  |  | 	setText(idx.data().toString()); | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | 	if (view->isVisible()) | 
					
						
							| 
									
										
										
										
											2015-09-23 13:56:49 -03:00
										 |  |  | 		view->hide(); | 
					
						
							| 
									
										
										
										
											2018-10-24 21:14:57 +02:00
										 |  |  | 	emit diveSiteSelected(); | 
					
						
							| 
									
										
										
										
											2015-09-21 17:18:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | void DiveLocationLineEdit::refreshDiveSiteCache() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	model->resetModel(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | static struct dive_site *get_dive_site_name_start_which_str(const QString &str) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | 	struct dive_site *ds; | 
					
						
							|  |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2019-02-26 22:26:11 +01:00
										 |  |  | 	for_each_dive_site (i, ds, &dive_site_table) { | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | 		QString dsName(ds->name); | 
					
						
							| 
									
										
										
										
											2015-09-21 15:04:52 -03:00
										 |  |  | 		if (dsName.toLower().startsWith(str.toLower())) { | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | 			return ds; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-15 20:15:40 +02:00
										 |  |  | void DiveLocationLineEdit::setTemporaryDiveSiteName(const QString &name) | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-10-08 22:23:47 +02:00
										 |  |  | 	// This function fills the first two entries with potential names of
 | 
					
						
							|  |  |  | 	// a dive site to be generated. The first entry is simply the entered
 | 
					
						
							|  |  |  | 	// text. The second entry is the first known dive site name starting
 | 
					
						
							|  |  |  | 	// with the entered text.
 | 
					
						
							| 
									
										
										
										
											2018-10-09 12:26:58 +02:00
										 |  |  | 	QModelIndex i0 = model->index(0, LocationInformationModel::NAME); | 
					
						
							|  |  |  | 	QModelIndex i1 = model->index(1, LocationInformationModel::NAME); | 
					
						
							| 
									
										
										
										
											2019-04-15 20:15:40 +02:00
										 |  |  | 	model->setData(i0, name); | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-08 22:23:47 +02:00
										 |  |  | 	// Note: if i1_name stays empty, the line will automatically
 | 
					
						
							|  |  |  | 	// be filtered out by the proxy filter, as it does not contain
 | 
					
						
							|  |  |  | 	// the user entered text.
 | 
					
						
							|  |  |  | 	QString i1_name; | 
					
						
							| 
									
										
										
										
											2019-04-15 20:15:40 +02:00
										 |  |  | 	if (struct dive_site *ds = get_dive_site_name_start_which_str(name)) { | 
					
						
							| 
									
										
										
										
											2015-09-21 15:04:52 -03:00
										 |  |  | 		const QString orig_name = QString(ds->name).toLower(); | 
					
						
							| 
									
										
										
										
											2019-04-15 20:15:40 +02:00
										 |  |  | 		const QString new_name = name.toLower(); | 
					
						
							| 
									
										
										
										
											2015-09-21 15:04:52 -03:00
										 |  |  | 		if (new_name != orig_name) | 
					
						
							|  |  |  | 			i1_name = QString(ds->name); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | 	model->setData(i1, i1_name); | 
					
						
							| 
									
										
										
										
											2019-04-15 20:15:40 +02:00
										 |  |  | 	proxy->setFilter(name); | 
					
						
							| 
									
										
										
										
											2015-09-23 16:27:44 -03:00
										 |  |  | 	fixPopupPosition(); | 
					
						
							|  |  |  | 	if (!view->isVisible()) | 
					
						
							|  |  |  | 		view->show(); | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 16:08:58 -03:00
										 |  |  | void DiveLocationLineEdit::keyPressEvent(QKeyEvent *ev) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-21 17:22:31 -03:00
										 |  |  | 	QLineEdit::keyPressEvent(ev); | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | 	if (ev->key() != Qt::Key_Left && | 
					
						
							|  |  |  | 	    ev->key() != Qt::Key_Right && | 
					
						
							|  |  |  | 	    ev->key() != Qt::Key_Escape && | 
					
						
							|  |  |  | 	    ev->key() != Qt::Key_Return) { | 
					
						
							| 
									
										
										
										
											2015-09-22 17:20:55 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-30 23:18:12 +02:00
										 |  |  | 		if (ev->key() != Qt::Key_Up && ev->key() != Qt::Key_Down) | 
					
						
							| 
									
										
										
										
											2018-10-25 08:02:06 +02:00
										 |  |  | 			currDs = RECENTLY_ADDED_DIVESITE; | 
					
						
							| 
									
										
										
										
											2019-06-30 23:18:12 +02:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2015-09-23 16:27:44 -03:00
										 |  |  | 			showPopup(); | 
					
						
							| 
									
										
										
										
											2015-09-21 16:51:39 -03:00
										 |  |  | 	} else if (ev->key() == Qt::Key_Escape) { | 
					
						
							|  |  |  | 		view->hide(); | 
					
						
							| 
									
										
										
										
											2015-09-21 16:08:58 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-23 16:03:28 -03:00
										 |  |  | void DiveLocationLineEdit::fixPopupPosition() | 
					
						
							| 
									
										
										
										
											2015-09-21 16:08:58 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-09-22 14:13:51 -03:00
										 |  |  | 	const QRect screen = QApplication::desktop()->availableGeometry(this); | 
					
						
							|  |  |  | 	const int maxVisibleItems = 5; | 
					
						
							|  |  |  | 	QPoint pos; | 
					
						
							|  |  |  | 	int rh, w; | 
					
						
							|  |  |  | 	int h = (view->sizeHintForRow(0) * qMin(maxVisibleItems, view->model()->rowCount()) + 3) + 3; | 
					
						
							|  |  |  | 	QScrollBar *hsb = view->horizontalScrollBar(); | 
					
						
							|  |  |  | 	if (hsb && hsb->isVisible()) | 
					
						
							|  |  |  | 		h += view->horizontalScrollBar()->sizeHint().height(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rh = height(); | 
					
						
							|  |  |  | 	pos = mapToGlobal(QPoint(0, height() - 2)); | 
					
						
							|  |  |  | 	w = width(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (w > screen.width()) | 
					
						
							|  |  |  | 		w = screen.width(); | 
					
						
							|  |  |  | 	if ((pos.x() + w) > (screen.x() + screen.width())) | 
					
						
							|  |  |  | 		pos.setX(screen.x() + screen.width() - w); | 
					
						
							|  |  |  | 	if (pos.x() < screen.x()) | 
					
						
							|  |  |  | 		pos.setX(screen.x()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int top = pos.y() - rh - screen.top() + 2; | 
					
						
							|  |  |  | 	int bottom = screen.bottom() - pos.y(); | 
					
						
							|  |  |  | 	h = qMax(h, view->minimumHeight()); | 
					
						
							|  |  |  | 	if (h > bottom) { | 
					
						
							|  |  |  | 		h = qMin(qMax(top, bottom), h); | 
					
						
							|  |  |  | 		if (top > bottom) | 
					
						
							|  |  |  | 			pos.setY(pos.y() - h - rh + 2); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-09-21 16:08:58 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-22 14:13:51 -03:00
										 |  |  | 	view->setGeometry(pos.x(), pos.y(), w, h); | 
					
						
							| 
									
										
										
										
											2015-10-01 16:27:22 -03:00
										 |  |  | 	if (!view->currentIndex().isValid() && view->model()->rowCount()) { | 
					
						
							| 
									
										
										
										
											2016-01-20 01:05:52 +05:30
										 |  |  | 		view->setCurrentIndex(view->model()->index(0, 1)); | 
					
						
							| 
									
										
										
										
											2015-09-23 16:19:58 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-09-23 16:03:28 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-09-21 16:08:58 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-25 00:26:48 +02:00
										 |  |  | void DiveLocationLineEdit::setCurrentDiveSite(struct dive *d) | 
					
						
							| 
									
										
										
										
											2015-09-25 14:51:10 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-27 16:08:50 -04:00
										 |  |  | 	location_t currentLocation; | 
					
						
							|  |  |  | 	if (d) { | 
					
						
							|  |  |  | 		currDs = get_dive_site_for_dive(d); | 
					
						
							|  |  |  | 		currentLocation = dive_get_gps_location(d); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		currDs = nullptr; | 
					
						
							|  |  |  | 		currentLocation = location_t{0, 0}; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-06-30 23:18:12 +02:00
										 |  |  | 	if (!currDs) | 
					
						
							| 
									
										
										
										
											2015-09-25 14:51:10 -03:00
										 |  |  | 		clear(); | 
					
						
							| 
									
										
										
										
											2019-06-30 23:18:12 +02:00
										 |  |  | 	else | 
					
						
							| 
									
										
										
										
											2019-10-27 16:08:50 -04:00
										 |  |  | 		setText(currDs->name); | 
					
						
							| 
									
										
										
										
											2019-04-25 00:26:48 +02:00
										 |  |  | 	proxy->setCurrentLocation(currentLocation); | 
					
						
							| 
									
										
										
										
											2019-04-25 09:35:46 +02:00
										 |  |  | 	delegate.setCurrentLocation(currentLocation); | 
					
						
							| 
									
										
										
										
											2015-09-25 14:51:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-23 16:03:28 -03:00
										 |  |  | void DiveLocationLineEdit::showPopup() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-25 13:09:11 +02:00
										 |  |  | 	if (!view->isVisible()) | 
					
						
							| 
									
										
										
										
											2015-09-22 16:27:07 -03:00
										 |  |  | 		setTemporaryDiveSiteName(text()); | 
					
						
							| 
									
										
										
										
											2015-09-21 16:08:58 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-25 13:16:30 +02:00
										 |  |  | void DiveLocationLineEdit::showAllSites() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!view->isVisible()) { | 
					
						
							|  |  |  | 		// By setting the "temporary dive site name" to the empty string,
 | 
					
						
							|  |  |  | 		// all dive sites are shown sorted by distance from the site of
 | 
					
						
							|  |  |  | 		// the current dive.
 | 
					
						
							|  |  |  | 		setTemporaryDiveSiteName(QString()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// By selecting the whole text, the user can immediately start
 | 
					
						
							|  |  |  | 		// typing to activate the full-text filter.
 | 
					
						
							|  |  |  | 		selectAll(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-25 08:02:06 +02:00
										 |  |  | struct dive_site *DiveLocationLineEdit::currDiveSite() const | 
					
						
							| 
									
										
										
										
											2015-09-23 14:46:29 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-30 23:08:02 +02:00
										 |  |  | 	// If there is no text, this corresponds to the empty dive site
 | 
					
						
							|  |  |  | 	return text().trimmed().isEmpty() ? nullptr : currDs; | 
					
						
							| 
									
										
										
										
											2015-09-23 14:46:29 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-21 18:09:09 +02:00
										 |  |  | DiveLocationListView::DiveLocationListView(QWidget*) | 
					
						
							| 
									
										
										
										
											2015-09-21 14:01:58 -03:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-09-25 13:21:23 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-29 19:57:53 -04:00
										 |  |  | void DiveLocationListView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) | 
					
						
							| 
									
										
										
										
											2015-09-25 13:21:23 -03:00
										 |  |  | { | 
					
						
							|  |  |  | 	QListView::currentChanged(current, previous); | 
					
						
							|  |  |  | 	emit currentIndexChanged(current); | 
					
						
							|  |  |  | } |