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