Add support for searching/displaying available lines
authorThomas Perl <m@thp.io>
Fri, 14 Oct 2011 11:39:22 +0000 (13:39 +0200)
committerThomas Perl <m@thp.io>
Fri, 14 Oct 2011 11:39:22 +0000 (13:39 +0200)
gotovienna-qml
qml/MainPage.qml

index d367357..3dab53a 100755 (executable)
@@ -7,7 +7,10 @@ __version__ = '1.0'
 __website__ = 'https://github.com/kelvan/gotoVienna/'
 __license__ = 'GNU General Public License v3 or later'
 
-from PySide import QtCore, QtGui, QtDeclarative
+from PySide.QtCore import *
+from PySide.QtGui import *
+from PySide.QtDeclarative import *
+
 from gotovienna.utils import *
 from gotovienna.realtime import *
 
@@ -15,21 +18,58 @@ import urllib2
 import os
 import sys
 
+class GotoViennaListModel(QAbstractListModel):
+    def __init__(self, objects=None):
+        QAbstractListModel.__init__(self)
+        if objects is None:
+            objects = []
+        self._objects = objects
+        self.setRoleNames({0: 'modelData'})
+
+    def set_objects(self, objects):
+        self._objects = objects
+
+    def get_objects(self):
+        return self._objects
+
+    def get_object(self, index):
+        return self._objects[index.row()]
+
+    def rowCount(self, parent=QModelIndex()):
+        return len(self._objects)
+
+    def data(self, index, role):
+        if index.isValid():
+            if role == 0:
+                return self.get_object(index)
+        return None
 
-class Gui(QtCore.QObject):
-    @QtCore.Slot(str, str)
+
+class Gui(QObject):
+    def __init__(self):
+        QObject.__init__(self)
+        self.itip = ITipParser()
+        self.lines = []
+
+        # Read line names in categorized/sorted order
+        for _, lines in categorize_lines(self.itip.lines):
+            self.lines.extend(lines)
+
+    @Slot(result='QStringList')
+    def get_lines(self):
+        return self.lines
+
+    @Slot(str, str)
     def search(self, line, station):
         line = line.upper()
         station = station.decode('utf-8')
         print line, station
-        
-        itip = ITipParser()
-        print itip.lines
-        if not line in itip.lines:
+
+        if line not in self.lines:
             return "Invalid line"
-        
+
         try:
-            stations = sorted(itip.get_stations(line).items())
+            stations = sorted(self.itip.get_stations(line).items())
             print stations
             headers, stations = zip(*stations)
             print headers
@@ -42,16 +82,16 @@ class Gui(QtCore.QObject):
             return e.message
 
 if __name__ == '__main__':
-    app = QtGui.QApplication(sys.argv)
+    app = QApplication(sys.argv)
 
-    view = QtDeclarative.QDeclarativeView()
+    view = QDeclarativeView()
 
     # instantiate the Python object
     itip = Gui()
 
     # expose the object to QML
     context = view.rootContext()
-    context.setContextProperty("itip", itip)
+    context.setContextProperty('itip', itip)
 
     if os.path.abspath(__file__).startswith('/usr/bin/'):
         # Assume system-wide installation, QML from /usr/share/
index 25cfbd9..a4b3a98 100644 (file)
@@ -17,6 +17,32 @@ Page {
         }
     }
 
+    SelectionDialog {
+        id: lineSelector
+        titleText: 'Select line'
+
+        model: ListModel {
+            id: lineSelectorModel
+
+            Component.onCompleted: {
+                var lines = itip.get_lines()
+
+                for (var idx in lines) {
+                    lineSelectorModel.append({'name': lines[idx]})
+                }
+            }
+        }
+
+        // XXX It would be nice if we could make a delegate with
+        // icons (i.e. U1, U2, ... in the right colors), but we
+        // would have to "copy" the default delegate style
+
+        onAccepted: {
+            console.log('accepted: ' + selectedIndex)
+            gline.text = lineSelectorModel.get(selectedIndex).name
+        }
+    }
+
     TextField {
         placeholderText: 'Line'
 
@@ -27,8 +53,22 @@ Page {
             topMargin: 20
             leftMargin: 10
             rightMargin: 10
+            right: lineSearchButton.left
+        }
+
+        onTextChanged: {
+            // TODO: Check if text matches an item in lineSelectorModel and
+            // set selectedIndex in lineSelector to the right item
+
+            if (lineSelector.selectedIndex == -1) {
+                return
+            }
+
+            // Disable selection in line selector if user changes the text
+            if (lineSelectorModel.get(lineSelector.selectedIndex).name != text) {
+                lineSelector.selectedIndex = -1
+            }
         }
-        width: parent.width - 20
 
          MouseArea {
              anchors.fill: parent
@@ -39,6 +79,22 @@ Page {
          }
     }
 
+    Button {
+        id: lineSearchButton
+
+        anchors {
+            top: gline.top
+            bottom: gline.bottom
+            right: parent.right
+            rightMargin: 10
+        }
+
+        width: 60
+        iconSource: 'image://theme/icon-m-common-search'
+
+        onClicked: lineSelector.open()
+    }
+
     TextField {
         placeholderText: 'Station'
         id: gstation