On Sun, Jun 14, 2015 at 11:55 PM, Tomaz Canabrava <[email protected]>
wrote:

> Grace, always do a rebase from master so your work is not hard to merge
> later.
> I'm doing the review right now.
>
>
>
Here are patches containing the work done so far.

To compile the mobile executable, call cmake with -DSUBSURFACE_MOBILE=True.
This
will result in a subsurface-mobile executable.



-- 
--
Grace K
From faf064b4b7e8b7b931e84ff2f3995a5169e1ac61 Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Thu, 18 Jun 2015 09:13:30 +0300
Subject: [PATCH 21/22] Display more details

Show more dive info in the extended view of the dive.

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-mobile/main.qml | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/qt-mobile/main.qml b/qt-mobile/main.qml
index e257477..8af0a9e 100644
--- a/qt-mobile/main.qml
+++ b/qt-mobile/main.qml
@@ -107,7 +107,13 @@ ApplicationWindow {
 						contentHeight: detailsView.height
 						clip: true
 						Row {
-							Text { text: '<b>Notes:</b><br/>' + notes; wrapMode: Text.WordWrap; width: details.width }
+							Text { text:
+								    '<b>Location: </b>' + location +
+								    '<br><b>Air temp: </b>' + airtemp + ' <b> Water temp: </b>' + watertemp +
+								    '<br><b>Suit: </b>' + suit +
+								    '<br><b>Buddy: </b>' + buddy +
+								    '<br><b>Dive Master: </b>' + divemaster +
+								    '<br/><b>Notes:</b><br/>' + notes; wrapMode: Text.WordWrap; width: details.width }
 						}
 					}
 				}
-- 
2.4.4

From 49d59bdf3d4f61fc45f9dcb994d18715705c08f6 Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Thu, 18 Jun 2015 09:12:52 +0300
Subject: [PATCH 20/22] Add more dive details to the DiveListModel

Add some more details to the model.

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-models/divelistmodel.cpp | 80 +++++++++++++++++++++++++++++++++++++--------
 qt-models/divelistmodel.h   | 27 ++++++++++++---
 2 files changed, 88 insertions(+), 19 deletions(-)

diff --git a/qt-models/divelistmodel.cpp b/qt-models/divelistmodel.cpp
index ad36096..add5af5 100644
--- a/qt-models/divelistmodel.cpp
+++ b/qt-models/divelistmodel.cpp
@@ -17,13 +17,7 @@ Dive::Dive(dive *d)
 	setDepth(get_depth_string(d->maxdepth));
 	setDuration(get_dive_duration_string(d->duration.seconds, "h:","min"));
 
-	if (!d->watertemp.mkelvin)
-		m_depth = "";
-
-	if (get_units()->temperature == units::CELSIUS)
-		m_depth = QString::number(mkelvin_to_C(d->watertemp.mkelvin), 'f', 1);
-	else
-		m_depth = QString::number(mkelvin_to_F(d->watertemp.mkelvin), 'f', 1);
+	setupDiveTempDetails();
 
 	weight_t tw = { total_weight(d) };
 	setWeight(weight_string(tw.grams));
@@ -33,6 +27,8 @@ Dive::Dive(dive *d)
 	setSac(QString::number(d->sac));
 	setLocation(get_dive_location(d));
 	setNotes(d->notes);
+	setBuddy(d->buddy);
+	setDivemaster(d->divemaster);
 }
 
 QString Dive::date() const
@@ -98,14 +94,14 @@ void Dive::setWeight(const QString &weight)
 {
 	m_weight = weight;
 }
-QString Dive::temp() const
+QString Dive::airtemp() const
 {
-	return m_temp;
+	return m_airtemp;
 }
 
-void Dive::setTemp(const QString &temp)
+void Dive::setAirTemp(const QString &airtemp)
 {
-	m_temp = temp;
+	m_airtemp = airtemp;
 }
 QString Dive::duration() const
 {
@@ -170,6 +166,53 @@ void Dive::setTrip(const QString &trip)
 {
 	m_trip = trip;
 }
+QString Dive::buddy() const
+{
+    return m_buddy;
+}
+
+void Dive::setBuddy(const QString &buddy)
+{
+    m_buddy = buddy;
+}
+QString Dive::divemaster() const
+{
+    return m_divemaster;
+}
+
+void Dive::setDivemaster(const QString &divemaster)
+{
+    m_divemaster = divemaster;
+}
+QString Dive::watertemp() const
+{
+	return m_watertemp;
+}
+
+void Dive::setWatertemp(const QString &watertemp)
+{
+	m_watertemp = watertemp;
+}
+
+void Dive::setupDiveTempDetails()
+{
+	const char *unit;
+	double d_airTemp, d_waterTemp;
+
+	d_airTemp = get_temp_units(m_thisDive->airtemp.mkelvin, &unit);
+	d_waterTemp = get_temp_units(m_thisDive->watertemp.mkelvin, &unit);
+
+	setAirTemp(QString::number(d_airTemp) + unit);
+	setWatertemp(QString::number(d_waterTemp) + unit);
+
+	if (!m_thisDive->airtemp.mkelvin)
+		setAirTemp("");
+
+	if (!m_thisDive->watertemp.mkelvin)
+		setWatertemp("");
+}
+
+
 
 
 
@@ -212,8 +255,10 @@ QVariant DiveListModel::data(const QModelIndex &index, int role) const
 		return dive.depth();
 	else if (role == DiveDurationRole)
 		return dive.duration();
-	else if (role == DiveTemperatureRole)
-		return dive.temp();
+	else if (role == DiveAirTemperatureRole)
+		return dive.airtemp();
+	else if (role == DiveWaterTemperatureRole)
+		return dive.watertemp();
 	else if (role == DiveWeightRole)
 		return dive.weight();
 	else if (role == DiveSuitRole)
@@ -228,6 +273,10 @@ QVariant DiveListModel::data(const QModelIndex &index, int role) const
 		return dive.location();
 	else if (role == DiveNotesRole)
 		return dive.notes();
+	else if (role == DiveBuddyRole)
+		return dive.buddy();
+	else if (role == DiveMasterRole)
+		return dive.divemaster();
 	return QVariant();
 
 
@@ -242,7 +291,8 @@ QHash<int, QByteArray> DiveListModel::roleNames() const
 	roles[DiveRatingRole] = "rating";
 	roles[DiveDepthRole] = "depth";
 	roles[DiveDurationRole] = "duration";
-	roles[DiveTemperatureRole] = "temp";
+	roles[DiveAirTemperatureRole] = "airtemp";
+	roles[DiveWaterTemperatureRole] = "watertemp";
 	roles[DiveWeightRole] = "weight";
 	roles[DiveSuitRole] = "suit";
 	roles[DiveCylinderRole] = "cylinder";
@@ -250,6 +300,8 @@ QHash<int, QByteArray> DiveListModel::roleNames() const
 	roles[DiveSacRole] = "sac";
 	roles[DiveLocationRole] = "location";
 	roles[DiveNotesRole] = "notes";
+	roles[DiveBuddyRole] = "buddy";
+	roles[DiveMasterRole] = "divemaster";
 
 	return roles;
 }
diff --git a/qt-models/divelistmodel.h b/qt-models/divelistmodel.h
index f580405..cb19188 100644
--- a/qt-models/divelistmodel.h
+++ b/qt-models/divelistmodel.h
@@ -29,8 +29,8 @@ public:
 	QString weight() const;
 	void setWeight(const QString &weight);
 
-	QString temp() const;
-	void setTemp(const QString &temp);
+	QString airtemp() const;
+	void setAirTemp(const QString &airtemp);
 
 	QString duration() const;
 	void setDuration(const QString &duration);
@@ -53,14 +53,26 @@ public:
 	QString trip() const;
 	void setTrip(const QString &trip);
 
+	QString buddy() const;
+	void setBuddy(const QString &buddy);
+
+	QString divemaster() const;
+	void setDivemaster(const QString &divemaster);
+
+	QString watertemp() const;
+	void setWatertemp(const QString &watertemp);
+
 private:
+	void setupDiveTempDetails();
+
 	QString m_diveNumber;
 	QString m_trip;
 	QString m_date;
 	QString m_rating;
 	QString m_depth;
 	QString m_duration;
-	QString m_temp;
+	QString m_airtemp;
+	QString m_watertemp;
 	QString m_weight;
 	QString m_suit;
 	QString m_cylinder;
@@ -68,6 +80,8 @@ private:
 	QString m_sac;
 	QString m_location;
 	QString m_notes;
+	QString m_buddy;
+	QString m_divemaster;
 
 
 	dive *m_thisDive;
@@ -85,14 +99,17 @@ public:
 		DiveRatingRole,
 		DiveDepthRole,
 		DiveDurationRole,
-		DiveTemperatureRole,
+		DiveWaterTemperatureRole,
+		DiveAirTemperatureRole,
 		DiveWeightRole,
 		DiveSuitRole,
 		DiveCylinderRole,
 		DiveGasRole,
 		DiveSacRole,
 		DiveLocationRole,
-		DiveNotesRole
+		DiveNotesRole,
+		DiveBuddyRole,
+		DiveMasterRole
 	};
 
 	static DiveListModel *instance();
-- 
2.4.4

From c8194ed8391946cf831da8c2052f9211c1855c07 Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Thu, 11 Jun 2015 09:56:18 +0300
Subject: [PATCH 19/22] Fix bug where dives are shown twice

On the QML page, dives are repeated. Adding process_dives to
QMLManager after calling parse_file solves this.

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-mobile/main.qml       | 2 +-
 qt-mobile/qmlmanager.cpp | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/qt-mobile/main.qml b/qt-mobile/main.qml
index bae117e..e257477 100644
--- a/qt-mobile/main.qml
+++ b/qt-mobile/main.qml
@@ -107,7 +107,7 @@ ApplicationWindow {
 						contentHeight: detailsView.height
 						clip: true
 						Row {
-							Text { text: 'Notes: ' + notes; wrapMode: Text.WordWrap; width: details.width }
+							Text { text: '<b>Notes:</b><br/>' + notes; wrapMode: Text.WordWrap; width: details.width }
 						}
 					}
 				}
diff --git a/qt-mobile/qmlmanager.cpp b/qt-mobile/qmlmanager.cpp
index 0f8ccbe..eeeada3 100644
--- a/qt-mobile/qmlmanager.cpp
+++ b/qt-mobile/qmlmanager.cpp
@@ -1,7 +1,8 @@
 #include "qmlmanager.h"
 #include <QUrl>
 
-#include "../qt-models/divelistmodel.h"
+#include "qt-models/divelistmodel.h"
+#include "divelist.h"
 
 QMLManager::QMLManager()
 {
@@ -21,7 +22,6 @@ void QMLManager::setFilename(const QString &f)
 {
 	m_fileName = f;
 	loadFile();
-	emit filenameChanged();
 }
 
 void QMLManager::loadFile()
@@ -30,7 +30,7 @@ void QMLManager::loadFile()
 	QString strippedFileName = url.toLocalFile();
 
 	parse_file(strippedFileName.toUtf8().data());
-
+	process_dives(false, false);
 	int i;
 	struct dive *d;
 
-- 
2.4.4

From 950253526191e3617066c55e5ca60e6b55cf8667 Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Thu, 11 Jun 2015 09:39:32 +0300
Subject: [PATCH 18/22] Group dives by trips

Group dives according to the allocated dive trips.

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-mobile/main.qml          | 45 +++++++++++++++++++++++++--------------------
 qt-models/divelistmodel.cpp | 21 +++++++++++++++++++++
 qt-models/divelistmodel.h   |  5 +++++
 3 files changed, 51 insertions(+), 20 deletions(-)

diff --git a/qt-mobile/main.qml b/qt-mobile/main.qml
index 20ea0c1..bae117e 100644
--- a/qt-mobile/main.qml
+++ b/qt-mobile/main.qml
@@ -72,21 +72,18 @@ ApplicationWindow {
 				//And other details at the bottom.
 				Row {
 					id: topLayout
-					x: 10; y: 10; height: 50; width: parent.width
+					x: 10; y: 10; height: 60; width: parent.width
 					spacing: 10
 
 					Column {
-						width: background.width; height: 50
+						width: background.width; height: 60
 						spacing: 5
 
 						Text {
 							text: diveNumber + ' (' + date + ')'
-							font.bold: true; font.pointSize: 16
-						}
-
-						Text {
-							text: location
 						}
+						Text { text: location; width: details.width }
+						Text { text: '<b>Depth:</b> ' + depth + ' <b>Duration:</b>' + duration; width: details.width }
 					}
 				}
 
@@ -109,19 +106,8 @@ ApplicationWindow {
 						anchors { top: detailsTitle.bottom; bottom: parent.bottom }
 						contentHeight: detailsView.height
 						clip: true
-
-						Column {
-							Row {
-								Text { text: 'Duration: ' + duration; width: details.width }
-							}
-
-							Row {
-								Text { text: 'Depth: ' + depth; width: details.width }
-							}
-
-							Row {
-								Text { text: 'Notes: ' + notes; wrapMode: Text.WordWrap; width: details.width }
-							}
+						Row {
+							Text { text: 'Notes: ' + notes; wrapMode: Text.WordWrap; width: details.width }
 						}
 					}
 				}
@@ -179,12 +165,31 @@ ApplicationWindow {
 			}
 		}
 
+		Component {
+			id: tripHeading
+			Rectangle {
+				width: page.width
+				height: childrenRect.height
+				color: "lightsteelblue"
+
+				Text {
+					text: section
+					font.bold: true
+					font.pointSize: 16
+				}
+			}
+		}
+
 		ListView {
 			id: diveListView
 			anchors.fill: parent
 			model: diveModel
 			delegate: diveDelegate
 			focus: true
+
+			section.property: "trip"
+			section.criteria: ViewSection.FullString
+			section.delegate: tripHeading
 		}
 	}
 }
diff --git a/qt-models/divelistmodel.cpp b/qt-models/divelistmodel.cpp
index c1862b8..ad36096 100644
--- a/qt-models/divelistmodel.cpp
+++ b/qt-models/divelistmodel.cpp
@@ -5,6 +5,14 @@ Dive::Dive(dive *d)
 {
 	m_thisDive = d;
 	setDiveNumber(QString::number(d->number));
+
+	dive_trip *trip = d->divetrip;
+
+	if(trip) {
+		//trip is valid
+		setTrip(trip->location);
+	}
+
 	setDate(get_dive_date_string(d->when));
 	setDepth(get_depth_string(d->maxdepth));
 	setDuration(get_dive_duration_string(d->duration.seconds, "h:","min"));
@@ -153,6 +161,16 @@ void Dive::setNotes(const QString &notes)
 {
 	m_notes = notes;
 }
+QString Dive::trip() const
+{
+	return m_trip;
+}
+
+void Dive::setTrip(const QString &trip)
+{
+	m_trip = trip;
+}
+
 
 
 
@@ -184,6 +202,8 @@ QVariant DiveListModel::data(const QModelIndex &index, int role) const
 
 	if (role == DiveNumberRole)
 		return dive.diveNumber();
+	else if (role == DiveTripRole)
+		return dive.trip();
 	else if (role == DiveDateRole)
 		return dive.date();
 	else if (role == DiveRatingRole)
@@ -217,6 +237,7 @@ QHash<int, QByteArray> DiveListModel::roleNames() const
 {
 	QHash<int, QByteArray> roles;
 	roles[DiveNumberRole] = "diveNumber";
+	roles[DiveTripRole] = "trip";
 	roles[DiveDateRole] = "date";
 	roles[DiveRatingRole] = "rating";
 	roles[DiveDepthRole] = "depth";
diff --git a/qt-models/divelistmodel.h b/qt-models/divelistmodel.h
index 307008c..f580405 100644
--- a/qt-models/divelistmodel.h
+++ b/qt-models/divelistmodel.h
@@ -50,8 +50,12 @@ public:
 	QString notes() const;
 	void setNotes(const QString &notes);
 
+	QString trip() const;
+	void setTrip(const QString &trip);
+
 private:
 	QString m_diveNumber;
+	QString m_trip;
 	QString m_date;
 	QString m_rating;
 	QString m_depth;
@@ -76,6 +80,7 @@ public:
 
 	enum DiveListRoles {
 		DiveNumberRole = Qt::UserRole + 1,
+		DiveTripRole,
 		DiveDateRole,
 		DiveRatingRole,
 		DiveDepthRole,
-- 
2.4.4

From 7e72062986fba14a78bfcd2c860fe70bcc041a98 Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Wed, 10 Jun 2015 21:39:43 +0300
Subject: [PATCH 17/22] Show dive details when a dive is clicked

When a dive is clicked, show the dive details on the QML page.
This contains basic details, and will be expanded further.

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-mobile/main.qml | 168 +++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 125 insertions(+), 43 deletions(-)

diff --git a/qt-mobile/main.qml b/qt-mobile/main.qml
index ee36b9c..20ea0c1 100644
--- a/qt-mobile/main.qml
+++ b/qt-mobile/main.qml
@@ -39,70 +39,152 @@ ApplicationWindow {
 	}
 
 	Rectangle {
+		id: page
 		width: parent.width; height: parent.height
-		anchors.fill: parent
 
 		Component {
 			id: diveDelegate
+
 			Item {
-				id: wrapper
-				width: parent.width; height: 55
-				Column {
-					Text { text: '#:' + diveNumber + "(" + date + ")"  }
-					Text { text: 'Duration: ' + duration }
-					Text { text: 'Depth: ' + depth }
+				id: dive
+
+				property real detailsOpacity : 0
+
+				width: diveListView.width
+				height: 70
+
+				//Bounded rect for the background
+				Rectangle {
+					id: background
+					x: 2; y: 2; width: parent.width - x*2; height: parent.height - y*2;
+					color: "ivory"
+					border.color: "orange"
+					radius: 5
 				}
-				MouseArea { anchors.fill: parent; onClicked: diveListView.currentIndex = index }
 
-				states: State {
-					name: "Current"
-					when: wrapper.ListView.isCurrentItem
-					PropertyChanges { target: wrapper; x:20 }
+				//Mouse region: When clicked, the mode changes to details view
+				MouseArea {
+					anchors.fill: parent
+					onClicked: dive.state = 'Details'
 				}
-				transitions: Transition {
-					NumberAnimation { properties: "x"; duration: 200  }
+
+				//Layout of the page: (mini profile, dive no, date at the tio
+				//And other details at the bottom.
+				Row {
+					id: topLayout
+					x: 10; y: 10; height: 50; width: parent.width
+					spacing: 10
+
+					Column {
+						width: background.width; height: 50
+						spacing: 5
+
+						Text {
+							text: diveNumber + ' (' + date + ')'
+							font.bold: true; font.pointSize: 16
+						}
+
+						Text {
+							text: location
+						}
+					}
 				}
-			}
-		}
 
-		Component {
-			id: highlightBar
-			Rectangle {
-				width: parent.width; height: 50
-				color: "lightsteelblue"
-				radius: 5
-				y: diveListView.currentItem.y;
-				Behavior on y {  SpringAnimation  { spring: 2; damping: 0.1 } }
-			}
-		}
+				Item {
+					id: details
+					x: 10; width: parent.width - 20
+					anchors { top: topLayout.bottom; topMargin: 10; bottom:parent.bottom; bottomMargin: 10 }
+					opacity: dive.detailsOpacity
 
-		Component {
-			id: tripHeading
-			Rectangle {
-				width: container.width
-				height: childrenRect.height
-				color: "lightgreen"
-
-				Text {
-					text: section
-					font.bold: true
+					Text {
+						id: detailsTitle
+						anchors.top: parent.top
+						text: "Dive Details"
+						font.pointSize: 12; font.bold: true
+					}
+
+					Flickable {
+						id: flick
+						width: parent.width
+						anchors { top: detailsTitle.bottom; bottom: parent.bottom }
+						contentHeight: detailsView.height
+						clip: true
+
+						Column {
+							Row {
+								Text { text: 'Duration: ' + duration; width: details.width }
+							}
+
+							Row {
+								Text { text: 'Depth: ' + depth; width: details.width }
+							}
+
+							Row {
+								Text { text: 'Notes: ' + notes; wrapMode: Text.WordWrap; width: details.width }
+							}
+						}
+					}
+				}
+
+				TextButton {
+					y: 10
+					anchors { right: background.right; rightMargin: 10 }
+					opacity: dive.detailsOpacity
+					text: "Close"
+
+					onClicked: dive.state = '';
+				}
+
+				states: State {
+					name: "Details"
+
+					PropertyChanges {
+						target: background
+						color: "white"
+					}
+
+					PropertyChanges {
+						target: dive
+						detailsOpacity: 1; x:0 //Make details visible
+						height: diveListView.height //Fill entire list area with the details
+					}
+
+					//Move the list so that this item is at the top
+					PropertyChanges {
+						target: dive.ListView.view
+						explicit: true
+						contentY: dive.y
+					}
+
+					//Disable flicking while we are in detailed view
+					PropertyChanges {
+						target: dive.ListView.view
+						interactive: false
+					}
+				}
+
+				transitions: Transition {
+					//make the state changes smooth
+					ParallelAnimation {
+						ColorAnimation {
+							property: "color"
+							duration: 500
+						}
+						NumberAnimation {
+							duration: 300
+							properties: "detailsOpacity,x,contentY,height,width"
+						}
+					}
 				}
 			}
 		}
 
 		ListView {
 			id: diveListView
-			width: parent.width; height: parent.height
 			anchors.fill: parent
 			model: diveModel
 			delegate: diveDelegate
 			focus: true
-			highlight: highlightBar
-			highlightFollowsCurrentItem: false
-
-			section.property: "location"
-			section.criteria: ViewSection.FullString
-			section.delegate: tripHeading
 		}
 	}
 }
-- 
2.4.4

From fa10db87d8f15449fe597ab1214ce3c2e2eb378e Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Wed, 10 Jun 2015 21:39:03 +0300
Subject: [PATCH 16/22] Add TextButton.qml file

This file contains a styled button for use in QML

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-mobile/TextButton.qml       | 38 ++++++++++++++++++++++++++++++++++++++
 qt-mobile/mobile-resources.qrc |  1 +
 2 files changed, 39 insertions(+)
 create mode 100644 qt-mobile/TextButton.qml

diff --git a/qt-mobile/TextButton.qml b/qt-mobile/TextButton.qml
new file mode 100644
index 0000000..cc497f4
--- /dev/null
+++ b/qt-mobile/TextButton.qml
@@ -0,0 +1,38 @@
+import QtQuick 2.3
+
+Rectangle {
+	id: container
+
+	property alias text: label.text
+
+	signal clicked
+
+	width: label.width + 20; height: label.height + 6
+	smooth: true
+	radius: 10
+
+	gradient: Gradient {
+		GradientStop { id: gradientStop; position: 0.0; color: palette.light }
+		GradientStop { position: 1.0; color: palette.button }
+	}
+
+	SystemPalette { id: palette }
+
+	MouseArea {
+		id: mouseArea
+		anchors.fill: parent
+		onClicked: { container.clicked() }
+	}
+
+	Text {
+		id: label
+		anchors.centerIn: parent
+	}
+
+	states: State {
+		name: "pressed"
+		when: mouseArea.pressed
+		PropertyChanges { target: gradientStop; color: palette.dark }
+	}
+}
+
diff --git a/qt-mobile/mobile-resources.qrc b/qt-mobile/mobile-resources.qrc
index 59d301c..2cee851 100644
--- a/qt-mobile/mobile-resources.qrc
+++ b/qt-mobile/mobile-resources.qrc
@@ -1,5 +1,6 @@
 <RCC>
     <qresource prefix="/qml">
         <file>main.qml</file>
+        <file>TextButton.qml</file>
     </qresource>
 </RCC>
-- 
2.4.4

From 59a00e55ee5a30ad2d9fdd6edf8e2481743e366d Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Wed, 10 Jun 2015 21:38:14 +0300
Subject: [PATCH 15/22] Add dive notes to the divelistmodel

Add the dive notes field into the DiveListModel class.

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-models/divelistmodel.cpp | 14 ++++++++++++++
 qt-models/divelistmodel.h   |  7 ++++++-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/qt-models/divelistmodel.cpp b/qt-models/divelistmodel.cpp
index 1786c85..c1862b8 100644
--- a/qt-models/divelistmodel.cpp
+++ b/qt-models/divelistmodel.cpp
@@ -24,6 +24,7 @@ Dive::Dive(dive *d)
 	setCylinder(QString(d->cylinder[0].type.description));
 	setSac(QString::number(d->sac));
 	setLocation(get_dive_location(d));
+	setNotes(d->notes);
 }
 
 QString Dive::date() const
@@ -143,6 +144,16 @@ void Dive::setDiveNumber(const QString &diveNumber)
 {
 	m_diveNumber = diveNumber;
 }
+QString Dive::notes() const
+{
+	return m_notes;
+}
+
+void Dive::setNotes(const QString &notes)
+{
+	m_notes = notes;
+}
+
 
 
 DiveListModel *DiveListModel::m_instance = NULL;
@@ -195,6 +206,8 @@ QVariant DiveListModel::data(const QModelIndex &index, int role) const
 		return dive.sac();
 	else if (role == DiveLocationRole)
 		return dive.location();
+	else if (role == DiveNotesRole)
+		return dive.notes();
 	return QVariant();
 
 
@@ -215,6 +228,7 @@ QHash<int, QByteArray> DiveListModel::roleNames() const
 	roles[DiveGasRole] = "gas";
 	roles[DiveSacRole] = "sac";
 	roles[DiveLocationRole] = "location";
+	roles[DiveNotesRole] = "notes";
 
 	return roles;
 }
diff --git a/qt-models/divelistmodel.h b/qt-models/divelistmodel.h
index 96f1691..307008c 100644
--- a/qt-models/divelistmodel.h
+++ b/qt-models/divelistmodel.h
@@ -47,6 +47,9 @@ public:
 	QString diveNumber() const;
 	void setDiveNumber(const QString &diveNumber);
 
+	QString notes() const;
+	void setNotes(const QString &notes);
+
 private:
 	QString m_diveNumber;
 	QString m_date;
@@ -60,6 +63,7 @@ private:
 	QString m_gas;
 	QString m_sac;
 	QString m_location;
+	QString m_notes;
 
 
 	dive *m_thisDive;
@@ -82,7 +86,8 @@ public:
 		DiveCylinderRole,
 		DiveGasRole,
 		DiveSacRole,
-		DiveLocationRole
+		DiveLocationRole,
+		DiveNotesRole
 	};
 
 	static DiveListModel *instance();
-- 
2.4.4

From 282f69b178a34901d17e4896f64334b3945cde06 Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Wed, 10 Jun 2015 18:49:55 +0300
Subject: [PATCH 14/22] Group dives by location

Group dives on the QML page by location.

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-mobile/main.qml | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/qt-mobile/main.qml b/qt-mobile/main.qml
index 914f51b..ee36b9c 100644
--- a/qt-mobile/main.qml
+++ b/qt-mobile/main.qml
@@ -48,9 +48,9 @@ ApplicationWindow {
 				id: wrapper
 				width: parent.width; height: 55
 				Column {
-					Text { text: '#:' + diveNumber + "(" + location + ")"  }
-					Text { text: date }
-					Text { text: duration + " " + depth }
+					Text { text: '#:' + diveNumber + "(" + date + ")"  }
+					Text { text: 'Duration: ' + duration }
+					Text { text: 'Depth: ' + depth }
 				}
 				MouseArea { anchors.fill: parent; onClicked: diveListView.currentIndex = index }
 
@@ -76,6 +76,20 @@ ApplicationWindow {
 			}
 		}
 
+		Component {
+			id: tripHeading
+			Rectangle {
+				width: container.width
+				height: childrenRect.height
+				color: "lightgreen"
+
+				Text {
+					text: section
+					font.bold: true
+				}
+			}
+		}
+
 		ListView {
 			id: diveListView
 			width: parent.width; height: parent.height
@@ -85,6 +99,10 @@ ApplicationWindow {
 			focus: true
 			highlight: highlightBar
 			highlightFollowsCurrentItem: false
+
+			section.property: "location"
+			section.criteria: ViewSection.FullString
+			section.delegate: tripHeading
 		}
 	}
 }
-- 
2.4.4

From 8ff67dffd43481ddfbb56ea64c88149814d71afe Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Wed, 10 Jun 2015 18:19:19 +0300
Subject: [PATCH 13/22] Better theme for dive list view

Set a rounded blue rectangle on the selected item.

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-mobile/main.qml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/qt-mobile/main.qml b/qt-mobile/main.qml
index 66a81e3..914f51b 100644
--- a/qt-mobile/main.qml
+++ b/qt-mobile/main.qml
@@ -69,7 +69,8 @@ ApplicationWindow {
 			id: highlightBar
 			Rectangle {
 				width: parent.width; height: 50
-				color: "#FFFF88"
+				color: "lightsteelblue"
+				radius: 5
 				y: diveListView.currentItem.y;
 				Behavior on y {  SpringAnimation  { spring: 2; damping: 0.1 } }
 			}
-- 
2.4.4

From a3dd4606a01d411c5c3e742015d5c9e92cd393ae Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Tue, 9 Jun 2015 22:20:44 +0300
Subject: [PATCH 12/22] Add DiveListModel

This model will be used to show the dives in QML. This commit adds
the model, and the means to link it to QML.

Signed-off-by: Grace Karanja <[email protected]>
---
 CMakeLists.txt              |   2 +-
 qt-gui.cpp                  |   5 +
 qt-mobile/main.qml          |  49 ++++++++++
 qt-mobile/qmlmanager.cpp    |  15 ++-
 qt-models/divelistmodel.cpp | 225 ++++++++++++++++++++++++++++++++++++++++++++
 qt-models/divelistmodel.h   | 100 ++++++++++++++++++++
 6 files changed, 392 insertions(+), 4 deletions(-)
 create mode 100644 qt-models/divelistmodel.cpp
 create mode 100644 qt-models/divelistmodel.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index a326a5a..79196b5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -420,7 +420,7 @@ endif()
 
 # create the executables
 if(SUBSURFACE_MOBILE)
-	set(MOBILE_SRC qt-mobile/qmlmanager.cpp)
+	set(MOBILE_SRC qt-mobile/qmlmanager.cpp qt-models/divelistmodel.cpp)
 	add_definitions(-DSUBSURFACE_MOBILE)
 	qt5_add_resources(MOBILE_RESOURCES qt-mobile/mobile-resources.qrc)
 	add_executable(subsurface-mobile ${MOBILE_SRC} ${SUBSURFACE_PKG} ${SUBSURFACE_APP} ${SUBSURFACE_RESOURCES} ${MOBILE_RESOURCES})
diff --git a/qt-gui.cpp b/qt-gui.cpp
index d415910..518f271 100644
--- a/qt-gui.cpp
+++ b/qt-gui.cpp
@@ -16,7 +16,9 @@
 #ifdef SUBSURFACE_MOBILE
 	#include <QQuickWindow>
 	#include <QQmlApplicationEngine>
+	#include <QQmlContext>
 	#include "qt-mobile/qmlmanager.h"
+	#include "qt-models/divelistmodel.h"
 #endif
 
 static MainWindow *window = NULL;
@@ -38,6 +40,9 @@ void run_ui()
 	window->hide();
 	qmlRegisterType<QMLManager>("com.subsurface.mobile", 1, 0, "QMLManager");
 	QQmlApplicationEngine engine;
+	DiveListModel diveListModel;
+	QQmlContext *ctxt = engine.rootContext();
+	ctxt->setContextProperty("diveModel", &diveListModel);
 	engine.load(QUrl(QStringLiteral("qrc:///qml/main.qml")));
 	QObject *mainWindow = engine.rootObjects().value(0);
 	QQuickWindow *qml_window = qobject_cast<QQuickWindow *>(mainWindow);
diff --git a/qt-mobile/main.qml b/qt-mobile/main.qml
index 99298bb..66a81e3 100644
--- a/qt-mobile/main.qml
+++ b/qt-mobile/main.qml
@@ -37,4 +37,53 @@ ApplicationWindow {
 			}
 		}
 	}
+
+	Rectangle {
+		width: parent.width; height: parent.height
+		anchors.fill: parent
+
+		Component {
+			id: diveDelegate
+			Item {
+				id: wrapper
+				width: parent.width; height: 55
+				Column {
+					Text { text: '#:' + diveNumber + "(" + location + ")"  }
+					Text { text: date }
+					Text { text: duration + " " + depth }
+				}
+				MouseArea { anchors.fill: parent; onClicked: diveListView.currentIndex = index }
+
+				states: State {
+					name: "Current"
+					when: wrapper.ListView.isCurrentItem
+					PropertyChanges { target: wrapper; x:20 }
+				}
+				transitions: Transition {
+					NumberAnimation { properties: "x"; duration: 200  }
+				}
+			}
+		}
+
+		Component {
+			id: highlightBar
+			Rectangle {
+				width: parent.width; height: 50
+				color: "#FFFF88"
+				y: diveListView.currentItem.y;
+				Behavior on y {  SpringAnimation  { spring: 2; damping: 0.1 } }
+			}
+		}
+
+		ListView {
+			id: diveListView
+			width: parent.width; height: parent.height
+			anchors.fill: parent
+			model: diveModel
+			delegate: diveDelegate
+			focus: true
+			highlight: highlightBar
+			highlightFollowsCurrentItem: false
+		}
+	}
 }
diff --git a/qt-mobile/qmlmanager.cpp b/qt-mobile/qmlmanager.cpp
index 6a770b2..0f8ccbe 100644
--- a/qt-mobile/qmlmanager.cpp
+++ b/qt-mobile/qmlmanager.cpp
@@ -1,15 +1,15 @@
 #include "qmlmanager.h"
 #include <QUrl>
 
+#include "../qt-models/divelistmodel.h"
+
 QMLManager::QMLManager()
 {
-
 }
 
 
 QMLManager::~QMLManager()
 {
-
 }
 
 QString QMLManager::filename()
@@ -20,12 +20,21 @@ QString QMLManager::filename()
 void QMLManager::setFilename(const QString &f)
 {
 	m_fileName = f;
-	emit filenameChanged();
 	loadFile();
+	emit filenameChanged();
 }
 
 void QMLManager::loadFile()
 {
 	QUrl url(m_fileName);
 	QString strippedFileName = url.toLocalFile();
+
+	parse_file(strippedFileName.toUtf8().data());
+
+	int i;
+	struct dive *d;
+
+	for_each_dive(i, d) {
+		DiveListModel::instance()->addDive(d);
+	}
 }
diff --git a/qt-models/divelistmodel.cpp b/qt-models/divelistmodel.cpp
new file mode 100644
index 0000000..1786c85
--- /dev/null
+++ b/qt-models/divelistmodel.cpp
@@ -0,0 +1,225 @@
+#include "divelistmodel.h"
+#include "helpers.h"
+
+Dive::Dive(dive *d)
+{
+	m_thisDive = d;
+	setDiveNumber(QString::number(d->number));
+	setDate(get_dive_date_string(d->when));
+	setDepth(get_depth_string(d->maxdepth));
+	setDuration(get_dive_duration_string(d->duration.seconds, "h:","min"));
+
+	if (!d->watertemp.mkelvin)
+		m_depth = "";
+
+	if (get_units()->temperature == units::CELSIUS)
+		m_depth = QString::number(mkelvin_to_C(d->watertemp.mkelvin), 'f', 1);
+	else
+		m_depth = QString::number(mkelvin_to_F(d->watertemp.mkelvin), 'f', 1);
+
+	weight_t tw = { total_weight(d) };
+	setWeight(weight_string(tw.grams));
+
+	setSuit(QString(d->suit));
+	setCylinder(QString(d->cylinder[0].type.description));
+	setSac(QString::number(d->sac));
+	setLocation(get_dive_location(d));
+}
+
+QString Dive::date() const
+{
+	return m_date;
+}
+
+void Dive::setDate(const QString &date)
+{
+	m_date = date;
+}
+QString Dive::location() const
+{
+	return m_location;
+}
+
+void Dive::setLocation(const QString &location)
+{
+	m_location = location;
+}
+QString Dive::sac() const
+{
+	return m_sac;
+}
+
+void Dive::setSac(const QString &sac)
+{
+	m_sac = sac;
+}
+QString Dive::gas() const
+{
+	return m_gas;
+}
+
+void Dive::setGas(const QString &gas)
+{
+	m_gas = gas;
+}
+QString Dive::cylinder() const
+{
+	return m_cylinder;
+}
+
+void Dive::setCylinder(const QString &cylinder)
+{
+	m_cylinder = cylinder;
+}
+QString Dive::suit() const
+{
+	return m_suit;
+}
+
+void Dive::setSuit(const QString &suit)
+{
+	m_suit = suit;
+}
+QString Dive::weight() const
+{
+	return m_weight;
+}
+
+void Dive::setWeight(const QString &weight)
+{
+	m_weight = weight;
+}
+QString Dive::temp() const
+{
+	return m_temp;
+}
+
+void Dive::setTemp(const QString &temp)
+{
+	m_temp = temp;
+}
+QString Dive::duration() const
+{
+	return m_duration;
+}
+
+void Dive::setDuration(const QString &duration)
+{
+	m_duration = duration;
+}
+QString Dive::depth() const
+{
+	return m_depth;
+}
+
+void Dive::setDepth(const QString &depth)
+{
+	m_depth = depth;
+}
+QString Dive::rating() const
+{
+	return m_rating;
+}
+
+void Dive::setRating(const QString &rating)
+{
+	m_rating = rating;
+}
+dive *Dive::thisDive() const
+{
+	return m_thisDive;
+}
+
+void Dive::setThisDive(dive *thisDive)
+{
+	m_thisDive = thisDive;
+}
+QString Dive::diveNumber() const
+{
+	return m_diveNumber;
+}
+
+void Dive::setDiveNumber(const QString &diveNumber)
+{
+	m_diveNumber = diveNumber;
+}
+
+
+DiveListModel *DiveListModel::m_instance = NULL;
+
+DiveListModel::DiveListModel(QObject *parent) : QAbstractListModel(parent)
+{
+	m_instance = this;
+}
+
+void DiveListModel::addDive(dive *d)
+{
+	beginInsertRows(QModelIndex(), rowCount(), rowCount());
+	m_dives.append(Dive(d));
+	endInsertRows();
+}
+
+int DiveListModel::rowCount(const QModelIndex &) const
+{
+	return m_dives.count();
+}
+
+QVariant DiveListModel::data(const QModelIndex &index, int role) const
+{
+	if(index.row() < 0 || index.row() > m_dives.count())
+		return QVariant();
+
+	const Dive &dive = m_dives[index.row()];
+
+	if (role == DiveNumberRole)
+		return dive.diveNumber();
+	else if (role == DiveDateRole)
+		return dive.date();
+	else if (role == DiveRatingRole)
+		return dive.rating();
+	else if (role == DiveDepthRole)
+		return dive.depth();
+	else if (role == DiveDurationRole)
+		return dive.duration();
+	else if (role == DiveTemperatureRole)
+		return dive.temp();
+	else if (role == DiveWeightRole)
+		return dive.weight();
+	else if (role == DiveSuitRole)
+		return dive.suit();
+	else if (role == DiveCylinderRole)
+		return dive.cylinder();
+	else if (role == DiveGasRole)
+		return dive.gas();
+	else if (role == DiveSacRole)
+		return dive.sac();
+	else if (role == DiveLocationRole)
+		return dive.location();
+	return QVariant();
+
+
+}
+
+QHash<int, QByteArray> DiveListModel::roleNames() const
+{
+	QHash<int, QByteArray> roles;
+	roles[DiveNumberRole] = "diveNumber";
+	roles[DiveDateRole] = "date";
+	roles[DiveRatingRole] = "rating";
+	roles[DiveDepthRole] = "depth";
+	roles[DiveDurationRole] = "duration";
+	roles[DiveTemperatureRole] = "temp";
+	roles[DiveWeightRole] = "weight";
+	roles[DiveSuitRole] = "suit";
+	roles[DiveCylinderRole] = "cylinder";
+	roles[DiveGasRole] = "gas";
+	roles[DiveSacRole] = "sac";
+	roles[DiveLocationRole] = "location";
+
+	return roles;
+}
+
+DiveListModel *DiveListModel::instance()
+{
+	return m_instance;
+}
diff --git a/qt-models/divelistmodel.h b/qt-models/divelistmodel.h
new file mode 100644
index 0000000..96f1691
--- /dev/null
+++ b/qt-models/divelistmodel.h
@@ -0,0 +1,100 @@
+#ifndef DIVELISTMODEL_H
+#define DIVELISTMODEL_H
+
+#include <QAbstractListModel>
+#include "dive.h"
+
+class Dive {
+public:
+	Dive(dive* d);
+
+	QString date() const;
+	void setDate(const QString &date);
+
+	QString location() const;
+	void setLocation(const QString &location);
+
+	QString sac() const;
+	void setSac(const QString &sac);
+
+	QString gas() const;
+	void setGas(const QString &gas);
+
+	QString cylinder() const;
+	void setCylinder(const QString &cylinder);
+
+	QString suit() const;
+	void setSuit(const QString &suit);
+
+	QString weight() const;
+	void setWeight(const QString &weight);
+
+	QString temp() const;
+	void setTemp(const QString &temp);
+
+	QString duration() const;
+	void setDuration(const QString &duration);
+
+	QString depth() const;
+	void setDepth(const QString &depth);
+
+	QString rating() const;
+	void setRating(const QString &rating);
+
+	dive *thisDive() const;
+	void setThisDive(dive *thisDive);
+
+	QString diveNumber() const;
+	void setDiveNumber(const QString &diveNumber);
+
+private:
+	QString m_diveNumber;
+	QString m_date;
+	QString m_rating;
+	QString m_depth;
+	QString m_duration;
+	QString m_temp;
+	QString m_weight;
+	QString m_suit;
+	QString m_cylinder;
+	QString m_gas;
+	QString m_sac;
+	QString m_location;
+
+
+	dive *m_thisDive;
+};
+
+class DiveListModel : public QAbstractListModel
+{
+	Q_OBJECT
+public:
+
+	enum DiveListRoles {
+		DiveNumberRole = Qt::UserRole + 1,
+		DiveDateRole,
+		DiveRatingRole,
+		DiveDepthRole,
+		DiveDurationRole,
+		DiveTemperatureRole,
+		DiveWeightRole,
+		DiveSuitRole,
+		DiveCylinderRole,
+		DiveGasRole,
+		DiveSacRole,
+		DiveLocationRole
+	};
+
+	static DiveListModel *instance();
+	DiveListModel(QObject *parent = 0);
+	void addDive(dive *d);
+	int rowCount(const QModelIndex &parent = QModelIndex()) const;
+	QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+	QHash<int, QByteArray> roleNames() const;
+
+private:
+	QList<Dive> m_dives;
+	static DiveListModel *m_instance;
+};
+
+#endif // DIVELISTMODEL_H
-- 
2.4.4

From 9c47d31d246b4bb55b129396f219a90811e3f521 Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Fri, 5 Jun 2015 07:46:24 +0300
Subject: [PATCH 11/22] Only include Qt Quick when on mobile

In qt-gui.cpp, move the Qt Quick includes so that they will only
be used when on cmake SUBSURFACE_MOBILE is True.

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-gui.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/qt-gui.cpp b/qt-gui.cpp
index 85367c2..d415910 100644
--- a/qt-gui.cpp
+++ b/qt-gui.cpp
@@ -10,12 +10,12 @@
 #include <QNetworkProxy>
 #include <QLibraryInfo>
 
-#include <QQuickWindow>
-#include <QQmlApplicationEngine>
 
 #include "qt-gui.h"
 
 #ifdef SUBSURFACE_MOBILE
+	#include <QQuickWindow>
+	#include <QQmlApplicationEngine>
 	#include "qt-mobile/qmlmanager.h"
 #endif
 
-- 
2.4.4

From 56e7bbbc5a63abaa22468a257b231129369b5d64 Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Thu, 4 Jun 2015 13:36:36 +0300
Subject: [PATCH 10/22] Link QMLManager to the main.qml file

Add a link between the C++ and QML parts of the app using the
qmlRegisterType function.

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-gui.cpp               | 5 +++++
 qt-mobile/main.qml       | 9 +++++++++
 qt-mobile/qmlmanager.cpp | 2 +-
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/qt-gui.cpp b/qt-gui.cpp
index 6bc2e1e..85367c2 100644
--- a/qt-gui.cpp
+++ b/qt-gui.cpp
@@ -15,6 +15,10 @@
 
 #include "qt-gui.h"
 
+#ifdef SUBSURFACE_MOBILE
+	#include "qt-mobile/qmlmanager.h"
+#endif
+
 static MainWindow *window = NULL;
 
 void init_ui()
@@ -32,6 +36,7 @@ void run_ui()
 {
 #ifdef SUBSURFACE_MOBILE
 	window->hide();
+	qmlRegisterType<QMLManager>("com.subsurface.mobile", 1, 0, "QMLManager");
 	QQmlApplicationEngine engine;
 	engine.load(QUrl(QStringLiteral("qrc:///qml/main.qml")));
 	QObject *mainWindow = engine.rootObjects().value(0);
diff --git a/qt-mobile/main.qml b/qt-mobile/main.qml
index a98fb14..99298bb 100644
--- a/qt-mobile/main.qml
+++ b/qt-mobile/main.qml
@@ -2,6 +2,7 @@ import QtQuick 2.3
 import QtQuick.Controls 1.2
 import QtQuick.Window 2.2
 import QtQuick.Dialogs 1.2
+import com.subsurface.mobile 1.0
 
 ApplicationWindow {
 	title: qsTr("Subsurface")
@@ -12,6 +13,14 @@ ApplicationWindow {
 		id: fileOpen
 		selectExisting: true
 		selectMultiple: true
+
+		onAccepted: {
+			manager.setFilename(fileUrl)
+		}
+	}
+
+	QMLManager {
+		id: manager
 	}
 
 	menuBar: MenuBar {
diff --git a/qt-mobile/qmlmanager.cpp b/qt-mobile/qmlmanager.cpp
index 2de94e8..6a770b2 100644
--- a/qt-mobile/qmlmanager.cpp
+++ b/qt-mobile/qmlmanager.cpp
@@ -1,5 +1,5 @@
 #include "qmlmanager.h"
-
+#include <QUrl>
 
 QMLManager::QMLManager()
 {
-- 
2.4.4

From 7362c2b18363a713c850834c0f86775a81e6499d Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Thu, 4 Jun 2015 13:31:03 +0300
Subject: [PATCH 09/22] Add QMLManager to the cmake

Build the QMLManager class when compiling for mobile.

Signed-off-by: Grace Karanja <[email protected]>
---
 CMakeLists.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6b75219..a326a5a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -420,9 +420,10 @@ endif()
 
 # create the executables
 if(SUBSURFACE_MOBILE)
+	set(MOBILE_SRC qt-mobile/qmlmanager.cpp)
 	add_definitions(-DSUBSURFACE_MOBILE)
 	qt5_add_resources(MOBILE_RESOURCES qt-mobile/mobile-resources.qrc)
-	add_executable(subsurface-mobile ${SUBSURFACE_PKG} ${SUBSURFACE_APP} ${SUBSURFACE_RESOURCES} ${MOBILE_RESOURCES})
+	add_executable(subsurface-mobile ${MOBILE_SRC} ${SUBSURFACE_PKG} ${SUBSURFACE_APP} ${SUBSURFACE_RESOURCES} ${MOBILE_RESOURCES})
 	target_link_libraries(
 		subsurface-mobile
 		subsurface_generated_ui
-- 
2.4.4

From 1e40a1e887c203267e623935f110e4b619459bcd Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Thu, 4 Jun 2015 13:29:50 +0300
Subject: [PATCH 08/22] Add QMLManager class

Add a QMLManager class. This class will be used as a link between
the C++ and QML aspects of the mobile application.

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-mobile/qmlmanager.cpp | 31 +++++++++++++++++++++++++++++++
 qt-mobile/qmlmanager.h   | 31 +++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+)
 create mode 100644 qt-mobile/qmlmanager.cpp
 create mode 100644 qt-mobile/qmlmanager.h

diff --git a/qt-mobile/qmlmanager.cpp b/qt-mobile/qmlmanager.cpp
new file mode 100644
index 0000000..2de94e8
--- /dev/null
+++ b/qt-mobile/qmlmanager.cpp
@@ -0,0 +1,31 @@
+#include "qmlmanager.h"
+
+
+QMLManager::QMLManager()
+{
+
+}
+
+
+QMLManager::~QMLManager()
+{
+
+}
+
+QString QMLManager::filename()
+{
+	return m_fileName;
+}
+
+void QMLManager::setFilename(const QString &f)
+{
+	m_fileName = f;
+	emit filenameChanged();
+	loadFile();
+}
+
+void QMLManager::loadFile()
+{
+	QUrl url(m_fileName);
+	QString strippedFileName = url.toLocalFile();
+}
diff --git a/qt-mobile/qmlmanager.h b/qt-mobile/qmlmanager.h
new file mode 100644
index 0000000..e74db0b
--- /dev/null
+++ b/qt-mobile/qmlmanager.h
@@ -0,0 +1,31 @@
+#ifndef QMLMANAGER_H
+#define QMLMANAGER_H
+
+#include <QObject>
+#include <QString>
+
+class QMLManager : public QObject
+{
+	Q_OBJECT
+	Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged)
+public:
+	QMLManager();
+	~QMLManager();
+
+	QString filename();
+
+	void getFile();
+
+
+public slots:
+	void setFilename(const QString &f);
+
+private:
+	QString m_fileName;
+	void loadFile();
+
+signals:
+	void filenameChanged();
+};
+
+#endif
-- 
2.4.4

From 9e2bfbc312828a9c956a68fda508f3c709e2fff8 Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Thu, 4 Jun 2015 11:27:38 +0300
Subject: [PATCH 07/22] Add FileOpen dialog to QML

Add a dialog to select dive files in the QML interface, and also
add a menu entry to open the dialog.

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-mobile/main.qml | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/qt-mobile/main.qml b/qt-mobile/main.qml
index 52cfd98..a98fb14 100644
--- a/qt-mobile/main.qml
+++ b/qt-mobile/main.qml
@@ -1,15 +1,28 @@
 import QtQuick 2.3
 import QtQuick.Controls 1.2
 import QtQuick.Window 2.2
+import QtQuick.Dialogs 1.2
 
 ApplicationWindow {
 	title: qsTr("Subsurface")
 	width: 500;
 	height: 700
+
+	FileDialog {
+		id: fileOpen
+		selectExisting: true
+		selectMultiple: true
+	}
+
 	menuBar: MenuBar {
 		Menu {
 			title: qsTr("File")
 			MenuItem {
+				text: qsTr("Open")
+				onTriggered: fileOpen.open()
+			}
+
+			MenuItem {
 				text: qsTr("Exit")
 				onTriggered: Qt.quit();
 			}
-- 
2.4.4

From 2993f1dfcb106bf5ffe529cfe0eb09d20e8e138e Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Wed, 3 Jun 2015 17:19:01 +0300
Subject: [PATCH 06/22] Hide MainWindow when running under mobile

When compiling the mobile version, hide the Qt MainWindow.

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-gui.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/qt-gui.cpp b/qt-gui.cpp
index fdcae2c..6bc2e1e 100644
--- a/qt-gui.cpp
+++ b/qt-gui.cpp
@@ -31,6 +31,7 @@ void init_ui()
 void run_ui()
 {
 #ifdef SUBSURFACE_MOBILE
+	window->hide();
 	QQmlApplicationEngine engine;
 	engine.load(QUrl(QStringLiteral("qrc:///qml/main.qml")));
 	QObject *mainWindow = engine.rootObjects().value(0);
-- 
2.4.4

From 1a7c61dfe0f33579612319e1c38e6d9b4beca83c Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Wed, 27 May 2015 15:36:39 +0300
Subject: [PATCH 05/22] Load main.qml on startup for mobile builds

When cmake is run with -DSUBSURFACE_MOBILE=True, the initial window
will be main.qml, instead of the MainWindow used when cmake is run
with -DSUBSURFACE_MOBILE=False

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-gui.cpp | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/qt-gui.cpp b/qt-gui.cpp
index 713fd53..fdcae2c 100644
--- a/qt-gui.cpp
+++ b/qt-gui.cpp
@@ -9,7 +9,9 @@
 #include <QDesktopWidget>
 #include <QNetworkProxy>
 #include <QLibraryInfo>
-#include <QTextCodec>
+
+#include <QQuickWindow>
+#include <QQmlApplicationEngine>
 
 #include "qt-gui.h"
 
@@ -28,7 +30,15 @@ void init_ui()
 
 void run_ui()
 {
+#ifdef SUBSURFACE_MOBILE
+	QQmlApplicationEngine engine;
+	engine.load(QUrl(QStringLiteral("qrc:///qml/main.qml")));
+	QObject *mainWindow = engine.rootObjects().value(0);
+	QQuickWindow *qml_window = qobject_cast<QQuickWindow *>(mainWindow);
+	qml_window->show();
+#else
 	window->show();
+#endif
 	qApp->exec();
 }
 
-- 
2.4.4

From 00071313ad62e32f5ba0c4b8c4eb45a94e8e3e7a Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Wed, 27 May 2015 15:33:23 +0300
Subject: [PATCH 04/22] Add subsurface-mobile app to cmake

Add a subsurface-mobile entry to the CMakeLists.txt file. When cmake
is run with -DSUBSURFACE_MOBILE=True, the compiled app will be named
subsurface-mobile, and the initial page (main.qml) will automatically
be loaded.

This will
ensure that the mobile app will be linked to QtQuick.

Signed-off-by: Grace Karanja <[email protected]>
---
 CMakeLists.txt | 49 +++++++++++++++++++++++++++++++++++++------------
 1 file changed, 37 insertions(+), 12 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d1b59c8..6b75219 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -132,8 +132,14 @@ if(NOT (insource OR insourcedir))
 endif()
 
 # configure Qt.
-find_package(Qt5 REQUIRED COMPONENTS Core Concurrent Widgets Network WebKitWidgets PrintSupport Svg Test LinguistTools)
+if(SUBSURFACE_MOBILE)
+	set(QT_QUICK Quick)
+endif()
+find_package(Qt5 REQUIRED COMPONENTS Core Concurrent Widgets Network WebKitWidgets PrintSupport Svg Test LinguistTools ${QT_QUICK})
 set(QT_LIBRARIES Qt5::Core Qt5::Concurrent Qt5::Widgets Qt5::Network Qt5::WebKitWidgets Qt5::PrintSupport Qt5::Svg)
+if(SUBSURFACE_MOBILE)
+	set(QT_LIBRARIES ${QT_LIBRARIES} Qt5::Quick)
+endif()
 set(QT_TEST_LIBRARIES ${QT_LIBRARIES} Qt5::Test)
 
 # Generate the ssrf-config.h every 'make'
@@ -413,17 +419,32 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
 endif()
 
 # create the executables
-add_executable(${SUBSURFACE_TARGET} MACOSX_BUNDLE WIN32 ${SUBSURFACE_PKG} ${SUBSURFACE_APP} ${SUBSURFACE_RESOURCES})
-target_link_libraries(
-	${SUBSURFACE_TARGET}
-	subsurface_generated_ui
-	subsurface_interface
-	subsurface_profile
-	subsurface_statistics
-	subsurface_models
-	subsurface_corelib
-	${SUBSURFACE_LINK_LIBRARIES}
+if(SUBSURFACE_MOBILE)
+	add_definitions(-DSUBSURFACE_MOBILE)
+	qt5_add_resources(MOBILE_RESOURCES qt-mobile/mobile-resources.qrc)
+	add_executable(subsurface-mobile ${SUBSURFACE_PKG} ${SUBSURFACE_APP} ${SUBSURFACE_RESOURCES} ${MOBILE_RESOURCES})
+	target_link_libraries(
+		subsurface-mobile
+		subsurface_generated_ui
+		subsurface_interface
+		subsurface_profile
+		subsurface_statistics
+		subsurface_models
+		subsurface_corelib
+		${SUBSURFACE_LINK_LIBRARIES})
+else()
+	add_executable(${SUBSURFACE_TARGET} MACOSX_BUNDLE WIN32 ${SUBSURFACE_PKG} ${SUBSURFACE_APP} ${SUBSURFACE_RESOURCES})
+	target_link_libraries(
+		${SUBSURFACE_TARGET}
+		subsurface_generated_ui
+		subsurface_interface
+		subsurface_profile
+		subsurface_statistics
+		subsurface_models
+		subsurface_corelib
+		${SUBSURFACE_LINK_LIBRARIES}
 )
+endif()
 
 add_dependencies(subsurface_statistics subsurface_generated_ui)
 add_dependencies(subsurface_profile subsurface_generated_ui)
@@ -634,7 +655,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
 	install(DIRECTORY theme DESTINATION share/subsurface)
 	install(DIRECTORY printing_templates DESTINATION share/subsurface)
 	install(FILES ${TRANSLATIONS} DESTINATION share/subsurface/translations)
-	install(TARGETS ${SUBSURFACE_TARGET} DESTINATION bin)
+	if(SUBSURFACE_MOBILE)
+		install(TARGETS subsurface-mobile DESTINATION bin)
+	else()
+		install(TARGETS ${SUBSURFACE_TARGET} DESTINATION bin)
+	endif()
 	if(DEFINED LIBMARBLEDEVEL)
 		install(
 			CODE "file(GLOB SSRFMARBLE_SHLIBS \"${LIBMARBLEDEVEL}/lib/libssrfmarblewidget.so*\")"
-- 
2.4.4

From 670db136e266772db4b3a4ff040ec00eae930ab2 Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Wed, 27 May 2015 13:34:55 +0300
Subject: [PATCH 03/22] Add a menu to main.qml

Add a menu with an Exit submenu in the main.qml file. This closes
the application when clicked.

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-mobile/main.qml | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/qt-mobile/main.qml b/qt-mobile/main.qml
index e69de29..52cfd98 100644
--- a/qt-mobile/main.qml
+++ b/qt-mobile/main.qml
@@ -0,0 +1,18 @@
+import QtQuick 2.3
+import QtQuick.Controls 1.2
+import QtQuick.Window 2.2
+
+ApplicationWindow {
+	title: qsTr("Subsurface")
+	width: 500;
+	height: 700
+	menuBar: MenuBar {
+		Menu {
+			title: qsTr("File")
+			MenuItem {
+				text: qsTr("Exit")
+				onTriggered: Qt.quit();
+			}
+		}
+	}
+}
-- 
2.4.4

From 5caec56b493d372812ad78b5b7c879f197c43e2b Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Wed, 27 May 2015 13:07:50 +0300
Subject: [PATCH 02/22] Add resource file to hold QML files

Add a resource file to hold any QML files that will be used in the
mobile port.

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-mobile/mobile-resources.qrc | 5 +++++
 1 file changed, 5 insertions(+)
 create mode 100644 qt-mobile/mobile-resources.qrc

diff --git a/qt-mobile/mobile-resources.qrc b/qt-mobile/mobile-resources.qrc
new file mode 100644
index 0000000..59d301c
--- /dev/null
+++ b/qt-mobile/mobile-resources.qrc
@@ -0,0 +1,5 @@
+<RCC>
+    <qresource prefix="/qml">
+        <file>main.qml</file>
+    </qresource>
+</RCC>
-- 
2.4.4

From bdd916077b017e4d486cb4ac30e28423f20a0d39 Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Thu, 18 Jun 2015 10:45:26 +0300
Subject: [PATCH 22/22] Rename dive class to avoid conflict

Rename the Dive class in divelistmodel.h to a void a conflict with
the Dive class in templatelayout.h

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-models/divelistmodel.cpp | 96 ++++++++++++++++++++-------------------------
 qt-models/divelistmodel.h   |  6 +--
 2 files changed, 45 insertions(+), 57 deletions(-)

diff --git a/qt-models/divelistmodel.cpp b/qt-models/divelistmodel.cpp
index add5af5..dfc175a 100644
--- a/qt-models/divelistmodel.cpp
+++ b/qt-models/divelistmodel.cpp
@@ -1,7 +1,7 @@
 #include "divelistmodel.h"
 #include "helpers.h"
 
-Dive::Dive(dive *d)
+MobileDive::MobileDive(dive *d)
 {
 	m_thisDive = d;
 	setDiveNumber(QString::number(d->number));
@@ -31,185 +31,173 @@ Dive::Dive(dive *d)
 	setDivemaster(d->divemaster);
 }
 
-QString Dive::date() const
+QString MobileDive::date() const
 {
 	return m_date;
 }
 
-void Dive::setDate(const QString &date)
+void MobileDive::setDate(const QString &date)
 {
 	m_date = date;
 }
-QString Dive::location() const
+QString MobileDive::location() const
 {
 	return m_location;
 }
 
-void Dive::setLocation(const QString &location)
+void MobileDive::setLocation(const QString &location)
 {
 	m_location = location;
 }
-QString Dive::sac() const
+QString MobileDive::sac() const
 {
 	return m_sac;
 }
 
-void Dive::setSac(const QString &sac)
+void MobileDive::setSac(const QString &sac)
 {
 	m_sac = sac;
 }
-QString Dive::gas() const
+QString MobileDive::gas() const
 {
 	return m_gas;
 }
 
-void Dive::setGas(const QString &gas)
+void MobileDive::setGas(const QString &gas)
 {
 	m_gas = gas;
 }
-QString Dive::cylinder() const
+QString MobileDive::cylinder() const
 {
 	return m_cylinder;
 }
 
-void Dive::setCylinder(const QString &cylinder)
+void MobileDive::setCylinder(const QString &cylinder)
 {
 	m_cylinder = cylinder;
 }
-QString Dive::suit() const
+QString MobileDive::suit() const
 {
 	return m_suit;
 }
 
-void Dive::setSuit(const QString &suit)
+void MobileDive::setSuit(const QString &suit)
 {
 	m_suit = suit;
 }
-QString Dive::weight() const
+QString MobileDive::weight() const
 {
 	return m_weight;
 }
 
-void Dive::setWeight(const QString &weight)
+void MobileDive::setWeight(const QString &weight)
 {
 	m_weight = weight;
 }
-QString Dive::airtemp() const
+QString MobileDive::airtemp() const
 {
 	return m_airtemp;
 }
 
-void Dive::setAirTemp(const QString &airtemp)
+void MobileDive::setAirTemp(const QString &airtemp)
 {
 	m_airtemp = airtemp;
 }
-QString Dive::duration() const
+QString MobileDive::duration() const
 {
 	return m_duration;
 }
 
-void Dive::setDuration(const QString &duration)
+void MobileDive::setDuration(const QString &duration)
 {
 	m_duration = duration;
 }
-QString Dive::depth() const
+QString MobileDive::depth() const
 {
 	return m_depth;
 }
 
-void Dive::setDepth(const QString &depth)
+void MobileDive::setDepth(const QString &depth)
 {
 	m_depth = depth;
 }
-QString Dive::rating() const
+QString MobileDive::rating() const
 {
 	return m_rating;
 }
 
-void Dive::setRating(const QString &rating)
+void MobileDive::setRating(const QString &rating)
 {
 	m_rating = rating;
 }
-dive *Dive::thisDive() const
+dive *MobileDive::thisDive() const
 {
 	return m_thisDive;
 }
 
-void Dive::setThisDive(dive *thisDive)
+void MobileDive::setThisDive(dive *thisDive)
 {
 	m_thisDive = thisDive;
 }
-QString Dive::diveNumber() const
+QString MobileDive::diveNumber() const
 {
 	return m_diveNumber;
 }
 
-void Dive::setDiveNumber(const QString &diveNumber)
+void MobileDive::setDiveNumber(const QString &diveNumber)
 {
 	m_diveNumber = diveNumber;
 }
-QString Dive::notes() const
+QString MobileDive::notes() const
 {
 	return m_notes;
 }
 
-void Dive::setNotes(const QString &notes)
+void MobileDive::setNotes(const QString &notes)
 {
 	m_notes = notes;
 }
-QString Dive::trip() const
+QString MobileDive::trip() const
 {
 	return m_trip;
 }
 
-void Dive::setTrip(const QString &trip)
+void MobileDive::setTrip(const QString &trip)
 {
 	m_trip = trip;
 }
-QString Dive::buddy() const
+QString MobileDive::buddy() const
 {
     return m_buddy;
 }
 
-void Dive::setBuddy(const QString &buddy)
+void MobileDive::setBuddy(const QString &buddy)
 {
     m_buddy = buddy;
 }
-QString Dive::divemaster() const
+QString MobileDive::divemaster() const
 {
     return m_divemaster;
 }
 
-void Dive::setDivemaster(const QString &divemaster)
+void MobileDive::setDivemaster(const QString &divemaster)
 {
     m_divemaster = divemaster;
 }
-QString Dive::watertemp() const
+QString MobileDive::watertemp() const
 {
 	return m_watertemp;
 }
 
-void Dive::setWatertemp(const QString &watertemp)
+void MobileDive::setWatertemp(const QString &watertemp)
 {
 	m_watertemp = watertemp;
 }
 
-void Dive::setupDiveTempDetails()
+void MobileDive::setupDiveTempDetails()
 {
-	const char *unit;
-	double d_airTemp, d_waterTemp;
-
-	d_airTemp = get_temp_units(m_thisDive->airtemp.mkelvin, &unit);
-	d_waterTemp = get_temp_units(m_thisDive->watertemp.mkelvin, &unit);
-
-	setAirTemp(QString::number(d_airTemp) + unit);
-	setWatertemp(QString::number(d_waterTemp) + unit);
-
-	if (!m_thisDive->airtemp.mkelvin)
-		setAirTemp("");
-
-	if (!m_thisDive->watertemp.mkelvin)
-		setWatertemp("");
+	setWatertemp(get_temperature_string(m_thisDive->watertemp, true));
+	setAirTemp(get_temperature_string(m_thisDive->airtemp, true));
 }
 
 
@@ -227,7 +215,7 @@ DiveListModel::DiveListModel(QObject *parent) : QAbstractListModel(parent)
 void DiveListModel::addDive(dive *d)
 {
 	beginInsertRows(QModelIndex(), rowCount(), rowCount());
-	m_dives.append(Dive(d));
+	m_dives.append(MobileDive(d));
 	endInsertRows();
 }
 
@@ -241,7 +229,7 @@ QVariant DiveListModel::data(const QModelIndex &index, int role) const
 	if(index.row() < 0 || index.row() > m_dives.count())
 		return QVariant();
 
-	const Dive &dive = m_dives[index.row()];
+	const MobileDive &dive = m_dives[index.row()];
 
 	if (role == DiveNumberRole)
 		return dive.diveNumber();
diff --git a/qt-models/divelistmodel.h b/qt-models/divelistmodel.h
index cb19188..68f0c6f 100644
--- a/qt-models/divelistmodel.h
+++ b/qt-models/divelistmodel.h
@@ -4,9 +4,9 @@
 #include <QAbstractListModel>
 #include "dive.h"
 
-class Dive {
+class MobileDive {
 public:
-	Dive(dive* d);
+	MobileDive(dive* d);
 
 	QString date() const;
 	void setDate(const QString &date);
@@ -120,7 +120,7 @@ public:
 	QHash<int, QByteArray> roleNames() const;
 
 private:
-	QList<Dive> m_dives;
+	QList<MobileDive> m_dives;
 	static DiveListModel *m_instance;
 };
 
-- 
2.4.4

From cadd4614a9f9cff753b02e8d5afe55cab8574afc Mon Sep 17 00:00:00 2001
From: Grace Karanja <[email protected]>
Date: Wed, 27 May 2015 12:12:31 +0300
Subject: [PATCH 01/22] Create empty qt-mobile directory

Create a qt-mobile directory, with a blank main.qml file. This file
will be built up-on to come up with a usable mobile interface.

Signed-off-by: Grace Karanja <[email protected]>
---
 qt-mobile/main.qml | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 qt-mobile/main.qml

diff --git a/qt-mobile/main.qml b/qt-mobile/main.qml
new file mode 100644
index 0000000..e69de29
-- 
2.4.4

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

Reply via email to