aboutsummaryrefslogtreecommitdiffstats
path: root/desktop-widgets/importgps.cpp
blob: 3802731216f6ddac645a8be387f267e708f9b669 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// SPDX-License-Identifier: GPL-2.0
#include "desktop-widgets/importgps.h"
#include "core/subsurface-time.h"

/* Import dive coordinates from a GPS device and synchronise them with the dive profile information
   of a dive computer. This file contains the infrastructure to:
   1) Read a .GPX file from a GPS system.
   2) Find the first gpx trackpoint that follows after the start of the dive.
   3) Allow modification of the coordinates dependent on international time zone and
	      on differences in local time settings between the GPS and the dive computer.
   4) Saving the coordinates into the Coordinates text box in the Dive Site Edit panel
	      and which which causes the map to show the location of the dive site.
   The structure coords is used to store critical information.  */
ImportGPS::ImportGPS(QWidget *parent, QString fileName, class Ui::LocationInformation *LocationUI) : QDialog(parent),
	fileName(fileName), LocationUI(LocationUI)
{
	ui.setupUi(this);
	connect(ui.timeDiffEdit, &QTimeEdit::timeChanged, this, &ImportGPS::timeDiffEditChanged);
	connect(ui.timeZoneEdit, &QTimeEdit::timeChanged, this, &ImportGPS::timeZoneEditChanged);
	connect(ui.timezone_backwards, &QRadioButton::toggled, this, &ImportGPS::changeZoneBackwards);
	connect(ui.timezone_forward, &QRadioButton::toggled, this, &ImportGPS::changeZoneForward);
	connect(ui.diff_backwards, &QRadioButton::toggled, this, &ImportGPS::changeDiffBackwards);
	connect(ui.diff_forward, &QRadioButton::toggled, this, &ImportGPS::changeDiffForward);
	connect(ui.GPSbuttonBox, &QDialogButtonBox::clicked, this, &ImportGPS::buttonClicked);
	coords.settingsDiff_offset = 0;
	coords.timeZone_offset = 0;
	coords.lat = 0;
	coords.lon = 0;
	pixmapSize = (int) (ui.diveDateLabel->height() / 2);
}

void ImportGPS::buttonClicked(QAbstractButton *button)
{
	if (ui.GPSbuttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole) {
		// Write the coordinates in decimal degree format to the Coordinates QLineEdit of the LocationaInformationWidget UI:
		LocationUI->diveSiteCoordinates->setText(QString::number(coords.lat) + ", " + QString::number(coords.lon));
		LocationUI->diveSiteCoordinates->editingFinished();
	} else {
		close();
	}
}

// Fill the visual elements of the synchronisation panel with information
void  ImportGPS::updateUI()
{
	struct tm time;
	int dive_day, gps_day;
	char datestr[50];
	QString problemString = "";

	utc_mkdate(coords.start_track, &time); // Display GPS date and local start and end times of track:
	gps_day = time.tm_mday;
	datestr[0] = 0x0;
	strftime(datestr, sizeof(datestr), "%A %d %B ", &time); // GPS date
	ui.trackDateLabel->setText("GPS date  = " + QString(datestr) + QString::number(time.tm_year));
	ui.startTimeLabel->setText(QString::number(time.tm_hour) + ":" + QString("%1").arg(time.tm_min, 2, 10, QChar('0'))); // track start time
	utc_mkdate(coords.end_track, &time);
	ui.endTimeLabel->setText(QString::number(time.tm_hour) + ":" + QString("%1").arg(time.tm_min, 2, 10, QChar('0')));  // track end time

	utc_mkdate(coords.start_dive, &time); // Display dive date and start and end times of dive:
	dive_day = time.tm_mday;
	datestr[0] = 0x0;
	strftime(datestr, sizeof(datestr), "%A %d %B ", localtime(&(coords.start_dive))); // dive date
	ui.diveDateLabel->setText("Dive date = " + QString(datestr) + QString::number(time.tm_year));
	ui.startTimeSyncLabel->setText( QString::number(time.tm_hour) + ":" + QString("%1").arg(time.tm_min, 2, 10, QChar('0'))); // dive start time
	utc_mkdate(coords.end_dive, &time);
	ui.endTimeSyncLabel->setText(QString::number(time.tm_hour) + ":" + QString("%1").arg(time.tm_min, 2, 10, QChar('0')));  // dive end time

	// This section implements extensive warnings in case there is not synchronisation between dive and GPS data:

	if (gps_day != dive_day)
		problemString = "(different dates)";
	// Create 3 icons to indicate the quality of the synchrinisation between dive and GPS
	QPixmap goodResultIcon (":gps_good_result-icon");
	ui.goodIconLabel->setPixmap(goodResultIcon.scaled(pixmapSize,pixmapSize,Qt::KeepAspectRatio));
	ui.goodIconLabel->setVisible(false);

	QPixmap warningResultIcon (":gps_warning_result-icon");
	ui.warningIconLabel->setPixmap(warningResultIcon.scaled(pixmapSize,pixmapSize,Qt::KeepAspectRatio));
	ui.warningIconLabel->setVisible(false);

	QPixmap badResultIcon (":gps_bad_result-icon");
	ui.badIconLabel->setPixmap(badResultIcon.scaled(pixmapSize,pixmapSize,Qt::KeepAspectRatio));
	ui.badIconLabel->setVisible(false);
	// Show information or warning message as well as synch quality icon
	if (coords.start_dive < coords.start_track) {
		ui.resultLabel->setStyleSheet("QLabel { color: red;} ");
		ui.resultLabel->setText("PROBLEM: Dive started before the GPS track "+ problemString);
		ui.badIconLabel->setVisible(true);
	} else {
		if (coords.start_dive > coords.end_track) {
			ui.resultLabel->setStyleSheet("QLabel { color: red;} ");
			ui.resultLabel->setText("PROBLEM: Dive started after the GPS track " + problemString);
			ui.badIconLabel->setVisible(true);
		} else {
			if (coords.end_dive > coords.end_track) {
				ui.resultLabel->setStyleSheet("QLabel { color: red;} ");
				ui.resultLabel->setText("WARNING: Dive ended after the GPS track " + problemString);
				ui.warningIconLabel->setVisible(true);
			} else {
				ui.resultLabel->setStyleSheet("QLabel { color: darkgreen;} ");
				ui.resultLabel->setText("Dive coordinates: "+ QString::number(coords.lat) + "S, " + QString::number(coords.lon) + "E");
				ui.goodIconLabel->setVisible(true);
			}
		}
	}
}

void ImportGPS::changeZoneForward()
{
	coords.timeZone_offset = abs(coords.timeZone_offset);
	getCoordsFromGPXFile(&coords, fileName); // If any of the time controls are changed
	updateUI();          // .. then recalculate the synchronisation
}

void ImportGPS::changeZoneBackwards()
{
	if (coords.timeZone_offset > 0)
		coords.timeZone_offset = 0 - coords.timeZone_offset;
	getCoordsFromGPXFile(&coords, fileName);
	updateUI();
}

void ImportGPS::changeDiffForward()
{
	coords.settingsDiff_offset = abs(coords.settingsDiff_offset);
	getCoordsFromGPXFile(&coords, fileName);
	updateUI();
}

void ImportGPS::changeDiffBackwards()
{
	if (coords.settingsDiff_offset > 0)
		coords.settingsDiff_offset = 0 - coords.settingsDiff_offset;
	getCoordsFromGPXFile(&coords, fileName);
	updateUI();
}

void  ImportGPS::timeDiffEditChanged()
{
	coords.settingsDiff_offset = ui.timeDiffEdit->time().hour() * 3600 + ui.timeDiffEdit->time().minute() * 60;
	if (ui.diff_backwards->isChecked())
		coords.settingsDiff_offset = 0 - coords.settingsDiff_offset;
	getCoordsFromGPXFile(&coords, fileName);
	updateUI();
}

void  ImportGPS::timeZoneEditChanged()
{
	coords.timeZone_offset = ui.timeZoneEdit->time().hour() * 3600;
	if (ui.timezone_backwards->isChecked())
		coords.timeZone_offset = 0 - coords.timeZone_offset;
	getCoordsFromGPXFile(&coords, fileName);
	updateUI();
}