subsurface/mobile-widgets/qml/main.qml

431 lines
12 KiB
QML
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0
import QtQuick 2.4
import QtQuick.Controls 2.0
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 2.0 as Kirigami
Kirigami.ApplicationWindow {
id: rootItem
title: qsTr("Subsurface-mobile")
header: Kirigami.ApplicationHeader {
minimumHeight: 0
preferredHeight: Math.round(Kirigami.Units.gridUnit * (Qt.platform.os == "ios" ? 2 : 1.5))
maximumHeight: Kirigami.Units.gridUnit * 2
}
property bool fullscreen: true
property alias oldStatus: manager.oldStatus
property alias notificationText: manager.notificationText
property QtObject notification: null
property bool showingDiveList: false
property alias syncToCloud: manager.syncToCloud
property alias showPin: manager.showPin
onNotificationTextChanged: {
if (notificationText != "") {
// there's a risk that we have a >5 second gap in update events;
// still, keep the timeout at 5s to avoid odd unchanging notifications
showPassiveNotification(notificationText, 5000)
} else {
// hiding the notification right away may be a mistake as it hides the last warning / error
hidePassiveNotification();
}
}
FontMetrics {
id: fontMetrics
Component.onCompleted: {
console.log("Using the following font: " + fontMetrics.font.family)
}
/* this shouldn't be needed anymore
Component.onCompleted: {
if (Math.round(rootItem.width / Kirigami.Units.gridUnit) < 20) {
fontMetrics.font.pointSize = fontMetrics.font.pointSize * 2 / 3
Kirigami.Theme.defaultFont.pointSize = fontMetrics.font.pointSize
console.log("Reduce font size for narrow screens: " + fontMetrics.font.pointSize)
}
}
*/
}
visible: false
// TODO: Verify where the opacity went to.
// 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.buddyModel = manager.buddyInit
detailsWindow.buddyIndex = -1
detailsWindow.buddyText = ""
detailsWindow.depth = ""
detailsWindow.divemasterModel = manager.divemasterInit
detailsWindow.divemasterIndex = -1
detailsWindow.divemasterText = ""
detailsWindow.notes = ""
detailsWindow.location = ""
detailsWindow.gps = ""
detailsWindow.duration = ""
detailsWindow.suitModel = manager.suitInit
detailsWindow.suitIndex = -1
detailsWindow.suitText = ""
detailsWindow.cylinderModel = manager.cylinderInit
detailsWindow.cylinderIndex = -1
detailsWindow.cylinderText = ""
detailsWindow.weight = ""
detailsWindow.gasmix = ""
detailsWindow.startpressure = ""
detailsWindow.endpressure = ""
detailsWindow.gpsCheckbox = false
stackView.push(detailsWindow)
}
globalDrawer: Kirigami.GlobalDrawer {
title: qsTr("Subsurface")
titleIcon: "qrc:/qml/subsurface-mobile-icon.png"
bannerImageSource: "dive.jpg"
actions: [
Kirigami.Action {
text: qsTr("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: qsTr("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: qsTr("Manage dives")
Kirigami.Action {
text: qsTr("Add dive manually")
enabled: manager.credentialStatus === QMLManager.VALID || manager.credentialStatus === QMLManager.VALID_EMAIL || manager.credentialStatus === QMLManager.NOCLOUD
onTriggered: {
returnTopPage() // otherwise odd things happen with the page stack
startAddDive()
}
}
Kirigami.Action {
text: qsTr("Download from DC")
enabled: true
onTriggered: {
downloadFromDc.dcImportModel.clearTable()
stackView.push(downloadFromDc)
}
}
Kirigami.Action {
text: qsTr("Manual sync with cloud")
enabled: manager.credentialStatus === QMLManager.VALID || manager.credentialStatus === QMLManager.VALID_EMAIL || manager.credentialStatus === QMLManager.NOCLOUD
onTriggered: {
if (manager.credentialStatus === QMLManager.NOCLOUD) {
returnTopPage()
oldStatus = manager.credentialStatus
manager.startPageText = "Enter valid cloud storage credentials"
manager.credentialStatus = QMLManager.UNKNOWN
globalDrawer.close()
} else {
globalDrawer.close()
detailsWindow.endEditMode()
manager.saveChangesCloud(true);
globalDrawer.close()
}
}
}
Kirigami.Action {
text: syncToCloud ? qsTr("Offline mode") : qsTr("Enable auto cloud sync")
enabled: manager.credentialStatus !== QMLManager.NOCLOUD
onTriggered: {
syncToCloud = !syncToCloud
if (!syncToCloud) {
var alertText = "Turning off automatic sync to cloud causes all data\n"
alertText +="to only be stored locally.\n"
alertText += "This can be very useful in situations with\n"
alertText += "limited or no network access.\n"
alertText += "Please chose 'Manual sync with cloud' if you have network\n"
alertText += "connectivity and want to sync your data to cloud storage."
showPassiveNotification(alertText, 10000)
}
}
}
},
Kirigami.Action {
text: qsTr("GPS")
enabled: manager.credentialStatus === QMLManager.VALID || manager.credentialStatus === QMLManager.VALID_EMAIL
visible: (Qt.platform.os !== "ios")
Kirigami.Action {
text: qsTr("GPS-tag dives")
onTriggered: {
manager.applyGpsData();
}
}
Kirigami.Action {
text: qsTr("Upload GPS data")
onTriggered: {
manager.sendGpsData();
}
}
Kirigami.Action {
text: qsTr("Download GPS data")
onTriggered: {
manager.downloadGpsData();
}
}
Kirigami.Action {
text: qsTr("Show GPS fixes")
onTriggered: {
returnTopPage()
manager.populateGpsData();
stackView.push(gpsWindow)
}
}
Kirigami.Action {
text: qsTr("Clear GPS cache")
onTriggered: {
manager.clearGpsData();
}
}
Kirigami.Action {
text: qsTr("Preferences")
onTriggered: {
stackView.push(prefsWindow)
detailsWindow.endEditMode()
}
}
},
Kirigami.Action {
text: qsTr("Developer")
Kirigami.Action {
text: qsTr("App log")
onTriggered: {
stackView.push(logWindow)
}
}
Kirigami.Action {
text: qsTr("Switch to pink theme")
onTriggered: {
pinkTheme()
}
}
Kirigami.Action {
text: qsTr("Switch to blue theme")
onTriggered: {
blueTheme()
}
}
Kirigami.Action {
text: qsTr("Theme information")
onTriggered: {
stackView.push(themetest)
}
}
},
Kirigami.Action {
text: qsTr("User manual")
onTriggered: {
Qt.openUrlExternally("https://subsurface-divelog.org/documentation/subsurface-mobile-user-manual/")
}
},
Kirigami.Action {
text: qsTr("About")
onTriggered: {
stackView.push(aboutWindow)
detailsWindow.endEditMode()
}
}
] // end actions
MouseArea {
height: childrenRect.height
width: Kirigami.Units.gridUnit * 10
CheckBox {
//text: qsTr("Run location service")
id: locationCheckbox
visible: manager.locationServiceAvailable
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: Qt.platform.os == "ios" ? "" : manager.locationServiceAvailable ? qsTr("Run location service") : qsTr("No GPS source available")
}
onClicked: {
print("Click.")
locationCheckbox.checked = !locationCheckbox.checked
}
}
}
function blueTheme() {
subsurfaceTheme.darkPrimaryColor = "#303F9f"
subsurfaceTheme.darkPrimaryTextColor= "#ECECEC"
subsurfaceTheme.primaryColor = "#3F51B5"
subsurfaceTheme.primaryTextColor = "#ECECEC"
subsurfaceTheme.lightPrimaryColor = "#C5CAE9"
subsurfaceTheme.lightPrimaryTextColor = "#212121"
}
function pinkTheme() {
subsurfaceTheme.darkPrimaryColor = "#FF1493"
subsurfaceTheme.darkPrimaryTextColor = "#ECECEC"
subsurfaceTheme.primaryColor = "#FF69B4"
subsurfaceTheme.primaryTextColor = "#212121"
subsurfaceTheme.lightPrimaryColor = "#FFDDF4"
subsurfaceTheme.lightPrimaryTextColor = "#212121"
}
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 darkPrimaryColor: "#303F9f"
property color darkPrimaryTextColor: "#ECECEC"
property color primaryColor: "#3F51B5"
property color primaryTextColor: "#ECECEC"
property color lightPrimaryColor: "#C5CAE9"
property color lightPrimaryTextColor: "#212121"
property color contrastAccentColor: "#FF9800" // used for delete button
property color diveListTextColor: lightPrimaryTextColor
property int columnWidth: Math.round(rootItem.width/(Kirigami.Units.gridUnit*28)) > 0 ? Math.round(rootItem.width / Math.round(rootItem.width/(Kirigami.Units.gridUnit*28))) : rootItem.width
Component.onCompleted: {
Kirigami.Theme.highlightColor = Qt.binding(function() { return darkPrimaryColor })
Kirigami.Theme.highlighedTextColor = Qt.binding(function() { return darkPrimaryTextColor })
}
}
property Item stackView: pageStack
pageStack.initialPage: DiveList {
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
anchors.fill: parent
}
Log {
id: logWindow
visible: false
}
GpsList {
id: gpsWindow
visible: false
}
DownloadFromDiveComputer {
id: downloadFromDc
visible: false
}
ThemeTest {
id: themetest
visible: false
}
Component.onCompleted: {
manager.finishSetup();
rootItem.visible = true
diveList.opacity = 1
rootItem.opacity = 1
pageStack.defaultColumnWidth = Kirigami.Units.gridUnit * 28
}
/* TODO: Verify where opacity went to.
Behavior on opacity {
NumberAnimation {
duration: 200
easing.type: Easing.OutQuad
}
}
*/
}