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