Bump version to 0.9.0
[quandoparte] / application / stationlistmodel.cpp
index 1dc66b8..abd9613 100644 (file)
@@ -20,6 +20,7 @@ Boston, MA 02110-1301, USA.
 */
 
 #include "stationlistmodel.h"
+#include "settings.h"
 
 #include <QFile>
 #include <QFileInfo>
@@ -27,13 +28,20 @@ Boston, MA 02110-1301, USA.
 #include <QStandardItem>
 #include <QGeoCoordinate>
 
+#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
 QTM_USE_NAMESPACE
 Q_DECLARE_METATYPE(QGeoCoordinate)
+#endif
 
 StationListModel::StationListModel(QObject *parent) :
-    QStandardItemModel(parent)
+    QAbstractListModel(parent)
 {
-    setRowCount(0);
+#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
+    setRoleNames(roleNames());
+#endif
+    Settings *settings = Settings::instance();
+    m_favorites = settings->favoriteStations().toSet();
+    qDebug() << "favorites:" << m_favorites;
 }
 
 bool StationListModel::load(const QString &filename)
@@ -44,7 +52,7 @@ bool StationListModel::load(const QString &filename)
     qDebug() << "loading file:" << fi.absoluteFilePath();
 
     emit layoutAboutToBeChanged();
-    beginInsertRows(QModelIndex(), 0, 0);
+    beginResetModel();
     if (!file.open(QFile::ReadOnly | QFile::Text)) {
         qDebug() << "cannot open file:" << filename;
         return false;
@@ -63,6 +71,7 @@ bool StationListModel::load(const QString &filename)
         }
     }
     file.close();
+    qDebug() << rowCount() << "stations loaded";
     if (m_reader.hasError()) {
         qDebug() << "parser error for:" << filename;
         return false;
@@ -70,11 +79,94 @@ bool StationListModel::load(const QString &filename)
         qDebug() << "file error for:" << filename;
         return false;
     }
+    endResetModel();
     emit layoutChanged();
-    endInsertRows();
     return true;
 }
 
+QHash<int, QByteArray> StationListModel::roleNames() const
+{
+    QHash<int, QByteArray> roles;
+    roles[Qt::DisplayRole] = "name";
+    roles[StationListModel::PositionRole] = "position";
+    roles[StationListModel::RecentIndicatorRole] = "recent";
+    roles[StationListModel::FavoriteIndicatorRole] = "favorite";
+    roles[StationListModel::StationCodeRole] = "code";
+    roles[StationListModel::LongitudeRole] = "longitude";
+    roles[StationListModel::LatitudeRole] = "latitude";
+    roles[StationListModel::SectionRole] = "section";
+    return roles;
+}
+
+int StationListModel::rowCount(const QModelIndex &) const
+{
+    return m_stations.count();
+}
+
+QVariant StationListModel::data(const QModelIndex &index, int role) const
+{
+    if (!index.isValid()) return QVariant();
+    if (index.row() < 0 || index.row() >= m_stations.count()) {
+        return QVariant();
+    }
+    StationItem item = m_stations[index.row()];
+    Settings *settings = Settings::instance();
+    switch (role) {
+    case Qt::DisplayRole:
+        return QVariant::fromValue(item.name());
+    case PositionRole:
+        return QVariant::fromValue(item.position());
+    case RecentIndicatorRole:
+        return QVariant(settings->recentStations().contains(item.name()));
+    case FavoriteIndicatorRole:
+        return QVariant(m_favorites.contains(item.name()));
+    case StationCodeRole:
+        return QVariant::fromValue(item.code());
+    case LatitudeRole:
+        return QVariant::fromValue(item.position().latitude());
+    case LongitudeRole:
+        return QVariant::fromValue(item.position().longitude());
+    case SectionRole:
+        if (m_favorites.contains(item.name()))
+            return QVariant::fromValue(tr("Favorites"));
+        else
+            return QVariant(item.name()[0]);
+    default:
+        return QVariant::fromValue(QString("Unknown role requested"));
+    }
+}
+
+bool StationListModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+    if (!index.isValid())
+        return false;
+    if (role == FavoriteIndicatorRole) {
+        bool favorite = value.toBool();
+        if (data(index, FavoriteIndicatorRole) != favorite) {
+            QString name =  m_stations[index.row()].name();
+            if (favorite) {
+                qDebug() << "adding" << name << "to favorites";
+                m_favorites.insert(name);
+            } else {
+                qDebug() << "removing" << name << "from favorites";
+                m_favorites.remove(name);
+            }
+            Settings *settings = Settings::instance();
+            settings->setFavoriteStations(QStringList::fromSet(m_favorites));
+            emit dataChanged(index, index);
+        }
+        return true;
+    }
+   return false;
+}
+
+Qt::ItemFlags StationListModel::flags(const QModelIndex &index) const
+{
+    if (!index.isValid())
+        return 0;
+    return Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+}
+
 void StationListModel::readStationsElement()
 {
     m_reader.readNext();
@@ -86,7 +178,7 @@ void StationListModel::readStationsElement()
             if (m_reader.name() == "station") {
                 readStationElement();
             } else {
-                skipUnknownElement();
+                skipUnknownElement(m_reader.name().toString());
             }
         } else {
             m_reader.readNext();
@@ -96,11 +188,11 @@ void StationListModel::readStationsElement()
 
 void StationListModel::readStationElement()
 {
-    QStandardItem *item = new QStandardItem;
+    StationItem item;
     m_reader.readNext();
     while (!m_reader.atEnd()) {
         if (m_reader.isEndElement()) {
-            this->appendRow(item);
+            m_stations.append(item);
             m_reader.readNext();
             break;
         } else if (m_reader.isStartElement()) {
@@ -108,8 +200,10 @@ void StationListModel::readStationElement()
                 readPosElement(item);
             } else  if (m_reader.name() == "name") {
                 readNameElement(item);
+            } else  if (m_reader.name() == "code") {
+                readCodeElement(item);
             } else {
-                skipUnknownElement();
+                skipUnknownElement(m_reader.name().toString());
             }
         } else {
             m_reader.readNext();
@@ -117,28 +211,39 @@ void StationListModel::readStationElement()
     }
 }
 
-void StationListModel::readPosElement(QStandardItem *item)
+void StationListModel::readPosElement(StationItem &item)
 {
     QStringList coordinates = m_reader.readElementText().split(",");
     QGeoCoordinate pos = QGeoCoordinate(coordinates[0].toDouble(), coordinates[1].toDouble());
-    item->setData(QVariant::fromValue(pos), PositionRole);
+    item.setPosition(pos);
     m_reader.readElementText();
     if (m_reader.isEndElement()) {
         m_reader.readNext();
     }
 }
 
-void StationListModel::readNameElement(QStandardItem *item)
+void StationListModel::readNameElement(StationItem &item)
 {
-    item->setText(m_reader.readElementText());
+    item.setName(m_reader.readElementText());
+    if (m_reader.isEndElement()) {
+        m_reader.readNext();
+    }
+}
+
+void StationListModel::readCodeElement(StationItem &item)
+{
+    const QString code = m_reader.readElementText();
+    qDebug() << "reading code element" << code;
+
+    item.setCode(code);
     if (m_reader.isEndElement()) {
         m_reader.readNext();
     }
 }
 
-void StationListModel::skipUnknownElement()
+void StationListModel::skipUnknownElement(const QString &name)
 {
-    qDebug() << "skipping unknown element";
+    qDebug() << "skipping unknown element" << name << "at line" << m_reader.lineNumber();
 
     m_reader.readNext();
     while (!m_reader.atEnd()) {
@@ -146,7 +251,7 @@ void StationListModel::skipUnknownElement()
             m_reader.readNext();
             break;
         } else if (!m_reader.isStartElement()) {
-            skipUnknownElement();
+            skipUnknownElement(m_reader.name().toString());
         } else {
             m_reader.readNext();
         }