Make the delay indicator a rounded rectangle
[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 <QtGlobal>
28 #include <QDebug>
29 #include <QGeoCoordinate>
30 #include <QGeoPositionInfo>
31
32 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
33 QTM_USE_NAMESPACE
34
35 Q_DECLARE_METATYPE(QGeoCoordinate)
36 #endif
37
38 StationListProxyModel::StationListProxyModel(QObject *parent) :
39     QSortFilterProxyModel(parent),
40     positionInfoSource(QGeoPositionInfoSource::createDefaultSource(this)),
41     m_here(44.5, 9.0),
42     m_filterRecentOnly(false)
43 {
44     Settings *settings = Settings::instance();
45     forceSortingMode(settings->stationListSortingMode());
46     setFilterCaseSensitivity(Qt::CaseInsensitive);
47     setSortCaseSensitivity(Qt::CaseInsensitive);
48     setDynamicSortFilter(true);
49     qRegisterMetaType<QGeoCoordinate>();
50     if (positionInfoSource) {
51         qDebug() << "position info source available";
52         connect(positionInfoSource, SIGNAL(positionUpdated(QGeoPositionInfo)),
53                 SLOT(updatePosition(QGeoPositionInfo)));
54         positionInfoSource->setUpdateInterval(5000);
55     } else {
56         qDebug() << "No position info source available";
57     }
58     connect(settings, SIGNAL(favoriteStationsChanged()),
59             this, SLOT(updateFavoriteStations()));
60     updateFavoriteStations();
61     connect(settings, SIGNAL(recentStationsChanged()),
62             this, SLOT(updateRecentStations()));
63     updateRecentStations();
64 }
65
66 Qt::ItemFlags StationListProxyModel::flags(const QModelIndex &index) const
67 {
68     return QSortFilterProxyModel::flags(index);
69 }
70
71 bool StationListProxyModel::setData(const QModelIndex &index, const QVariant &value, int role)
72 {
73     return QSortFilterProxyModel::setData(index, value, role);
74 }
75
76 bool StationListProxyModel::lessThan(const QModelIndex &left,
77                                      const QModelIndex &right) const
78 {
79     int role = sortRole();
80
81     if (role == StationListModel::PositionRole) {
82         QGeoCoordinate first = left.data(role).value<QGeoCoordinate>();
83         QGeoCoordinate second = right.data(role).value<QGeoCoordinate>();
84        return first.distanceTo(m_here) < second.distanceTo(m_here);
85     } else {
86         bool leftIsFavorite = left.data(StationListModel::FavoriteIndicatorRole).toBool();
87         bool rightIsFavorite = right.data(StationListModel::FavoriteIndicatorRole).toBool();
88         if (leftIsFavorite && !rightIsFavorite) {
89             return true;
90         } else if (rightIsFavorite && !leftIsFavorite) {
91             return false;
92         } else
93             return QString::compare(left.data(role).toString(),
94                                     right.data(role).toString(),
95                                     sortCaseSensitivity()) < 0;
96     }
97 }
98
99
100 void StationListProxyModel::setUserPosition(const QGeoCoordinate &pos)
101 {
102     qDebug() << "Position is now" << pos;
103     m_here = pos;
104     if (sortingMode() == StationListProxyModel::DistanceSorting) {
105         invalidate();
106     }
107 }
108
109 void StationListProxyModel::setRecentStations(const QStringList &stations)
110 {
111     qDebug() << "Recent stations are now" << stations;
112     m_stations = stations;
113     if (sortingMode() == StationListProxyModel::RecentUsageSorting) {
114         invalidate();
115     }
116 }
117
118 void StationListProxyModel::updateRecentStations(void)
119 {
120     Settings *settings = Settings::instance();
121     setRecentStations(settings->recentStations());
122 }
123
124 void StationListProxyModel::setFavoriteStations(const QStringList &stations)
125 {
126     qDebug() << "Favorite stations are now" << stations;
127     if (sortingMode() == StationListProxyModel::AlphaSorting) {
128         invalidate();
129     }
130 }
131
132 void StationListProxyModel::updateFavoriteStations(void)
133 {
134     Settings *settings = Settings::instance();
135     setFavoriteStations(settings->favoriteStations());
136 }
137
138 bool StationListProxyModel::filterAcceptsRow(int sourceRow,
139                                              const QModelIndex &sourceParent) const
140 {
141     bool acceptable;
142     QModelIndex i = sourceModel()->index(sourceRow, 0, sourceParent);
143     QString stationName = sourceModel()->data(i).toString();
144     if (m_filterRecentOnly) {
145         acceptable =  m_stations.contains(stationName);
146     } else {
147         acceptable = true;
148     }
149     return acceptable && stationName.contains(filterRegExp());
150 }
151
152 void StationListProxyModel::setRecentOnlyFilter(bool activation)
153 {
154     m_filterRecentOnly = activation;
155 }
156
157 QString StationListProxyModel::searchPattern() const
158 {
159     return m_searchPattern;
160 }
161
162 void StationListProxyModel::setSearchPattern(const QString &pattern)
163 {
164     m_searchPattern = pattern;
165     setFilterFixedString(m_searchPattern);
166     qDebug() << "set Search pattern to" << pattern;
167 }
168
169 StationListProxyModel::SortingMode StationListProxyModel::sortingMode()
170 {
171     return m_sortingMode;
172 }
173
174 void StationListProxyModel::setSortingMode(SortingMode mode)
175 {
176     if (mode != m_sortingMode) {
177         beginResetModel();
178         forceSortingMode(mode);
179         endResetModel();
180     }
181     Settings *settings = Settings::instance();
182     settings->setStationListSortingMode(m_sortingMode);
183
184     emit sortingModeChanged(mode);
185 }
186
187 void StationListProxyModel::forceSortingMode(SortingMode mode)
188 {
189     m_sortingMode = mode;
190     setRecentOnlyFilter(false);
191
192     switch (mode) {
193     case StationListProxyModel::AlphaSorting:
194         setSortRole(Qt::DisplayRole);
195         break;
196     case StationListProxyModel::DistanceSorting:
197         setSortRole(StationListModel::PositionRole);
198         break;
199     case StationListProxyModel::RecentUsageSorting:
200         setRecentOnlyFilter(true);
201         break;
202     default:
203         break;
204     }
205     if (mode == StationListProxyModel::DistanceSorting) {
206         if (positionInfoSource) {
207             positionInfoSource->startUpdates();
208         }
209     } else {
210         if (positionInfoSource) {
211             positionInfoSource->stopUpdates();
212         }
213     }
214     invalidate();
215     sort(0);
216 }
217
218 void StationListProxyModel::updatePosition(const QGeoPositionInfo &update)
219 {
220     qDebug() << "Position update received" << update;
221     if (update.isValid()) {
222         QGeoCoordinate newPosition = update.coordinate();
223         if (newPosition.distanceTo(m_here) > 50.0) {
224             setUserPosition(update.coordinate());
225             invalidate();
226             sort(0);
227         }
228     }
229 }