Start of a proper station schedule parsing.
[quandoparte] / application / stationlistmodel.cpp
1 /*
2
3 Copyright (C) 2011 Luciano Montanaro <mikelima@cirulla.net>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file COPYING.  If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19
20 */
21
22 #include "stationlistmodel.h"
23
24 #include <QFile>
25 #include <QFileInfo>
26 #include <QDebug>
27 #include <QStandardItem>
28 #include <QGeoCoordinate>
29
30 QTM_USE_NAMESPACE
31 Q_DECLARE_METATYPE(QGeoCoordinate)
32
33 StationListModel::StationListModel(QObject *parent) :
34     QStandardItemModel(parent)
35 {
36     setRowCount(0);
37 }
38
39 bool StationListModel::load(const QString &filename)
40 {
41     QFile file(filename);
42     QFileInfo fi(file);
43
44     qDebug() << "loading file:" << fi.absoluteFilePath();
45
46     emit layoutAboutToBeChanged();
47     if (!file.open(QFile::ReadOnly | QFile::Text)) {
48         qDebug() << "cannot open file:" << filename;
49         return false;
50     }
51     m_reader.setDevice(&file);
52     m_reader.readNext();
53     while (!m_reader.atEnd()) {
54         if (m_reader.isStartElement()) {
55             if(m_reader.name() == "stations") {
56                 readStationsElement();
57             } else {
58                 m_reader.raiseError(tr("Not a qpl file"));
59             }
60         } else {
61             m_reader.readNext();
62         }
63     }
64     file.close();
65     if (m_reader.hasError()) {
66         qDebug() << "parser error for:" << filename;
67         return false;
68     } else if (file.error() != QFile::NoError) {
69         qDebug() << "file error for:" << filename;
70         return false;
71     }
72     emit layoutChanged();
73     return true;
74 }
75
76 void StationListModel::readStationsElement()
77 {
78     m_reader.readNext();
79     while (!m_reader.atEnd()) {
80         if (m_reader.isEndElement()) {
81             m_reader.readNext();
82             break;
83         } else if (m_reader.isStartElement()) {
84             if (m_reader.name() == "station") {
85                 readStationElement();
86             } else {
87                 skipUnknownElement();
88             }
89         } else {
90             m_reader.readNext();
91         }
92     }
93 }
94
95 void StationListModel::readStationElement()
96 {
97     QStandardItem *item = new QStandardItem;
98     m_reader.readNext();
99     while (!m_reader.atEnd()) {
100         if (m_reader.isEndElement()) {
101             this->appendRow(item);
102             m_reader.readNext();
103             break;
104         } else if (m_reader.isStartElement()) {
105             if (m_reader.name() == "pos") {
106                 readPosElement(item);
107             } else  if (m_reader.name() == "name") {
108                 readNameElement(item);
109             } else {
110                 skipUnknownElement();
111             }
112         } else {
113             m_reader.readNext();
114         }
115     }
116 }
117
118 void StationListModel::readPosElement(QStandardItem *item)
119 {
120     QStringList coordinates = m_reader.readElementText().split(",");
121     QGeoCoordinate pos = QGeoCoordinate(coordinates[0].toDouble(), coordinates[1].toDouble());
122     item->setData(QVariant::fromValue(pos), PositionRole);
123     m_reader.readElementText();
124     if (m_reader.isEndElement()) {
125         m_reader.readNext();
126     }
127 }
128
129 void StationListModel::readNameElement(QStandardItem *item)
130 {
131     item->setText(m_reader.readElementText());
132     if (m_reader.isEndElement()) {
133         m_reader.readNext();
134     }
135 }
136
137 void StationListModel::skipUnknownElement()
138 {
139     qDebug() << "skipping unknown element";
140
141     m_reader.readNext();
142     while (!m_reader.atEnd()) {
143         if (m_reader.isEndElement()) {
144             m_reader.readNext();
145             break;
146         } else if (!m_reader.isStartElement()) {
147             skipUnknownElement();
148         } else {
149             m_reader.readNext();
150         }
151     }
152 }