CONFIG += sailfishapp
-SOURCES += src/harbour-pedalo.cpp
+SOURCES += src/harbour-pedalo.cpp \
+ src/journey.cpp \
+ src/journeymodel.cpp
DISTFILES += qml/harbour-pedalo.qml \
qml/cover/CoverPage.qml \
- qml/pages/FirstPage.qml \
- qml/pages/SecondPage.qml \
rpm/harbour-pedalo.changes.in \
rpm/harbour-pedalo.changes.run.in \
rpm/harbour-pedalo.spec \
rpm/harbour-pedalo.yaml \
translations/*.ts \
- harbour-pedalo.desktop
+ harbour-pedalo.desktop \
+ qml/pages/MainPage.qml \
+ qml/pages/AddJourney.qml \
+ qml/pages/Stats.qml \
+ qml/pages/JourneyList.qml \
+ qml/pages/About.qml \
+ qml/components/InfoRow.qml
SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172
# following TRANSLATIONS line. And also do not forget to
# modify the localized app name in the the .desktop file.
TRANSLATIONS += translations/harbour-pedalo-de.ts
+
+HEADERS += \
+ src/journey.h \
+ src/journeymodel.h
--- /dev/null
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+
+Item {
+ id: detailItem
+ width: parent.width
+ height: Math.max(labelText.height, valueText.height)
+
+ property alias label: labelText.text
+ property alias value: valueText.text
+ property real leftMargin: Theme.horizontalPageMargin
+ property real rightMargin: Theme.horizontalPageMargin
+ property real midlineRatio: 0.5
+ property real midlineMin: 0.0
+ property real midlineMax: width
+ property real midLine: Math.min(Math.max((width * midlineRatio), midlineMin), midlineMax)
+ property int pixelSize: Theme.fontSizeSmall
+ property alias labelTextBold: labelText.font.bold
+ property alias valueTextBold: valueText.font.bold
+
+ Text {
+ id: labelText
+
+ y: Theme.paddingSmall
+ anchors {
+ left: parent.left
+ right: parent.right
+ rightMargin: (width - midLine) + Theme.paddingSmall
+ leftMargin: detailItem.leftMargin
+ }
+ horizontalAlignment: Text.AlignLeft
+ color: Theme.primaryColor
+ font.pixelSize: pixelSize
+ textFormat: Text.PlainText
+ wrapMode: Text.Wrap
+ }
+
+ Text {
+ id: valueText
+
+ y: Theme.paddingSmall
+ anchors {
+ left: parent.left
+ right: parent.right
+ leftMargin: midLine + Theme.paddingSmall
+ rightMargin: detailItem.rightMargin
+ }
+ horizontalAlignment: Text.AlignLeft
+ color: Theme.primaryColor
+ font.pixelSize: pixelSize
+ textFormat: Text.PlainText
+ wrapMode: Text.Wrap
+ }
+}
ApplicationWindow
{
- initialPage: Component { FirstPage { } }
+ initialPage: Component { MainPage { } }
cover: Qt.resolvedUrl("cover/CoverPage.qml")
allowedOrientations: defaultAllowedOrientations
}
--- /dev/null
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+
+Page {
+ id: page
+
+ // The effective value will be restricted by ApplicationWindow.allowedOrientations
+ allowedOrientations: Orientation.All
+
+ SilicaListView {
+ id: listView
+ model: 20
+ anchors.fill: parent
+ header: PageHeader {
+ title: qsTr("About")
+ }
+ delegate: BackgroundItem {
+ id: delegate
+
+ Label {
+ x: Theme.horizontalPageMargin
+ text: qsTr("Item") + " " + index
+ anchors.verticalCenter: parent.verticalCenter
+ color: delegate.highlighted ? Theme.highlightColor : Theme.primaryColor
+ }
+ onClicked: console.log("Clicked " + index)
+ }
+ VerticalScrollDecorator {}
+ }
+}
--- /dev/null
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+
+Dialog {
+ id: addJourneyDialog
+ canAccept: true
+ property string title: "Add journey"
+
+ // The effective value will be restricted by ApplicationWindow.allowedOrientations
+ allowedOrientations: Orientation.All
+
+ SilicaFlickable {
+ id: addJourneyView
+ anchors.fill: parent
+ contentHeight: addJourneyColumn.implicitHeight
+
+ VerticalScrollDecorator {}
+
+ Column {
+ id: addJourneyColumn
+ spacing: Theme.paddingMedium
+ width: parent.width
+
+ DialogHeader {
+ title: addJourneyDialog.title
+ }
+
+ ValueButton {
+ id: startDate
+ function openDateDialog() {
+ var dialog = pageStack.push("Sailfish.Silica.DatePickerDialog", {
+ date: value
+ })
+
+ dialog.accepted.connect(function() {
+ value = dialog.dateText
+ selectedDate = dialog.date
+ })
+ }
+
+ label: "Date"
+ value: Qt.formatDate(new Date(), 'd MMM yyyy')
+ width: parent.width
+ onClicked: openDateDialog()
+ }
+
+ ValueButton {
+ id: startTime
+ property date time: new Date()
+ label: qsTr("Start time")
+ value: Qt.formatTime(time, 'hh:mm')
+ width: parent.width
+ onClicked: {
+ console.log("Hours: " + time.getHours())
+ console.log("Mins: " + time.getMinutes())
+ var dialog = pageStack.push("Sailfish.Silica.TimePickerDialog", { hour: time.getHours(), minute: time.getMinutes()})
+ dialog.accepted.connect(function() {
+ time = new Date(0, 0, 0, dialog.hour, dialog.minute)
+ })
+ }
+ onTimeChanged: {
+ value = Qt.formatTime(time, 'hh:mm')
+ endTime.time = new Date(0, 0, 0, startTime.time.getHours() + durationTime.duration.getHours(), startTime.time.getMinutes() + durationTime.duration.getMinutes())
+ }
+ }
+
+ ValueButton {
+ id: endTime
+ property date time: new Date()
+ label: qsTr("End time")
+ value: Qt.formatTime(time, 'hh:mm')
+ width: parent.width
+ onClicked: {
+ var dialog = pageStack.push("Sailfish.Silica.TimePickerDialog", { hour: time.getHours(), minute: time.getMinutes()})
+ dialog.accepted.connect(function() {
+ time = new Date(0, 0, 0, dialog.hour, dialog.minute)
+ })
+ }
+ onTimeChanged: {
+ value = Qt.formatTime(time, 'hh:mm')
+ durationTime.duration = new Date(0, 0, 0, endTime.time.getHours() - startTime.time.getHours(), endTime.time.getMinutes() - startTime.time.getMinutes())
+ }
+ }
+
+ ValueButton {
+ id: durationTime
+ property date duration: new Date(0, 0, 0, 0, 0)
+ label: qsTr("Duration")
+ value: Qt.formatTime(duration, 'hh:mm')
+ width: parent.width
+ onClicked: {
+ var dialog = pageStack.push("Sailfish.Silica.TimePickerDialog", { hour: duration.getHours(), minute: duration.getMinutes()})
+ dialog.accepted.connect(function() {
+ duration = new Date(0, 0, 0, dialog.hour, dialog.minute)
+ })
+ }
+ onDurationChanged: {
+ value = Qt.formatTime(duration, 'hh:mm')
+ endTime.time = new Date(0, 0, 0, startTime.time.getHours() + durationTime.duration.getHours(), startTime.time.getMinutes() + durationTime.duration.getMinutes())
+ }
+ }
+
+ TextField {
+ id: faster
+ width: parent.width
+ inputMethodHints: Qt.ImhDigitsOnly
+ label: qsTr("Cycles which you overtook")
+ placeholderText: label
+ horizontalAlignment: TextInput.AlignLeft
+ EnterKey.iconSource: "image://theme/icon-m-enter-next"
+ EnterKey.onClicked: slower.focus = true
+ }
+
+ TextField {
+ id: slower
+ width: parent.width
+ inputMethodHints: Qt.ImhDigitsOnly
+ label: qsTr("Cycles which overtook you")
+ placeholderText: label
+ horizontalAlignment: TextInput.AlignLeft
+ EnterKey.iconSource: "image://theme/icon-m-enter-next"
+ EnterKey.onClicked: addJourneyDialog.accept()
+ }
+ }
+ }
+}
+++ /dev/null
-import QtQuick 2.0
-import Sailfish.Silica 1.0
-
-Page {
- id: page
-
- // The effective value will be restricted by ApplicationWindow.allowedOrientations
- allowedOrientations: Orientation.All
-
- // To enable PullDownMenu, place our content in a SilicaFlickable
- SilicaFlickable {
- anchors.fill: parent
-
- // PullDownMenu and PushUpMenu must be declared in SilicaFlickable, SilicaListView or SilicaGridView
- PullDownMenu {
- MenuItem {
- text: qsTr("Show Page 2")
- onClicked: pageStack.push(Qt.resolvedUrl("SecondPage.qml"))
- }
- }
-
- // Tell SilicaFlickable the height of its content.
- contentHeight: column.height
-
- // Place our content in a Column. The PageHeader is always placed at the top
- // of the page, followed by our content.
- Column {
- id: column
-
- width: page.width
- spacing: Theme.paddingLarge
- PageHeader {
- title: qsTr("UI Template")
- }
- Label {
- x: Theme.horizontalPageMargin
- text: qsTr("Hello Sailors")
- color: Theme.secondaryHighlightColor
- font.pixelSize: Theme.fontSizeExtraLarge
- }
- }
- }
-}
--- /dev/null
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+
+Page {
+ id: page
+
+ // The effective value will be restricted by ApplicationWindow.allowedOrientations
+ allowedOrientations: Orientation.All
+ property int columnwidth: page.width - 2 * Theme.horizontalPageMargin
+
+ SilicaListView {
+ id: listView
+ model: 20
+ anchors.fill: parent
+ header: PageHeader {
+ title: qsTr("Journey list")
+ }
+ delegate: BackgroundItem {
+ id: delegate
+
+ Row {
+ spacing: Theme.paddingLarge
+ x: Theme.horizontalPageMargin
+
+ Label {
+ width: columnwidth / 3.0
+ text: qsTr("Item") + " " + index
+ color: delegate.highlighted ? Theme.highlightColor : Theme.primaryColor
+ }
+ Label {
+ width: columnwidth / 3.0
+ text: qsTr("1 May 2018")
+ color: delegate.highlighted ? Theme.highlightColor : Theme.primaryColor
+ }
+ Label {
+ width: columnwidth / 3.0
+ text: qsTr("20 mins")
+ color: delegate.highlighted ? Theme.highlightColor : Theme.primaryColor
+ }
+ }
+ onClicked: pageStack.push(Qt.resolvedUrl("AddJourney.qml"), {title: "Edit journey"})
+ }
+ VerticalScrollDecorator {}
+ }
+}
--- /dev/null
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+
+Page {
+ id: page
+ property bool cycling: false
+
+ // The effective value will be restricted by ApplicationWindow.allowedOrientations
+ allowedOrientations: Orientation.All
+
+ // To enable PullDownMenu, place our content in a SilicaFlickable
+ SilicaFlickable {
+ anchors.fill: parent
+
+ // PullDownMenu and PushUpMenu must be declared in SilicaFlickable, SilicaListView or SilicaGridView
+ PullDownMenu {
+ MenuItem {
+ text: qsTr("Show Page 2")
+ onClicked: pageStack.push(Qt.resolvedUrl("SecondPage.qml"))
+ }
+ }
+
+ // Tell SilicaFlickable the height of its content.
+ contentHeight: column.height
+
+ // Place our content in a Column. The PageHeader is always placed at the top
+ // of the page, followed by our content.
+ Column {
+ id: column
+
+ width: page.width
+ spacing: Theme.paddingLarge
+ PageHeader {
+ title: qsTr("Pedalo")
+ }
+
+ SectionHeader {
+ text: qsTr("Cycle!")
+ }
+
+ Button {
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: cycling ? qsTr("Finish") : qsTr("Start a journey")
+ onClicked: {
+ if (cycling) {
+ var dialog = pageStack.push(Qt.resolvedUrl("AddJourney.qml"))
+
+ dialog.accepted.connect(function() {
+ cycling = false
+ })
+ }
+ else {
+ cycling = true
+ }
+ }
+ }
+
+ SectionHeader {
+ text: qsTr("Add a journey")
+ }
+
+ Button {
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: qsTr("Enter journey")
+ onClicked: pageStack.push(Qt.resolvedUrl("AddJourney.qml"))
+ }
+
+ SectionHeader {
+ text: qsTr("Latest stats")
+ }
+
+ Button {
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: qsTr("View stats")
+ onClicked: pageStack.push(Qt.resolvedUrl("Stats.qml"))
+ }
+
+ SectionHeader {
+ text: qsTr("Previous journeys")
+ }
+
+ Button {
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: qsTr("View journeys")
+ onClicked: pageStack.push(Qt.resolvedUrl("JourneyList.qml"))
+ }
+
+ }
+ }
+}
+++ /dev/null
-import QtQuick 2.0
-import Sailfish.Silica 1.0
-
-Page {
- id: page
-
- // The effective value will be restricted by ApplicationWindow.allowedOrientations
- allowedOrientations: Orientation.All
-
- SilicaListView {
- id: listView
- model: 20
- anchors.fill: parent
- header: PageHeader {
- title: qsTr("Nested Page")
- }
- delegate: BackgroundItem {
- id: delegate
-
- Label {
- x: Theme.horizontalPageMargin
- text: qsTr("Item") + " " + index
- anchors.verticalCenter: parent.verticalCenter
- color: delegate.highlighted ? Theme.highlightColor : Theme.primaryColor
- }
- onClicked: console.log("Clicked " + index)
- }
- VerticalScrollDecorator {}
- }
-}
--- /dev/null
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import "../components"
+
+Page {
+ id: statsPage
+
+ // The effective value will be restricted by ApplicationWindow.allowedOrientations
+ allowedOrientations: Orientation.All
+
+ SilicaFlickable {
+ id: statsView
+ anchors.fill: parent
+ contentHeight: statsColumn.implicitHeight
+
+ VerticalScrollDecorator {}
+
+ Column {
+ id: statsColumn
+ spacing: Theme.paddingLarge
+ width: parent.width
+
+ PageHeader {
+ title: qsTr("Stats")
+ }
+
+ InfoRow {
+ label: qsTr("Journeys:")
+ value: "0"
+ midlineRatio: 0.7
+ midlineMin: Theme.fontSizeSmall * 10
+ midlineMax: Theme.fontSizeSmall * 15
+ pixelSize: Theme.fontSizeMedium
+ labelTextBold: true
+ }
+
+ InfoRow {
+ label: qsTr("Time spent cycling:")
+ value: "0"
+ midlineRatio: 0.7
+ midlineMin: Theme.fontSizeSmall * 10
+ midlineMax: Theme.fontSizeSmall * 15
+ pixelSize: Theme.fontSizeMedium
+ labelTextBold: true
+ }
+
+ InfoRow {
+ label: qsTr("Average journey duration:")
+ value: "0"
+ midlineRatio: 0.7
+ midlineMin: Theme.fontSizeSmall * 10
+ midlineMax: Theme.fontSizeSmall * 15
+ pixelSize: Theme.fontSizeMedium
+ labelTextBold: true
+ }
+
+ InfoRow {
+ label: qsTr("Speed percentile:")
+ value: "0%"
+ midlineRatio: 0.7
+ midlineMin: Theme.fontSizeSmall * 10
+ midlineMax: Theme.fontSizeSmall * 15
+ pixelSize: Theme.fontSizeMedium
+ labelTextBold: true
+ }
+ }
+ }
+}
--- /dev/null
+#include "journey.h"
+#include <QDebug>
+
+Journey::Journey() :
+ start(0u),
+ duration(0u),
+ overtook(0u),
+ overtakenby(0u)
+{
+}
+
+Journey::Journey(quint64 start, quint32 duration, quint32 overtook, quint32 overtakenby) :
+ start(start),
+ duration(duration),
+ overtook(overtook),
+ overtakenby(overtakenby)
+{
+}
+
+quint64 Journey::getStart () const {
+ return start;
+}
+
+qint32 Journey::getDuration () const {
+ return duration;
+}
+
+qint32 Journey::getOvertook () const {
+ return overtook;
+}
+
+qint32 Journey::getOvertakenBy () const {
+ return overtakenby;
+}
+
+
+void Journey::setStart (const quint64 value) {
+ start = value;
+}
+
+void Journey::setDuration (qint32 value) {
+ duration = value;
+}
+
+void Journey::setOvertook (qint32 value) {
+ overtook = value;
+}
+
+void Journey::setOvertakenBy (qint32 value) {
+ overtakenby = value;
+}
+
--- /dev/null
+#ifndef JOURNEY_H
+#define JOURNEY_H
+
+#include <QObject>
+#include <QTime>
+
+class Journey
+{
+public:
+ Journey();
+ Journey(quint64 start, quint32 duration, quint32 overtook, quint32 overtakenby);
+
+ quint64 getStart () const;
+ qint32 getDuration () const;
+ qint32 getOvertook () const;
+ qint32 getOvertakenBy () const;
+
+ void setStart (const quint64 value);
+ void setDuration (qint32 value);
+ void setOvertook (qint32 value);
+ void setOvertakenBy (qint32 value);
+
+private:
+ quint64 start;
+ quint32 duration;
+ quint32 overtook;
+ quint32 overtakenby;
+};
+
+
+#endif // JOURNEY_H
--- /dev/null
+#include "journeymodel.h"
+#include <QDebug>
+
+JourneyModel::JourneyModel(QObject *parent) : QAbstractListModel(parent) {
+ roles[StartRole] = "start";
+ roles[DurationRole] = "duration";
+ roles[OvertookRole] = "overtook";
+ roles[OvertakenByRole] = "overtakenby";
+}
+
+QHash<int, QByteArray> JourneyModel::roleNames() const {
+ return roles;
+}
+
+void JourneyModel::addJourney(const Journey &journey)
+{
+ beginInsertRows(QModelIndex(), rowCount(), rowCount());
+ journeys << journey;
+ endInsertRows();
+}
+
+int JourneyModel::rowCount(const QModelIndex & parent) const {
+ Q_UNUSED(parent)
+ return journeys.count();
+}
+
+QVariant JourneyModel::data(const QModelIndex & index, int role) const {
+ if (index.row() < 0 || index.row() > journeys.count())
+ return QVariant();
+
+ const Journey &journey = journeys[index.row()];
+ if (role == StartRole)
+ return journey.getStart();
+ else if (role == DurationRole)
+ return journey.getDuration();
+ else if (role == OvertookRole)
+ return journey.getOvertook();
+ else if (role == OvertakenByRole)
+ return journey.getOvertakenBy();
+ return QVariant();
+}
+
+void JourneyModel::clear() {
+ journeys.clear();
+}
+
+void JourneyModel::exportToFile(QFile & file) {
+ if (file.open(QIODevice::WriteOnly)) {
+ QTextStream out(&file);
+ for (QList<Journey>::iterator journeyIter = journeys.begin(); journeyIter != journeys.end(); journeyIter++) {
+ out << journeyIter->getStart() << ",";
+ out << journeyIter->getDuration() << ",";
+ out << journeyIter->getOvertook() << ",";
+ out << journeyIter->getOvertakenBy() << endl;
+ }
+ file.close();
+ }
+}
+
+void JourneyModel::importFromFile(QFile & file) {
+ if (file.open(QIODevice::ReadOnly)) {
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QStringList data;
+ quint64 start;
+ qint32 duration = 0;
+ qint32 overtook = 0;
+ qint32 overtakenby = 0;
+
+ data = in.readLine().split(",");
+ if (data.length() == 4) {
+ start = data[0].toLongLong();
+ duration = data[1].toLongLong();
+ overtook = data[2].toLongLong();
+ overtakenby = data[3].toLongLong();
+
+ addJourney(Journey(start, duration, overtook, overtakenby));
+ }
+ }
+ file.close();
+ }
+}
+
+
--- /dev/null
+#ifndef JOURNEYMODEL_H
+#define JOURNEYMODEL_H
+
+#include <QAbstractListModel>
+#include <QStringList>
+#include <QFile>
+
+#include "journey.h"
+
+class JourneyModel : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ enum JourneyRoles {
+ StartRole = Qt::UserRole + 1,
+ DurationRole,
+ OvertookRole,
+ OvertakenByRole
+ };
+
+ QHash<int, QByteArray> roleNames() const;
+
+ JourneyModel(QObject *parent = 0);
+
+ void addJourney(const Journey &journey);
+
+ int rowCount(const QModelIndex & parent = QModelIndex()) const;
+
+ QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
+
+ void clear();
+
+ void exportToFile(QFile & file);
+ void importFromFile(QFile & file);
+
+signals:
+ // General signals
+ void journeysChanged();
+
+private:
+ QHash<int, QByteArray> roles;
+ QList<Journey> journeys;
+};
+
+#endif // JOURNEYMODEL_H
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
-<TS version="2.0">
+<TS version="2.1">
+<context>
+ <name>About</name>
+ <message>
+ <source>About</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Item</source>
+ <translation type="unfinished">Element</translation>
+ </message>
+</context>
+<context>
+ <name>AddJourney</name>
+ <message>
+ <source>Add journey</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start time</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>End time</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cycles which you overtook</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cycles which overtook you</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
<context>
<name>CoverPage</name>
<message>
</message>
</context>
<context>
- <name>FirstPage</name>
+ <name>JourneyList</name>
+ <message>
+ <source>Item</source>
+ <translation type="unfinished">Element</translation>
+ </message>
+ <message>
+ <source>Journey list</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MainPage</name>
<message>
<source>Show Page 2</source>
- <translation>Zur Seite 2</translation>
+ <translation type="unfinished">Zur Seite 2</translation>
+ </message>
+ <message>
+ <source>Pedalo</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>UI Template</source>
- <translation>UI-Vorlage</translation>
+ <source>Cycle!</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Hello Sailors</source>
- <translation>Hallo Matrosen</translation>
+ <source>Start a journey</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add a journey</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter journey</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Latest stats</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>View stats</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Previous journeys</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>View journeys</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Finish</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>SecondPage</name>
+ <name>Stats</name>
<message>
- <source>Nested Page</source>
- <translation>Unterseite</translation>
+ <source>Stats</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Item</source>
- <translation>Element</translation>
+ <source>Time spent cycling</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Average journey duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Speed percentile</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Journeys:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
</TS>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
-<TS version="2.0">
+<TS version="2.1">
+<context>
+ <name>About</name>
+ <message>
+ <source>About</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Item</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>AddJourney</name>
+ <message>
+ <source>Add journey</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start time</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>End time</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cycles which you overtook</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cycles which overtook you</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
<context>
<name>CoverPage</name>
<message>
</message>
</context>
<context>
- <name>FirstPage</name>
+ <name>JourneyList</name>
+ <message>
+ <source>Item</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Journey list</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MainPage</name>
<message>
<source>Show Page 2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>UI Template</source>
+ <source>Pedalo</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cycle!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start a journey</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add a journey</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter journey</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Latest stats</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>View stats</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Previous journeys</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hello Sailors</source>
+ <source>View journeys</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Finish</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>SecondPage</name>
+ <name>Stats</name>
<message>
- <source>Nested Page</source>
+ <source>Stats</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Item</source>
+ <source>Time spent cycling</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Average journey duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Speed percentile</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Journeys:</source>
<translation type="unfinished"></translation>
</message>
</context>