Implement list sections for Harmattan
[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 <QtLocation/QGeoCoordinate>
29
30 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
31 QTM_USE_NAMESPACE
32 Q_DECLARE_METATYPE(QGeoCoordinate)
33 #endif
34
35 static QHash<int, QByteArray> roles;
36
37 StationListModel::StationListModel(QObject *parent) :
38     QStandardItemModel(parent)
39 {
40     setRowCount(0);
41 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
42     QHash<int, QByteArray> roles;
43 #endif
44     roles[Qt::DisplayRole] = "name";
45     roles[StationListModel::PositionRole] = "position";
46     roles[StationListModel::StationCodeRole] = "code";
47 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
48     setRoleNames(roles);
49 #endif
50 }
51
52 bool StationListModel::load(const QString &filename)
53 {
54     QFile file(filename);
55     QFileInfo fi(file);
56
57     qDebug() << "loading file:" << fi.absoluteFilePath();
58
59     emit layoutAboutToBeChanged();
60     beginResetModel();
61     if (!file.open(QFile::ReadOnly | QFile::Text)) {
62         qDebug() << "cannot open file:" << filename;
63         return false;
64     }
65     m_reader.setDevice(&file);
66     m_reader.readNext();
67     while (!m_reader.atEnd()) {
68         if (m_reader.isStartElement()) {
69             if(m_reader.name() == "stations") {
70                 readStationsElement();
71             } else {
72                 m_reader.raiseError(tr("Not a qpl file"));
73             }
74         } else {
75             m_reader.readNext();
76         }
77     }
78     file.close();
79     qDebug() << rowCount() << "stations loaded";
80     if (m_reader.hasError()) {
81         qDebug() << "parser error for:" << filename;
82         return false;
83     } else if (file.error() != QFile::NoError) {
84         qDebug() << "file error for:" << filename;
85         return false;
86     }
87     endResetModel();
88     emit layoutChanged();
89     return true;
90 }
91
92 QHash<int, QByteArray> StationListModel::roleNames() const
93 {
94     return roles;
95 }
96
97 void StationListModel::readStationsElement()
98 {
99     m_reader.readNext();
100     while (!m_reader.atEnd()) {
101         if (m_reader.isEndElement()) {
102             m_reader.readNext();
103             break;
104         } else if (m_reader.isStartElement()) {
105             if (m_reader.name() == "station") {
106                 readStationElement();
107             } else {
108                 skipUnknownElement();
109             }
110         } else {
111             m_reader.readNext();
112         }
113     }
114 }
115
116 void StationListModel::readStationElement()
117 {
118     QStandardItem *item = new QStandardItem;
119     m_reader.readNext();
120     while (!m_reader.atEnd()) {
121         if (m_reader.isEndElement()) {
122             this->appendRow(item);
123             m_reader.readNext();
124             break;
125         } else if (m_reader.isStartElement()) {
126             if (m_reader.name() == "pos") {
127                 readPosElement(item);
128             } else  if (m_reader.name() == "name") {
129                 readNameElement(item);
130             } else  if (m_reader.name() == "code") {
131                 readCodeElement(item);
132             } else {
133                 skipUnknownElement();
134             }
135         } else {
136             m_reader.readNext();
137         }
138     }
139 }
140
141 void StationListModel::readPosElement(QStandardItem *item)
142 {
143     QStringList coordinates = m_reader.readElementText().split(",");
144     QGeoCoordinate pos = QGeoCoordinate(coordinates[0].toDouble(), coordinates[1].toDouble());
145     item->setData(QVariant::fromValue(pos), PositionRole);
146     m_reader.readElementText();
147     if (m_reader.isEndElement()) {
148         m_reader.readNext();
149     }
150 }
151
152 void StationListModel::readNameElement(QStandardItem *item)
153 {
154     item->setText(m_reader.readElementText());
155     if (m_reader.isEndElement()) {
156         m_reader.readNext();
157     }
158 }
159
160 void StationListModel::readCodeElement(QStandardItem *item)
161 {
162     const QString code = m_reader.readElementText();
163     qDebug() << "reading code element" << code;
164
165     item->setData(QVariant::fromValue(code), StationCodeRole);
166     if (m_reader.isEndElement()) {
167         m_reader.readNext();
168     }
169 }
170
171 void StationListModel::skipUnknownElement()
172 {
173     qDebug() << "skipping unknown element";
174
175     m_reader.readNext();
176     while (!m_reader.atEnd()) {
177         if (m_reader.isEndElement()) {
178             m_reader.readNext();
179             break;
180         } else if (!m_reader.isStartElement()) {
181             skipUnknownElement();
182         } else {
183             m_reader.readNext();
184         }
185     }
186 }