Fix error reporting in the station page
[quandoparte] / application / stationlistproxymodel.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 "stationlistproxymodel.h"
23
24 #include "settings.h"
25 #include "stationlistmodel.h"
26
27 #include <QDebug>
28 #include <QGeoCoordinate>
29
30 QTM_USE_NAMESPACE
31
32 Q_DECLARE_METATYPE(QGeoCoordinate)
33
34 StationListProxyModel::StationListProxyModel(QObject *parent) :
35     QSortFilterProxyModel(parent),
36     positionInfoSource(QGeoPositionInfoSource::createDefaultSource(this)),
37     m_here(44.5, 9.0),
38     m_filterRecentOnly(false)
39 {
40     Settings *settings = Settings::instance();
41     forceSortingMode(settings->stationListSortingMode());
42     setFilterCaseSensitivity(Qt::CaseInsensitive);
43     setSortCaseSensitivity(Qt::CaseInsensitive);
44     setDynamicSortFilter(true);
45     if (positionInfoSource) {
46         qDebug() << "position info source available";
47         connect(positionInfoSource, SIGNAL(positionUpdated(QGeoPositionInfo)),
48                 SLOT(updatePosition(QGeoPositionInfo)));
49         positionInfoSource->setUpdateInterval(5000);
50     } else {
51         qDebug() << "No position info source available";
52     }
53     connect(settings, SIGNAL(recentStationsChanged()),
54             this, SLOT(updateRecentStations()));
55     updateRecentStations();
56 }
57
58 bool StationListProxyModel::lessThan(const QModelIndex &left,
59                                      const QModelIndex &right) const
60 {
61     int role = sortRole();
62
63     if (role == StationListModel::PositionRole) {
64         QGeoCoordinate first = left.data(role).value<QGeoCoordinate>();
65         QGeoCoordinate second = right.data(role).value<QGeoCoordinate>();
66        return first.distanceTo(m_here) < second.distanceTo(m_here);
67     } else {
68         return QString::compare(left.data(role).toString(),
69                                 right.data(role).toString(),
70                                 sortCaseSensitivity()) < 0;
71     }
72 }
73
74 void StationListProxyModel::setUserPosition(const QtMobility::QGeoCoordinate &pos)
75 {
76     qDebug() << "Position is now" << pos;
77     m_here = pos;
78     if (sortingMode() == StationListProxyModel::DistanceSorting) {
79         invalidate();
80     }
81 }
82
83 void StationListProxyModel::setRecentStations(const QStringList &stations)
84 {
85     qDebug() << "Recent stations are now" << stations;
86     m_stations = stations;
87     if (sortingMode() == StationListProxyModel::RecentUsageSorting) {
88         invalidate();
89     }
90 }
91
92 void StationListProxyModel::updateRecentStations(void)
93 {
94     Settings *settings = Settings::instance();
95     setRecentStations(settings->recentStations());
96 }
97
98 bool StationListProxyModel::filterAcceptsRow(int sourceRow,
99                                              const QModelIndex &sourceParent) const
100 {
101     bool acceptable;
102     QModelIndex i = sourceModel()->index(sourceRow, 0, sourceParent);
103     QString stationName = sourceModel()->data(i).toString();
104     if (m_filterRecentOnly) {
105         acceptable =  m_stations.contains(stationName);
106     } else {
107         acceptable = true;
108     }
109     return acceptable && stationName.contains(filterRegExp());
110 }
111
112 void StationListProxyModel::setRecentOnlyFilter(bool activation)
113 {
114     m_filterRecentOnly = activation;
115 }
116
117 QString StationListProxyModel::searchPattern() const
118 {
119     return m_searchPattern;
120 }
121
122 void StationListProxyModel::setSearchPattern(const QString &pattern)
123 {
124     m_searchPattern = pattern;
125     setFilterFixedString(m_searchPattern);
126     qDebug() << "set Search pattern to" << pattern;
127 }
128
129 StationListProxyModel::SortingMode StationListProxyModel::sortingMode()
130 {
131     return m_sortingMode;
132 }
133
134 void StationListProxyModel::setSortingMode(SortingMode mode)
135 {
136     if (mode != m_sortingMode) {
137         beginResetModel();
138         forceSortingMode(mode);
139         endResetModel();
140     }
141     Settings *settings = Settings::instance();
142     settings->setStationListSortingMode(m_sortingMode);
143
144     emit sortingModeChanged(mode);
145 }
146
147 void StationListProxyModel::forceSortingMode(SortingMode mode)
148 {
149     m_sortingMode = mode;
150     setRecentOnlyFilter(false);
151
152     switch (mode) {
153     case StationListProxyModel::AlphaSorting:
154         setSortRole(Qt::DisplayRole);
155         break;
156     case StationListProxyModel::DistanceSorting:
157         setSortRole(StationListModel::PositionRole);
158         break;
159     case StationListProxyModel::RecentUsageSorting:
160         setRecentOnlyFilter(true);
161         break;
162     default:
163         break;
164     }
165     if (mode == StationListProxyModel::DistanceSorting) {
166         positionInfoSource->startUpdates();
167     } else {
168         positionInfoSource->stopUpdates();
169     }
170     invalidate();
171     sort(0);
172 }
173
174 void StationListProxyModel::updatePosition(const QtMobility::QGeoPositionInfo &update)
175 {
176     qDebug() << "Position update received" << update;
177     if (update.isValid()) {
178         QGeoCoordinate newPosition = update.coordinate();
179         if (newPosition.distanceTo(m_here) > 50.0) {
180             setUserPosition(update.coordinate());
181             invalidate();
182             sort(0);
183         }
184     }
185 }