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