diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f45eb9d582adf6b92eefefe24670cbe4ad514539..78e31c9e60efe6ee1f88444ad7afc8517407a823 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,5 +12,5 @@ target_link_libraries(vehiclevoyage Qt5::Core Qt5::Qml Qt5::Quick Qt5::QuickCont install(TARGETS vehiclevoyage ${KF5_INSTALL_TARGETS_DEFAULT_ARGS}) if (CMAKE_SYSTEM_NAME STREQUAL "Android") - kirigami_package_breeze_icons(ICONS list-add application-javascript help-about edit-find edit-delete window-close mail-sent globe) + kirigami_package_breeze_icons(ICONS list-add application-javascript help-about edit-find edit-delete window-close mail-sent globe preferences-system edit-symbolic) endif() diff --git a/src/contents/ui/EditRecord.qml b/src/contents/ui/EditRecord.qml new file mode 100644 index 0000000000000000000000000000000000000000..128c16d36401007611075656d17bae75780d5314 --- /dev/null +++ b/src/contents/ui/EditRecord.qml @@ -0,0 +1,125 @@ +import QtQuick 2.14 +import org.kde.kirigami 2.12 as Kirigami +import QtQuick.Controls 2.14 as Controls +import QtQuick.Layouts 1.14 as Layouts +import QtQuick.Controls 1.4 as Old +import QtQuick.Dialogs 1.3 as Dialogs + +Kirigami.PageRoute { + name: "editrecord" + Component { + Kirigami.Page { + id: editRecordPage + title: qsTr("Edit Service Record") + property var serviceId: Kirigami.PageRouter.data.id + property var record: recordModel.getRecord(serviceId) + Layouts.ColumnLayout { + anchors.fill: parent + Kirigami.InlineMessage { + Layouts.Layout.fillWidth: true + Layouts.Layout.leftMargin: 10 + Layouts.Layout.rightMargin: 10 + z: 9997 + type: Kirigami.MessageType.Error + showCloseButton: true + id: formError + } + Kirigami.FormLayout { + Layouts.Layout.alignment: Qt.AlignHCenter + Layouts.Layout.fillWidth: true + width: editRecordPage.width + + Item { + Kirigami.FormData.isSection: true + Kirigami.FormData.label: "Service Information" + } + + Controls.TextField { + id: providerField + selectByMouse: true + Kirigami.FormData.label: qsTr("Service Provider")+":" + text: record["serviceprovider"] + } + + Controls.TextField { + id: typeField + enabled: false + text: record["servicetypename"] + Kirigami.FormData.label: qsTr("Service Type")+":" + } + + Layouts.RowLayout { + Kirigami.FormData.label: qsTr("Date")+":" + Controls.TextField { + id: dateField + text: new Date(record["servicedate"]).toLocaleDateString(Qt.locale()) + readOnly: true + } + Controls.Button { + icon.name: "office-calendar" + text: qsTr("Select Date") + display: Controls.AbstractButton.IconOnly + onClicked: { + calendarPopup.open(); + } + } + } + + Controls.TextField { + id: milesField + selectByMouse: true + Kirigami.FormData.label: qsTr("Miles")+":" + text: record["miles"] + inputMethodHints: Qt.ImhDigitsOnly + validator: IntValidator { + bottom: 0 + top: 500000 + } + } + + Controls.TextArea { + id: notesField + placeholderText: qsTr("Notes about service") + selectByMouse: true + Kirigami.FormData.label: qsTr("Notes")+":" + text: record["notes"] + } + + Layouts.RowLayout { + + Controls.Button { + text: qsTr("Save") + highlighted: true + onClicked: { + var dateObj = Date.fromLocaleDateString(Qt.locale(), dateField.text); + if(milesField.acceptableInput) { + recordModel.updateRecord(serviceId, providerField.text, dateObj.toISOString(), parseInt(milesField.text), notesField.text); + router.popRoute(); + } else { + formError.text = qsTr("Invalid number of miles."); + formError.visible = true; + } + } + } + Controls.Button { + text: qsTr("Cancel") + onClicked: { + router.popRoute(); + } + } + } + } + } + + Kirigami.OverlaySheet { + id: calendarPopup + Old.Calendar { + selectedDate: Date.fromLocaleDateString(Qt.locale(), dateField.text) + onClicked: { + dateField.text = date.toLocaleDateString(Qt.locale()); + } + } + } + } + } +} diff --git a/src/contents/ui/MainPage.qml b/src/contents/ui/MainPage.qml index 465687ec9d2413a871cdbca021d22929555d8bff..97dcbc69f0bda40c97da7138859287bce80c28ed 100644 --- a/src/contents/ui/MainPage.qml +++ b/src/contents/ui/MainPage.qml @@ -25,6 +25,13 @@ Kirigami.PageRoute { importDialog.visible = true; } }, + Kirigami.Action { + iconName: "preferences-system" + text: qsTr("Settings") + onTriggered: { + router.navigateToRoute(["main","settings"]); + } + }, Kirigami.Action { iconName: "help-about" text: qsTr("About") diff --git a/src/contents/ui/ServiceRecords.qml b/src/contents/ui/ServiceRecords.qml index d1b72b77fbd008fbc30254e67ddee61ddd214212..a99446493752f55f000eb187d306023edac2bcec 100644 --- a/src/contents/ui/ServiceRecords.qml +++ b/src/contents/ui/ServiceRecords.qml @@ -8,17 +8,17 @@ Kirigami.PageRoute { Component { Kirigami.ScrollablePage { - property var serviceId: Kirigami.PageRouter.data.id + property var vehicleId: Kirigami.PageRouter.data.id Component.onCompleted: { - recordModel.changeVehicleFilter(serviceId); + recordModel.changeVehicleFilter(vehcileId); //Check vehicle warnings - dbAnalytics.checkOilChangeNeededForVehicle(serviceId, appAnalyticsSettings.value("milesForOilChange",5000), appAnalyticsSettings.value("monthsForOilChange",6)); + dbAnalytics.checkOilChangeNeededForVehicle(vehicleId, appAnalyticsSettings.value("milesForOilChange",5000), appAnalyticsSettings.value("monthsForOilChange",6)); } Connections { target: recordModel function onVehicleUpdated(vehicleId) { //Check vehicle warnings - if(vehicleId == serviceId) { + if(vehicleId == vehicleId) { dbAnalytics.checkOilChangeNeededForVehicle(vehicleId, appAnalyticsSettings.value("milesForOilChange",5000), appAnalyticsSettings.value("monthsForOilChange",6)); } } @@ -29,7 +29,7 @@ Kirigami.PageRoute { text: qsTr("Add Service Record") iconName: "list-add" onTriggered: { - router.pushRoute({"route": "addrecord", "data": serviceId}); + router.pushRoute({"route": "addrecord", "data": vehicleId}); } } ListView { @@ -90,6 +90,16 @@ Kirigami.PageRoute { onTriggered: { recordModel.removeRecord(index); } + }, + Kirigami.Action { + text: qsTr("Edit") + iconName: "edit-symbolic" + onTriggered: { + if(router.routeActive(["main","servicerecords","editrecord"])) { + router.popRoute(); + } + router.pushRoute({"route": "editrecord", "data": {"id": index}}); + } } ] } diff --git a/src/contents/ui/Settings.qml b/src/contents/ui/Settings.qml new file mode 100644 index 0000000000000000000000000000000000000000..df49fa4270e8cdff4f685a2d8978c445f64ff38f --- /dev/null +++ b/src/contents/ui/Settings.qml @@ -0,0 +1,83 @@ +import QtQuick 2.14 +import org.kde.kirigami 2.12 as Kirigami +import QtQuick.Controls 2.14 as Controls +import QtQuick.Layouts 1.14 as Layouts + +Kirigami.PageRoute { + name: "settings" + Component { + Kirigami.Page { + id: settingsPage + title: qsTr("Settings") + Layouts.ColumnLayout { + anchors.fill: parent + Kirigami.InlineMessage { + Layouts.Layout.fillWidth: true + Layouts.Layout.leftMargin: 10 + Layouts.Layout.rightMargin: 10 + z: 9997 + type: Kirigami.MessageType.Error + showCloseButton: true + id: formError + } + Kirigami.FormLayout { + Layouts.Layout.alignment: Qt.AlignHCenter + Layouts.Layout.fillWidth: true + width: settingsPage.width + Item { + Kirigami.FormData.label: qsTr("Warning Thresholds") + Kirigami.FormData.isSection: true + } + Controls.TextField { + id: oilChangeMiles + Kirigami.FormData.label: qsTr("Oil Change Miles") + text: appAnalyticsSettings.value("milesForOilChange",5000) + validator: IntValidator { + bottom: 1 + top: 500000 + } + } + Controls.TextField { + id: oilChangeMonths + Kirigami.FormData.label: qsTr("Oil Change Months") + text: appAnalyticsSettings.value("monthsForOilChange",6) + validator: IntValidator { + bottom: 1 + top: 500000 + } + } + + Layouts.RowLayout { + + Controls.Button { + text: qsTr("Save") + highlighted: true + onClicked: { + if(oilChangeMiles.acceptableInput) { + if(oilChangeMonths.acceptableInput) { + appAnalyticsSettings.setValue("milesForOilChange", parseInt(oilChangeMiles.text)); + appAnalyticsSettings.setValue("monthsForOilChange", parseInt(oilChangeMonths.text)); + router.popRoute(); + } else { + formError.text = qsTr("Number of Months is invalid!"); + formError.visible = true; + } + } else { + formError.text = qsTr("Number of Miles is invalid!"); + formError.visible = true; + } + } + } + + Controls.Button { + text: qsTr("Cancel") + onClicked: { + router.popRoute(); + } + } + } + } + } + } + } +} diff --git a/src/contents/ui/main.qml b/src/contents/ui/main.qml index 5f46ac535f7b7eba53b38ee09a1bb79994a9fcb8..d7e423d7cafdc3a2e61e7ab9b0bc29bc72ee443e 100644 --- a/src/contents/ui/main.qml +++ b/src/contents/ui/main.qml @@ -4,7 +4,7 @@ import QtQuick.Controls 2.14 as Controls import QtQuick.Layouts 1.14 as Layouts import QtQuick.Controls 1.4 as Old import QtQuick.Dialogs 1.3 as Dialogs -import Qt.labs.settings 1.0 as Settings +import Qt.labs.settings 1.0 as QtSettings Kirigami.ApplicationWindow { id: root @@ -26,7 +26,7 @@ Kirigami.ApplicationWindow { id: contextDrawer } - Settings.Settings { + QtSettings.Settings { id: appAnalyticsSettings category: "analytics" } @@ -60,5 +60,9 @@ Kirigami.ApplicationWindow { ServiceRecords{} AddRecord{} + + Settings{} + + EditRecord{} } } diff --git a/src/db/sqlservicerecord.cpp b/src/db/sqlservicerecord.cpp index ed7a842c7065e6ba3ae872fdac9f3008932979e2..2d4632d9f4c1b27260406f7cca7d5364206eea47 100644 --- a/src/db/sqlservicerecord.cpp +++ b/src/db/sqlservicerecord.cpp @@ -99,6 +99,28 @@ void SqlServiceRecord::changeVehicleFilter(int id) this->currentVehicleID = id; } +QVariantMap SqlServiceRecord::getRecord(int index) +{ + QHash names = roleNames(); + QHashIterator i(names); + QVariantMap res; + QModelIndex idx = this->index(index, 0); + while(i.hasNext()) { + i.next(); + QVariant data = idx.data(i.key()); + res[i.value()] = data; + + } + return res; +} + +void SqlServiceRecord::updateRecord(int index, QString serviceProvider, QString dateISO, int miles, QString notes) +{ + //TODO +} + + + diff --git a/src/db/sqlservicerecord.h b/src/db/sqlservicerecord.h index 8069207977c0ac52dab6773bd31f20806bc18efc..75e7aea9280eb43a342e4fc7aef28e6a70f6a11d 100644 --- a/src/db/sqlservicerecord.h +++ b/src/db/sqlservicerecord.h @@ -19,6 +19,7 @@ #define SQLSERVICERECORD_H #include +#include /** * Model to access service records. @@ -34,6 +35,8 @@ public: Q_INVOKABLE void addNewRecord(QString serviceProvider, int serviceType, QString serviceTypeName, QString dateISO, int miles, QString notes); Q_INVOKABLE void removeRecord(int index); Q_INVOKABLE void changeVehicleFilter(int id); + Q_INVOKABLE QVariantMap getRecord(int index); + Q_INVOKABLE void updateRecord(int index, QString serviceProvider, QString dateISO, int miles, QString notes); signals: void vehicleUpdated(int vehicleId); diff --git a/src/resources.qrc b/src/resources.qrc index 69578300d6834307a706ef56b8340232746553b8..cc310e33e1df0a2b717315fcab749e3306781f8a 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -5,6 +5,8 @@ contents/ui/AddVehicle.qml contents/ui/ServiceRecords.qml contents/ui/AddRecord.qml + contents/ui/Settings.qml + contents/ui/EditRecord.qml contents/speed.svg contents/license.svg ../packaging/org.eyecreate.vehiclevoyage.svg