summaryrefslogtreecommitdiffstats
path: root/qt-mobile
diff options
context:
space:
mode:
Diffstat (limited to 'qt-mobile')
-rw-r--r--qt-mobile/qml/About.qml59
-rw-r--r--qt-mobile/qml/CloudCredentials.qml84
-rw-r--r--qt-mobile/qml/DiveDetails.qml216
-rw-r--r--qt-mobile/qml/DiveDetailsEdit.qml236
-rw-r--r--qt-mobile/qml/DiveDetailsView.qml303
-rw-r--r--qt-mobile/qml/DiveList.qml302
-rw-r--r--qt-mobile/qml/DownloadFromDiveComputer.qml125
-rw-r--r--qt-mobile/qml/GpsList.qml128
-rw-r--r--qt-mobile/qml/Log.qml40
-rw-r--r--qt-mobile/qml/Preferences.qml74
-rw-r--r--qt-mobile/qml/StartPage.qml42
-rw-r--r--qt-mobile/qml/SubsurfaceButton.qml26
-rw-r--r--qt-mobile/qml/TextButton.qml37
-rw-r--r--qt-mobile/qml/ThemeTest.qml115
-rw-r--r--qt-mobile/qml/TopBar.qml59
-rw-r--r--qt-mobile/qml/dive.jpgbin235727 -> 0 bytes
-rw-r--r--qt-mobile/qml/icons/context-menu.pngbin641 -> 0 bytes
-rw-r--r--qt-mobile/qml/icons/context-menu.svg1
-rw-r--r--qt-mobile/qml/icons/main-menu.pngbin112 -> 0 bytes
-rw-r--r--qt-mobile/qml/icons/main-menu.svg1
-rw-r--r--qt-mobile/qml/icons/menu-back.pngbin3715 -> 0 bytes
-rw-r--r--qt-mobile/qml/icons/menu-edit.pngbin7369 -> 0 bytes
-rw-r--r--qt-mobile/qml/main.qml360
-rw-r--r--qt-mobile/qml/mobile-resources.qrc66
-rw-r--r--qt-mobile/qml/theme/Theme.qml57
-rw-r--r--qt-mobile/qml/theme/Units.qml99
-rw-r--r--qt-mobile/qml/theme/qmldir2
-rw-r--r--qt-mobile/qmlmanager.cpp1078
-rw-r--r--qt-mobile/qmlmanager.h162
-rw-r--r--qt-mobile/qmlprofile.cpp111
-rw-r--r--qt-mobile/qmlprofile.h40
31 files changed, 0 insertions, 3823 deletions
diff --git a/qt-mobile/qml/About.qml b/qt-mobile/qml/About.qml
deleted file mode 100644
index b1ca6e6bc..000000000
--- a/qt-mobile/qml/About.qml
+++ /dev/null
@@ -1,59 +0,0 @@
-import QtQuick 2.3
-import QtQuick.Controls 1.2
-import QtQuick.Layouts 1.1
-import org.kde.kirigami 1.0 as Kirigami
-import org.subsurfacedivelog.mobile 1.0
-
-Kirigami.ScrollablePage {
- id: aboutPage
- property int pageWidth: subsurfaceTheme.columnWidth - Kirigami.Units.smallSpacing
- title: "About Subsurface-mobile"
-
- ColumnLayout {
- spacing: Kirigami.Units.largeSpacing
- width: aboutPage.width
- Layout.margins: Kirigami.Units.gridUnit / 2
-
-
- Kirigami.Heading {
- text: "About Subsurface-mobile"
- Layout.topMargin: Kirigami.Units.gridUnit
- Layout.alignment: Qt.AlignHCenter
- Layout.maximumWidth: pageWidth
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- }
- Image {
- id: image
- source: "qrc:/qml/subsurface-mobile-icon.png"
- width: pageWidth / 2
- height: width
- fillMode: Image.Stretch
- Layout.alignment: Qt.AlignCenter
- horizontalAlignment: Image.AlignHCenter
- }
-
- Kirigami.Heading {
- text: "A mobile version of the free Subsurface divelog software.\n" +
- "View your dive logs while on the go."
- level: 4
- Layout.alignment: Qt.AlignHCenter
- Layout.topMargin: Kirigami.Units.largeSpacing * 3
- Layout.maximumWidth: pageWidth
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- anchors.horizontalCenter: parent.Center
- horizontalAlignment: Text.AlignHCenter
- }
-
- Kirigami.Heading {
- text: "Version: " + manager.getVersion() + "\n\n© Subsurface developer team\n2011-2016"
- level: 5
- font.pointSize: subsurfaceTheme.smallPointSize + 1
- Layout.alignment: Qt.AlignHCenter
- Layout.topMargin: Kirigami.Units.largeSpacing
- Layout.maximumWidth: pageWidth
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- anchors.horizontalCenter: parent.Center
- horizontalAlignment: Text.AlignHCenter
- }
- }
-}
diff --git a/qt-mobile/qml/CloudCredentials.qml b/qt-mobile/qml/CloudCredentials.qml
deleted file mode 100644
index aa7c57651..000000000
--- a/qt-mobile/qml/CloudCredentials.qml
+++ /dev/null
@@ -1,84 +0,0 @@
-import QtQuick 2.3
-import QtQuick.Controls 1.2
-import QtQuick.Window 2.2
-import QtQuick.Dialogs 1.2
-import QtQuick.Layouts 1.1
-import org.kde.kirigami 1.0 as Kirigami
-import org.subsurfacedivelog.mobile 1.0
-
-Item {
- id: loginWindow
- height: outerLayout.height + 2 * Kirigami.Units.gridUnit
-
- property string username: login.text;
- property string password: password.text;
-
- function saveCredentials() {
- manager.cloudUserName = login.text
- manager.cloudPassword = password.text
- manager.saveCloudCredentials()
- }
-
- ColumnLayout {
- id: outerLayout
- width: subsurfaceTheme.columnWidth - 2 * Kirigami.Units.gridUnit
-
- onVisibleChanged: {
- if (visible && manager.accessingCloud < 0) {
- manager.appendTextToLog("Credential scrn: show kbd was: " + (Qt.inputMethod.isVisible ? "visible" : "invisible"))
- Qt.inputMethod.show()
- login.forceActiveFocus()
- } else {
- manager.appendTextToLog("Credential scrn: hide kbd was: " + (Qt.inputMethod.isVisible ? "visible" : "invisible"))
- Qt.inputMethod.hide()
- }
- }
-
- Kirigami.Heading {
- text: "Cloud credentials"
- level: headingLevel
- Layout.bottomMargin: Kirigami.Units.largeSpacing / 2
- }
-
- Kirigami.Label {
- text: "Email"
- }
-
- TextField {
- id: login
- text: manager.cloudUserName
- Layout.fillWidth: true
- inputMethodHints: Qt.ImhEmailCharactersOnly |
- Qt.ImhNoAutoUppercase
- }
-
- Kirigami.Label {
- text: "Password"
- }
-
- TextField {
- id: password
- text: manager.cloudPassword
- echoMode: TextInput.Password
- inputMethodHints: Qt.ImhSensitiveData |
- Qt.ImhHiddenText |
- Qt.ImhNoAutoUppercase
- Layout.fillWidth: true
- }
- GridLayout {
- columns: 2
-
- CheckBox {
- checked: false
- id: showPassword
- onCheckedChanged: {
- password.echoMode = checked ? TextInput.Normal : TextInput.Password
- }
- }
- Kirigami.Label {
- text: "Show password"
- }
- }
- Item { width: Kirigami.Units.gridUnit; height: width }
- }
-}
diff --git a/qt-mobile/qml/DiveDetails.qml b/qt-mobile/qml/DiveDetails.qml
deleted file mode 100644
index 108833470..000000000
--- a/qt-mobile/qml/DiveDetails.qml
+++ /dev/null
@@ -1,216 +0,0 @@
-import QtQuick 2.4
-import QtQuick.Controls 1.4
-import QtQuick.Controls.Styles 1.4
-import QtQuick.Dialogs 1.2
-import QtQuick.Layouts 1.2
-import org.subsurfacedivelog.mobile 1.0
-import org.kde.kirigami 1.0 as Kirigami
-
-Kirigami.Page {
- id: diveDetailsPage
- property alias currentIndex: diveDetailsListView.currentIndex
- property alias dive_id: detailsEdit.dive_id
- property alias number: detailsEdit.number
- property alias date: detailsEdit.dateText
- property alias airtemp: detailsEdit.airtempText
- property alias watertemp: detailsEdit.watertempText
- property alias buddy: detailsEdit.buddyText
- property alias divemaster: detailsEdit.divemasterText
- property alias depth: detailsEdit.depthText
- property alias duration: detailsEdit.durationText
- property alias location: detailsEdit.locationText
- property alias notes: detailsEdit.notesText
- property alias suit: detailsEdit.suitText
- property alias weight: detailsEdit.weightText
- property alias startpressure: detailsEdit.startpressureText
- property alias endpressure: detailsEdit.endpressureText
- property alias gasmix: detailsEdit.gasmixText
-
- topPadding: applicationWindow().header.Layout.preferredHeight
- leftPadding: 0
- rightPadding: 0
- bottomPadding: 0
-
- title: diveDetailsListView.currentItem.modelData.dive.location
- state: "view"
-
- states: [
- State {
- name: "view"
- PropertyChanges { target: diveDetailsPage; contextualActions: Qt.platform.os == "ios" ? [ deleteAction, backAction ] : [ deleteAction ] }
- PropertyChanges { target: detailsEditScroll; opened: false }
- },
- State {
- name: "edit"
- PropertyChanges { target: diveDetailsPage; contextualActions: Qt.platform.os == "ios" ? [ cancelAction ] : null }
- PropertyChanges { target: detailsEditScroll; opened: true }
- },
- State {
- name: "add"
- PropertyChanges { target: diveDetailsPage; contextualActions: Qt.platform.os == "ios" ? [ cancelAction ] : null }
- PropertyChanges { target: detailsEditScroll; opened: true }
- }
-
- ]
-
- property QtObject deleteAction: Action {
- text: "Delete dive"
- iconName: "trash-empty"
- onTriggered: {
- contextDrawer.close()
- var deletedId = diveDetailsListView.currentItem.modelData.dive.id
- manager.deleteDive(deletedId)
- stackView.pop()
- showPassiveNotification("Dive deleted", 3000, "Undo",
- function() {
- manager.undoDelete(deletedId)
- });
- }
- }
-
- property QtObject cancelAction: Kirigami.Action {
- text: state === "edit" ? "Cancel edit" : "Cancel dive add"
- iconName: "dialog-cancel"
- onTriggered: {
- contextDrawer.close()
- if (state === "add")
- returnTopPage()
- else
- endEditMode()
- }
- }
-
- property QtObject backAction: Action {
- text: "Back to dive list"
- iconName: "go-previous"
- onTriggered: {
- contextDrawer.close()
- returnTopPage()
- }
- }
-
- mainAction: Action {
- iconName: state !== "view" ? "document-save" : "document-edit"
- onTriggered: {
- if (state === "edit" || state === "add") {
- detailsEdit.saveData()
- } else {
- startEditMode()
- }
- }
- }
-
- onBackRequested: {
- if (state === "edit") {
- endEditMode()
- event.accepted = true;
- } else if (state === "add") {
- endEditMode()
- stackView.pop()
- event.accepted = true;
- }
- // if we were in view mode, don't accept the event and pop the page
- }
-
- function showDiveIndex(index) {
- currentIndex = index;
- diveDetailsListView.positionViewAtIndex(index, ListView.Beginning);
- }
-
- function endEditMode() {
- // if we were adding a dive, we need to remove it
- if (state === "add")
- manager.addDiveAborted(dive_id)
- // just cancel the edit/add state
- state = "view";
- Qt.inputMethod.hide();
- }
-
- function startEditMode() {
- // set things up for editing - so make sure that the detailsEdit has
- // all the right data (using the property aliases set up above)
- dive_id = diveDetailsListView.currentItem.modelData.dive.id
- number = diveDetailsListView.currentItem.modelData.dive.number
- date = diveDetailsListView.currentItem.modelData.dive.date + " " + diveDetailsListView.currentItem.modelData.dive.time
- location = diveDetailsListView.currentItem.modelData.dive.location
- duration = diveDetailsListView.currentItem.modelData.dive.duration
- depth = diveDetailsListView.currentItem.modelData.dive.depth
- airtemp = diveDetailsListView.currentItem.modelData.dive.airTemp
- watertemp = diveDetailsListView.currentItem.modelData.dive.waterTemp
- suit = diveDetailsListView.currentItem.modelData.dive.suit
- buddy = diveDetailsListView.currentItem.modelData.dive.buddy
- divemaster = diveDetailsListView.currentItem.modelData.dive.divemaster
- notes = diveDetailsListView.currentItem.modelData.dive.notes
- if (diveDetailsListView.currentItem.modelData.dive.singleWeight) {
- // we have only one weight, go ahead, have fun and edit it
- weight = diveDetailsListView.currentItem.modelData.dive.sumWeight
- } else {
- // careful when translating, this text is "magic" in DiveDetailsEdit.qml
- weight = "cannot edit multiple weight systems"
- }
- if (diveDetailsListView.currentItem.modelData.dive.getCylinder != "Multiple" ) {
- startpressure = diveDetailsListView.currentItem.modelData.dive.startPressure
- endpressure = diveDetailsListView.currentItem.modelData.dive.endPressure
- gasmix = diveDetailsListView.currentItem.modelData.dive.firstGas
- } else {
- // careful when translating, this text is "magic" in DiveDetailsEdit.qml
- startpressure = "cannot edit multiple cylinders"
- endpressure = "cannot edit multiple cylinders"
- gasmix = "cannot edit multiple gases"
- }
-
- diveDetailsPage.state = "edit"
- }
-
- onWidthChanged: diveDetailsListView.positionViewAtIndex(diveDetailsListView.currentIndex, ListView.Beginning);
-
- Item {
- anchors.fill: parent
- ScrollView {
- id: diveDetailList
- anchors.fill: parent
- ListView {
- id: diveDetailsListView
- anchors.fill: parent
- model: diveModel
- currentIndex: -1
- boundsBehavior: Flickable.StopAtBounds
- maximumFlickVelocity: parent.width * 5
- orientation: ListView.Horizontal
- focus: true
- clip: true
- snapMode: ListView.SnapOneItem
- onMovementEnded: {
- currentIndex = indexAt(contentX+1, 1);
- }
- delegate: ScrollView {
- id: internalScrollView
- width: diveDetailsListView.width
- height: diveDetailsListView.height
- property var modelData: model
- Flickable {
- //contentWidth: parent.width
- contentHeight: diveDetails.height
- boundsBehavior: Flickable.StopAtBounds
- DiveDetailsView {
- id: diveDetails
- width: internalScrollView.width
- }
- }
- }
- }
- }
- Kirigami.OverlaySheet {
- id: detailsEditScroll
- anchors.fill: parent
- onOpenedChanged: {
- if (!opened) {
- endEditMode()
- }
- }
- DiveDetailsEdit {
- id: detailsEdit
- }
- }
- }
-}
diff --git a/qt-mobile/qml/DiveDetailsEdit.qml b/qt-mobile/qml/DiveDetailsEdit.qml
deleted file mode 100644
index e4338b3b8..000000000
--- a/qt-mobile/qml/DiveDetailsEdit.qml
+++ /dev/null
@@ -1,236 +0,0 @@
-import QtQuick 2.3
-import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
-import QtQuick.Dialogs 1.2
-import QtQuick.Layouts 1.1
-import org.subsurfacedivelog.mobile 1.0
-import org.kde.kirigami 1.0 as Kirigami
-
-Item {
- id: detailsEdit
- property int dive_id
- property int number
- property alias dateText: txtDate.text
- property alias locationText: txtLocation.text
- property string gpsText
- property alias airtempText: txtAirTemp.text
- property alias watertempText: txtWaterTemp.text
- property alias suitText: txtSuit.text
- property alias buddyText: txtBuddy.text
- property alias divemasterText: txtDiveMaster.text
- property alias notesText: txtNotes.text
- property alias durationText: txtDuration.text
- property alias depthText: txtDepth.text
- property alias weightText: txtWeight.text
- property alias startpressureText: txtStartPressure.text
- property alias endpressureText: txtEndPressure.text
- property alias gasmixText: txtGasMix.text
-
- function saveData() {
- // apply the changes to the dive_table
- manager.commitChanges(dive_id, detailsEdit.dateText, detailsEdit.locationText, detailsEdit.gpsText, detailsEdit.durationText,
- detailsEdit.depthText, detailsEdit.airtempText, detailsEdit.watertempText, detailsEdit.suitText,
- detailsEdit.buddyText, detailsEdit.divemasterText, detailsEdit.weightText, detailsEdit.notesText,
- detailsEdit.startpressureText, detailsEdit.endpressureText, detailsEdit.gasmixText)
- // trigger the profile to be redrawn
- QMLProfile.diveId = dive_id
-
- // apply the changes to the dive detail view - since the edit could have changed the order
- // first make sure that we are looking at the correct dive - our model allows us to look
- // up the index based on the unique dive_id
- var newIdx = diveModel.getIdxForId(dive_id)
- diveDetailsListView.currentIndex = newIdx
- diveDetailsListView.currentItem.modelData.date = detailsEdit.dateText
- diveDetailsListView.currentItem.modelData.location = detailsEdit.locationText
- diveDetailsListView.currentItem.modelData.duration = detailsEdit.durationText
- diveDetailsListView.currentItem.modelData.depth = detailsEdit.depthText
- diveDetailsListView.currentItem.modelData.airtemp = detailsEdit.airtempText
- diveDetailsListView.currentItem.modelData.watertemp = detailsEdit.watertempText
- diveDetailsListView.currentItem.modelData.suit = detailsEdit.suitText
- diveDetailsListView.currentItem.modelData.buddy = detailsEdit.buddyText
- diveDetailsListView.currentItem.modelData.divemaster = detailsEdit.divemasterText
- diveDetailsListView.currentItem.modelData.notes = detailsEdit.notesText
- diveDetailsPage.state = "view"
- Qt.inputMethod.hide()
- // now make sure we directly show the saved dive (this may be a new dive, or it may have moved)
- showDiveIndex(newIdx)
- }
-
- height: editArea.height
- ColumnLayout {
- id: editArea
- spacing: Kirigami.Units.smallSpacing
- width: subsurfaceTheme.columnWidth - 2 * Kirigami.Units.gridUnit
-
- GridLayout {
- id: editorDetails
- width: parent.width
- columns: 2
-
- Kirigami.Heading {
- Layout.columnSpan: 2
- text: "Dive " + number
- }
- Kirigami.Label {
- Layout.alignment: Qt.AlignRight
- text: "Date:"
- }
- TextField {
- id: txtDate;
- Layout.fillWidth: true
- }
- Kirigami.Label {
- Layout.alignment: Qt.AlignRight
- text: "Location:"
- }
- TextField {
- id: txtLocation;
- Layout.fillWidth: true
- }
-
- // we should add a checkbox here that allows the user
- // to add the current location as the dive location
- // (think of someone adding a dive while on the boat or
- // at the dive site)
- Kirigami.Label {
- Layout.alignment: Qt.AlignRight
- text: "Use current\nGPS location:"
- }
- CheckBox {
- id: checkboxGPS
- onCheckedChanged: {
- if (checked)
- gpsText = manager.getCurrentPosition()
- }
- }
-
- Kirigami.Label {
- Layout.alignment: Qt.AlignRight
- text: "Depth:"
- }
- TextField {
- id: txtDepth
- Layout.fillWidth: true
- validator: RegExpValidator { regExp: /[^-]*/ }
- }
- Kirigami.Label {
- Layout.alignment: Qt.AlignRight
- text: "Duration:"
- }
- TextField {
- id: txtDuration
- Layout.fillWidth: true
- validator: RegExpValidator { regExp: /[^-]*/ }
- }
-
- Kirigami.Label {
- Layout.alignment: Qt.AlignRight
- text: "Air Temp:"
- }
- TextField {
- id: txtAirTemp
- Layout.fillWidth: true
- }
-
- Kirigami.Label {
- Layout.alignment: Qt.AlignRight
- text: "Water Temp:"
- }
- TextField {
- id: txtWaterTemp
- Layout.fillWidth: true
- }
-
- Kirigami.Label {
- Layout.alignment: Qt.AlignRight
- text: "Suit:"
- }
- TextField {
- id: txtSuit
- Layout.fillWidth: true
- }
-
- Kirigami.Label {
- Layout.alignment: Qt.AlignRight
- text: "Buddy:"
- }
- TextField {
- id: txtBuddy
- Layout.fillWidth: true
- }
-
- Kirigami.Label {
- Layout.alignment: Qt.AlignRight
- text: "Dive Master:"
- }
- TextField {
- id: txtDiveMaster
- Layout.fillWidth: true
- }
-
- Kirigami.Label {
- Layout.alignment: Qt.AlignRight
- text: "Weight:"
- }
- TextField {
- id: txtWeight
- readOnly: (text == "cannot edit multiple weight systems" ? true : false)
- Layout.fillWidth: true
- }
-
- Kirigami.Label {
- Layout.alignment: Qt.AlignRight
- text: "Gas mix:"
- }
- TextField {
- id: txtGasMix
- readOnly: (text == "cannot edit multiple gases" ? true : false)
- Layout.fillWidth: true
- validator: RegExpValidator { regExp: /(EAN100|EAN\d\d|AIR|100|\d{1,2}|\d{1,2}\/\d{1,2})/ }
- }
-
- Kirigami.Label {
- Layout.alignment: Qt.AlignRight
- text: "Start Pressure:"
- }
- TextField {
- id: txtStartPressure
- readOnly: (text == "cannot edit multiple cylinders" ? true : false)
- Layout.fillWidth: true
- }
-
- Kirigami.Label {
- Layout.alignment: Qt.AlignRight
- text: "End Pressure:"
- }
- TextField {
- id: txtEndPressure
- readOnly: (text == "cannot edit multiple cylinders" ? true : false)
- Layout.fillWidth: true
- }
-
-
- Kirigami.Label {
- Layout.columnSpan: 2
- Layout.alignment: Qt.AlignLeft
- text: "Notes:"
- }
- TextArea {
- Layout.columnSpan: 2
- width: parent.width
- id: txtNotes
- textFormat: TextEdit.RichText
- focus: true
- Layout.fillWidth: true
- Layout.fillHeight: true
- Layout.minimumHeight: Kirigami.Units.gridUnit * 6
- selectByMouse: true
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- }
- }
- Item {
- height: Kirigami.Units.gridUnit * 3
- width: height // just to make sure the spacer doesn't produce scrollbars, but also isn't null
- }
- }
-}
diff --git a/qt-mobile/qml/DiveDetailsView.qml b/qt-mobile/qml/DiveDetailsView.qml
deleted file mode 100644
index ef1dc5605..000000000
--- a/qt-mobile/qml/DiveDetailsView.qml
+++ /dev/null
@@ -1,303 +0,0 @@
-import QtQuick 2.3
-/*
-import QtWebView 1.0
-*/
-import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
-import QtQuick.Dialogs 1.2
-import QtQuick.Layouts 1.1
-import org.subsurfacedivelog.mobile 1.0
-import org.kde.kirigami 1.0 as Kirigami
-
-Item {
- id: detailsView
- property real gridWidth: subsurfaceTheme.columnWidth - 2 * Kirigami.Units.gridUnit
- property real col1Width: gridWidth * 0.23
- property real col2Width: gridWidth * 0.37
- property real col3Width: gridWidth * 0.20
- property real col4Width: gridWidth * 0.20
-
- width: SubsurfaceTheme.columnWidth
- height: mainLayout.implicitHeight + bottomLayout.implicitHeight + Kirigami.Units.iconSizes.large
- Rectangle {
- z: 99
- color: Kirigami.Theme.textColor
- opacity: 0.3
- width: Kirigami.Units.smallSpacing/4
- anchors {
- right: parent.right
- top: parent.top
- bottom: parent.bottom
- }
- }
- GridLayout {
- id: mainLayout
- anchors {
- top: parent.top
- left: parent.left
- right: parent.right
- margins: Math.round(Kirigami.Units.gridUnit / 2)
- }
- columns: 4
- rowSpacing: Kirigami.Units.smallSpacing * 2
- columnSpacing: Kirigami.Units.smallSpacing
-
- Kirigami.Heading {
- id: detailsViewHeading
- Layout.fillWidth: true
- text: dive.location
- font.underline: dive.gps !== ""
- Layout.columnSpan: 4
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- Layout.topMargin: Kirigami.Units.largeSpacing
- MouseArea {
- anchors.fill: parent
- onClicked: {
- if (dive.gps !== "")
- showMap(dive.gps)
- }
- }
- }
- Kirigami.Label {
- id: dateLabel
- text: "Date: "
- opacity: 0.6
- Layout.alignment: Qt.AlignRight
- }
- Kirigami.Label {
- text: dive.date + " " + dive.time
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- Layout.columnSpan: 2
- }
- Kirigami.Label {
- id: numberText
- text: "#" + dive.number
- color: Kirigami.Theme.textColor
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- }
-
- Kirigami.Label {
- id: depthLabel
- text: "Depth: "
- opacity: 0.6
- Layout.alignment: Qt.AlignRight
- }
- Kirigami.Label {
- text: dive.depth
- Layout.fillWidth: true
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- }
- Kirigami.Label {
- text: "Duration: "
- opacity: 0.6
- Layout.alignment: Qt.AlignRight
- }
- Kirigami.Label {
- text: dive.duration
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- }
-
- QMLProfile {
- id: qmlProfile
- visible: !dive.noDive
- Layout.fillWidth: true
- Layout.preferredHeight: Layout.minimumHeight
- Layout.minimumHeight: width * 0.75
- Layout.columnSpan: 4
- clip: false
- Rectangle {
- color: "transparent"
- opacity: 0.6
- border.width: 1
- border.color: Kirigami.Theme.textColor;
- anchors.fill: parent
- }
- }
- Kirigami.Label {
- id: noProfile
- visible: dive.noDive
- Layout.fillWidth: true
- Layout.columnSpan: 4
- Layout.margins: Kirigami.Units.gridUnit
- horizontalAlignment: Text.AlignHCenter
- text: "No profile to show"
- }
- }
- GridLayout {
- id: bottomLayout
- anchors {
- top: mainLayout.bottom
- left: parent.left
- right: parent.right
- margins: Math.round(Kirigami.Units.gridUnit / 2)
- }
- columns: 4
- rowSpacing: Kirigami.Units.smallSpacing * 2
- columnSpacing: Kirigami.Units.smallSpacing
-
- Kirigami.Heading {
- Layout.fillWidth: true
- level: 3
- text: "Dive Details"
- Layout.columnSpan: 4
- }
-
- // first row - here we set up the column widths - total is 90% of width
- Kirigami.Label {
- text: "Suit:"
- wrapMode: Text.WrapAtWordBoundaryOrAnywhere
- opacity: 0.6
- Layout.maximumWidth: detailsView.col1Width
- Layout.preferredWidth: detailsView.col1Width
- Layout.alignment: Qt.AlignRight
- }
- Kirigami.Label {
- id: txtSuit
- text: dive.suit
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- Layout.maximumWidth: detailsView.col2Width
- Layout.preferredWidth: detailsView.col2Width
- }
-
- Kirigami.Label {
- text: "Air Temp:"
- wrapMode: Text.WrapAtWordBoundaryOrAnywhere
- opacity: 0.6
- Layout.maximumWidth: detailsView.col3Width
- Layout.preferredWidth: detailsView.col3Width
- Layout.alignment: Qt.AlignRight
- }
- Kirigami.Label {
- id: txtAirTemp
- text: dive.airTemp
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- Layout.maximumWidth: detailsView.col4Width
- Layout.preferredWidth: detailsView.col4Width
- }
-
- Kirigami.Label {
- text: "Cylinder:"
- wrapMode: Text.WrapAtWordBoundaryOrAnywhere
- opacity: 0.6
- Layout.maximumWidth: detailsView.col1Width
- Layout.preferredWidth: detailsView.col1Width
- Layout.alignment: Qt.AlignRight
- }
- Kirigami.Label {
- id: txtCylinder
- text: dive.getCylinder
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- Layout.maximumWidth: detailsView.col2Width
- Layout.preferredWidth: detailsView.col2Width
- }
-
- Kirigami.Label {
- text: "Water Temp:"
- wrapMode: Text.WrapAtWordBoundaryOrAnywhere
- opacity: 0.6
- Layout.maximumWidth: detailsView.col3Width
- Layout.preferredWidth: detailsView.col3Width
- Layout.alignment: Qt.AlignRight
- }
- Kirigami.Label {
- id: txtWaterTemp
- text: dive.waterTemp
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- Layout.maximumWidth: detailsView.col4Width
- Layout.preferredWidth: detailsView.col4Width
- }
-
- Kirigami.Label {
- text: "Dive Master:"
- wrapMode: Text.WrapAtWordBoundaryOrAnywhere
- opacity: 0.6
- Layout.maximumWidth: detailsView.col1Width
- Layout.preferredWidth: detailsView.col1Width
- Layout.alignment: Qt.AlignRight
- }
- Kirigami.Label {
- id: txtDiveMaster
- text: dive.divemaster
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- Layout.maximumWidth: detailsView.col2Width
- Layout.preferredWidth: detailsView.col2Width
- }
-
- Kirigami.Label {
- text: "Weight:"
- wrapMode: Text.WrapAtWordBoundaryOrAnywhere
- opacity: 0.6
- Layout.maximumWidth: detailsView.col3Width
- Layout.preferredWidth: detailsView.col3Width
- Layout.alignment: Qt.AlignRight
- }
- Kirigami.Label {
- id: txtWeight
- text: dive.sumWeight
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- Layout.maximumWidth: detailsView.col4Width
- Layout.preferredWidth: detailsView.col4Width
- }
-
- Kirigami.Label {
- text: "Buddy:"
- wrapMode: Text.WrapAtWordBoundaryOrAnywhere
- opacity: 0.6
- Layout.maximumWidth: detailsView.col1Width
- Layout.preferredWidth: detailsView.col1Width
- Layout.alignment: Qt.AlignRight
- }
- Kirigami.Label {
- id: txtBuddy
- text: dive.buddy
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- Layout.maximumWidth: detailsView.col2Width
- Layout.preferredWidth: detailsView.col2Width
- }
-
- Kirigami.Label {
- text: "SAC:"
- wrapMode: Text.WrapAtWordBoundaryOrAnywhere
- opacity: 0.6
- Layout.maximumWidth: detailsView.col3Width
- Layout.preferredWidth: detailsView.col3Width
- Layout.alignment: Qt.AlignRight
- }
- Kirigami.Label {
- id: txtSAC
- text: dive.sac
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- Layout.maximumWidth: detailsView.col4Width
- Layout.preferredWidth: detailsView.col4Width
- }
-
- Kirigami.Heading {
- Layout.fillWidth: true
- level: 3
- text: "Notes"
- wrapMode: Text.WrapAtWordBoundaryOrAnywhere
- Layout.columnSpan: 4
- }
-
- Kirigami.Label {
- id: txtNotes
- text: dive.notes
- focus: true
- Layout.columnSpan: 4
- Layout.fillWidth: true
- Layout.fillHeight: true
- //selectByMouse: true
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- }
- Item {
- Layout.columnSpan: 4
- Layout.fillWidth: true
- Layout.minimumHeight: Kirigami.Units.gridUnit * 3
- }
- Component.onCompleted: {
- qmlProfile.setMargin(Kirigami.Units.smallSpacing)
- qmlProfile.diveId = model.dive.id;
- qmlProfile.update();
- }
- }
-}
diff --git a/qt-mobile/qml/DiveList.qml b/qt-mobile/qml/DiveList.qml
deleted file mode 100644
index 95af9a973..000000000
--- a/qt-mobile/qml/DiveList.qml
+++ /dev/null
@@ -1,302 +0,0 @@
-import QtQuick 2.4
-import QtQuick.Controls 1.2
-import QtQuick.Layouts 1.2
-import QtQuick.Window 2.2
-import QtQuick.Dialogs 1.2
-import org.kde.kirigami 1.0 as Kirigami
-import org.subsurfacedivelog.mobile 1.0
-
-Kirigami.ScrollablePage {
- id: page
- objectName: "DiveList"
- title: "Subsurface-mobile"
- background: Rectangle {
- color: Kirigami.Theme.viewBackgroundColor
- }
-
- property int credentialStatus: manager.credentialStatus
- property int numDives: diveListView.count
- property color textColor: subsurfaceTheme.diveListTextColor
-
- function scrollToTop() {
- diveListView.positionViewAtBeginning()
- }
-
- Component {
- id: diveDelegate
- Kirigami.AbstractListItem {
- enabled: true
- supportsMouseEvents: true
- checked: diveListView.currentIndex === model.index
- width: parent.width
-
- property real detailsOpacity : 0
- property int horizontalPadding: Kirigami.Units.gridUnit / 2 - Kirigami.Units.smallSpacing + 1
-
- // When clicked, the mode changes to details view
- onClicked: {
- if (detailsWindow.state === "view") {
- diveListView.currentIndex = index
- detailsWindow.showDiveIndex(index);
- stackView.push(detailsWindow);
- }
- }
-
- property bool deleteButtonVisible: false
-
- onPressAndHold: {
- deleteButtonVisible = true
- timer.restart()
- }
-
- Row {
- width: parent.width - Kirigami.Units.gridUnit
- height: childrenRect.height - Kirigami.Units.smallSpacing
- spacing: horizontalPadding
- add: Transition {
- NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 400 }
- NumberAnimation { property: "scale"; from: 0; to: 1.0; duration: 400 }
- }
- Item {
- id: diveListEntry
- width: parent.width - Kirigami.Units.gridUnit
- height: childrenRect.height - Kirigami.Units.smallSpacing
-
- Kirigami.Label {
- id: locationText
- text: dive.location
- font.weight: Font.Light
- elide: Text.ElideRight
- maximumLineCount: 1 // needed for elide to work at all
- color: textColor
- anchors {
- left: parent.left
- leftMargin: horizontalPadding
- top: parent.top
- right: dateLabel.left
- }
- }
- Kirigami.Label {
- id: dateLabel
- text: dive.date + " " + dive.time
- font.pointSize: subsurfaceTheme.smallPointSize
- color: textColor
- anchors {
- right: parent.right
- top: parent.top
- }
- }
- Row {
- anchors {
- left: parent.left
- leftMargin: horizontalPadding
- right: parent.right
- rightMargin: horizontalPadding
- topMargin: - Kirigami.Units.smallSpacing * 2
- bottom: numberText.bottom
- }
- Kirigami.Label {
- text: 'Depth: '
- font.pointSize: subsurfaceTheme.smallPointSize
- color: textColor
- }
- Kirigami.Label {
- text: dive.depth
- width: Math.max(Kirigami.Units.gridUnit * 3, paintedWidth) // helps vertical alignment throughout listview
- font.pointSize: subsurfaceTheme.smallPointSize
- color: textColor
- }
- Kirigami.Label {
- text: 'Duration: '
- font.pointSize: subsurfaceTheme.smallPointSize
- color: textColor
- }
- Kirigami.Label {
- text: dive.duration
- font.pointSize: subsurfaceTheme.smallPointSize
- color: textColor
- }
- }
- Kirigami.Label {
- id: numberText
- text: "#" + dive.number
- font.pointSize: subsurfaceTheme.smallPointSize
- color: textColor
- anchors {
- right: parent.right
- top: locationText.bottom
- topMargin: - Kirigami.Units.smallSpacing * 2
- }
- }
- }
- Rectangle {
- visible: deleteButtonVisible
- height: diveListEntry.height - Kirigami.Units.smallSpacing
- width: height - 3 * Kirigami.Units.smallSpacing
- color: "#FF3030"
- antialiasing: true
- radius: Kirigami.Units.smallSpacing
- Kirigami.Icon {
- anchors {
- horizontalCenter: parent.horizontalCenter
- verticalCenter: parent.verticalCenter
- }
- source: "trash-empty"
- }
- MouseArea {
- anchors.fill: parent
- enabled: parent.visible
- onClicked: {
- parent.visible = false
- timer.stop()
- manager.deleteDive(dive.id)
- }
- }
- }
- Item {
- Timer {
- id: timer
- interval: 4000
- onTriggered: {
- deleteButtonVisible = false
- }
- }
- }
- }
- }
- }
-
- Component {
- id: tripHeading
- Item {
- width: page.width - Kirigami.Units.gridUnit
- height: childrenRect.height + Kirigami.Units.smallSpacing * 2 + Math.max(2, Kirigami.Units.gridUnit / 2)
-
- Kirigami.Heading {
- id: sectionText
- text: {
- // if the tripMeta (which we get as "section") ends in ::-- we know
- // that there's no trip -- otherwise strip the meta information before
- // the :: and show the trip location
- var shownText
- var endsWithDoubleDash = /::--$/;
- if (endsWithDoubleDash.test(section) || section === "--") {
- shownText = ""
- } else {
- shownText = section.replace(/.*::/, "")
- }
- shownText
- }
- anchors {
- top: parent.top
- left: parent.left
- topMargin: Math.max(2, Kirigami.Units.gridUnit / 2)
- leftMargin: Kirigami.Units.gridUnit / 2
- right: parent.right
- }
- color: textColor
- level: 2
- }
- Rectangle {
- height: Math.max(2, Kirigami.Units.gridUnit / 12) // we want a thicker line
- anchors {
- top: sectionText.bottom
- left: parent.left
- leftMargin: Kirigami.Units.gridUnit * -2
- rightMargin: Kirigami.Units.gridUnit * -2
- right: parent.right
- }
- color: subsurfaceTheme.accentColor
- }
- }
- }
-
- ScrollView {
- id: startPageWrapper
- anchors.fill: parent
- opacity: (diveListView.count > 0 && (credentialStatus == QMLManager.VALID || credentialStatus == QMLManager.VALID_EMAIL)) ? 0 : 1
- visible: opacity > 0
- Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration } }
- onVisibleChanged: {
- if (visible) {
- page.mainAction = page.saveAction
- } else {
- page.mainAction = page.addDiveAction
- }
- }
-
- StartPage {
- id: startPage
- }
- }
-
- ListView {
- id: diveListView
- anchors.fill: parent
- opacity: 0.8 - startPageWrapper.opacity
- visible: opacity > 0
- model: diveModel
- currentIndex: -1
- delegate: diveDelegate
- //boundsBehavior: Flickable.StopAtBounds
- maximumFlickVelocity: parent.height * 5
- bottomMargin: Kirigami.Units.iconSizes.medium + Kirigami.Units.gridUnit
- cacheBuffer: 0 // seems to avoid empty rendered profiles
- section.property: "dive.tripMeta"
- section.criteria: ViewSection.FullString
- section.delegate: tripHeading
- header: Kirigami.Heading {
- x: Kirigami.Units.gridUnit / 2
- height: paintedHeight + Kirigami.Units.gridUnit / 2
- verticalAlignment: Text.AlignBottom
- text: "Dive Log"
- }
- Connections {
- target: detailsWindow
- onCurrentIndexChanged: diveListView.currentIndex = detailsWindow.currentIndex
- }
- Connections {
- target: stackView
- onDepthChanged: {
- if (stackView.depth === 1) {
- diveListView.currentIndex = -1;
- }
- }
- }
- Connections {
- target: header
- onTitleBarClicked: {
- // if we can see the dive list and it's not at the top already, go to the top,
- // otherwise have the title bar handle the click (for bread-crumb navigation)
- if (stackView.currentItem.objectName === "DiveList" && diveListView.contentY > Kirigami.Units.gridUnit) {
- diveListView.positionViewAtBeginning()
- event.accepted = true
- } else {
- event.accepted = false
- }
- }
- }
-
- }
-
- property QtObject addDiveAction: Action {
- iconName: "list-add"
- onTriggered: {
- startAddDive()
- }
- }
-
- property QtObject saveAction: Action {
- iconName: "document-save"
- onTriggered: {
- startPage.saveCredentials();
- }
- }
-
- onBackRequested: {
- if (startPageWrapper.visible && diveListView.count > 0 && manager.credentialStatus != QMLManager.INVALID) {
- manager.credentialStatus = oldStatus
- event.accepted = true;
- }
- }
-}
diff --git a/qt-mobile/qml/DownloadFromDiveComputer.qml b/qt-mobile/qml/DownloadFromDiveComputer.qml
deleted file mode 100644
index a062ffaa0..000000000
--- a/qt-mobile/qml/DownloadFromDiveComputer.qml
+++ /dev/null
@@ -1,125 +0,0 @@
-import QtQuick 2.3
-import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
-import QtQuick.Window 2.2
-import QtQuick.Dialogs 1.2
-import QtQuick.Layouts 1.1
-import org.subsurfacedivelog.mobile 1.0
-import org.kde.kirigami 1.0 as Kirigami
-
-Kirigami.Page {
- id: diveComputerDownloadWindow
- anchors.top:parent.top
- width: parent.width
- height: parent.height
- Layout.fillWidth: true;
- title: "Dive Computer"
-
-/* this can be done by hitting the back key
- contextualActions: [
- Action {
- text: "Close Preferences"
- iconName: "dialog-cancel"
- onTriggered: {
- stackView.pop()
- contextDrawer.close()
- }
- }
- ]
- */
- ColumnLayout {
- anchors.top: parent.top
- height: parent.height
- width: parent.width
- Layout.fillWidth: true
- RowLayout {
- anchors.top:parent.top
- Layout.fillWidth: true
- Text { text: " Vendor name : " }
- ComboBox { Layout.fillWidth: true }
- }
- RowLayout {
- Text { text: " Dive Computer:" }
- ComboBox { Layout.fillWidth: true }
- }
- RowLayout {
- Text { text: " Progress:" }
- Layout.fillWidth: true
- ProgressBar { Layout.fillWidth: true }
- }
- RowLayout {
- SubsurfaceButton {
- text: "Download"
- onClicked: {
- text: "Retry"
- stackView.pop();
- }
- }
- SubsurfaceButton {
- id:quitbutton
- text: "Quit"
- onClicked: {
- stackView.pop();
- }
- }
- }
- RowLayout {
- Text {
- text: " Downloaded dives"
- }
- }
- TableView {
- width: parent.width
- Layout.fillWidth: true // The tableview should fill
- Layout.fillHeight: true // all remaining vertical space
- height: parent.height // on this screen
- TableViewColumn {
- width: parent.width / 2
- role: "datetime"
- title: "Date / Time"
- }
- TableViewColumn {
- width: parent.width / 4
- role: "duration"
- title: "Duration"
- }
- TableViewColumn {
- width: parent.width / 4
- role: "depth"
- title: "Depth"
- }
- }
- RowLayout {
- Layout.fillWidth: true
- SubsurfaceButton {
- text: "Accept"
- onClicked: {
- stackView.pop();
- }
- }
- SubsurfaceButton {
- text: "Quit"
- onClicked: {
- stackView.pop();
- }
- }
- Text {
- text: "" // Spacer between 2 button groups
- Layout.fillWidth: true
- }
- SubsurfaceButton {
- text: "Select All"
- }
- SubsurfaceButton {
- id: unselectbutton
- text: "Unselect All"
- }
- }
- RowLayout { // spacer to make space for silly button
- Layout.minimumHeight: 1.2 * unselectbutton.height
- Text {
- text:""
- }
- }
- }
-}
diff --git a/qt-mobile/qml/GpsList.qml b/qt-mobile/qml/GpsList.qml
deleted file mode 100644
index 6903acd80..000000000
--- a/qt-mobile/qml/GpsList.qml
+++ /dev/null
@@ -1,128 +0,0 @@
-import QtQuick 2.3
-import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
-import QtQuick.Window 2.2
-import QtQuick.Dialogs 1.2
-import QtQuick.Layouts 1.1
-import QtQuick.Window 2.2
-import org.subsurfacedivelog.mobile 1.0
-import org.kde.kirigami 1.0 as Kirigami
-
-Kirigami.ScrollablePage {
- id: gpsListWindow
- width: parent.width - Kirigami.Units.gridUnit
- anchors.margins: Kirigami.Units.gridUnit / 2
- objectName: "gpsList"
- title: "GPS Fixes"
-
-/* this can be done by hitting the back key
- contextualActions: [
- Action {
- text: "Close GPS list"
- iconName: "dialog-cancel"
- onTriggered: {
- stackView.pop()
- contextDrawer.close()
- }
- }
- ]
- */
- Component {
- id: gpsDelegate
- Kirigami.SwipeListItem {
- id: gpsFix
- enabled: true
- width: parent.width
- property int horizontalPadding: Kirigami.Units.gridUnit / 2 - Kirigami.Units.smallSpacing + 1
-
- Kirigami.BasicListItem {
- supportsMouseEvents: true
- width: parent.width - Kirigami.Units.gridUnit
- height: childrenRect.height - Kirigami.Units.smallSpacing
- GridLayout {
- columns: 4
- id: timeAndName
- anchors {
- left: parent.left
- leftMargin: horizontalPadding
- right: parent.right
- rightMargin: horizontalPadding
- }
- Kirigami.Label {
- text: 'Date: '
- opacity: 0.6
- font.pointSize: subsurfaceTheme.smallPointSize
- }
- Kirigami.Label {
- text: date
- Layout.preferredWidth: Math.max(parent.width / 5, paintedWidth)
- font.pointSize: subsurfaceTheme.smallPointSize
- }
- Kirigami.Label {
- text: 'Name: '
- opacity: 0.6
- font.pointSize: subsurfaceTheme.smallPointSize
- }
- Kirigami.Label {
- text: name
- Layout.preferredWidth: Math.max(parent.width / 5, paintedWidth)
- font.pointSize: subsurfaceTheme.smallPointSize
- }
- Kirigami.Label {
- text: 'Latitude: '
- opacity: 0.6
- font.pointSize: subsurfaceTheme.smallPointSize
- }
- Kirigami.Label {
- text: latitude
- font.pointSize: subsurfaceTheme.smallPointSize
- }
- Kirigami.Label {
- text: 'Longitude: '
- opacity: 0.6
- font.pointSize: subsurfaceTheme.smallPointSize
- }
- Kirigami.Label {
- text: longitude
- font.pointSize: subsurfaceTheme.smallPointSize
- }
- }
- }
- actions: [
- Kirigami.Action {
- iconName: "trash-empty"
- onTriggered: {
- print("delete this!")
- manager.deleteGpsFix(when)
- }
- },
- Kirigami.Action {
- iconName: "gps"
- onTriggered: {
- showMap(latitude + " " + longitude)
- }
- }
-
- ]
- }
- }
-
- ListView {
- id: gpsListView
- anchors.fill: parent
- model: gpsModel
- currentIndex: -1
- delegate: gpsDelegate
- boundsBehavior: Flickable.StopAtBounds
- maximumFlickVelocity: parent.height * 5
- cacheBuffer: Math.max(5000, parent.height * 5)
- focus: true
- clip: true
- header: Kirigami.Heading {
- x: Kirigami.Units.gridUnit / 2
- height: paintedHeight + Kirigami.Units.gridUnit / 2
- verticalAlignment: Text.AlignBottom
- text: "List of stored GPS fixes"
- }
- }
-}
diff --git a/qt-mobile/qml/Log.qml b/qt-mobile/qml/Log.qml
deleted file mode 100644
index d617901de..000000000
--- a/qt-mobile/qml/Log.qml
+++ /dev/null
@@ -1,40 +0,0 @@
-import QtQuick 2.3
-import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
-import QtQuick.Window 2.2
-import QtQuick.Dialogs 1.2
-import QtQuick.Layouts 1.1
-import QtQuick.Window 2.2
-import org.subsurfacedivelog.mobile 1.0
-import org.kde.kirigami 1.0 as Kirigami
-
-Kirigami.ScrollablePage {
- id: logWindow
- width: parent.width - Kirigami.Units.gridUnit
- anchors.margins: Kirigami.Units.gridUnit / 2
- objectName: "Log"
- title: "Application Log"
-
- property int pageWidth: subsurfaceTheme.columnWidth - Kirigami.Units.smallSpacing
-
- ColumnLayout {
- width: pageWidth
- spacing: Kirigami.Units.smallSpacing
- Kirigami.Heading {
- text: "Application Log"
- }
- Kirigami.Label {
- id: logContent
- width: parent.width
- Layout.preferredWidth: parent.width
- Layout.maximumWidth: parent.width
- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
- text: manager.logText
- }
- Rectangle {
- color: "transparent"
- height: Kirigami.Units.gridUnit * 2
- width: pageWidth
- }
- }
-}
diff --git a/qt-mobile/qml/Preferences.qml b/qt-mobile/qml/Preferences.qml
deleted file mode 100644
index 3ec96d198..000000000
--- a/qt-mobile/qml/Preferences.qml
+++ /dev/null
@@ -1,74 +0,0 @@
-import QtQuick 2.3
-import QtQuick.Controls 1.2
-import QtQuick.Window 2.2
-import QtQuick.Dialogs 1.2
-import QtQuick.Layouts 1.1
-import org.kde.kirigami 1.0 as Kirigami
-import org.subsurfacedivelog.mobile 1.0
-
-Kirigami.Page {
-
- title: "Preferences"
- mainAction: Action {
- text: "Save"
- iconName: "document-save"
- onTriggered: {
- manager.distanceThreshold = distanceThreshold.text
- manager.timeThreshold = timeThreshold.text
- manager.savePreferences()
- stackView.pop()
- }
- }
-
- GridLayout {
-
- signal accept
-
- columns: 2
- width: parent.width - Kirigami.Units.gridUnit
- anchors {
- fill: parent
- margins: Kirigami.Units.gridUnit / 2
- }
-
- Kirigami.Heading {
- text: "Preferences"
- Layout.bottomMargin: Kirigami.Units.largeSpacing / 2
- Layout.columnSpan: 2
- }
-
- Kirigami.Heading {
- text: "Subsurface GPS data webservice"
- level: 3
- Layout.topMargin: Kirigami.Units.largeSpacing
- Layout.bottomMargin: Kirigami.Units.largeSpacing / 2
- Layout.columnSpan: 2
- }
-
- Kirigami.Label {
- text: "Distance threshold (meters)"
- Layout.alignment: Qt.AlignRight
- }
-
- TextField {
- id: distanceThreshold
- text: manager.distanceThreshold
- Layout.fillWidth: true
- }
-
- Kirigami.Label {
- text: "Time threshold (minutes)"
- Layout.alignment: Qt.AlignRight
- }
-
- TextField {
- id: timeThreshold
- text: manager.timeThreshold
- Layout.fillWidth: true
- }
-
- Item {
- Layout.fillHeight: true
- }
- }
-}
diff --git a/qt-mobile/qml/StartPage.qml b/qt-mobile/qml/StartPage.qml
deleted file mode 100644
index 2d70cfcb3..000000000
--- a/qt-mobile/qml/StartPage.qml
+++ /dev/null
@@ -1,42 +0,0 @@
-import QtQuick 2.5
-import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
-import QtQuick.Layouts 1.1
-import org.kde.kirigami 1.0 as Kirigami
-import org.subsurfacedivelog.mobile 1.0
-
-ColumnLayout {
- id: startpage
- width: subsurfaceTheme.columnWidth
-
- function saveCredentials() { cloudCredentials.saveCredentials() }
-
- Kirigami.Heading {
- Layout.margins: Kirigami.Units.gridUnit
- text: "Subsurface-mobile"
- }
- Kirigami.Label {
- id: explanationText
- Layout.fillWidth: true
- Layout.margins: Kirigami.Units.gridUnit
- Layout.topMargin: 0
- text: "In order to use Subsurface-mobile you need to have a Subsurface cloud storage account " +
- "(which can be created with the Subsurface desktop application)."
- wrapMode: Text.WordWrap
- }
- Kirigami.Label {
- id: messageArea
- Layout.fillWidth: true
- Layout.margins: Kirigami.Units.gridUnit
- Layout.topMargin: 0
- text: manager.startPageText
- wrapMode: Text.WordWrap
- }
- CloudCredentials {
- id: cloudCredentials
- Layout.fillWidth: true
- Layout.margins: Kirigami.Units.gridUnit
- Layout.topMargin: 0
- property int headingLevel: 3
- }
-}
diff --git a/qt-mobile/qml/SubsurfaceButton.qml b/qt-mobile/qml/SubsurfaceButton.qml
deleted file mode 100644
index 174d44659..000000000
--- a/qt-mobile/qml/SubsurfaceButton.qml
+++ /dev/null
@@ -1,26 +0,0 @@
-import QtQuick 2.5
-import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
-import org.kde.kirigami 1.0 as Kirigami
-
-Button {
- style: ButtonStyle {
- padding {
- top: Kirigami.Units.smallSpacing * 2
- left: Kirigami.Units.smallSpacing * 4
- right: Kirigami.Units.smallSpacing * 4
- bottom: Kirigami.Units.smallSpacing * 2
- }
- background: Rectangle {
- border.width: 1
- radius: height / 3
- color: control.pressed ? subsurfaceTheme.shadedColor : subsurfaceTheme.accentColor
- }
- label: Text{
- text: control.text
- color: subsurfaceTheme.accentTextColor
- verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignHCenter
- }
- }
-}
diff --git a/qt-mobile/qml/TextButton.qml b/qt-mobile/qml/TextButton.qml
deleted file mode 100644
index 3e5a36735..000000000
--- a/qt-mobile/qml/TextButton.qml
+++ /dev/null
@@ -1,37 +0,0 @@
-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/qml/ThemeTest.qml b/qt-mobile/qml/ThemeTest.qml
deleted file mode 100644
index c0916aea0..000000000
--- a/qt-mobile/qml/ThemeTest.qml
+++ /dev/null
@@ -1,115 +0,0 @@
-import QtQuick 2.5
-import QtQuick.Controls 1.4
-import QtQuick.Layouts 1.1
-import QtQuick.Window 2.2
-import org.kde.kirigami 1.0 as Kirigami
-
-Kirigami.Page {
-
- title: "Theme Information"
-/* this can be done by hitting the back key
- contextualActions: [
- Action {
- text: "Close Theme info"
- iconName: "dialog-cancel"
- onTriggered: {
- stackView.pop()
- contextDrawer.close()
- }
- }
- ]
- */
- GridLayout {
- id: themetest
- columns: 2
- anchors.margins: Kirigami.Units.gridUnit / 2
-
- Kirigami.Heading {
- Layout.columnSpan: 2
- text: "Theme Information"
- }
-
- Kirigami.Heading {
- text: "Screen"
- Layout.columnSpan: 2
- level: 3
- }
- FontMetrics {
- id: fm
- }
-
- Kirigami.Label {
- text: "Geometry (pixels):"
- }
- Kirigami.Label {
- text: rootItem.width + "x" + rootItem.height
- }
-
- Kirigami.Label {
- text: "Geometry (gridUnits):"
- }
- Kirigami.Label {
- text: Math.round(rootItem.width / Kirigami.Units.gridUnit) + "x" + Math.round(rootItem.height / Kirigami.Units.gridUnit)
- }
-
- Kirigami.Label {
- text: "Units.gridUnit:"
- }
- Kirigami.Label {
- text: Kirigami.Units.gridUnit
- }
-
- Kirigami.Label {
- text: "Units.devicePixelRatio:"
- }
- Kirigami.Label {
- text: Screen.devicePixelRatio
- }
-
- Kirigami.Heading {
- text: "Font Metrics"
- level: 3
- Layout.columnSpan: 2
- }
-
- Kirigami.Label {
- text: "FontMetrics pointSize:"
- }
- Kirigami.Label {
- text: fm.font.pointSize
- }
-
- Kirigami.Label {
- text: "FontMetrics pixelSize:"
- }
- Kirigami.Label {
- text: fm.height
- }
-
- Kirigami.Label {
- text: "FontMetrics devicePixelRatio:"
- }
- Kirigami.Label {
- text: fm.height / fm.font.pointSize
- }
-
- Kirigami.Label {
- text: "Text item pixelSize:"
- }
- Text {
- text: font.pixelSize
- }
-
- Kirigami.Label {
- text: "Text item pointSize:"
- }
- Text {
- text: font.pointSize
- }
-
- Kirigami.Label {
- Layout.columnSpan: 2
- Layout.fillHeight: true
- }
- }
-}
diff --git a/qt-mobile/qml/TopBar.qml b/qt-mobile/qml/TopBar.qml
deleted file mode 100644
index 024b818b0..000000000
--- a/qt-mobile/qml/TopBar.qml
+++ /dev/null
@@ -1,59 +0,0 @@
-import QtQuick 2.3
-import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
-import QtQuick.Window 2.2
-import QtQuick.Dialogs 1.2
-import QtQuick.Layouts 1.1
-import QtQuick.Window 2.2
-import org.kde.kirigami 1.0 as Kirigami
-import org.subsurfacedivelog.mobile 1.0
-
-Rectangle {
- id: topPart
-
- color: subsurfaceTheme.accentColor
- Layout.minimumHeight: Math.round(Kirigami.Units.gridUnit * 1.5)
- Layout.fillWidth: true
- Layout.margins: 0
- RowLayout {
- anchors.verticalCenter: topPart.verticalCenter
- Item {
- Layout.preferredHeight: subsurfaceLogo.height
- Layout.leftMargin: Kirigami.Units.gridUnit / 4
- Image {
- id: subsurfaceLogo
- source: "qrc:/qml/subsurface-mobile-icon.png"
- anchors {
- verticalCenter: parent.Center
- left: parent.left
- }
- width: Math.round(Kirigami.Units.gridUnit)
- height: width
- }
- Kirigami.Label {
- text: qsTr("Subsurface-mobile")
- font.pointSize: Math.round(Kirigami.Theme.defaultFont.pointSize)
- height: subsurfaceLogo.height
- anchors {
- left: subsurfaceLogo.right
- leftMargin: Math.round(Kirigami.Units.gridUnit / 2)
- }
- font.weight: Font.Light
- verticalAlignment: Text.AlignVCenter
- Layout.fillWidth: false
- color: subsurfaceTheme.accentTextColor
- }
- }
- Item {
- Layout.fillWidth: true
- }
- }
- MouseArea {
- anchors.fill: topPart
- onClicked: {
- if (stackView.depth == 1 && showingDiveList) {
- scrollToTop()
- }
- }
- }
-}
diff --git a/qt-mobile/qml/dive.jpg b/qt-mobile/qml/dive.jpg
deleted file mode 100644
index 56445648a..000000000
--- a/qt-mobile/qml/dive.jpg
+++ /dev/null
Binary files differ
diff --git a/qt-mobile/qml/icons/context-menu.png b/qt-mobile/qml/icons/context-menu.png
deleted file mode 100644
index df34cfd4f..000000000
--- a/qt-mobile/qml/icons/context-menu.png
+++ /dev/null
Binary files differ
diff --git a/qt-mobile/qml/icons/context-menu.svg b/qt-mobile/qml/icons/context-menu.svg
deleted file mode 100644
index e0750c57e..000000000
--- a/qt-mobile/qml/icons/context-menu.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><path d="M24 16c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 4c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 12c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4z"/></svg> \ No newline at end of file
diff --git a/qt-mobile/qml/icons/main-menu.png b/qt-mobile/qml/icons/main-menu.png
deleted file mode 100644
index 20729b8f5..000000000
--- a/qt-mobile/qml/icons/main-menu.png
+++ /dev/null
Binary files differ
diff --git a/qt-mobile/qml/icons/main-menu.svg b/qt-mobile/qml/icons/main-menu.svg
deleted file mode 100644
index 1e89193f5..000000000
--- a/qt-mobile/qml/icons/main-menu.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><path d="M6 36h36v-4H6v4zm0-10h36v-4H6v4zm0-14v4h36v-4H6z"/></svg>
diff --git a/qt-mobile/qml/icons/menu-back.png b/qt-mobile/qml/icons/menu-back.png
deleted file mode 100644
index dc96b7728..000000000
--- a/qt-mobile/qml/icons/menu-back.png
+++ /dev/null
Binary files differ
diff --git a/qt-mobile/qml/icons/menu-edit.png b/qt-mobile/qml/icons/menu-edit.png
deleted file mode 100644
index ea7dd055a..000000000
--- a/qt-mobile/qml/icons/menu-edit.png
+++ /dev/null
Binary files differ
diff --git a/qt-mobile/qml/main.qml b/qt-mobile/qml/main.qml
deleted file mode 100644
index f4f6ea28b..000000000
--- a/qt-mobile/qml/main.qml
+++ /dev/null
@@ -1,360 +0,0 @@
-import QtQuick 2.4
-import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
-import QtQuick.Window 2.2
-import QtQuick.Dialogs 1.2
-import QtQuick.Layouts 1.1
-import QtQuick.Window 2.2
-import org.subsurfacedivelog.mobile 1.0
-import org.kde.kirigami 1.0 as Kirigami
-
-Kirigami.ApplicationWindow {
- id: rootItem
- title: qsTr("Subsurface-mobile")
-
- header.minimumHeight: 0
- header.preferredHeight: Kirigami.Units.gridUnit
- header.maximumHeight: Kirigami.Units.gridUnit * 2
- property bool fullscreen: true
- property int oldStatus: -1
- property alias accessingCloud: manager.accessingCloud
- property QtObject notification: null
- property bool showingDiveList: false
- property alias syncToCloud: manager.syncToCloud
- onAccessingCloudChanged: {
- if (accessingCloud >= 0) {
- // we now keep updating this to show progress, so timing out after 30 seconds is more useful
- // but should still be very conservative
- showPassiveNotification("Accessing Subsurface Cloud Storage " + accessingCloud +"%", 30000);
- } else {
- hidePassiveNotification();
- }
- }
-
- FontMetrics {
- id: fontMetrics
- }
-
- visible: false
- opacity: 0
-
- function returnTopPage() {
- for (var i=stackView.depth; i>1; i--) {
- stackView.pop()
- }
- detailsWindow.endEditMode()
- }
-
- function scrollToTop() {
- diveList.scrollToTop()
- }
-
- function showMap(location) {
- var urlPrefix = "https://www.google.com/maps/place/"
- var locationPair = location + "/@" + location
- var urlSuffix = ",5000m/data=!3m1!1e3!4m2!3m1!1s0x0:0x0"
- Qt.openUrlExternally(urlPrefix + locationPair + urlSuffix)
-
- }
-
- function startAddDive() {
- detailsWindow.state = "add"
- detailsWindow.dive_id = manager.addDive();
- detailsWindow.number = manager.getNumber(detailsWindow.dive_id)
- detailsWindow.date = manager.getDate(detailsWindow.dive_id)
- detailsWindow.airtemp = ""
- detailsWindow.watertemp = ""
- detailsWindow.buddy = ""
- detailsWindow.depth = ""
- detailsWindow.divemaster = ""
- detailsWindow.notes = ""
- detailsWindow.location = ""
- detailsWindow.duration = ""
- detailsWindow.suit = ""
- detailsWindow.weight = ""
- detailsWindow.gasmix = ""
- detailsWindow.startpressure = ""
- detailsWindow.endpressure = ""
- stackView.push(detailsWindow)
- }
-
- globalDrawer: Kirigami.GlobalDrawer {
- title: "Subsurface"
- titleIcon: "qrc:/qml/subsurface-mobile-icon.png"
-
- bannerImageSource: "dive.jpg"
- actions: [
- Kirigami.Action {
- text: "Dive list"
- onTriggered: {
- manager.appendTextToLog("requested dive list with credential status " + manager.credentialStatus)
- if (manager.credentialStatus == QMLManager.UNKNOWN) {
- // the user has asked to change credentials - if the credentials before that
- // were valid, go back to dive list
- if (oldStatus == QMLManager.VALID || oldStatus == QMLManager.VALID_EMAIL) {
- manager.credentialStatus = oldStatus
- }
- }
- returnTopPage()
- globalDrawer.close()
- }
- },
- Kirigami.Action {
- text: "Cloud credentials"
- onTriggered: {
- returnTopPage()
- oldStatus = manager.credentialStatus
- if (diveList.numDives > 0) {
- manager.startPageText = "Enter different credentials or return to dive list"
- } else {
- manager.startPageText = "Enter valid cloud storage credentials"
- }
-
- manager.credentialStatus = QMLManager.UNKNOWN
- }
- },
- Kirigami.Action {
- text: "Manage dives"
- enabled: manager.credentialStatus === QMLManager.VALID || manager.credentialStatus === QMLManager.VALID_EMAIL
- /*
- * disable for the beta to avoid confusion
- Action {
- text: "Download from computer"
- onTriggered: {
- detailsWindow.endEditMode()
- stackView.push(downloadDivesWindow)
- }
- }
- */
- Kirigami.Action {
- text: "Add dive manually"
- onTriggered: {
- returnTopPage() // otherwise odd things happen with the page stack
- startAddDive()
- }
- }
- Kirigami.Action {
- text: "Manual sync with cloud"
- onTriggered: {
- globalDrawer.close()
- detailsWindow.endEditMode()
- manager.saveChanges();
- }
- }
- Kirigami.Action {
- text: syncToCloud ? "Disable auto cloud sync" : "Enable auto cloud sync"
- onTriggered: {
- syncToCloud = !syncToCloud
- if (!syncToCloud) {
- var alertText = "Turning off automatic sync to cloud causes all data to only be stored locally.\n"
- alertText += "This can be very useful in situations with limited or no network access.\n"
- alertText += "Please chose 'Manual sync with cloud' if you have network connectivity\n"
- alertText += "and want to sync your data to cloud storage."
- showPassiveNotification(alertText, 10000)
- }
- }
- }
- },
-
- Kirigami.Action {
- text: "GPS"
- enabled: manager.credentialStatus === QMLManager.VALID || manager.credentialStatus === QMLManager.VALID_EMAIL
- Kirigami.Action {
- text: "GPS-tag dives"
- onTriggered: {
- manager.applyGpsData();
- }
- }
-
- Kirigami.Action {
- text: "Upload GPS data"
- onTriggered: {
- manager.sendGpsData();
- }
- }
-
- Kirigami.Action {
- text: "Download GPS data"
- onTriggered: {
- manager.downloadGpsData();
- }
- }
-
- Kirigami.Action {
- text: "Show GPS fixes"
- onTriggered: {
- returnTopPage()
- manager.populateGpsData();
- stackView.push(gpsWindow)
- }
- }
-
- Kirigami.Action {
- text: "Clear GPS cache"
- onTriggered: {
- manager.clearGpsData();
- }
- }
- Kirigami.Action {
- text: "Preferences"
- onTriggered: {
- stackView.push(prefsWindow)
- detailsWindow.endEditMode()
- }
- }
- },
-
- Kirigami.Action {
- text: "Developer"
- Kirigami.Action {
- text: "App log"
- onTriggered: {
- stackView.push(logWindow)
- }
- }
-
- Kirigami.Action {
- text: "Theme information"
- onTriggered: {
- stackView.push(themetest)
- }
- }
- },
- Kirigami.Action {
- text: "User manual"
- onTriggered: {
- Qt.openUrlExternally("https://subsurface-divelog.org/documentation/subsurface-mobile-user-manual/")
- }
- },
- Kirigami.Action {
- text: "About"
- onTriggered: {
- stackView.push(aboutWindow)
- detailsWindow.endEditMode()
- }
- }
- ] // end actions
-
- MouseArea {
- height: childrenRect.height
- width: Kirigami.Units.gridUnit * 10
- CheckBox {
- //text: "Run location service"
- id: locationCheckbox
- anchors {
- left: parent.left
- top: parent.top
- }
- checked: manager.locationServiceEnabled
- onCheckedChanged: {
- manager.locationServiceEnabled = checked;
- }
- }
- Kirigami.Label {
- x: Kirigami.Units.gridUnit * 1.5
- anchors {
- left: locationCheckbox.right
- //leftMargin: units.smallSpacing
- verticalCenter: locationCheckbox.verticalCenter
- }
- text: "Run location service"
- }
- onClicked: {
- print("Click.")
- locationCheckbox.checked = !locationCheckbox.checked
- }
- }
- }
-
- contextDrawer: Kirigami.ContextDrawer {
- id: contextDrawer
- actions: rootItem.pageStack.currentPage ? rootItem.pageStack.currentPage.contextualActions : null
- title: "Actions"
- }
-
- QtObject {
- id: subsurfaceTheme
- property int titlePointSize: Math.round(fontMetrics.font.pointSize * 1.5)
- property int smallPointSize: Math.round(fontMetrics.font.pointSize * 0.8)
- property color accentColor: "#2d5b9a"
- property color shadedColor: "#132744"
- property color accentTextColor: "#ececec"
- property color diveListTextColor: "#000000" // the Kirigami theme text color is too light
- property int columnWidth: Math.round(rootItem.width/(Kirigami.Units.gridUnit*30)) > 0 ? Math.round(rootItem.width / Math.round(rootItem.width/(Kirigami.Units.gridUnit*30))) : rootItem.width
- }
-/*
- toolBar: TopBar {
- width: parent.width
- height: Layout.minimumHeight
- }
- */
-
- property Item stackView: pageStack
- pageStack.initialPage: DiveList {
- anchors.fill: detailsPage
- id: diveList
- opacity: 0
- Behavior on opacity {
- NumberAnimation {
- duration: 200
- easing.type: Easing.OutQuad
- }
- }
-
- }
-
- QMLManager {
- id: manager
- }
-
- Preferences {
- id: prefsWindow
- visible: false
- }
-
- About {
- id: aboutWindow
- visible: false
- }
-
- DiveDetails {
- id: detailsWindow
- visible: false
- width: parent.width
- height: parent.height
- }
-
- DownloadFromDiveComputer {
- id: downloadDivesWindow
- visible: false
- }
-
- Log {
- id: logWindow
- visible: false
- }
-
- GpsList {
- id: gpsWindow
- visible: false
- }
-
- ThemeTest {
- id: themetest
- visible: false
- }
-
- Component.onCompleted: {
- Kirigami.Theme.highlightColor = subsurfaceTheme.accentColor
- manager.finishSetup();
- rootItem.visible = true
- diveList.opacity = 1
- rootItem.opacity = 1
- }
- Behavior on opacity {
- NumberAnimation {
- duration: 200
- easing.type: Easing.OutQuad
- }
- }
-}
diff --git a/qt-mobile/qml/mobile-resources.qrc b/qt-mobile/qml/mobile-resources.qrc
deleted file mode 100644
index e6c1fba65..000000000
--- a/qt-mobile/qml/mobile-resources.qrc
+++ /dev/null
@@ -1,66 +0,0 @@
-<RCC>
- <qresource prefix="/qml">
- <file>main.qml</file>
- <file>TextButton.qml</file>
- <file>Preferences.qml</file>
- <file>About.qml</file>
- <file>CloudCredentials.qml</file>
- <file>DiveList.qml</file>
- <file>DiveDetails.qml</file>
- <file>DiveDetailsEdit.qml</file>
- <file>DiveDetailsView.qml</file>
- <file>DownloadFromDiveComputer.qml</file>
- <file>GpsList.qml</file>
- <file>Log.qml</file>
- <file>TopBar.qml</file>
- <file>ThemeTest.qml</file>
- <file>StartPage.qml</file>
- <file>dive.jpg</file>
- <file>SubsurfaceButton.qml</file>
- <file alias="subsurface-mobile-icon.png">../../icons/subsurface-mobile-icon.png</file>
- <file alias="main-menu.png">icons/main-menu.png</file>
- <file alias="context-menu.png">icons/context-menu.png</file>
- <file alias="menu-edit.png">icons/menu-edit.png</file>
- <file alias="menu-back.png">icons/menu-back.png</file>
- </qresource>
- <qresource prefix="/imports">
- <file alias="org/kde/kirigami/qmldir">kirigami/qmldir</file>
- <file alias="org/kde/kirigami/Action.qml">kirigami/Action.qml</file>
- <file alias="org/kde/kirigami/ApplicationWindow.qml">kirigami/ApplicationWindow.qml</file>
- <file alias="org/kde/kirigami/BasicListItem.qml">kirigami/BasicListItem.qml</file>
- <file alias="org/kde/kirigami/GlobalDrawer.qml">kirigami/GlobalDrawer.qml</file>
- <file alias="org/kde/kirigami/ContextDrawer.qml">kirigami/ContextDrawer.qml</file>
- <file alias="org/kde/kirigami/Page.qml">kirigami/Page.qml</file>
- <file alias="org/kde/kirigami/ScrollablePage.qml">kirigami/ScrollablePage.qml</file>
- <file alias="org/kde/kirigami/Icon.qml">kirigami/Icon.qml</file>
- <file alias="org/kde/kirigami/Heading.qml">kirigami/Heading.qml</file>
- <file alias="org/kde/kirigami/OverlaySheet.qml">kirigami/OverlaySheet.qml</file>
- <file alias="org/kde/kirigami/ApplicationHeader.qml">kirigami/ApplicationHeader.qml</file>
- <file alias="org/kde/kirigami/private/PageRow.qml">kirigami/private/PageRow.qml</file>
- <file alias="org/kde/kirigami/Label.qml">kirigami/Label.qml</file>
- <file alias="org/kde/kirigami/AbstractListItem.qml">kirigami/AbstractListItem.qml</file>
- <file alias="org/kde/kirigami/SwipeListItem.qml">kirigami/SwipeListItem.qml</file>
- <file alias="org/kde/kirigami/OverlayDrawer.qml">kirigami/OverlayDrawer.qml</file>
- <file alias="org/kde/kirigami/Theme.qml">kirigami/Theme.qml</file>
- <file alias="org/kde/kirigami/Units.qml">kirigami/Units.qml</file>
- <file alias="org/kde/kirigami/private/RefreshableScrollView.qml">kirigami/private/RefreshableScrollView.qml</file>
- <file alias="org/kde/kirigami/private/ActionButton.qml">kirigami/private/ActionButton.qml</file>
- <file alias="org/kde/kirigami/private/BackButton.qml">kirigami/private/BackButton.qml</file>
- <file alias="org/kde/kirigami/private/MenuIcon.qml">kirigami/private/MenuIcon.qml</file>
- <file alias="org/kde/kirigami/private/ContextIcon.qml">kirigami/private/ContextIcon.qml</file>
- <file alias="org/kde/kirigami/private/AbstractDrawer.qml">kirigami/private/AbstractDrawer.qml</file>
- <file alias="org/kde/kirigami/private/PageStack.js">kirigami/private/PageStack.js</file>
- <file alias="org/kde/kirigami/private/PassiveNotification.qml">kirigami/private/PassiveNotification.qml</file>
- <file alias="org/kde/kirigami/icons/go-next.svg">kirigami/icons/go-next.svg</file>
- <file alias="org/kde/kirigami/icons/go-previous.svg">kirigami/icons/go-previous.svg</file>
- <file alias="org/kde/kirigami/icons/distribute-horizontal-x.svg">kirigami/icons/distribute-horizontal-x.svg</file>
- <file alias="org/kde/kirigami/icons/document-edit.svg">kirigami/icons/document-edit.svg</file>
- <file alias="org/kde/kirigami/icons/document-save.svg">kirigami/icons/document-save.svg</file>
- <file alias="org/kde/kirigami/icons/view-readermode.svg">kirigami/icons/view-readermode.svg</file>
- <file alias="org/kde/kirigami/icons/dialog-cancel.svg">kirigami/icons/dialog-cancel.svg</file>
- <file alias="org/kde/kirigami/icons/application-menu.svg">kirigami/icons/application-menu.svg</file>
- <file alias="org/kde/kirigami/icons/gps.svg">kirigami/icons/gps.svg</file>
- <file alias="org/kde/kirigami/icons/trash-empty.svg">kirigami/icons/trash-empty.svg</file>
- <file alias="org/kde/kirigami/icons/list-add.svg">kirigami/icons/list-add.svg</file>
- </qresource>
-</RCC>
diff --git a/qt-mobile/qml/theme/Theme.qml b/qt-mobile/qml/theme/Theme.qml
deleted file mode 100644
index 2c51ae00f..000000000
--- a/qt-mobile/qml/theme/Theme.qml
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2015 Marco Martin <mart@kde.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-import QtQuick 2.0
-
-//pragma Singleton
-
-/*!
- \qmltype Theme
- \inqmlmodule Material 0.1
-
- \brief Provides access to standard colors that follow the Material Design specification.
-
- See \l {http://www.google.com/design/spec/style/color.html#color-ui-color-application} for
- details about choosing a color scheme for your application.
- */
-QtObject {
- id: theme
-
- property color textColor: Qt.rgba(0,0,0, 0.54)
-
- property color highlightColor: "#2196F3"
- property color backgroundColor: "#f3f3f3"
- property color linkColor: "#2196F3"
- property color visitedLinkColor: "#2196F3"
-
- property color buttonTextColor: Qt.rgba(0,0,0, 0.54)
- property color buttonBackgroundColor: "#f3f3f3"
- property color buttonHoverColor: "#2196F3"
- property color buttonFocusColor: "#2196F3"
-
- property color viewTextColor: Qt.rgba(0,0,0, 0.54)
- property color viewBackgroundColor: "#f3f3f3"
- property color viewHoverColor: "#2196F3"
- property color viewFocusColor: "#2196F3"
-
- property color complementaryTextColor: "#f3f3f3"
- property color complementaryBackgroundColor: Qt.rgba(0,0,0, 0.54)
- property color complementaryHoverColor: "#2196F3"
- property color complementaryFocusColor: "#2196F3"
-}
diff --git a/qt-mobile/qml/theme/Units.qml b/qt-mobile/qml/theme/Units.qml
deleted file mode 100644
index 7cfa5c23b..000000000
--- a/qt-mobile/qml/theme/Units.qml
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2015 Marco Martin <mart@kde.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-import QtQuick 2.5
-import QtQuick.Window 2.2
-
-//pragma Singleton
-
-
-QtObject {
- id: units
-
- /**
- * The fundamental unit of space that should be used for sizes, expressed in pixels.
- * Given the screen has an accurate DPI settings, it corresponds to a width of
- * the capital letter M
- */
- property int gridUnit: fontMetrics.height
-
- /**
- * units.iconSizes provides access to platform-dependent icon sizing
- *
- * The icon sizes provided are normalized for different DPI, so icons
- * will scale depending on the DPI.
- *
- * Icon sizes from KIconLoader, adjusted to devicePixelRatio:
- * * small
- * * smallMedium
- * * medium
- * * large
- * * huge
- * * enormous
- *
- * Not devicePixelRation-adjusted::
- * * desktop
- */
- property QtObject iconSizes: QtObject {
- property int small: 16 * devicePixelRatio
- property int smallMedium: 22 * devicePixelRatio
- property int medium: 32 * devicePixelRatio
- property int large: 48 * devicePixelRatio
- property int huge: 64 * devicePixelRatio
- property int enormous: 128 * devicePixelRatio
- }
-
- /**
- * units.smallSpacing is the amount of spacing that should be used around smaller UI elements,
- * for example as spacing in Columns. Internally, this size depends on the size of
- * the default font as rendered on the screen, so it takes user-configured font size and DPI
- * into account.
- */
- property int smallSpacing: gridUnit/4
-
- /**
- * units.largeSpacing is the amount of spacing that should be used inside bigger UI elements,
- * for example between an icon and the corresponding text. Internally, this size depends on
- * the size of the default font as rendered on the screen, so it takes user-configured font
- * size and DPI into account.
- */
- property int largeSpacing: gridUnit
-
- /**
- * The ratio between physical and device-independent pixels. This value does not depend on the \
- * size of the configured font. If you want to take font sizes into account when scaling elements,
- * use theme.mSize(theme.defaultFont), units.smallSpacing and units.largeSpacing.
- * The devicePixelRatio follows the definition of "device independent pixel" by Microsoft.
- */
- property real devicePixelRatio: Screen.devicePixelRatio
-
- /**
- * units.longDuration should be used for longer, screen-covering animations, for opening and
- * closing of dialogs and other "not too small" animations
- */
- property int longDuration: 250
-
- /**
- * units.shortDuration should be used for short animations, such as accentuating a UI event,
- * hover events, etc..
- */
- property int shortDuration: 150
-
- property QtObject fontMetrics: FontMetrics {}
-}
diff --git a/qt-mobile/qml/theme/qmldir b/qt-mobile/qml/theme/qmldir
deleted file mode 100644
index c654dbad6..000000000
--- a/qt-mobile/qml/theme/qmldir
+++ /dev/null
@@ -1,2 +0,0 @@
-#singleton Units Units.qml
-#//singleton Theme Theme.qml
diff --git a/qt-mobile/qmlmanager.cpp b/qt-mobile/qmlmanager.cpp
deleted file mode 100644
index c6e6c5025..000000000
--- a/qt-mobile/qmlmanager.cpp
+++ /dev/null
@@ -1,1078 +0,0 @@
-#include "qmlmanager.h"
-#include <QUrl>
-#include <QSettings>
-#include <QDebug>
-#include <QNetworkAccessManager>
-#include <QAuthenticator>
-#include <QDesktopServices>
-#include <QTextDocument>
-#include <QRegularExpression>
-#include <QApplication>
-#include <QElapsedTimer>
-
-#include "qt-models/divelistmodel.h"
-#include <gpslistmodel.h>
-#include "divelist.h"
-#include "device.h"
-#include "pref.h"
-#include "qthelper.h"
-#include "qt-gui.h"
-#include "git-access.h"
-#include "subsurface-core/cloudstorage.h"
-
-QMLManager *QMLManager::m_instance = NULL;
-
-#define RED_FONT QLatin1Literal("<font color=\"red\">")
-#define END_FONT QLatin1Literal("</font>")
-
-static void appendTextToLogStandalone(const char *text)
-{
- QMLManager *self = QMLManager::instance();
- if (self)
- self->appendTextToLog(QString(text));
-}
-
-extern "C" int gitProgressCB(int percent, const char *text)
-{
- static QElapsedTimer timer;
- static qint64 lastTime = 0;
- static int lastPercent = -100;
-
- if (!timer.isValid() || percent == 0) {
- timer.restart();
- lastTime = 0;
- lastPercent = -100;
- }
- QMLManager *self = QMLManager::instance();
- if (self) {
- qint64 elapsed = timer.elapsed();
- // don't show the same status twice in 200ms
- if (percent == lastPercent && elapsed - lastTime < 200)
- return 0;
- self->loadDiveProgress(percent);
- QString logText = QString::number(elapsed / 1000.0, 'f', 1) + " / " + QString::number((elapsed - lastTime) / 1000.0, 'f', 3) +
- QString(" : git progress %1 (%2)").arg(percent).arg(text);
- self->appendTextToLog(logText);
- qDebug() << logText;
- qApp->processEvents();
- qApp->flush();
- lastTime = elapsed;
- }
- // return 0 so that we don't end the download
- return 0;
-}
-
-QMLManager::QMLManager() : m_locationServiceEnabled(false),
- m_verboseEnabled(false),
- reply(0),
- deletedDive(0),
- deletedTrip(0),
- m_credentialStatus(UNKNOWN),
- m_lastDevicePixelRatio(1.0),
- alreadySaving(false)
-{
- m_instance = this;
- connect(qobject_cast<QApplication *>(QApplication::instance()), &QApplication::applicationStateChanged, this, &QMLManager::applicationStateChanged);
- appendTextToLog(getUserAgent());
- appendTextToLog(QStringLiteral("build with Qt Version %1, runtime from Qt Version %2").arg(QT_VERSION_STR).arg(qVersion()));
- qDebug() << "Starting" << getUserAgent();
- qDebug() << QStringLiteral("build with Qt Version %1, runtime from Qt Version %2").arg(QT_VERSION_STR).arg(qVersion());
- setStartPageText(tr("Starting..."));
- setAccessingCloud(-1);
- setSyncToCloud(true);
- // create location manager service
- locationProvider = new GpsLocation(&appendTextToLogStandalone, this);
- set_git_update_cb(&gitProgressCB);
-
- // make sure we know if the current cloud repo has been successfully synced
- syncLoadFromCloud();
-}
-
-void QMLManager::applicationStateChanged(Qt::ApplicationState state)
-{
- if (!timer.isValid())
- timer.start();
- QString stateText;
- switch (state) {
- case Qt::ApplicationActive: stateText = "active"; break;
- case Qt::ApplicationHidden: stateText = "hidden"; break;
- case Qt::ApplicationSuspended: stateText = "suspended"; break;
- case Qt::ApplicationInactive: stateText = "inactive"; break;
- default: stateText = QString("none of the four: 0x") + QString::number(state, 16);
- }
- stateText.prepend(QString::number(timer.elapsed() / 1000.0,'f', 3) + ": AppState changed to ");
- stateText.append(" with ");
- stateText.append((alreadySaving ? QLatin1Literal("") : QLatin1Literal("no ")) + QLatin1Literal("save ongoing"));
- stateText.append(" and ");
- stateText.append((unsaved_changes() ? QLatin1Literal("") : QLatin1Literal("no ")) + QLatin1Literal("unsaved changes"));
- appendTextToLog(stateText);
- qDebug() << stateText;
-
- if (!alreadySaving && state == Qt::ApplicationInactive && unsaved_changes()) {
- // FIXME
- // make sure the user sees that we are saving data if they come back
- // while this is running
- alreadySaving = true;
- saveChanges();
- alreadySaving = false;
- appendTextToLog(QString::number(timer.elapsed() / 1000.0,'f', 3) + ": done saving to git local / remote");
- mark_divelist_changed(false);
- }
-}
-
-void QMLManager::openLocalThenRemote(QString url)
-{
- clear_dive_file_data();
- QByteArray fileNamePrt = QFile::encodeName(url);
- bool glo = prefs.git_local_only;
- prefs.git_local_only = true;
- int error = parse_file(fileNamePrt.data());
- setAccessingCloud(-1);
- prefs.git_local_only = glo;
- if (error) {
- appendTextToLog(QStringLiteral("loading dives from cache failed %1").arg(error));
- } else {
- // if we can load from the cache, we know that we have at least a valid email
- if (credentialStatus() == UNKNOWN)
- setCredentialStatus(VALID_EMAIL);
- prefs.unit_system = informational_prefs.unit_system;
- if (informational_prefs.unit_system == IMPERIAL)
- informational_prefs.units = IMPERIAL_units;
- prefs.units = informational_prefs.units;
- int i;
- struct dive *d;
- process_dives(false, false);
- DiveListModel::instance()->clear();
- for_each_dive (i, d) {
- DiveListModel::instance()->addDive(d);
- }
- appendTextToLog(QStringLiteral("%1 dives loaded from cache").arg(i));
- }
- appendTextToLog(QStringLiteral("have cloud credentials, trying to connect"));
- tryRetrieveDataFromBackend();
-}
-
-void QMLManager::finishSetup()
-{
- // Initialize cloud credentials.
- setCloudUserName(prefs.cloud_storage_email);
- setCloudPassword(prefs.cloud_storage_password);
- // if the cloud credentials are valid, we should get the GPS Webservice ID as well
- QString url;
- if (!cloudUserName().isEmpty() &&
- !cloudPassword().isEmpty() &&
- getCloudURL(url) == 0) {
- openLocalThenRemote(url);
- } else {
- setCredentialStatus(INCOMPLETE);
- appendTextToLog(QStringLiteral("no cloud credentials"));
- setStartPageText(RED_FONT + tr("Please enter valid cloud credentials.") + END_FONT);
- }
- setDistanceThreshold(prefs.distance_threshold);
- setTimeThreshold(prefs.time_threshold / 60);
-}
-
-QMLManager::~QMLManager()
-{
- m_instance = NULL;
-}
-
-QMLManager *QMLManager::instance()
-{
- return m_instance;
-}
-
-void QMLManager::savePreferences()
-{
- QSettings s;
- s.beginGroup("LocationService");
- s.setValue("time_threshold", timeThreshold() * 60);
- prefs.time_threshold = timeThreshold() * 60;
- s.setValue("distance_threshold", distanceThreshold());
- prefs.distance_threshold = distanceThreshold();
- s.sync();
-}
-
-#define CLOUDURL QString(prefs.cloud_base_url)
-#define CLOUDREDIRECTURL CLOUDURL + "/cgi-bin/redirect.pl"
-
-void QMLManager::saveCloudCredentials()
-{
- QSettings s;
- bool cloudCredentialsChanged = false;
- s.beginGroup("CloudStorage");
- s.setValue("email", cloudUserName());
- s.setValue("password", cloudPassword());
- s.sync();
- if (!same_string(prefs.cloud_storage_email, qPrintable(cloudUserName()))) {
- free(prefs.cloud_storage_email);
- prefs.cloud_storage_email = strdup(qPrintable(cloudUserName()));
- cloudCredentialsChanged = true;
- }
-
- cloudCredentialsChanged |= !same_string(prefs.cloud_storage_password, qPrintable(cloudPassword()));
-
- if (!same_string(prefs.cloud_storage_password, qPrintable(cloudPassword()))) {
- free(prefs.cloud_storage_password);
- prefs.cloud_storage_password = strdup(qPrintable(cloudPassword()));
- }
- if (cloudUserName().isEmpty() || cloudPassword().isEmpty()) {
- setStartPageText(RED_FONT + tr("Please enter valid cloud credentials.") + END_FONT);
- } else if (cloudCredentialsChanged) {
- free(prefs.userid);
- prefs.userid = NULL;
- syncLoadFromCloud();
- QString url;
- getCloudURL(url);
- manager()->clearAccessCache(); // remove any chached credentials
- clear_git_id(); // invalidate our remembered GIT SHA
- clear_dive_file_data();
- DiveListModel::instance()->clear();
- GpsListModel::instance()->clear();
- setStartPageText(tr("Attempting to open cloud storage with new credentials"));
- openLocalThenRemote(url);
- }
-}
-
-void QMLManager::checkCredentialsAndExecute(execute_function_type execute)
-{
- // if the cloud credentials are present, we should try to get the GPS Webservice ID
- // and (if we haven't done so) load the dive list
- if (!same_string(prefs.cloud_storage_email, "") &&
- !same_string(prefs.cloud_storage_password, "")) {
- setAccessingCloud(0);
- setStartPageText(tr("Testing cloud credentials"));
- appendTextToLog("Have credentials, let's see if they are valid");
- connect(manager(), &QNetworkAccessManager::authenticationRequired, this, &QMLManager::provideAuth, Qt::UniqueConnection);
- connect(manager(), &QNetworkAccessManager::finished, this, execute, Qt::UniqueConnection);
- QUrl url(CLOUDREDIRECTURL);
- request = QNetworkRequest(url);
- request.setRawHeader("User-Agent", getUserAgent().toUtf8());
- request.setRawHeader("Accept", "text/html");
- reply = manager()->get(request);
- connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(handleError(QNetworkReply::NetworkError)));
- connect(reply, &QNetworkReply::sslErrors, this, &QMLManager::handleSslErrors);
- }
-}
-
-void QMLManager::tryRetrieveDataFromBackend()
-{
- checkCredentialsAndExecute(&QMLManager::retrieveUserid);
-}
-
-void QMLManager::provideAuth(QNetworkReply *reply, QAuthenticator *auth)
-{
- if (auth->user() == QString(prefs.cloud_storage_email) &&
- auth->password() == QString(prefs.cloud_storage_password)) {
- // OK, credentials have been tried and didn't work, so they are invalid
- appendTextToLog("Cloud credentials are invalid");
- setStartPageText(RED_FONT + tr("Cloud credentials are invalid") + END_FONT);
- setCredentialStatus(INVALID);
- reply->disconnect();
- reply->abort();
- reply->deleteLater();
- return;
- }
- auth->setUser(prefs.cloud_storage_email);
- auth->setPassword(prefs.cloud_storage_password);
-}
-
-void QMLManager::handleSslErrors(const QList<QSslError> &errors)
-{
- setStartPageText(RED_FONT + tr("Cannot open cloud storage: Error creating https connection") + END_FONT);
- Q_FOREACH (QSslError e, errors) {
- qDebug() << e.errorString();
- }
- reply->abort();
- reply->deleteLater();
- setAccessingCloud(-1);
-}
-
-void QMLManager::handleError(QNetworkReply::NetworkError nError)
-{
- QString errorString = reply->errorString();
- qDebug() << "handleError" << nError << errorString;
- setStartPageText(RED_FONT + tr("Cannot open cloud storage: %1").arg(errorString) + END_FONT);
- reply->abort();
- reply->deleteLater();
- setAccessingCloud(-1);
-}
-
-void QMLManager::retrieveUserid()
-{
- if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) != 302) {
- appendTextToLog(QStringLiteral("Cloud storage connection not working correctly: %1").arg(QString(reply->readAll())));
- setAccessingCloud(-1);
- return;
- }
- setCredentialStatus(VALID);
- QString userid(prefs.userid);
- if (userid.isEmpty()) {
- if (same_string(prefs.cloud_storage_email, "") || same_string(prefs.cloud_storage_password, "")) {
- appendTextToLog("cloud user name or password are empty, can't retrieve web user id");
- setAccessingCloud(-1);
- return;
- }
- appendTextToLog(QStringLiteral("calling getUserid with user %1").arg(prefs.cloud_storage_email));
- userid = locationProvider->getUserid(prefs.cloud_storage_email, prefs.cloud_storage_password);
- }
- if (!userid.isEmpty()) {
- // overwrite the existing userid
- free(prefs.userid);
- prefs.userid = strdup(qPrintable(userid));
- QSettings s;
- s.setValue("subsurface_webservice_uid", prefs.userid);
- s.sync();
- }
- loadDivesWithValidCredentials();
-}
-
-void QMLManager::loadDiveProgress(int percent)
-{
- QString text(tr("Loading dive list from cloud storage."));
- setAccessingCloud(percent);
- while (percent > 0) {
- text.append(".");
- percent -= 10;
- }
- setStartPageText(text);
-}
-
-void QMLManager::loadDivesWithValidCredentials()
-{
- if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) != 302) {
- appendTextToLog(QStringLiteral("Cloud storage connection not working correctly: ") + reply->readAll());
- setStartPageText(RED_FONT + tr("Cannot connect to cloud storage") + END_FONT);
- setAccessingCloud(-1);
- return;
- }
- setCredentialStatus(VALID);
- appendTextToLog("Cloud credentials valid, loading dives...");
- setStartPageText("Cloud credentials valid, loading dives...");
- git_storage_update_progress(0, "load dives with valid credentials");
- QString url;
- if (getCloudURL(url)) {
- QString errorString(get_error_string());
- appendTextToLog(errorString);
- setStartPageText(RED_FONT + tr("Cloud storage error: %1").arg(errorString) + END_FONT);
- setAccessingCloud(-1);
- return;
- }
- QByteArray fileNamePrt = QFile::encodeName(url);
- if (check_git_sha(fileNamePrt.data()) == 0) {
- qDebug() << "local cache was current, no need to modify dive list";
- appendTextToLog("Cloud sync shows local cache was current");
- setLoadFromCloud(true);
- setAccessingCloud(-1);
- return;
- }
- clear_dive_file_data();
- DiveListModel::instance()->clear();
-
- int error = parse_file(fileNamePrt.data());
- setAccessingCloud(-1);
- if (!error) {
- report_error("filename is now %s", fileNamePrt.data());
- const char *error_string = get_error_string();
- appendTextToLog(error_string);
- set_filename(fileNamePrt.data(), true);
- } else {
- report_error("failed to open file %s", fileNamePrt.data());
- QString errorString(get_error_string());
- appendTextToLog(errorString);
- setStartPageText(RED_FONT + tr("Cloud storage error: %1").arg(errorString) + END_FONT);
- return;
- }
- prefs.unit_system = informational_prefs.unit_system;
- if (informational_prefs.unit_system == IMPERIAL)
- informational_prefs.units = IMPERIAL_units;
- prefs.units = informational_prefs.units;
- process_dives(false, false);
-
- int i;
- struct dive *d;
-
- for_each_dive (i, d) {
- DiveListModel::instance()->addDive(d);
- }
- appendTextToLog(QStringLiteral("%1 dives loaded").arg(i));
- if (dive_table.nr == 0)
- setStartPageText(tr("Cloud storage open successfully. No dives in dive list."));
- setLoadFromCloud(true);
-}
-
-void QMLManager::refreshDiveList()
-{
- int i;
- struct dive *d;
- DiveListModel::instance()->clear();
- for_each_dive (i, d) {
- DiveListModel::instance()->addDive(d);
- }
-}
-
-// update the dive and return the notes field, stripped of the HTML junk
-void QMLManager::commitChanges(QString diveId, QString date, QString location, QString gps, QString duration, QString depth,
- QString airtemp, QString watertemp, QString suit, QString buddy, QString diveMaster, QString weight, QString notes,
- QString startpressure, QString endpressure, QString gasmix)
-{
-#define DROP_EMPTY_PLACEHOLDER(_s) if ((_s) == QLatin1Literal("--")) (_s).clear()
-
- DROP_EMPTY_PLACEHOLDER(location);
- DROP_EMPTY_PLACEHOLDER(duration);
- DROP_EMPTY_PLACEHOLDER(depth);
- DROP_EMPTY_PLACEHOLDER(airtemp);
- DROP_EMPTY_PLACEHOLDER(watertemp);
- DROP_EMPTY_PLACEHOLDER(suit);
- DROP_EMPTY_PLACEHOLDER(buddy);
- DROP_EMPTY_PLACEHOLDER(diveMaster);
- DROP_EMPTY_PLACEHOLDER(weight);
- DROP_EMPTY_PLACEHOLDER(gasmix);
- DROP_EMPTY_PLACEHOLDER(startpressure);
- DROP_EMPTY_PLACEHOLDER(endpressure);
- DROP_EMPTY_PLACEHOLDER(notes);
-
-#undef DROP_EMPTY_PLACEHOLDER
-
- struct dive *d = get_dive_by_uniq_id(diveId.toInt());
- // notes comes back as rich text - let's convert this into plain text
- QTextDocument doc;
- doc.setHtml(notes);
- notes = doc.toPlainText();
-
- if (!d) {
- qDebug() << "don't touch this... no dive";
- return;
- }
- bool diveChanged = false;
- bool needResort = false;
-
- invalidate_dive_cache(d);
- if (date != get_dive_date_string(d->when)) {
- diveChanged = needResort = true;
- QDateTime newDate;
- // what a pain - Qt will not parse dates if the day of the week is incorrect
- // so if the user changed the date but didn't update the day of the week (most likely behavior, actually),
- // we need to make sure we don't try to parse that
- QString format(QString(prefs.date_format) + QChar(' ') + prefs.time_format);
- if (format.contains(QLatin1String("ddd")) || format.contains(QLatin1String("dddd"))) {
- QString dateFormatToDrop = format.contains(QLatin1String("ddd")) ? QStringLiteral("ddd") : QStringLiteral("dddd");
- QDateTime ts;
- QLocale loc = getLocale();
- ts.setMSecsSinceEpoch(d->when * 1000L);
- QString drop = loc.toString(ts.toUTC(), dateFormatToDrop);
- format.replace(dateFormatToDrop, "");
- date.replace(drop, "");
- }
- newDate = QDateTime::fromString(date, format);
- if (!newDate.isValid()) {
- qDebug() << "unable to parse date" << date << "with the given format" << format;
- QRegularExpression isoDate("\\d+-\\d+-\\d+[^\\d]+\\d+:\\d+");
- if (date.contains(isoDate)) {
- newDate = QDateTime::fromString(date, "yyyy-M-d h:m:s");
- if (newDate.isValid())
- goto parsed;
- newDate = QDateTime::fromString(date, "yy-M-d h:m:s");
- if (newDate.isValid())
- goto parsed;
- }
- QRegularExpression isoDateNoSecs("\\d+-\\d+-\\d+[^\\d]+\\d+");
- if (date.contains(isoDateNoSecs)) {
- newDate = QDateTime::fromString(date, "yyyy-M-d h:m");
- if (newDate.isValid())
- goto parsed;
- newDate = QDateTime::fromString(date, "yy-M-d h:m");
- if (newDate.isValid())
- goto parsed;
- }
- QRegularExpression usDate("\\d+/\\d+/\\d+[^\\d]+\\d+:\\d+:\\d+");
- if (date.contains(usDate)) {
- newDate = QDateTime::fromString(date, "M/d/yyyy h:m:s");
- if (newDate.isValid())
- goto parsed;
- newDate = QDateTime::fromString(date, "M/d/yy h:m:s");
- if (newDate.isValid())
- goto parsed;
- newDate = QDateTime::fromString(date.toLower(), "M/d/yyyy h:m:sap");
- if (newDate.isValid())
- goto parsed;
- newDate = QDateTime::fromString(date.toLower(), "M/d/yy h:m:sap");
- if (newDate.isValid())
- goto parsed;
- }
- QRegularExpression usDateNoSecs("\\d+/\\d+/\\d+[^\\d]+\\d+:\\d+");
- if (date.contains(usDateNoSecs)) {
- newDate = QDateTime::fromString(date, "M/d/yyyy h:m");
- if (newDate.isValid())
- goto parsed;
- newDate = QDateTime::fromString(date, "M/d/yy h:m");
- if (newDate.isValid())
- goto parsed;
- newDate = QDateTime::fromString(date.toLower(), "M/d/yyyy h:map");
- if (newDate.isValid())
- goto parsed;
- newDate = QDateTime::fromString(date.toLower(), "M/d/yy h:map");
- if (newDate.isValid())
- goto parsed;
- }
- QRegularExpression leDate("\\d+\\.\\d+\\.\\d+[^\\d]+\\d+:\\d+:\\d+");
- if (date.contains(leDate)) {
- newDate = QDateTime::fromString(date, "d.M.yyyy h:m:s");
- if (newDate.isValid())
- goto parsed;
- newDate = QDateTime::fromString(date, "d.M.yy h:m:s");
- if (newDate.isValid())
- goto parsed;
- }
- QRegularExpression leDateNoSecs("\\d+\\.\\d+\\.\\d+[^\\d]+\\d+:\\d+");
- if (date.contains(leDateNoSecs)) {
- newDate = QDateTime::fromString(date, "d.M.yyyy h:m");
- if (newDate.isValid())
- goto parsed;
- newDate = QDateTime::fromString(date, "d.M.yy h:m");
- if (newDate.isValid())
- goto parsed;
- }
- }
-parsed:
- if (newDate.isValid()) {
- // stupid Qt... two digit years are always 19xx - WTF???
- // so if adding a hundred years gets you into something before a year from now...
- // add a hundred years.
- if (newDate.addYears(100) < QDateTime::currentDateTime().addYears(1))
- newDate = newDate.addYears(100);
- d->dc.when = d->when = newDate.toMSecsSinceEpoch() / 1000 + gettimezoneoffset(newDate.toMSecsSinceEpoch() / 1000);
- } else {
- qDebug() << "none of our parsing attempts worked for the date string";
- }
- }
- struct dive_site *ds = get_dive_site_by_uuid(d->dive_site_uuid);
- char *locationtext = NULL;
- if (ds)
- locationtext = ds->name;
- if (!same_string(locationtext, qPrintable(location))) {
- diveChanged = true;
- // this is not ideal - and it's missing the gps information
- // but for now let's just create a new dive site
- ds = get_dive_site_by_uuid(create_dive_site(qPrintable(location), d->when));
- d->dive_site_uuid = ds->uuid;
- }
- if (!gps.isEmpty()) {
- QString gpsString = getCurrentPosition();
- if (gpsString != QString("waiting for the next gps location")) {
- qDebug() << "from commitChanges call to getCurrentPosition returns" << gpsString;
- double lat, lon;
- if (parseGpsText(qPrintable(gpsString), &lat, &lon)) {
- struct dive_site *ds = get_dive_site_by_uuid(d->dive_site_uuid);
- if (ds) {
- ds->latitude.udeg = lat * 1000000;
- ds->longitude.udeg = lon * 1000000;
- } else {
- degrees_t latData, lonData;
- latData.udeg = lat;
- lonData.udeg = lon;
- d->dive_site_uuid = create_dive_site_with_gps("new site", latData, lonData, d->when);
- }
- qDebug() << "set up dive site with new GPS data";
- }
- } else {
- qDebug() << "still don't have a position - will need to implement some sort of callback";
- }
- }
- if (get_dive_duration_string(d->duration.seconds, tr("h:"), tr("min")) != duration) {
- diveChanged = true;
- int h = 0, m = 0, s = 0;
- QRegExp r1(QStringLiteral("(\\d*)\\s*%1[\\s,:]*(\\d*)\\s*%2[\\s,:]*(\\d*)\\s*%3").arg(tr("h")).arg(tr("min")).arg(tr("sec")), Qt::CaseInsensitive);
- QRegExp r2(QStringLiteral("(\\d*)\\s*%1[\\s,:]*(\\d*)\\s*%2").arg(tr("h")).arg(tr("min")), Qt::CaseInsensitive);
- QRegExp r3(QStringLiteral("(\\d*)\\s*%1").arg(tr("min")), Qt::CaseInsensitive);
- QRegExp r4(QStringLiteral("(\\d*):(\\d*):(\\d*)"));
- QRegExp r5(QStringLiteral("(\\d*):(\\d*)"));
- QRegExp r6(QStringLiteral("(\\d*)"));
- if (r1.indexIn(duration) >= 0) {
- h = r1.cap(1).toInt();
- m = r1.cap(2).toInt();
- s = r1.cap(3).toInt();
- } else if (r2.indexIn(duration) >= 0) {
- h = r2.cap(1).toInt();
- m = r2.cap(2).toInt();
- } else if (r3.indexIn(duration) >= 0) {
- m = r3.cap(1).toInt();
- } else if (r4.indexIn(duration) >= 0) {
- h = r4.cap(1).toInt();
- m = r4.cap(2).toInt();
- s = r4.cap(3).toInt();
- } else if (r5.indexIn(duration) >= 0) {
- h = r5.cap(1).toInt();
- m = r5.cap(2).toInt();
- } else if (r6.indexIn(duration) >= 0) {
- m = r6.cap(1).toInt();
- }
- d->dc.duration.seconds = d->duration.seconds = h * 3600 + m * 60 + s;
- if (same_string(d->dc.model, "manually added dive")) {
- free(d->dc.sample);
- d->dc.sample = 0;
- d->dc.samples = 0;
- } else {
- qDebug() << "changing the duration on a dive that wasn't manually added - Uh-oh";
- }
-
- }
- if (get_depth_string(d->maxdepth.mm, true, true) != depth) {
- int depthValue = parseLengthToMm(depth);
- // the QML code should stop negative depth, but massively huge depth can make
- // the profile extremely slow or even run out of memory and crash, so keep
- // the depth <= 500m
- if (0 <= depthValue && depthValue <= 500000) {
- diveChanged = true;
- d->maxdepth.mm = depthValue;
- if (same_string(d->dc.model, "manually added dive")) {
- d->dc.maxdepth.mm = d->maxdepth.mm;
- free(d->dc.sample);
- d->dc.sample = 0;
- d->dc.samples = 0;
- }
- }
- }
- if (get_temperature_string(d->airtemp, true) != airtemp) {
- diveChanged = true;
- d->airtemp.mkelvin = parseTemperatureToMkelvin(airtemp);
- }
- if (get_temperature_string(d->watertemp, true) != watertemp) {
- diveChanged = true;
- d->watertemp.mkelvin = parseTemperatureToMkelvin(watertemp);
- }
- // not sure what we'd do if there was more than one weight system
- // defined - for now just ignore that case
- if (weightsystem_none((void *)&d->weightsystem[1])) {
- if (get_weight_string(d->weightsystem[0].weight, true) != weight) {
- diveChanged = true;
- d->weightsystem[0].weight.grams = parseWeightToGrams(weight);
- }
- }
- // start and end pressures for first cylinder only
- if (get_pressure_string(d->cylinder[0].start, true) != startpressure || get_pressure_string(d->cylinder[0].end, true) != endpressure) {
- diveChanged = true;
- d->cylinder[0].start.mbar = parsePressureToMbar(startpressure);
- d->cylinder[0].end.mbar = parsePressureToMbar(endpressure);
- if (d->cylinder[0].end.mbar > d->cylinder[0].start.mbar)
- d->cylinder[0].end.mbar = d->cylinder[0].start.mbar;
- }
- // gasmix for first cylinder
- if (get_gas_string(d->cylinder[0].gasmix) != gasmix) {
- int o2 = parseGasMixO2(gasmix);
- int he = parseGasMixHE(gasmix);
- // the QML code SHOULD only accept valid gas mixes, but just to make sure
- if (o2 >= 0 && o2 <= 1000 &&
- he >= 0 && he <= 1000 &&
- o2 + he <= 1000) {
- diveChanged = true;
- d->cylinder[0].gasmix.o2.permille = o2;
- d->cylinder[0].gasmix.he.permille = he;
- }
- }
- if (!same_string(d->suit, qPrintable(suit))) {
- diveChanged = true;
- free(d->suit);
- d->suit = strdup(qPrintable(suit));
- }
- if (!same_string(d->buddy, qPrintable(buddy))) {
- diveChanged = true;
- free(d->buddy);
- d->buddy = strdup(qPrintable(buddy));
- }
- if (!same_string(d->divemaster, qPrintable(diveMaster))) {
- diveChanged = true;
- free(d->divemaster);
- d->divemaster = strdup(qPrintable(diveMaster));
- }
- if (!same_string(d->notes, qPrintable(notes))) {
- diveChanged = true;
- free(d->notes);
- d->notes = strdup(qPrintable(notes));
- }
- // now that we have it all figured out, let's see what we need
- // to update
- DiveListModel *dm = DiveListModel::instance();
- int oldModelIdx = dm->getDiveIdx(d->id);
- int oldIdx = get_idx_by_uniq_id(d->id);
- if (needResort) {
- // we know that the only thing that might happen in a resort is that
- // this one dive moves to a different spot in the dive list
- sort_table(&dive_table);
- int newIdx = get_idx_by_uniq_id(d->id);
- if (newIdx != oldIdx) {
- DiveObjectHelper *newDive = new DiveObjectHelper(d);
- DiveListModel::instance()->removeDive(oldModelIdx);
- DiveListModel::instance()->insertDive(oldModelIdx - (newIdx - oldIdx), newDive);
- diveChanged = false; // because we already modified things
- }
- }
- if (diveChanged) {
- if (d->maxdepth.mm == d->dc.maxdepth.mm &&
- d->maxdepth.mm > 0 &&
- same_string(d->dc.model, "manually added dive") &&
- d->dc.samples == 0) {
- // so we have depth > 0, a manually added dive and no samples
- // let's create an actual profile so the desktop version can work it
- // first clear out the mean depth (or the fake_dc() function tries
- // to be too clever
- d->meandepth.mm = d->dc.meandepth.mm = 0;
- d->dc = *fake_dc(&d->dc, true);
- }
- DiveListModel::instance()->updateDive(oldModelIdx, d);
- }
- if (diveChanged || needResort)
- // we no longer save right away, but only the next time the app is not
- // in the foreground (or when explicitly requested)
- mark_divelist_changed(true);
-
-}
-
-void QMLManager::saveChanges()
-{
- if (!loadFromCloud()) {
- appendTextToLog("Don't save dives without loading from the cloud, first.");
- return;
- }
- appendTextToLog("Saving dives.");
- git_storage_update_progress(0, "saveChanges"); // reset the timers
- QString fileName;
- if (getCloudURL(fileName)) {
- appendTextToLog(get_error_string());
- return;
- }
- if (prefs.git_local_only == false) {
- setAccessingCloud(0);
- qApp->processEvents(); // make sure that the notification is actually shown
- }
- if (save_dives(fileName.toUtf8().data())) {
- appendTextToLog(get_error_string());
- setAccessingCloud(-1);
- return;
- }
- setAccessingCloud(-1);
- appendTextToLog("Updated dive list saved.");
- set_filename(fileName.toUtf8().data(), true);
- mark_divelist_changed(false);
-}
-
-void QMLManager::undoDelete(int id)
-{
- if (!deletedDive || deletedDive->id != id) {
- qDebug() << "can't find the deleted dive";
- return;
- }
- if (deletedTrip)
- insert_trip(&deletedTrip);
- if (deletedDive->divetrip) {
- struct dive_trip *trip = deletedDive->divetrip;
- tripflag_t tripflag = deletedDive->tripflag; // this gets overwritten in add_dive_to_trip()
- deletedDive->divetrip = NULL;
- deletedDive->next = NULL;
- deletedDive->pprev = NULL;
- add_dive_to_trip(deletedDive, trip);
- deletedDive->tripflag = tripflag;
- }
- record_dive(deletedDive);
- DiveListModel::instance()->addDive(deletedDive);
- // make sure the changes get saved if the app is no longer in the foreground
- // or if the user requests a save
- mark_divelist_changed(true);
- deletedDive = NULL;
- deletedTrip = NULL;
-}
-
-void QMLManager::deleteDive(int id)
-{
- struct dive *d = get_dive_by_uniq_id(id);
- if (!d) {
- qDebug() << "oops, trying to delete non-existing dive";
- return;
- }
- // clean up (or create) the storage for the deleted dive and trip (if applicable)
- if (!deletedDive)
- deletedDive = alloc_dive();
- else
- clear_dive(deletedDive);
- copy_dive(d, deletedDive);
- if (!deletedTrip) {
- deletedTrip = (struct dive_trip *)calloc(1, sizeof(struct dive_trip));
- } else {
- free(deletedTrip->location);
- free(deletedTrip->notes);
- memset(deletedTrip, 0, sizeof(struct dive_trip));
- }
- // if this is the last dive in that trip, remember the trip as well
- if (d->divetrip && d->divetrip->nrdives == 1) {
- *deletedTrip = *d->divetrip;
- deletedTrip->location = copy_string(d->divetrip->location);
- deletedTrip->notes = copy_string(d->divetrip->notes);
- deletedTrip->nrdives = 0;
- deletedDive->divetrip = deletedTrip;
- }
- DiveListModel::instance()->removeDiveById(id);
- delete_single_dive(get_idx_by_uniq_id(id));
- // make sure the changes get saved if the app is no longer in the foreground
- // or if the user requests a save
- mark_divelist_changed(true);
-}
-
-QString QMLManager::addDive()
-{
- appendTextToLog("Adding new dive.");
- return DiveListModel::instance()->startAddDive();
-}
-
-void QMLManager::addDiveAborted(int id)
-{
- DiveListModel::instance()->removeDiveById(id);
-}
-
-QString QMLManager::getCurrentPosition()
-{
- return locationProvider->currentPosition();
-}
-
-void QMLManager::applyGpsData()
-{
- if (locationProvider->applyLocations())
- refreshDiveList();
-}
-
-void QMLManager::sendGpsData()
-{
- locationProvider->uploadToServer();
-}
-
-void QMLManager::downloadGpsData()
-{
- locationProvider->downloadFromServer();
- populateGpsData();
-}
-
-void QMLManager::populateGpsData()
-{
- if (GpsListModel::instance())
- GpsListModel::instance()->update();
-}
-
-void QMLManager::clearGpsData()
-{
- locationProvider->clearGpsData();
- populateGpsData();
-}
-
-void QMLManager::deleteGpsFix(quint64 when)
-{
- locationProvider->deleteGpsFix(when);
- populateGpsData();
-}
-
-
-QString QMLManager::logText() const
-{
- QString logText = m_logText + QString("\nNumer of GPS fixes: %1").arg(locationProvider->getGpsNum());
- return logText;
-}
-
-void QMLManager::setLogText(const QString &logText)
-{
- m_logText = logText;
- emit logTextChanged();
-}
-
-void QMLManager::appendTextToLog(const QString &newText)
-{
- m_logText += "\n" + newText;
- emit logTextChanged();
-}
-
-bool QMLManager::locationServiceEnabled() const
-{
- return m_locationServiceEnabled;
-}
-
-void QMLManager::setLocationServiceEnabled(bool locationServiceEnabled)
-{
- m_locationServiceEnabled = locationServiceEnabled;
- locationProvider->serviceEnable(m_locationServiceEnabled);
-}
-
-bool QMLManager::verboseEnabled() const
-{
- return m_verboseEnabled;
-}
-
-void QMLManager::setVerboseEnabled(bool verboseMode)
-{
- m_verboseEnabled = verboseMode;
- verbose = verboseMode;
- qDebug() << "verbose is" << verbose;
- emit verboseEnabledChanged();
-}
-
-QString QMLManager::cloudPassword() const
-{
- return m_cloudPassword;
-}
-
-void QMLManager::setCloudPassword(const QString &cloudPassword)
-{
- m_cloudPassword = cloudPassword;
- emit cloudPasswordChanged();
-}
-
-QString QMLManager::cloudUserName() const
-{
- return m_cloudUserName;
-}
-
-void QMLManager::setCloudUserName(const QString &cloudUserName)
-{
- m_cloudUserName = cloudUserName.toLower();
- emit cloudUserNameChanged();
-}
-
-int QMLManager::distanceThreshold() const
-{
- return m_distanceThreshold;
-}
-
-void QMLManager::setDistanceThreshold(int distance)
-{
- m_distanceThreshold = distance;
- emit distanceThresholdChanged();
-}
-
-int QMLManager::timeThreshold() const
-{
- return m_timeThreshold;
-}
-
-void QMLManager::setTimeThreshold(int time)
-{
- m_timeThreshold = time;
- emit timeThresholdChanged();
-}
-
-bool QMLManager::loadFromCloud() const
-{
- return m_loadFromCloud;
-}
-
-void QMLManager::syncLoadFromCloud()
-{
- QSettings s;
- QString cloudMarker = QLatin1Literal("loadFromCloud") + QString(prefs.cloud_storage_email);
- m_loadFromCloud = s.contains(cloudMarker) && s.value(cloudMarker).toBool();
-}
-
-void QMLManager::setLoadFromCloud(bool done)
-{
- QSettings s;
- QString cloudMarker = QLatin1Literal("loadFromCloud") + QString(prefs.cloud_storage_email);
- s.setValue(cloudMarker, done);
- m_loadFromCloud = done;
- emit loadFromCloudChanged();
-}
-
-QString QMLManager::startPageText() const
-{
- return m_startPageText;
-}
-
-void QMLManager::setStartPageText(const QString& text)
-{
- m_startPageText = text;
- emit startPageTextChanged();
-}
-
-// this is an enum, but I don't know how to do enums in QML
-QMLManager::credentialStatus_t QMLManager::credentialStatus() const
-{
- return m_credentialStatus;
-}
-
-void QMLManager::setCredentialStatus(const credentialStatus_t value)
-{
- if (m_credentialStatus != value) {
- m_credentialStatus = value;
- emit credentialStatusChanged();
- }
-}
-
-// where in the QML dive list is that dive?
-int QMLManager::getIndex(const QString &diveId)
-{
- int dive_id = diveId.toInt();
- int idx = DiveListModel::instance()->getDiveIdx(dive_id);
- return idx;
-}
-
-QString QMLManager::getNumber(const QString& diveId)
-{
- int dive_id = diveId.toInt();
- struct dive *d = get_dive_by_uniq_id(dive_id);
- QString number;
- if (d)
- number = QString::number(d->number);
- return number;
-}
-
-QString QMLManager::getDate(const QString& diveId)
-{
- int dive_id = diveId.toInt();
- struct dive *d = get_dive_by_uniq_id(dive_id);
- QString datestring;
- if (d)
- datestring = get_dive_date_string(d->when);
- return datestring;
-}
-
-QString QMLManager::getVersion() const
-{
- QRegExp versionRe(".*:([()\\.,\\d]+).*");
- if (!versionRe.exactMatch(getUserAgent()))
- return QString();
-
- return versionRe.cap(1);
-}
-
-int QMLManager::accessingCloud() const
-{
- return m_accessingCloud;
-}
-
-void QMLManager::setAccessingCloud(int status)
-{
- m_accessingCloud = status;
- emit accessingCloudChanged();
-}
-
-bool QMLManager::syncToCloud() const
-{
- return m_syncToCloud;
-}
-
-void QMLManager::setSyncToCloud(bool status)
-{
- m_syncToCloud = status;
- prefs.git_local_only = !status;
- prefs.cloud_background_sync = status;
- QSettings s;
- s.beginGroup("CloudStorage");
- s.setValue("git_local_only", prefs.git_local_only);
- s.setValue("cloud_background_sync", prefs.cloud_background_sync);
- emit syncToCloudChanged();
-}
-
-qreal QMLManager::lastDevicePixelRatio()
-{
- return m_lastDevicePixelRatio;
-}
-
-void QMLManager::screenChanged(QScreen *screen)
-{
- m_lastDevicePixelRatio = screen->devicePixelRatio();
- emit sendScreenChanged(screen);
-}
diff --git a/qt-mobile/qmlmanager.h b/qt-mobile/qmlmanager.h
deleted file mode 100644
index 7c56119d5..000000000
--- a/qt-mobile/qmlmanager.h
+++ /dev/null
@@ -1,162 +0,0 @@
-#ifndef QMLMANAGER_H
-#define QMLMANAGER_H
-
-#include <QObject>
-#include <QString>
-#include <QNetworkAccessManager>
-#include <QScreen>
-#include <QElapsedTimer>
-
-#include "gpslocation.h"
-
-class QMLManager : public QObject {
- Q_OBJECT
- Q_ENUMS(credentialStatus_t)
- Q_PROPERTY(QString cloudUserName READ cloudUserName WRITE setCloudUserName NOTIFY cloudUserNameChanged)
- Q_PROPERTY(QString cloudPassword READ cloudPassword WRITE setCloudPassword NOTIFY cloudPasswordChanged)
- Q_PROPERTY(QString logText READ logText WRITE setLogText NOTIFY logTextChanged)
- Q_PROPERTY(bool locationServiceEnabled READ locationServiceEnabled WRITE setLocationServiceEnabled NOTIFY locationServiceEnabledChanged)
- Q_PROPERTY(int distanceThreshold READ distanceThreshold WRITE setDistanceThreshold NOTIFY distanceThresholdChanged)
- Q_PROPERTY(int timeThreshold READ timeThreshold WRITE setTimeThreshold NOTIFY timeThresholdChanged)
- Q_PROPERTY(bool loadFromCloud READ loadFromCloud WRITE setLoadFromCloud NOTIFY loadFromCloudChanged)
- Q_PROPERTY(QString startPageText READ startPageText WRITE setStartPageText NOTIFY startPageTextChanged)
- Q_PROPERTY(bool verboseEnabled READ verboseEnabled WRITE setVerboseEnabled NOTIFY verboseEnabledChanged)
- Q_PROPERTY(credentialStatus_t credentialStatus READ credentialStatus WRITE setCredentialStatus NOTIFY credentialStatusChanged)
- Q_PROPERTY(int accessingCloud READ accessingCloud WRITE setAccessingCloud NOTIFY accessingCloudChanged)
- Q_PROPERTY(bool syncToCloud READ syncToCloud WRITE setSyncToCloud NOTIFY syncToCloudChanged)
-
-public:
- QMLManager();
- ~QMLManager();
-
- enum credentialStatus_t {
- INCOMPLETE,
- UNKNOWN,
- INVALID,
- VALID_EMAIL,
- VALID
- };
-
- static QMLManager *instance();
-
- QString cloudUserName() const;
- void setCloudUserName(const QString &cloudUserName);
-
- QString cloudPassword() const;
- void setCloudPassword(const QString &cloudPassword);
-
- bool locationServiceEnabled() const;
- void setLocationServiceEnabled(bool locationServiceEnable);
-
- bool verboseEnabled() const;
- void setVerboseEnabled(bool verboseMode);
-
- int distanceThreshold() const;
- void setDistanceThreshold(int distance);
-
- int timeThreshold() const;
- void setTimeThreshold(int time);
-
- bool loadFromCloud() const;
- void setLoadFromCloud(bool done);
- void syncLoadFromCloud();
-
- QString startPageText() const;
- void setStartPageText(const QString& text);
-
- credentialStatus_t credentialStatus() const;
- void setCredentialStatus(const credentialStatus_t value);
-
- QString logText() const;
- void setLogText(const QString &logText);
-
- int accessingCloud() const;
- void setAccessingCloud(int status);
-
- bool syncToCloud() const;
- void setSyncToCloud(bool status);
-
- typedef void (QMLManager::*execute_function_type)();
-
-public slots:
- void applicationStateChanged(Qt::ApplicationState state);
- void savePreferences();
- void saveCloudCredentials();
- void checkCredentialsAndExecute(execute_function_type execute);
- void tryRetrieveDataFromBackend();
- void handleError(QNetworkReply::NetworkError nError);
- void handleSslErrors(const QList<QSslError> &errors);
- void retrieveUserid();
- void loadDivesWithValidCredentials();
- void loadDiveProgress(int percent);
- void provideAuth(QNetworkReply *reply, QAuthenticator *auth);
- void commitChanges(QString diveId, QString date, QString location,
- QString gps, QString duration, QString depth,
- QString airtemp, QString watertemp, QString suit,
- QString buddy, QString diveMaster, QString weight, QString notes,
- QString startpressure, QString endpressure, QString gasmix);
-
- void saveChanges();
- void deleteDive(int id);
- void undoDelete(int id);
- QString addDive();
- void addDiveAborted(int id);
- void applyGpsData();
- void sendGpsData();
- void downloadGpsData();
- void populateGpsData();
- void clearGpsData();
- void finishSetup();
- void openLocalThenRemote(QString url);
- int getIndex(const QString& diveId);
- QString getNumber(const QString& diveId);
- QString getDate(const QString& diveId);
- QString getCurrentPosition();
- QString getVersion() const;
- void deleteGpsFix(quint64 when);
- void refreshDiveList();
- void screenChanged(QScreen *screen);
- qreal lastDevicePixelRatio();
- void appendTextToLog(const QString &newText);
-
-private:
- QString m_cloudUserName;
- QString m_cloudPassword;
- QString m_ssrfGpsWebUserid;
- QString m_startPageText;
- QString m_logText;
- bool m_locationServiceEnabled;
- bool m_verboseEnabled;
- int m_distanceThreshold;
- int m_timeThreshold;
- GpsLocation *locationProvider;
- bool m_loadFromCloud;
- static QMLManager *m_instance;
- QNetworkReply *reply;
- QNetworkRequest request;
- struct dive *deletedDive;
- struct dive_trip *deletedTrip;
- int m_accessingCloud;
- bool m_syncToCloud;
- credentialStatus_t m_credentialStatus;
- qreal m_lastDevicePixelRatio;
- QElapsedTimer timer;
- bool alreadySaving;
-
-signals:
- void cloudUserNameChanged();
- void cloudPasswordChanged();
- void locationServiceEnabledChanged();
- void verboseEnabledChanged();
- void logTextChanged();
- void timeThresholdChanged();
- void distanceThresholdChanged();
- void loadFromCloudChanged();
- void startPageTextChanged();
- void credentialStatusChanged();
- void accessingCloudChanged();
- void syncToCloudChanged();
- void sendScreenChanged(QScreen *screen);
-};
-
-#endif
diff --git a/qt-mobile/qmlprofile.cpp b/qt-mobile/qmlprofile.cpp
deleted file mode 100644
index ad686561d..000000000
--- a/qt-mobile/qmlprofile.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-#include "qmlprofile.h"
-#include "qmlmanager.h"
-#include "profile-widget/profilewidget2.h"
-#include "subsurface-core/dive.h"
-#include "subsurface-core/metrics.h"
-#include <QTransform>
-#include <QScreen>
-
-QMLProfile::QMLProfile(QQuickItem *parent) :
- QQuickPaintedItem(parent),
- m_devicePixelRatio(1.0),
- m_margin(0)
-{
- setAntialiasing(true);
- m_profileWidget = new ProfileWidget2(0);
- m_profileWidget->setProfileState();
- m_profileWidget->setPrintMode(true);
- m_profileWidget->setFontPrintScale(0.8);
- connect(QMLManager::instance(), &QMLManager::sendScreenChanged, this, &QMLProfile::screenChanged);
- setDevicePixelRatio(QMLManager::instance()->lastDevicePixelRatio());
-}
-
-QMLProfile::~QMLProfile()
-{
- m_profileWidget->deleteLater();
-}
-
-void QMLProfile::paint(QPainter *painter)
-{
- // let's look at the intended size of the content and scale our scene accordingly
- QRect painterRect = painter->viewport();
- QRect profileRect = m_profileWidget->viewport()->rect();
- // qDebug() << "profile viewport and painter viewport" << profileRect << painterRect;
- qreal sceneSize = 104; // that should give us 2% margin all around (100x100 scene)
- qreal dprComp = devicePixelRatio() * painterRect.width() / profileRect.width();
- qreal sx = painterRect.width() / sceneSize / dprComp;
- qreal sy = painterRect.height() / sceneSize / dprComp;
-
- // next figure out the weird magic by which we need to shift the painter so the profile is shown
- int dpr = rint(devicePixelRatio());
- qreal magicShiftFactor = (dpr == 2 ? 0.25 : (dpr == 3 ? 0.33 : 0.0));
-
- // now set up the transformations scale the profile and
- // shift the painter (taking its existing transformation into account)
- QTransform profileTransform = QTransform();
- profileTransform.scale(sx, sy);
- QTransform painterTransform = painter->transform();
- painterTransform.translate(-painterRect.width() * magicShiftFactor ,-painterRect.height() * magicShiftFactor);
-
-#if PROFILE_SCALING_DEBUG
- // some debugging messages to help adjust this in case the magic above is insufficient
- QMLManager::instance()->appendTextToLog(QString("dpr %1 profile viewport %2 %3 painter viewport %4 %5").arg(dpr).arg(profileRect.width()).arg(profileRect.height())
- .arg(painterRect.width()).arg(painterRect.height()));
- QMLManager::instance()->appendTextToLog(QString("profile matrix %1 %2 %3 %4 %5 %6 %7 %8 %9").arg(profileTransform.m11()).arg(profileTransform.m12()).arg(profileTransform.m13())
- .arg(profileTransform.m21()).arg(profileTransform.m22()).arg(profileTransform.m23())
- .arg(profileTransform.m31()).arg(profileTransform.m32()).arg(profileTransform.m33()));
- QMLManager::instance()->appendTextToLog(QString("painter matrix %1 %2 %3 %4 %5 %6 %7 %8 %9").arg(painterTransform.m11()).arg(painterTransform.m12()).arg(painterTransform.m13())
- .arg(painterTransform.m21()).arg(painterTransform.m22()).arg(painterTransform.m23())
- .arg(painterTransform.m31()).arg(painterTransform.m32()).arg(painterTransform.m33()));
- qDebug() << "profile scaled by" << profileTransform.m11() << profileTransform.m22() << "and translated by" << profileTransform.m31() << profileTransform.m32();
- qDebug() << "exist profile transform" << m_profileWidget->transform() << "painter transform" << painter->transform();
-#endif
- // apply the transformation
- painter->setTransform(painterTransform);
- m_profileWidget->setTransform(profileTransform);
-
- // finally, render the profile
- m_profileWidget->render(painter);
-}
-
-void QMLProfile::setMargin(int margin)
-{
- m_margin = margin;
-}
-
-QString QMLProfile::diveId() const
-{
- return m_diveId;
-}
-
-void QMLProfile::setDiveId(const QString &diveId)
-{
- m_diveId = diveId;
- struct dive *d = get_dive_by_uniq_id(m_diveId.toInt());
- if (m_diveId.toInt() < 1)
- return;
- if (!d)
- return;
- qDebug() << "setDiveId called with valid dive" << d->number;
- m_profileWidget->plotDive(d, true);
-}
-
-qreal QMLProfile::devicePixelRatio() const
-{
- return m_devicePixelRatio;
-}
-
-void QMLProfile::setDevicePixelRatio(qreal dpr)
-{
- if (dpr != m_devicePixelRatio) {
- m_devicePixelRatio = dpr;
- m_profileWidget->setFontPrintScale(0.8 * dpr);
- updateDevicePixelRatio(dpr);
- emit devicePixelRatioChanged();
- }
-}
-
-void QMLProfile::screenChanged(QScreen *screen)
-{
- setDevicePixelRatio(screen->devicePixelRatio());
-}
diff --git a/qt-mobile/qmlprofile.h b/qt-mobile/qmlprofile.h
deleted file mode 100644
index c8a77d700..000000000
--- a/qt-mobile/qmlprofile.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef QMLPROFILE_H
-#define QMLPROFILE_H
-
-#include <QQuickPaintedItem>
-
-class ProfileWidget2;
-
-class QMLProfile : public QQuickPaintedItem
-{
- Q_OBJECT
- Q_PROPERTY(QString diveId READ diveId WRITE setDiveId NOTIFY diveIdChanged)
- Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio WRITE setDevicePixelRatio NOTIFY devicePixelRatioChanged)
-
-public:
- explicit QMLProfile(QQuickItem *parent = 0);
- virtual ~QMLProfile();
-
- void paint(QPainter *painter);
-
- QString diveId() const;
- void setDiveId(const QString &diveId);
- qreal devicePixelRatio() const;
- void setDevicePixelRatio(qreal dpr);
-
-public slots:
- void setMargin(int margin);
- void screenChanged(QScreen *screen);
-private:
- QString m_diveId;
- qreal m_devicePixelRatio;
- int m_margin;
- ProfileWidget2 *m_profileWidget;
-
-signals:
- void rightAlignedChanged();
- void diveIdChanged();
- void devicePixelRatioChanged();
-};
-
-#endif // QMLPROFILE_H