From a5ef0388237fbd42509503bae811d75a16bdf9ca Mon Sep 17 00:00:00 2001 From: Zoe Moore Date: Fri, 1 Apr 2022 16:08:02 -0700 Subject: [PATCH] Add and delete works now! --- main.qml | 56 ++++++++++++++++++++++++++++++---------- metar.nim | 76 +++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 106 insertions(+), 26 deletions(-) diff --git a/main.qml b/main.qml index 5f2d2a9..4414c14 100644 --- a/main.qml +++ b/main.qml @@ -37,23 +37,53 @@ Kirigami.ApplicationWindow { contentItem: Item { implicitWidth: delegateLayout.implicitWidth implicitHeight: delegateLayout.implicitHeight - RowLayout { - id: delegateLayout - anchors { - left: parent.left - top: parent.top - right: parent.right - } - Kirigami.Heading { - text: flightCategory - } - Controls.Label { - text: rawMetar + ColumnLayout { + id: delegateLayout + anchors { + left: parent.left + top: parent.top + right: parent.right + } + RowLayout { + Layout.fillWidth: true + Kirigami.Heading { + text: stationId + } + Kirigami.Heading { + text: flightCategory + + // Dynamically set the color based on the flight category + Component.onCompleted: { + color = Qt.binding(function() { + if (flightCategory == "VFR") { + return "green"; + } else if (flightCategory == "MVFR") { + return "blue"; + } else if (flightCategory == "IFR") { + return "red"; + } else if (flightCategory == "LIFR") { + return "fuchsia"; + } else { + return "white"; + } + }); + } + } + Controls.Button { + Layout.alignment: Qt.AlignRight + icon.name: "edit-delete" + onClicked: logic.deleteAirport(stationId) + } + } + Controls.Label { + text: rawMetar + Layout.fillWidth: true + wrapMode: Text.WordWrap + } } } } } - } Kirigami.OverlaySheet { id: addAirport diff --git a/metar.nim b/metar.nim index 9c348c8..7c07ee9 100644 --- a/metar.nim +++ b/metar.nim @@ -1,4 +1,4 @@ -import std/[httpclient, times, xmlparser, xmltree] +import std/[httpclient, os, sequtils, sugar, strutils, xmlparser, xmltree] import Tables import strformat import NimQml @@ -58,6 +58,38 @@ proc newMetarData*(xmlData: XMLNode): MetarData = type AirportRoles {.pure.} = enum RawMetar = UserRole + 1 FlightCategory = UserRole + 2 + StationId = UserRole + 3 + +proc readConfig(): seq[string] = + let metarConfigDir = getConfigDir() & "/metarweather" + let metarConf = metarConfigDir & "/metarweather.conf" + + if not dirExists(metarConfigDir): + createDir(metarConfigDir) + + if not fileExists(metarConf): + return @[] + + let config = readFile(metarConf) + + if config.isEmptyOrWhiteSpace: + return @[] + + return config.strip().split(",") + +proc writeConfig(airports: seq[string]) = + let config = airports.join(",") + + let metarConfigDir = getConfigDir() & "/metarweather" + let metarConf = metarConfigDir & "/metarweather.conf" + + writeFile(metarConf, config) + + +proc getMetars(airports: seq[string]): seq[MetarData] = + let client = newHttpClient() + airports.map(airportCode => client.getMetar(airportCode)).map(metarXml => newMetarData(metarXml)) + QtObject: type MetarList* = ref object of QAbstractListModel @@ -87,10 +119,12 @@ QtObject: case airportRole: of AirportRoles.RawMetar: result = newQVariant(airport.rawText) of AirportRoles.FlightCategory: result = newQVariant(airport.flightCategory) + of AirportRoles.StationId: result = newQVariant(airport.stationId) method roleNames(self: MetarList): Table[int, string] = { AirportRoles.RawMetar.int:"rawMetar", - AirportRoles.FlightCategory.int:"flightCategory"}.toTable + AirportRoles.FlightCategory.int:"flightCategory", + AirportRoles.StationId.int:"stationId"}.toTable QtObject: type ApplicationLogic* = ref object of QObject @@ -103,6 +137,11 @@ QtObject: proc setup(self: ApplicationLogic) = self.QObject.setup + + proc getMetarList(self: ApplicationLogic): QVariant {.slot.} = + return newQVariant(self.metarList) + + proc metarListChanged(self: ApplicationLogic, metarList: QVariant) {.signal.} proc newApplicationLogic*(app: QApplication, airports: seq[MetarData]): ApplicationLogic = new(result, delete) @@ -111,19 +150,34 @@ QtObject: result.setup() proc refresh(self: ApplicationLogic) {.slot.} = - echo "Refresh called" + let airports = self.metarList.airports.map(metar => metar.stationId) + + self.metarList.delete + self.metarList = newMetarList(airports.getMetars()) + self.metarListChanged(newQVariant(self.metarList)) proc addAirport(self: ApplicationLogic, code: string) {.slot.} = - echo &"Add airport called {code}" + let airports = self.metarList.airports.map(metar => metar.stationId) & code + + writeConfig(airports) + + self.metarList.delete + self.metarList = newMetarList(airports.getMetars()) + self.metarListChanged(newQVariant(self.metarList)) proc deleteAirport(self: ApplicationLogic, code: string) {.slot.} = - echo &"Delete {code}" + let airports = self.metarList.airports.map(metar => metar.stationId) + .filter(stationId => stationId != code) - proc getMetarList(self: ApplicationLogic): QVariant {.slot.} = - return newQVariant(self.metarList) + writeConfig(airports) + + self.metarList.delete + self.metarList = newMetarList(airports.getMetars()) + self.metarListChanged(newQVariant(self.metarList)) QtProperty[QVariant] metarList: read = getMetarList + notify = metarListChanged proc mainProc() = let app = newQApplication() @@ -132,12 +186,8 @@ proc mainProc() = let engine = newQQmlApplicationEngine() defer: engine.delete() - let client = newHttpClient() - - let metarData = @[ - newMetarData(client.getMetar("KOAK")), - newMetarData(client.getMetar("KHWD")), - ] + let airports = readConfig() + let metarData = getMetars(airports) let logic = newApplicationLogic(app, metarData) let logicVariant = newQVariant(logic)