Moved StationListModel to AbstractListModel base
authorLuciano Montanaro <mikelima@cirulla.net>
Sun, 24 Nov 2013 18:33:46 +0000 (19:33 +0100)
committerLuciano Montanaro <mikelima@cirulla.net>
Sun, 24 Nov 2013 18:33:46 +0000 (19:33 +0100)
This is a needed prerequisite for the favorites feature

application/stationitem.cpp [new file with mode: 0644]
application/stationitem.h [new file with mode: 0644]
application/stationlistmodel.cpp
application/stationlistmodel.h

diff --git a/application/stationitem.cpp b/application/stationitem.cpp
new file mode 100644 (file)
index 0000000..74e6b4f
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+
+Copyright (C) 2013 Luciano Montanaro <mikelima@cirulla.net>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.
+
+*/
+
+#include "stationitem.h"
+#include <QGeoCoordinate>
+#include <QSharedData>
+#include <QString>
+
+class StationItemData : public QSharedData {
+public:
+    QGeoCoordinate position;
+    QString name;
+    QString code;
+};
+
+StationItem::StationItem() : d(new StationItemData)
+{
+}
+
+StationItem::StationItem(const StationItem &rhs) : d(rhs.d)
+{
+}
+
+StationItem &StationItem::operator=(const StationItem &rhs)
+{
+    if (this != &rhs)
+        d.operator=(rhs.d);
+    return *this;
+}
+
+StationItem::~StationItem()
+{
+}
+
+QString &StationItem::name()
+{
+    return d->name;
+}
+
+void StationItem::setName(const QString &value)
+{
+    d->name = value;
+}
+
+QString &StationItem::code()
+{
+    return d->code;
+}
+
+void StationItem::setCode(const QString &value)
+{
+    d->code = value;
+}
+
+QGeoCoordinate &StationItem::position()
+{
+    return d->position;
+}
+
+void StationItem::setPosition(const QGeoCoordinate &value)
+{
+    d->position = value;
+}
+
+bool StationItem::isValid()
+{
+    return !d->name.isEmpty();
+}
diff --git a/application/stationitem.h b/application/stationitem.h
new file mode 100644 (file)
index 0000000..384df0d
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+
+Copyright (C) 2013 Luciano Montanaro <mikelima@cirulla.net>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef STATIONSCHEDULEITEM_H
+#define STATIONSCHEDULEITEM_H
+
+#include <QSharedDataPointer>
+#include <QGeoCoordinate>
+
+#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
+QTM_USE_NAMESPACE
+#endif
+
+class StationItemData;
+
+class StationItem
+{
+public:
+    StationItem();
+    StationItem(const StationItem &);
+    StationItem &operator=(const StationItem &);
+    ~StationItem();
+
+    QString &name();
+    void setName(const QString &value);
+
+    QString &code();
+    void setCode(const QString &value);
+
+    QGeoCoordinate &position();
+    void setPosition(const QGeoCoordinate &value);
+
+    bool isValid();
+private:
+    QSharedDataPointer<StationItemData> d;
+};
+
+#endif // STATIONSCHEDULEITEM_H
index f739b02..d7b6561 100644 (file)
@@ -20,6 +20,7 @@ Boston, MA 02110-1301, USA.
 */
 
 #include "stationlistmodel.h"
+#include "settings.h"
 
 #include <QFile>
 #include <QFileInfo>
@@ -33,12 +34,14 @@ 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)
@@ -95,10 +98,76 @@ QHash<int, QByteArray> StationListModel::roleNames() const
     return roles;
 }
 
-int StationListModel::rowCount(const QModelIndex &parent) const
+int StationListModel::rowCount(const QModelIndex &) const
 {
-    return QStandardItemModel::rowCount(parent);
+    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, 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));
+            QVector<int> changedRoles;
+            changedRoles << FavoriteIndicatorRole;
+            //emit dataChanged(index, index, changedRoles);
+            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()
@@ -122,11 +191,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()) {
@@ -139,40 +208,37 @@ void StationListModel::readStationElement()
             } else {
                 skipUnknownElement(m_reader.name().toString());
             }
-            item->setData(QVariant::fromValue(false), FavoriteIndicatorRole);
         } else {
             m_reader.readNext();
         }
     }
 }
 
-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->setData(QVariant::fromValue(pos.longitude()), LongitudeRole);
-    item->setData(QVariant::fromValue(pos.latitude()), LatitudeRole);
+    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(QStandardItem *item)
+void StationListModel::readCodeElement(StationItem &item)
 {
     const QString code = m_reader.readElementText();
     qDebug() << "reading code element" << code;
 
-    item->setData(QVariant::fromValue(code), StationCodeRole);
+    item.setCode(code);
     if (m_reader.isEndElement()) {
         m_reader.readNext();
     }
index 785122b..2f68d41 100644 (file)
@@ -22,13 +22,16 @@ Boston, MA 02110-1301, USA.
 
 */
 
-#include <QStandardItemModel>
+#include <QAbstractItemModel>
+#include <QSet>
 #include <QXmlStreamReader>
 
-class QStandardItem;
+#include "stationitem.h"
+
+class StationItem;
 class StationListModel;
 
-class StationListModel : public QStandardItemModel
+class StationListModel : public QAbstractListModel
 {
     Q_OBJECT
     Q_ENUMS(StationListRole)
@@ -51,9 +54,10 @@ public:
 
     QHash<int, QByteArray> roleNames() const;
 
-    // Needed to make SectionScroller happy.
+    Q_INVOKABLE Qt::ItemFlags flags(const QModelIndex &index) const;
     Q_INVOKABLE int rowCount(const QModelIndex &parent = QModelIndex()) const;
-
+    Q_INVOKABLE QVariant data(const QModelIndex &index, int role) const;
+    Q_INVOKABLE bool setData(const QModelIndex &index, QVariant &value, int role = Qt::EditRole);
 
 signals:
 
@@ -62,12 +66,14 @@ public slots:
 private:
     void readStationsElement();
     void readStationElement();
-    void readPosElement(QStandardItem *item);
-    void readNameElement(QStandardItem *item);
-    void readCodeElement(QStandardItem *item);
+    void readPosElement(StationItem &item);
+    void readNameElement(StationItem &item);
+    void readCodeElement(StationItem &item);
     void skipUnknownElement(const QString &name = QString());
 
     QXmlStreamReader m_reader;
+    QList<StationItem> m_stations;
+    QSet<QString> m_favorites;
 };
 
 #endif // STATIONLISTMODEL_H