--- /dev/null
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+
+CoverBackground {
+ Label {
+ id: label
+ anchors.centerIn: parent
+ text: qsTr("Quando Parte")
+ }
+
+/*
+ CoverActionList {
+ id: coverAction
+
+ CoverAction {
+ iconSource: "image://theme/icon-cover-next"
+ }
+
+ CoverAction {
+ iconSource: "image://theme/icon-cover-pause"
+ }
+ }
+*/
+}
+
+
--- /dev/null
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import "pages"
+
+ApplicationWindow {
+ id: window
+ initialPage: StationListPage { }
+ cover: Qt.resolvedUrl("cover/CoverPage.qml")
+}
--- /dev/null
+var view = undefined
+var about = undefined
+
+function showAboutPage()
+{
+ var component = Qt.createComponent("AboutPage.qml")
+ if (component.status === Component.Ready) {
+ about = component.createObject(stationListPage)
+ pageStack.push(about)
+ } else
+ console.log('Cannot load component: ' + component.errorString());
+}
+
+function loadStation(name, code)
+{
+ var component = Qt.createComponent("StationPage.qml");
+ if (component.status === Component.Ready) {
+ view = component.createObject(stationListPage)
+ stationListPage.stationView = view
+ pageStack.push(view)
+
+ /*
+ XXX Ugliness ahead! Changing the name triggers the station
+ schedule to be fetched. So any extra data (the code specifically)
+ must be set before changing the name.
+ */
+ if (code !== undefined) view.code = code
+ view.name = name
+ }
+ else
+ console.log('Cannot load component: ' + component.errorString());
+}
+
+function highlightSearch(s, color)
+{
+ // TODO compile RegExp on change, or find a way to cleanly use
+ // stationListProxyModel.filterRegExp
+ if (searchField.text.length) {
+ var r = new RegExp(searchField.text, 'i')
+ var match = r.exec(s)
+ return s.replace(r, '<span style="text-decoration:underline;color:' + color + ';">' +
+ match + '</span>')
+ } else {
+ return s
+ }
+}
+
--- /dev/null
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import net.cirulla.quandoparte 1.0
+import "StationListPage.js" as Private
+
+Page {
+ property variant stationView
+ id: stationListPage
+ Binding {
+ target: stationListProxyModel
+ property: "searchPattern"
+ value: searchField.text
+ }
+ Binding {
+ target: stationListProxyModel
+ property: "sortingMode"
+ value: header.currentIndex
+ }
+ Binding {
+ target: stationListView
+ property: "section.property"
+ value: header.currentIndex === 0 ? "name" : ""
+ }
+ SilicaListView {
+ id: stationListView
+ clip: true
+ width: parent.width
+ cacheBuffer: 10
+ anchors.fill: parent
+ model: stationListProxyModel
+ header: Column {
+ ComboBox {
+ id: header
+ currentIndex: stationListProxyModel.sortingMode
+ menu: ContextMenu {
+ MenuItem {
+ text: qsTr("by Name")
+ }
+ MenuItem {
+ text: qsTr("by Distance")
+ }
+ MenuItem {
+ text: qsTr("Recently Seen")
+ }
+ }
+ label: qsTr("Stations")
+ }
+ SearchField {
+ id: searchField
+ placeholderText: qsTr("Search station...")
+ }
+ }
+ section {
+ criteria: ViewSection.FirstCharacter
+ delegate: Item {
+ width: parent.width
+ height: Theme.itemSizeSmall
+ anchors {
+ margins: Theme.paddingMedium
+ }
+ Image {
+ anchors {
+ left: parent.left
+ right: sectionLabel.left
+ verticalCenter: parent.verticalCenter
+ margins: Theme.paddingMedium
+ }
+ source: "image://theme/meegotouch-separator-" + (theme.inverted ? "inverted-" : "") + "background-horizontal"
+ }
+ Label {
+ id: sectionLabel
+ anchors {
+ right: sectionRightMargin.left
+ verticalCenter: parent.verticalCenter
+ }
+ text: section
+ }
+ Item {
+ id: sectionRightMargin
+ anchors {
+ right: parent.right
+ }
+ width: Theme.paddingMedium
+ height: Theme.paddingMedium
+ }
+ }
+ delegate: BackgroundItem {
+ id: listItem
+ height: Theme.itemSizeSmall
+ width: parent.width
+ Label {
+ id: mainText
+ x: Theme.paddingLarge
+ text: Private.highlightSearch(model.name, Theme.highlightColor)
+ }
+ onClicked: Private.loadStation(model.name, model.code)
+ }
+ }
+ }
+ ScrollDecorator {
+ id: decorator
+ flickable: stationListView
+ }
+}
--- /dev/null
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import net.cirulla.quandoparte 1.0
+
+Page {
+ property alias name: schedule.name
+ property alias code: schedule.code
+
+ tools: ToolBarLayout {
+ id: toolBar
+ ToolIcon {
+ iconId: "icon-m-toolbar-back" + (theme.inverted ? "-white": "")
+ onClicked: pageStack.pop()
+ }
+ ToolIcon {
+ iconId: "icon-m-toolbar-refresh" + (theme.inverted ? "-white": "")
+ onClicked: updateStation() }
+ ToolIcon {
+ iconId: "icon-m-toolbar-view-menu" + (theme.inverted ? "-white": "")
+ onClicked: menu.open()
+ }
+ }
+ PageHeader {
+ id: header
+ anchors.top: parent.top
+ selectedIndex: schedule.type
+ options: [
+ qsTr("Departures"),
+ qsTr("Arrivals")
+ ]
+ }
+ InfoBar {
+ id: infoBar
+ anchors.top: header.bottom
+ text: parent.name
+ }
+ Binding {
+ target: schedule
+ property: "type"
+ value: header.selectedIndex
+ }
+ LabelStyle {
+ id: labelStyle
+ }
+ Item {
+ id: view
+ anchors {
+ top: infoBar.bottom
+ bottom: parent.bottom
+ left: parent.left
+ right: parent.right
+ }
+ DroppedShadow {
+ id: shadow
+ anchors.top: view.top
+ }
+ ListView {
+ id: stationScheduleView
+ clip: true
+ visible: false
+ width: parent.width
+ cacheBuffer: 40
+ anchors {
+ top: shadow.top
+ bottom: parent.bottom
+ }
+ model: schedule
+ delegate: StationScheduleDelegate {
+ width: stationScheduleView.width
+ type: schedule.type
+ arrivalTime: model.arrivalTime
+ departureTime: model.departureTime
+ train: model.train
+ arrivalStation: model.arrivalStation
+ departureStation: model.departureStation
+ delay: model.delay
+ actualPlatform: model.actualPlatform
+ expectedPlatfrom: model.expectedPlatform
+ }
+ }
+ ScrollDecorator {
+ id: decorator
+ flickableItem: stationScheduleView
+ }
+ BusyIndicator {
+ id: busyIndicator
+ platformStyle: BusyIndicatorStyle {
+ size: "large"
+ }
+ anchors.centerIn: parent
+ running: visible
+ }
+ Item {
+ id: errorDisplay
+ anchors.centerIn: parent
+ Column {
+ anchors.centerIn: parent
+ spacing: UiConstants.DefaultMargin
+ Text {
+ text: qsTr("Error!")
+ width: parent.width
+ font.pixelSize: UiConstants.HeaderFontPixelSize
+ font.bold: UiConstants.HeaderFontBoldness
+ horizontalAlignment: Text.AlignHCenter
+ }
+ Text {
+ text: schedule.error
+ width: parent.width
+ font.pixelSize: UiConstants.HeaderFontPixelSize
+ font.bold: UiConstants.DefaultFontBoldness
+ horizontalAlignment: Text.AlignHCenter
+ }
+ }
+ }
+ states: [
+ State {
+ name: "loading"
+ when: !completed
+ PropertyChanges {
+ target: stationScheduleView
+ visible: false
+ }
+ PropertyChanges {
+ target: errorDisplay
+ visible: false
+ }
+ PropertyChanges {
+ target: busyIndicator
+ visible: true
+ }
+ },
+ State {
+ name: "ready"
+ PropertyChanges {
+ target: stationScheduleView
+ visible: true
+ }
+ PropertyChanges {
+ target: errorDisplay
+ visible: false
+ }
+ PropertyChanges {
+ target: busyIndicator
+ visible: false
+ }
+ },
+ State {
+ name: "error"
+ when: schedule.error
+ PropertyChanges {
+ target: stationScheduleView
+ visible: false
+ }
+ PropertyChanges {
+ target: errorDisplay
+ visible: true
+ }
+ PropertyChanges {
+ target: busyIndicator
+ visible: false
+ }
+ }
+ ]
+ }
+ StationScheduleModel {
+ id: schedule
+ onNameChanged: updateStation()
+ onLayoutChanged: if (error) view.state = "error"
+ else view.state = "ready"
+ }
+ Component.onCompleted: {
+ updateTimer.timeout.connect(updateStation)
+ view.state = "loading"
+ }
+ function updateStation() {
+ view.state = "loading"
+ console.log("Updating station with " + schedule.name + ", " + schedule.code)
+ schedule.fetch(schedule.name, schedule.code)
+ }
+}