He said, "Patches, I'm depending on you son
To pull the family through, my son, it's all left up to you"
From 0c09e925bc25ca647c3e8902091eb3e1938073ad Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Mon, 12 May 2014 13:19:57 -0300
Subject: [PATCH 1/5] Move printGpsCoords from MainTab to QtHelper

Last time I touched this I got a scream from dirk, but then I
looked at the code again and the problem that I faced was that
I broke translations in a sad way, well, now I broke it again.

However, this method shouldn't belong to MainTab ( because of
that thingy that I said before and also many others: Separate
the logic of your application from the UI specific code )

This generates a string that's going to be used on the Interface,
it doesn't display it on the interface. Move it down below makes
it easier to test ( I don't need to create an Widget and worry
about the parent-relationship with the mainwindow just to test
this function, for instance. )

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 qt-ui/maintab.cpp | 26 --------------------------
 qt-ui/maintab.h   |  1 -
 qthelper.cpp      | 35 ++++++++++++++++++++++++++++++-----
 qthelper.h        |  2 +-
 4 files changed, 31 insertions(+), 33 deletions(-)

diff --git a/qt-ui/maintab.cpp b/qt-ui/maintab.cpp
index 234a01c..172e4e2 100644
--- a/qt-ui/maintab.cpp
+++ b/qt-ui/maintab.cpp
@@ -1076,32 +1076,6 @@ void MainTab::editWeightWidget(const QModelIndex &index)
 		ui.weights->edit(index);
 }
 
-QString MainTab::printGPSCoords(int lat, int lon)
-{
-	unsigned int latdeg, londeg;
-	unsigned int latmin, lonmin;
-	double latsec, lonsec;
-	QString lath, lonh, result;
-
-	if (!lat && !lon)
-		return QString("");
-
-	lath = lat >= 0 ? tr("N") : tr("S");
-	lonh = lon >= 0 ? tr("E") : tr("W");
-	lat = abs(lat);
-	lon = abs(lon);
-	latdeg = lat / 1000000;
-	londeg = lon / 1000000;
-	latmin = (lat % 1000000) * 60;
-	lonmin = (lon % 1000000) * 60;
-	latsec = (latmin % 1000000) * 60;
-	lonsec = (lonmin % 1000000) * 60;
-	result.sprintf("%u%s%02d\'%06.3f\"%s %u%s%02d\'%06.3f\"%s",
-		       latdeg, UTF8_DEGREE, latmin / 1000000, latsec / 1000000, lath.toUtf8().data(),
-		       londeg, UTF8_DEGREE, lonmin / 1000000, lonsec / 1000000, lonh.toUtf8().data());
-	return result;
-}
-
 void MainTab::updateCoordinatesText(qreal lat, qreal lon)
 {
 	int ulat = rint(lat * 1000000);
diff --git a/qt-ui/maintab.h b/qt-ui/maintab.h
index ece2c40..d201d2a 100644
--- a/qt-ui/maintab.h
+++ b/qt-ui/maintab.h
@@ -120,7 +120,6 @@ private:
 	Completers completers;
 	void resetPallete();
 	void saveTags();
-	QString printGPSCoords(int lat, int lon);
 	void updateGpsCoordinates(const struct dive *dive);
 };
 
diff --git a/qthelper.cpp b/qthelper.cpp
index a5e450e..f056f52 100644
--- a/qthelper.cpp
+++ b/qthelper.cpp
@@ -110,6 +110,32 @@ QString weight_string(int weight_in_grams)
 	return (str);
 }
 
+QString printGPSCoords(int lat, int lon)
+{
+	unsigned int latdeg, londeg;
+	unsigned int latmin, lonmin;
+	double latsec, lonsec;
+	QString lath, lonh, result;
+
+	if (!lat && !lon)
+		return QString();
+
+	lath = lat >= 0 ? tr("N") : tr("S");
+	lonh = lon >= 0 ? tr("E") : tr("W");
+	lat = abs(lat);
+	lon = abs(lon);
+	latdeg = lat / 1000000;
+	londeg = lon / 1000000;
+	latmin = (lat % 1000000) * 60;
+	lonmin = (lon % 1000000) * 60;
+	latsec = (latmin % 1000000) * 60;
+	lonsec = (lonmin % 1000000) * 60;
+	result.sprintf("%u%s%02d\'%06.3f\"%s %u%s%02d\'%06.3f\"%s",
+		       latdeg, UTF8_DEGREE, latmin / 1000000, latsec / 1000000, lath.toUtf8().data(),
+		       londeg, UTF8_DEGREE, lonmin / 1000000, lonsec / 1000000, lonh.toUtf8().data());
+	return result;
+}
+
 bool parseGpsText(const QString &gps_text, double *latitude, double *longitude)
 {
 	enum {
@@ -121,10 +147,10 @@ bool parseGpsText(const QString &gps_text, double *latitude, double *longitude)
 	int eastWest = 4;
 	int northSouth = 1;
 	QString trHemisphere[4];
-	trHemisphere[0] = MainWindow::instance()->information()->trHemisphere("N");
-	trHemisphere[1] = MainWindow::instance()->information()->trHemisphere("S");
-	trHemisphere[2] = MainWindow::instance()->information()->trHemisphere("E");
-	trHemisphere[3] = MainWindow::instance()->information()->trHemisphere("W");
+	trHemisphere[0] = tr("N");
+	trHemisphere[1] = tr("S");
+	trHemisphere[2] = tr("E");
+	trHemisphere[3] = tr("W");
 	QString regExp;
 	/* an empty string is interpreted as 0.0,0.0 and therefore "no gps location" */
 	if (gps_text.trimmed().isEmpty()) {
@@ -302,7 +328,6 @@ extern "C" void call_for_each_dc(void *f, void (*callback)(void *, const char *,
 	}
 }
 
-
 static xmlDocPtr get_stylesheet_doc(const xmlChar *uri, xmlDictPtr, int, void *, xsltLoadType)
 {
 	QFile f(QLatin1String(":/xslt/") + (const char *)uri);
diff --git a/qthelper.h b/qthelper.h
index 9d31f5a..6067e13 100644
--- a/qthelper.h
+++ b/qthelper.h
@@ -41,6 +41,6 @@ public:
 
 QString weight_string(int weight_in_grams);
 bool gpsHasChanged(struct dive *dive, struct dive *master, const QString &gps_text, bool *parsed);
-
+QString printGPSCoords(int lat, int lon);
 QList<int> getDivesInTrip(dive_trip_t *trip);
 #endif // QTHELPER_H
-- 
1.9.2

From a02051c0ddbc753aea92cfcf5593c6a276458962 Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Mon, 12 May 2014 13:53:26 -0300
Subject: [PATCH 2/5] Moved DiveList related methods/ classes to own file.

The DiveList classes was a partial mess ( and some of it
is still in a messy state. ), The classes that deal with
it where done in 'qtHelpers.h', the extern global variable
in dive.h, a few methods here and there. This concentrates
most - but not all - functions on it's own file. the reason
for that is to make the new developer faster when looking for
things: if it's a divecomputer related method, it should
be in a single file, not scattered around.

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 CMakeLists.txt                     |   1 +
 divecomputer.cpp                   | 187 +++++++++++++++++++++++++++++++++++++
 divecomputer.h                     |  38 ++++++++
 helpers.h                          |   2 -
 qt-ui/divelistview.cpp             |   2 +-
 qt-ui/downloadfromdivecomputer.cpp |   3 +-
 qt-ui/models.h                     |   2 +-
 qthelper.cpp                       | 178 -----------------------------------
 qthelper.h                         |  28 ------
 subsurface.pro                     |   2 +
 10 files changed, 232 insertions(+), 211 deletions(-)
 create mode 100644 divecomputer.cpp
 create mode 100644 divecomputer.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index ba318ca..153f8d6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -104,6 +104,7 @@ SET(SUBSURFACE_CORE_LIB_SRCS
 	gettextfromc.cpp
 	#dirk ported some core functionality to c++.
 	qthelper.cpp
+	divecomputer.cpp
 )
 
 #the interface, in C++
diff --git a/divecomputer.cpp b/divecomputer.cpp
new file mode 100644
index 0000000..c02bbea
--- /dev/null
+++ b/divecomputer.cpp
@@ -0,0 +1,187 @@
+#include "divecomputer.h"
+#include "dive.h"
+
+#include <QSettings>
+
+const char *default_dive_computer_vendor;
+const char *default_dive_computer_product;
+const char *default_dive_computer_device;
+DiveComputerList dcList;
+
+DiveComputerList::DiveComputerList()
+{
+}
+
+DiveComputerList::~DiveComputerList()
+{
+}
+
+bool DiveComputerNode::operator==(const DiveComputerNode &a) const
+{
+	return model == a.model &&
+	       deviceId == a.deviceId &&
+	       firmware == a.firmware &&
+	       serialNumber == a.serialNumber &&
+	       nickName == a.nickName;
+}
+
+bool DiveComputerNode::operator!=(const DiveComputerNode &a) const
+{
+	return !(*this == a);
+}
+
+bool DiveComputerNode::changesValues(const DiveComputerNode &b) const
+{
+	if (model != b.model || deviceId != b.deviceId) {
+		qDebug("DiveComputerNodes were not for the same DC");
+		return false;
+	}
+	return (firmware != b.firmware) ||
+	       (serialNumber != b.serialNumber) ||
+	       (nickName != b.nickName);
+}
+
+const DiveComputerNode *DiveComputerList::getExact(const QString& m, uint32_t d)
+{
+	for (QMap<QString, DiveComputerNode>::iterator it = dcMap.find(m); it != dcMap.end() && it.key() == m; ++it)
+		if (it->deviceId == d)
+			return &*it;
+	return NULL;
+}
+
+const DiveComputerNode *DiveComputerList::get(const QString& m)
+{
+	QMap<QString, DiveComputerNode>::iterator it = dcMap.find(m);
+	if (it != dcMap.end())
+		return &*it;
+	return NULL;
+}
+
+void DiveComputerList::addDC(const QString& m, uint32_t d, const QString& n, const QString& s,const QString& f)
+{
+	if (m.isEmpty() || d == 0)
+		return;
+	const DiveComputerNode *existNode = this->getExact(m, d);
+	DiveComputerNode newNode(m, d, s, f, n);
+	if (existNode) {
+		if (newNode.changesValues(*existNode)) {
+			if (n.size() && existNode->nickName != n)
+				qDebug("new nickname %s for DC model %s deviceId 0x%x", n.toUtf8().data(), m.toUtf8().data(), d);
+			if (f.size() && existNode->firmware != f)
+				qDebug("new firmware version %s for DC model %s deviceId 0x%x", f.toUtf8().data(), m.toUtf8().data(), d);
+			if (s.size() && existNode->serialNumber != s)
+				qDebug("new serial number %s for DC model %s deviceId 0x%x", s.toUtf8().data(), m.toUtf8().data(), d);
+		} else {
+			return;
+		}
+		dcMap.remove(m, *existNode);
+	}
+	dcMap.insert(m, newNode);
+}
+
+void DiveComputerList::rmDC(const QString& m, uint32_t d)
+{
+	const DiveComputerNode *existNode = this->getExact(m, d);
+	dcMap.remove(m, *existNode);
+}
+
+
+extern "C" void create_device_node(const char *model, uint32_t deviceid, const char *serial, const char *firmware, const char *nickname)
+{
+	dcList.addDC(model, deviceid, nickname, serial, firmware);
+}
+
+extern "C" bool compareDC(const DiveComputerNode &a, const DiveComputerNode &b)
+{
+	return a.deviceId < b.deviceId;
+}
+
+extern "C" void call_for_each_dc(void *f, void (*callback)(void *, const char *, uint32_t,
+						const char *, const char *, const char *))
+{
+	QList<DiveComputerNode> values = dcList.dcMap.values();
+	qSort(values.begin(), values.end(), compareDC);
+	for (int i = 0; i < values.size(); i++) {
+		const DiveComputerNode *node = &values.at(i);
+		callback(f, node->model.toUtf8().data(), node->deviceId, node->nickName.toUtf8().data(),
+			 node->serialNumber.toUtf8().data(), node->firmware.toUtf8().data());
+	}
+}
+
+
+extern "C" int is_default_dive_computer(const char *vendor, const char *product)
+{
+	return default_dive_computer_vendor && !strcmp(vendor, default_dive_computer_vendor) &&
+	       default_dive_computer_product && !strcmp(product, default_dive_computer_product);
+}
+
+extern "C" int is_default_dive_computer_device(const char *name)
+{
+	return default_dive_computer_device && !strcmp(name, default_dive_computer_device);
+}
+
+void set_default_dive_computer(const char *vendor, const char *product)
+{
+	QSettings s;
+
+	if (!vendor || !*vendor)
+		return;
+	if (!product || !*product)
+		return;
+	if (is_default_dive_computer(vendor, product))
+		return;
+	if (default_dive_computer_vendor)
+		free((void *)default_dive_computer_vendor);
+	if (default_dive_computer_product)
+		free((void *)default_dive_computer_product);
+	default_dive_computer_vendor = strdup(vendor);
+	default_dive_computer_product = strdup(product);
+	s.beginGroup("DiveComputer");
+	s.setValue("dive_computer_vendor", vendor);
+	s.setValue("dive_computer_product", product);
+	s.endGroup();
+}
+
+void set_default_dive_computer_device(const char *name)
+{
+	QSettings s;
+
+	if (!name || !*name)
+		return;
+	if (is_default_dive_computer_device(name))
+		return;
+	if (default_dive_computer_device)
+		free((void *)default_dive_computer_device);
+	default_dive_computer_device = strdup(name);
+	s.beginGroup("DiveComputer");
+	s.setValue("dive_computer_device", name);
+	s.endGroup();
+}
+
+extern "C" void set_dc_nickname(struct dive *dive)
+{
+	if (!dive)
+		return;
+
+	struct divecomputer *dc = &dive->dc;
+
+	while (dc) {
+		if (dc->model && *dc->model && dc->deviceid &&
+		    !dcList.getExact(dc->model, dc->deviceid)) {
+			// we don't have this one, yet
+			const DiveComputerNode *existNode = dcList.get(dc->model);
+			if (existNode) {
+				// we already have this model but a different deviceid
+				QString simpleNick(dc->model);
+				if (dc->deviceid == 0)
+					simpleNick.append(" (unknown deviceid)");
+				else
+					simpleNick.append(" (").append(QString::number(dc->deviceid, 16)).append(")");
+				dcList.addDC(dc->model, dc->deviceid, simpleNick);
+			} else {
+				dcList.addDC(dc->model, dc->deviceid);
+			}
+		}
+		dc = dc->next;
+	}
+}
diff --git a/divecomputer.h b/divecomputer.h
new file mode 100644
index 0000000..e515a6b
--- /dev/null
+++ b/divecomputer.h
@@ -0,0 +1,38 @@
+#ifndef DIVECOMPUTER_H
+#define DIVECOMPUTER_H
+
+#include <QString>
+#include <QMap>
+#include <stdint.h>
+
+class DiveComputerNode {
+public:
+	DiveComputerNode(QString m, uint32_t d, QString s, QString f, QString n)
+	    : model(m), deviceId(d), serialNumber(s), firmware(f), nickName(n) {};
+	bool operator==(const DiveComputerNode &a) const;
+	bool operator!=(const DiveComputerNode &a) const;
+	bool changesValues(const DiveComputerNode &b) const;
+	QString model;
+	uint32_t deviceId;
+	QString serialNumber;
+	QString firmware;
+	QString nickName;
+};
+
+class DiveComputerList {
+public:
+	DiveComputerList();
+	~DiveComputerList();
+	const DiveComputerNode *getExact(const QString& m, uint32_t d);
+	const DiveComputerNode *get(const QString& m);
+	void addDC(const QString& m, uint32_t d,const QString& n = QString(),const QString& s = QString(), const QString& f = QString());
+	void rmDC(const QString& m, uint32_t d);
+	DiveComputerNode matchDC(const QString& m, uint32_t d);
+	DiveComputerNode matchModel(const QString& m);
+	QMultiMap<QString, DiveComputerNode> dcMap;
+	QMultiMap<QString, DiveComputerNode> dcWorkingMap;
+};
+
+extern DiveComputerList dcList;
+
+#endif
\ No newline at end of file
diff --git a/helpers.h b/helpers.h
index fcc3be6..e4bc1c6 100644
--- a/helpers.h
+++ b/helpers.h
@@ -33,8 +33,6 @@ QString get_dive_date_string(timestamp_t when);
 QString get_short_dive_date_string(timestamp_t when);
 QString get_trip_date_string(timestamp_t when, int nr);
 
-extern DiveComputerList dcList;
-
 #define M_OR_FT(_m, _f) ((prefs.units.length == units::METERS) ? ((_m) * 1000) : (feet_to_mm(_f)))
 
 #if defined __APPLE__
diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp
index 00906c6..6fd5dee 100644
--- a/qt-ui/divelistview.cpp
+++ b/qt-ui/divelistview.cpp
@@ -25,7 +25,7 @@
 #include <QFileDialog>
 #include <string>
 #include <iostream>
-
+#include "../qthelper.h"
 
 DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelection(false), sortColumn(0), currentOrder(Qt::DescendingOrder), searchBox(this)
 {
diff --git a/qt-ui/downloadfromdivecomputer.cpp b/qt-ui/downloadfromdivecomputer.cpp
index 4f93cef..bc82924 100644
--- a/qt-ui/downloadfromdivecomputer.cpp
+++ b/qt-ui/downloadfromdivecomputer.cpp
@@ -1,9 +1,10 @@
 #include "downloadfromdivecomputer.h"
-
+#include "../divecomputer.h"
 #include "../libdivecomputer.h"
 #include "../helpers.h"
 #include "../display.h"
 #include "../divelist.h"
+
 #include "mainwindow.h"
 #include <cstdlib>
 #include <QThread>
diff --git a/qt-ui/models.h b/qt-ui/models.h
index d638e7d..34d7d48 100644
--- a/qt-ui/models.h
+++ b/qt-ui/models.h
@@ -14,7 +14,7 @@
 
 #include "../dive.h"
 #include "../divelist.h"
-#include "../qthelper.h"
+#include "../divecomputer.h"
 
 QFont defaultModelFont();
 
diff --git a/qthelper.cpp b/qthelper.cpp
index f056f52..101530d 100644
--- a/qthelper.cpp
+++ b/qthelper.cpp
@@ -10,87 +10,7 @@
 
 #define tr(_arg) QObject::tr(_arg)
 
-const char *default_dive_computer_vendor;
-const char *default_dive_computer_product;
-const char *default_dive_computer_device;
-DiveComputerList dcList;
 
-DiveComputerList::DiveComputerList()
-{
-}
-
-DiveComputerList::~DiveComputerList()
-{
-}
-
-bool DiveComputerNode::operator==(const DiveComputerNode &a) const
-{
-	return model == a.model &&
-	       deviceId == a.deviceId &&
-	       firmware == a.firmware &&
-	       serialNumber == a.serialNumber &&
-	       nickName == a.nickName;
-}
-
-bool DiveComputerNode::operator!=(const DiveComputerNode &a) const
-{
-	return !(*this == a);
-}
-
-bool DiveComputerNode::changesValues(const DiveComputerNode &b) const
-{
-	if (model != b.model || deviceId != b.deviceId) {
-		qDebug("DiveComputerNodes were not for the same DC");
-		return false;
-	}
-	return (firmware != b.firmware) ||
-	       (serialNumber != b.serialNumber) ||
-	       (nickName != b.nickName);
-}
-
-const DiveComputerNode *DiveComputerList::getExact(const QString& m, uint32_t d)
-{
-	for (QMap<QString, DiveComputerNode>::iterator it = dcMap.find(m); it != dcMap.end() && it.key() == m; ++it)
-		if (it->deviceId == d)
-			return &*it;
-	return NULL;
-}
-
-const DiveComputerNode *DiveComputerList::get(const QString& m)
-{
-	QMap<QString, DiveComputerNode>::iterator it = dcMap.find(m);
-	if (it != dcMap.end())
-		return &*it;
-	return NULL;
-}
-
-void DiveComputerList::addDC(const QString& m, uint32_t d, const QString& n, const QString& s,const QString& f)
-{
-	if (m.isEmpty() || d == 0)
-		return;
-	const DiveComputerNode *existNode = this->getExact(m, d);
-	DiveComputerNode newNode(m, d, s, f, n);
-	if (existNode) {
-		if (newNode.changesValues(*existNode)) {
-			if (n.size() && existNode->nickName != n)
-				qDebug("new nickname %s for DC model %s deviceId 0x%x", n.toUtf8().data(), m.toUtf8().data(), d);
-			if (f.size() && existNode->firmware != f)
-				qDebug("new firmware version %s for DC model %s deviceId 0x%x", f.toUtf8().data(), m.toUtf8().data(), d);
-			if (s.size() && existNode->serialNumber != s)
-				qDebug("new serial number %s for DC model %s deviceId 0x%x", s.toUtf8().data(), m.toUtf8().data(), d);
-		} else {
-			return;
-		}
-		dcMap.remove(m, *existNode);
-	}
-	dcMap.insert(m, newNode);
-}
-
-void DiveComputerList::rmDC(const QString& m, uint32_t d)
-{
-	const DiveComputerNode *existNode = this->getExact(m, d);
-	dcMap.remove(m, *existNode);
-}
 
 QString weight_string(int weight_in_grams)
 {
@@ -306,27 +226,6 @@ int dive_getUniqID(struct dive *d)
 	return id;
 }
 
-extern "C" void create_device_node(const char *model, uint32_t deviceid, const char *serial, const char *firmware, const char *nickname)
-{
-	dcList.addDC(model, deviceid, nickname, serial, firmware);
-}
-
-extern "C" bool compareDC(const DiveComputerNode &a, const DiveComputerNode &b)
-{
-	return a.deviceId < b.deviceId;
-}
-
-extern "C" void call_for_each_dc(void *f, void (*callback)(void *, const char *, uint32_t,
-						const char *, const char *, const char *))
-{
-	QList<DiveComputerNode> values = dcList.dcMap.values();
-	qSort(values.begin(), values.end(), compareDC);
-	for (int i = 0; i < values.size(); i++) {
-		const DiveComputerNode *node = &values.at(i);
-		callback(f, node->model.toUtf8().data(), node->deviceId, node->nickName.toUtf8().data(),
-			 node->serialNumber.toUtf8().data(), node->firmware.toUtf8().data());
-	}
-}
 
 static xmlDocPtr get_stylesheet_doc(const xmlChar *uri, xmlDictPtr, int, void *, xsltLoadType)
 {
@@ -360,80 +259,3 @@ extern "C" xsltStylesheetPtr get_stylesheet(const char *name)
 
 	return xslt;
 }
-
-extern "C" int is_default_dive_computer(const char *vendor, const char *product)
-{
-	return default_dive_computer_vendor && !strcmp(vendor, default_dive_computer_vendor) &&
-	       default_dive_computer_product && !strcmp(product, default_dive_computer_product);
-}
-
-extern "C" int is_default_dive_computer_device(const char *name)
-{
-	return default_dive_computer_device && !strcmp(name, default_dive_computer_device);
-}
-
-void set_default_dive_computer(const char *vendor, const char *product)
-{
-	QSettings s;
-
-	if (!vendor || !*vendor)
-		return;
-	if (!product || !*product)
-		return;
-	if (is_default_dive_computer(vendor, product))
-		return;
-	if (default_dive_computer_vendor)
-		free((void *)default_dive_computer_vendor);
-	if (default_dive_computer_product)
-		free((void *)default_dive_computer_product);
-	default_dive_computer_vendor = strdup(vendor);
-	default_dive_computer_product = strdup(product);
-	s.beginGroup("DiveComputer");
-	s.setValue("dive_computer_vendor", vendor);
-	s.setValue("dive_computer_product", product);
-	s.endGroup();
-}
-
-void set_default_dive_computer_device(const char *name)
-{
-	QSettings s;
-
-	if (!name || !*name)
-		return;
-	if (is_default_dive_computer_device(name))
-		return;
-	if (default_dive_computer_device)
-		free((void *)default_dive_computer_device);
-	default_dive_computer_device = strdup(name);
-	s.beginGroup("DiveComputer");
-	s.setValue("dive_computer_device", name);
-	s.endGroup();
-}
-
-extern "C" void set_dc_nickname(struct dive *dive)
-{
-	if (!dive)
-		return;
-
-	struct divecomputer *dc = &dive->dc;
-
-	while (dc) {
-		if (dc->model && *dc->model && dc->deviceid &&
-		    !dcList.getExact(dc->model, dc->deviceid)) {
-			// we don't have this one, yet
-			const DiveComputerNode *existNode = dcList.get(dc->model);
-			if (existNode) {
-				// we already have this model but a different deviceid
-				QString simpleNick(dc->model);
-				if (dc->deviceid == 0)
-					simpleNick.append(" (unknown deviceid)");
-				else
-					simpleNick.append(" (").append(QString::number(dc->deviceid, 16)).append(")");
-				dcList.addDC(dc->model, dc->deviceid, simpleNick);
-			} else {
-				dcList.addDC(dc->model, dc->deviceid);
-			}
-		}
-		dc = dc->next;
-	}
-}
diff --git a/qthelper.h b/qthelper.h
index 6067e13..116bb0d 100644
--- a/qthelper.h
+++ b/qthelper.h
@@ -11,34 +11,6 @@
 // global pointers for our translation
 extern QTranslator *qtTranslator, *ssrfTranslator;
 
-class DiveComputerNode {
-public:
-	DiveComputerNode(QString m, uint32_t d, QString s, QString f, QString n)
-	    : model(m), deviceId(d), serialNumber(s), firmware(f), nickName(n) {};
-	bool operator==(const DiveComputerNode &a) const;
-	bool operator!=(const DiveComputerNode &a) const;
-	bool changesValues(const DiveComputerNode &b) const;
-	QString model;
-	uint32_t deviceId;
-	QString serialNumber;
-	QString firmware;
-	QString nickName;
-};
-
-class DiveComputerList {
-public:
-	DiveComputerList();
-	~DiveComputerList();
-	const DiveComputerNode *getExact(const QString& m, uint32_t d);
-	const DiveComputerNode *get(const QString& m);
-	void addDC(const QString& m, uint32_t d,const QString& n = QString(),const QString& s = QString(), const QString& f = QString());
-	void rmDC(const QString& m, uint32_t d);
-	DiveComputerNode matchDC(const QString& m, uint32_t d);
-	DiveComputerNode matchModel(const QString& m);
-	QMultiMap<QString, DiveComputerNode> dcMap;
-	QMultiMap<QString, DiveComputerNode> dcWorkingMap;
-};
-
 QString weight_string(int weight_in_grams);
 bool gpsHasChanged(struct dive *dive, struct dive *master, const QString &gps_text, bool *parsed);
 QString printGPSCoords(int lat, int lon);
diff --git a/subsurface.pro b/subsurface.pro
index 829a459..7762318 100644
--- a/subsurface.pro
+++ b/subsurface.pro
@@ -39,6 +39,7 @@ HEADERS = \
 	profile.h \
 	qt-gui.h \
 	qthelper.h \
+	divecomputer.h \
 	qt-ui/about.h \
 	qt-ui/completionmodels.h \
 	qt-ui/divecomputermanagementdialog.h \
@@ -105,6 +106,7 @@ SOURCES =  \
 	parse-xml.c \
 	planner.c \
 	profile.c \
+	divecomputer.cpp \
 	worldmap-save.c \
 	qt-gui.cpp \
 	qthelper.cpp \
-- 
1.9.2

From 674acbbaf01590c0ebe00a90a358e08b3109e771 Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Mon, 12 May 2014 14:10:13 -0300
Subject: [PATCH 3/5] rename 'get_dive_by_diveid' to 'get_dive_by_uemis_diveid'

A bit longer, but we had a function named get_dive_by_diveid
and another one named getDiveByDiveid that did completely
different things, it was too easy to hit the wrong one..

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 dive.h             | 7 ++-----
 uemis-downloader.c | 2 +-
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/dive.h b/dive.h
index 31115df..6ad21aa 100644
--- a/dive.h
+++ b/dive.h
@@ -421,7 +421,7 @@ static inline struct divecomputer *get_dive_dc(struct dive *dive, int nr)
 #define for_each_gps_location(_i, _x) \
 	for ((_i) = 0; ((_x) = get_gps_location(_i, &gps_location_table)) != NULL; (_i)++)
 
-static inline struct dive *get_dive_by_diveid(uint32_t diveid, uint32_t deviceid)
+static inline struct dive *get_dive_by_uemis_diveid(uint32_t diveid, uint32_t deviceid)
 {
 	int i;
 	struct dive *dive;
@@ -435,10 +435,7 @@ static inline struct dive *get_dive_by_diveid(uint32_t diveid, uint32_t deviceid
 	}
 	return NULL;
 }
-// this is very different from get_dive_by_diveid() (which is only used
-// by the UEMIS downloader) -- this uses the unique diveID to allow us
-// to hold an identifier for a dive across operations that might change
-// the dive_table
+
 static inline struct dive *getDiveById(int id)
 {
 	int i;
diff --git a/uemis-downloader.c b/uemis-downloader.c
index c1980de..8172c78 100644
--- a/uemis-downloader.c
+++ b/uemis-downloader.c
@@ -751,7 +751,7 @@ static bool process_raw_buffer(uint32_t deviceid, char *inbuf, char **max_divenr
 				dive->number = atoi(val);
 		} else if (!log && !strcmp(tag, "logfilenr")) {
 			/* this one tells us which dive we are adding data to */
-			dive = get_dive_by_diveid(atoi(val), deviceid);
+			dive = get_dive_by_uemis_diveid(atoi(val), deviceid);
 			if (for_dive)
 				*for_dive = atoi(val);
 		} else if (!log && dive && !strcmp(tag, "divespot_id")) {
-- 
1.9.2

From 8a517fcd926a7ecb8d2ef8afb91da766f591b876 Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Mon, 12 May 2014 14:22:46 -0300
Subject: [PATCH 4/5] Renomed getDiveById to get_dive_by_id to keep current c
 code organized.

This commit renames getDiveById to get_dive_by_id, and it also removes
the Q_ASSERTS and if(!dive) return that the callers of this function
were calling. if it has a Q_ASSERT this means that the dive must exist,
so checking for nullness was bogus too. I'v changed the assert ( done
in a silly C-Way, someone that understands a bit more of C should try
to fix it for me ) to the function call to simplify code.

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 dive.h                              |  8 +++++++-
 qt-ui/models.cpp                    | 26 +++++++++-----------------
 qt-ui/profile/diveplotdatamodel.cpp |  4 +---
 qt-ui/profile/diveprofileitem.cpp   |  7 ++-----
 qt-ui/profile/profilewidget2.cpp    |  4 ++--
 5 files changed, 21 insertions(+), 28 deletions(-)

diff --git a/dive.h b/dive.h
index 6ad21aa..bef6c6f 100644
--- a/dive.h
+++ b/dive.h
@@ -436,7 +436,7 @@ static inline struct dive *get_dive_by_uemis_diveid(uint32_t diveid, uint32_t de
 	return NULL;
 }
 
-static inline struct dive *getDiveById(int id)
+static inline struct dive *get_dive_by_diveid(int id)
 {
 	int i;
 	struct dive *dive = NULL;
@@ -445,6 +445,12 @@ static inline struct dive *getDiveById(int id)
 		if (dive->id == id)
 			break;
 	}
+#ifdef DEBUG
+	if(dive == NULL){
+		printf("Invalid id passed to get_dive_by_diveid, try to fix the code.");
+		exit(1);
+	}
+#endif
 	return dive;
 }
 
diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp
index 43f08e1..c04b973 100644
--- a/qt-ui/models.cpp
+++ b/qt-ui/models.cpp
@@ -1056,7 +1056,7 @@ static int nitrox_sort_value(struct dive *dive)
 QVariant DiveItem::data(int column, int role) const
 {
 	QVariant retVal;
-	struct dive *dive = getDiveById(diveId);
+	struct dive *dive = get_dive_by_diveid(diveId);
 
 	switch (role) {
 	case Qt::TextAlignmentRole:
@@ -1203,8 +1203,7 @@ bool DiveItem::setData(const QModelIndex &index, const QVariant &value, int role
 		if (d->number == v)
 			return false;
 	}
-	d = getDiveById(diveId);
-	Q_ASSERT(d != NULL);
+	d = get_dive_by_diveid(diveId);
 	d->number = value.toInt();
 	mark_divelist_changed(true);
 	return true;
@@ -1212,8 +1211,7 @@ bool DiveItem::setData(const QModelIndex &index, const QVariant &value, int role
 
 QString DiveItem::displayDate() const
 {
-	struct dive *dive = getDiveById(diveId);
-	Q_ASSERT(dive != NULL);
+	struct dive *dive = get_dive_by_diveid(diveId);
 	return get_dive_date_string(dive->when);
 }
 
@@ -1221,8 +1219,7 @@ QString DiveItem::displayDepth() const
 {
 	QString fract, str;
 	const int scale = 1000;
-	struct dive *dive = getDiveById(diveId);
-	Q_ASSERT(dive != NULL);
+	struct dive *dive = get_dive_by_diveid(diveId);
 	if (get_units()->length == units::METERS) {
 		fract = QString::number((unsigned)(dive->maxdepth.mm % scale) / 100);
 		str = QString("%1.%2").arg((unsigned)(dive->maxdepth.mm / scale)).arg(fract, 1, QChar('0'));
@@ -1236,8 +1233,7 @@ QString DiveItem::displayDepth() const
 QString DiveItem::displayDuration() const
 {
 	int hrs, mins, secs;
-	struct dive *dive = getDiveById(diveId);
-	Q_ASSERT(dive != NULL);
+	struct dive *dive = get_dive_by_diveid(diveId);
 	secs = dive->duration.seconds % 60;
 	mins = dive->duration.seconds / 60;
 	hrs = mins / 60;
@@ -1255,8 +1251,7 @@ QString DiveItem::displayDuration() const
 QString DiveItem::displayTemperature() const
 {
 	QString str;
-	struct dive *dive = getDiveById(diveId);
-	Q_ASSERT(dive != NULL);
+	struct dive *dive = get_dive_by_diveid(diveId);
 	if (!dive->watertemp.mkelvin)
 		return str;
 	if (get_units()->temperature == units::CELSIUS)
@@ -1269,8 +1264,7 @@ QString DiveItem::displayTemperature() const
 QString DiveItem::displaySac() const
 {
 	QString str;
-	struct dive *dive = getDiveById(diveId);
-	Q_ASSERT(dive != NULL);
+	struct dive *dive = get_dive_by_diveid(diveId);
 	if (get_units()->volume == units::LITER)
 		str = QString::number(dive->sac / 1000.0, 'f', 1).append(tr(" l/min"));
 	else
@@ -1286,8 +1280,7 @@ QString DiveItem::displayWeight() const
 
 int DiveItem::weight() const
 {
-	struct dive *dive = getDiveById(diveId);
-	Q_ASSERT(dive != 0);
+	struct dive *dive = get_dive_by_diveid(diveId);
 	weight_t tw = { total_weight(dive) };
 	return tw.grams;
 }
@@ -1907,8 +1900,7 @@ QVariant ProfilePrintModel::data(const QModelIndex &index, int role) const
 
 	switch (role) {
 	case Qt::DisplayRole: {
-		struct dive *dive = getDiveById(diveId);
-		Q_ASSERT(dive != NULL);
+		struct dive *dive = get_dive_by_diveid(diveId);
 		struct DiveItem di;
 		di.diveId = diveId;
 
diff --git a/qt-ui/profile/diveplotdatamodel.cpp b/qt-ui/profile/diveplotdatamodel.cpp
index ad2859b..990564f 100644
--- a/qt-ui/profile/diveplotdatamodel.cpp
+++ b/qt-ui/profile/diveplotdatamodel.cpp
@@ -178,9 +178,7 @@ void DivePlotDataModel::emitDataChanged()
 
 void DivePlotDataModel::calculateDecompression()
 {
-	struct dive *d = getDiveById(id());
-	if (!d)
-		return;
+	struct dive *d = get_dive_by_diveid(id());
 	struct divecomputer *dc = select_dc(d);
 	init_decompression(d);
 	calculate_deco_information(d, dc, &pInfo, false);
diff --git a/qt-ui/profile/diveprofileitem.cpp b/qt-ui/profile/diveprofileitem.cpp
index c239d39..1615be8 100644
--- a/qt-ui/profile/diveprofileitem.cpp
+++ b/qt-ui/profile/diveprofileitem.cpp
@@ -427,8 +427,7 @@ void DiveGasPressureItem::modelDataChanged(const QModelIndex &topLeft, const QMo
 	int last_pressure[MAX_CYLINDERS] = { 0, };
 	int last_time[MAX_CYLINDERS] = { 0, };
 	struct plot_data *entry;
-	struct dive *dive = getDiveById(dataModel->id());
-	Q_ASSERT(dive != NULL);
+	struct dive *dive = get_dive_by_diveid(dataModel->id());
 
 	cyl = -1;
 	for (int i = 0, count = dataModel->rowCount(); i < count; i++) {
@@ -490,9 +489,7 @@ void DiveGasPressureItem::paint(QPainter *painter, const QStyleOptionGraphicsIte
 	QPen pen;
 	pen.setCosmetic(true);
 	pen.setWidth(2);
-	struct dive *d = getDiveById(dataModel->id());
-	if (!d)
-		return;
+	struct dive *d = get_dive_by_diveid(dataModel->id());
 	struct plot_data *entry = dataModel->data().entry;
 	Q_FOREACH(const QPolygonF & poly, polygons) {
 		for (int i = 1, count = poly.count(); i < count; i++, entry++) {
diff --git a/qt-ui/profile/profilewidget2.cpp b/qt-ui/profile/profilewidget2.cpp
index 17eb2a3..d2d01a3 100644
--- a/qt-ui/profile/profilewidget2.cpp
+++ b/qt-ui/profile/profilewidget2.cpp
@@ -227,7 +227,7 @@ void ProfileWidget2::replot()
 {
 	int diveId = dataModel->id();
 	dataModel->clear();
-	plotDives(QList<dive *>() << getDiveById(diveId));
+	plotDives(QList<dive *>() << get_dive_by_diveid(diveId));
 }
 
 void ProfileWidget2::setupItemSizes()
@@ -808,7 +808,7 @@ void ProfileWidget2::changeGas()
 	int diveId = dataModel->id();
 	int o2, he;
 	int seconds = timeAxis->valueAt(scenePos);
-	struct dive *d = getDiveById(diveId);
+	struct dive *d = get_dive_by_diveid(diveId);
 
 	validate_gas(gas.toUtf8().constData(), &o2, &he);
 	add_gas_switch_event(d, get_dive_dc(d, diveComputer), seconds, get_gasidx(d, o2, he));
-- 
1.9.2

From 8e47967ca2d447a6321639cfb0bf50c21be9f24d Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Mon, 12 May 2014 14:58:15 -0300
Subject: [PATCH 5/5] do not check for null before free.

C specs says that we can safelly delete a NULL pointer,
so there's no reason to check that it's null before
deleting it.

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 dive.c                             |  3 +--
 divecomputer.cpp                   | 11 +++++------
 divelist.c                         | 24 ++++++++----------------
 profile.c                          |  4 ++--
 qt-gui.cpp                         |  6 ++----
 qt-ui/downloadfromdivecomputer.cpp |  8 +++-----
 qt-ui/mainwindow.cpp               |  7 +++----
 statistics.c                       |  9 ++++-----
 8 files changed, 28 insertions(+), 44 deletions(-)

diff --git a/dive.c b/dive.c
index 0c4b91f..68f619b 100644
--- a/dive.c
+++ b/dive.c
@@ -1758,8 +1758,7 @@ static void free_events(struct event *ev)
 static void free_dc(struct divecomputer *dc)
 {
 	free(dc->sample);
-	if (dc->model)
-		free((void *)dc->model);
+	free((void *)dc->model);
 	free_events(dc->events);
 	free(dc);
 }
diff --git a/divecomputer.cpp b/divecomputer.cpp
index c02bbea..6044f1a 100644
--- a/divecomputer.cpp
+++ b/divecomputer.cpp
@@ -130,10 +130,9 @@ void set_default_dive_computer(const char *vendor, const char *product)
 		return;
 	if (is_default_dive_computer(vendor, product))
 		return;
-	if (default_dive_computer_vendor)
-		free((void *)default_dive_computer_vendor);
-	if (default_dive_computer_product)
-		free((void *)default_dive_computer_product);
+
+	free((void *)default_dive_computer_vendor);
+	free((void *)default_dive_computer_product);
 	default_dive_computer_vendor = strdup(vendor);
 	default_dive_computer_product = strdup(product);
 	s.beginGroup("DiveComputer");
@@ -150,8 +149,8 @@ void set_default_dive_computer_device(const char *name)
 		return;
 	if (is_default_dive_computer_device(name))
 		return;
-	if (default_dive_computer_device)
-		free((void *)default_dive_computer_device);
+
+	free((void *)default_dive_computer_device);
 	default_dive_computer_device = strdup(name);
 	s.beginGroup("DiveComputer");
 	s.setValue("dive_computer_device", name);
diff --git a/divelist.c b/divelist.c
index f8d3d70..b199710 100644
--- a/divelist.c
+++ b/divelist.c
@@ -566,10 +566,8 @@ static void delete_trip(dive_trip_t *trip)
 	}
 
 	/* .. and free it */
-	if (trip->location)
-		free(trip->location);
-	if (trip->notes)
-		free(trip->notes);
+	free(trip->location);
+	free(trip->notes);
 	free(trip);
 }
 
@@ -703,18 +701,12 @@ void delete_single_dive(int idx)
 	dive_table.dives[--dive_table.nr] = NULL;
 	/* free all allocations */
 	free(dive->dc.sample);
-	if (dive->location)
-		free((void *)dive->location);
-	if (dive->notes)
-		free((void *)dive->notes);
-	if (dive->divemaster)
-		free((void *)dive->divemaster);
-	if (dive->buddy)
-		free((void *)dive->buddy);
-	if (dive->suit)
-		free((void *)dive->suit);
-	if (dive->tag_list)
-		taglist_free(dive->tag_list);
+	free((void *)dive->location);
+	free((void *)dive->notes);
+	free((void *)dive->divemaster);
+	free((void *)dive->buddy);
+	free((void *)dive->suit);
+	taglist_free(dive->tag_list);
 	free(dive);
 }
 
diff --git a/profile.c b/profile.c
index 8289f68..fea0330 100644
--- a/profile.c
+++ b/profile.c
@@ -1184,8 +1184,8 @@ void create_plot_info_new(struct dive *dive, struct divecomputer *dc, struct plo
 {
 	int o2, he, o2low;
 	init_decompression(dive);
-	if (last_pi_entry_new) /* Create the new plot data */
-		free((void *)last_pi_entry_new);
+	/* Create the new plot data */
+	free((void *)last_pi_entry_new);
 	get_dive_gas(dive, &o2, &he, &o2low);
 	if (he > 0) {
 		pi->dive_type = TRIMIX;
diff --git a/qt-gui.cpp b/qt-gui.cpp
index 868389e..9d6dde4 100644
--- a/qt-gui.cpp
+++ b/qt-gui.cpp
@@ -165,10 +165,8 @@ void exit_ui(void)
 {
 	delete window;
 	delete application;
-	if (existing_filename)
-		free((void *)existing_filename);
-	if (default_dive_computer_device)
-		free((void *)default_dive_computer_device);
+	free((void *)existing_filename);
+	free((void *)default_dive_computer_device);
 }
 
 void set_filename(const char *filename, bool force)
diff --git a/qt-ui/downloadfromdivecomputer.cpp b/qt-ui/downloadfromdivecomputer.cpp
index bc82924..17c2a4e 100644
--- a/qt-ui/downloadfromdivecomputer.cpp
+++ b/qt-ui/downloadfromdivecomputer.cpp
@@ -243,7 +243,7 @@ void DownloadFromDCWidget::fill_computer_list()
 	if (!productList["Uemis"].contains("Zurich"))
 		productList["Uemis"].push_back("Zurich");
 
-	descriptorLookup[QString("UemisZurich")] = (dc_descriptor_t *)mydescriptor;
+	descriptorLookup["UemisZurich"] = (dc_descriptor_t *)mydescriptor;
 
 	qSort(vendorList);
 }
@@ -322,8 +322,7 @@ void DownloadFromDCWidget::pickLogFile()
 	logFile = QFileDialog::getSaveFileName(this, tr("Choose file for divecomputer download logfile"),
 					       filename, tr("Log files (*.log)"));
 	if (!logFile.isEmpty()) {
-		if (logfile_name)
-			free(logfile_name);
+		free(logfile_name);
 		logfile_name = strdup(logFile.toUtf8().data());
 	}
 }
@@ -351,8 +350,7 @@ void DownloadFromDCWidget::pickDumpFile()
 	dumpFile = QFileDialog::getSaveFileName(this, tr("Choose file for divecomputer binary dump file"),
 						filename, tr("Dump files (*.bin)"));
 	if (!dumpFile.isEmpty()) {
-		if (dumpfile_name)
-			free(dumpfile_name);
+		free(dumpfile_name);
 		dumpfile_name = strdup(dumpFile.toUtf8().data());
 	}
 }
diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp
index 769f486..709693c 100644
--- a/qt-ui/mainwindow.cpp
+++ b/qt-ui/mainwindow.cpp
@@ -245,10 +245,9 @@ void MainWindow::on_actionClose_triggered()
 	/* clear the selection and the statistics */
 	selected_dive = -1;
 
-	if (existing_filename) {
-		free((void *)existing_filename);
-		existing_filename = NULL;
-	}
+	free((void *)existing_filename);
+	existing_filename = NULL;
+
 	cleanUpEmpty();
 	mark_divelist_changed(false);
 
diff --git a/statistics.c b/statistics.c
index ad5a95d..2a96efb 100644
--- a/statistics.c
+++ b/statistics.c
@@ -114,11 +114,10 @@ void process_all_dives(struct dive *dive, struct dive **prev_dive)
 	 * case (one dive per year or all dives during
 	 * one month) for yearly and monthly statistics*/
 
-	if (stats_yearly != NULL) {
-		free(stats_yearly);
-		free(stats_monthly);
-		free(stats_by_trip);
-	}
+	free(stats_yearly);
+	free(stats_monthly);
+	free(stats_by_trip);
+
 	size = sizeof(stats_t) * (dive_table.nr + 1);
 	stats_yearly = malloc(size);
 	stats_monthly = malloc(size);
-- 
1.9.2

_______________________________________________
subsurface mailing list
[email protected]
http://lists.hohndel.org/cgi-bin/mailman/listinfo/subsurface

Reply via email to