7319abfc1516e376a6f5b7ee15aa96c8c8a008c2
[situare] / src / engine / engine.cpp
1  /*
2     Situare - A location system for Facebook
3     Copyright (C) 2010  Ixonos Plc. Authors:
4
5         Kaj Wallin - kaj.wallin@ixonos.com
6         Henri Lampela - henri.lampela@ixonos.com
7         Jussi Laitinen - jussi.laitinen@ixonos.com
8         Sami Rämö - sami.ramo@ixonos.com
9
10     Situare is free software; you can redistribute it and/or
11     modify it under the terms of the GNU General Public License
12     version 2 as published by the Free Software Foundation.
13
14     Situare is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU General Public License for more details.
18
19     You should have received a copy of the GNU General Public License
20     along with Situare; if not, write to the Free Software
21     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
22     USA.
23  */
24
25
26 #include "common.h"
27 #include "facebookservice/facebookauthentication.h"
28 #include "gps/gpsposition.h"
29 #include "map/mapengine.h"
30 #include "situareservice/situareservice.h"
31 #include "ui/mainwindow.h"
32
33 #include "engine.h"
34
35 const QString SETTINGS_GPS_ENABLED = "GPS_ENABLED";
36 const QString SETTINGS_AUTO_CENTERING_ENABLED = "AUTO_CENTERING_ENABLED";
37 const int DEFAULT_ZOOM_LEVEL_WHEN_GPS_IS_AVAILABLE = 12;
38
39 SituareEngine::SituareEngine(QMainWindow *parent)
40     : QObject(parent),
41       m_autoCenteringEnabled(false),
42       m_loggedIn(false)
43 {
44     qDebug() << __PRETTY_FUNCTION__;
45     m_ui = new MainWindow;
46     m_ui->showPanels(m_loggedIn);
47
48     // build MapEngine
49     m_mapEngine = new MapEngine(this);
50     m_ui->setMapViewScene(m_mapEngine->scene());
51
52     // build GPS
53     m_gps = new GPSPosition(this);
54     m_gps->setMode(GPSPosition::Default);
55
56     // build SituareService
57     m_situareService = new SituareService(this);
58
59     // build FacebookAuthenticator
60     m_facebookAuthenticator = new FacebookAuthentication(this);
61
62     // connect signals
63     signalsFromMapEngine();
64     signalsFromGPS();
65     signalsFromSituareService();
66     signalsFromMainWindow();
67     signalsFromFacebookAuthenticator();
68
69     connect(this, SIGNAL(userLocationReady(User*)),
70             m_ui, SIGNAL(userLocationReady(User*)));
71
72     connect(this, SIGNAL(friendsLocationsReady(QList<User*>&)),
73             m_ui, SIGNAL(friendsLocationsReady(QList<User*>&)));
74
75     connect(this, SIGNAL(userLocationReady(User*)),
76             m_mapEngine, SLOT(receiveOwnLocation(User*)));
77
78     connect(this, SIGNAL(friendsLocationsReady(QList<User*>&)),
79             m_mapEngine, SIGNAL(friendsLocationsReady(QList<User*>&)));
80
81     initializeGpsAndAutocentering();
82
83     // signals connected, now it's time to show the main window
84     // but init the MapEngine before so starting location is set
85     m_mapEngine->init();
86     m_ui->show();
87
88     m_facebookAuthenticator->start();
89 }
90
91 SituareEngine::~SituareEngine()
92 {
93     qDebug() << __PRETTY_FUNCTION__;
94
95     delete m_ui;
96
97     QSettings settings(DIRECTORY_NAME, FILE_NAME);
98     qDebug() << __PRETTY_FUNCTION__ << m_autoCenteringEnabled;
99     settings.setValue(SETTINGS_GPS_ENABLED, m_gps->isRunning());
100     settings.setValue(SETTINGS_AUTO_CENTERING_ENABLED, m_autoCenteringEnabled);
101 }
102
103 void SituareEngine::changeAutoCenteringSetting(bool enabled)
104 {
105     qDebug() << __PRETTY_FUNCTION__;
106
107     m_autoCenteringEnabled = enabled;
108     enableAutoCentering(enabled);
109 }
110
111
112 void SituareEngine::disableAutoCentering()
113 {
114     qDebug() << __PRETTY_FUNCTION__;
115
116     changeAutoCenteringSetting(false);
117     m_ui->showMaemoInformationBox(tr("Auto centering disabled"));
118 }
119
120 void SituareEngine::enableAutoCentering(bool enabled)
121 {
122     qDebug() << __PRETTY_FUNCTION__;
123
124     m_ui->setAutoCenteringButtonEnabled(enabled);
125     m_mapEngine->setAutoCentering(enabled);
126
127     if (enabled)
128         m_gps->requestLastPosition();
129 }
130
131 void SituareEngine::enableGPS(bool enabled)
132 {
133     qDebug() << __PRETTY_FUNCTION__;
134
135     m_ui->setGPSButtonEnabled(enabled);
136     m_mapEngine->setGPSEnabled(enabled);
137
138     if (enabled) {
139         m_gps->start();
140         enableAutoCentering(m_autoCenteringEnabled);
141         m_gps->requestLastPosition();
142     }
143     else {
144         m_gps->stop();
145         enableAutoCentering(false);
146     }
147 }
148
149 void SituareEngine::error(const QString &error)
150 {
151     qDebug() << __PRETTY_FUNCTION__;
152     qDebug() << error;
153     // ToDo: signal UI?
154 }
155
156 void SituareEngine::fetchUsernameFromSettings()
157 {
158     qDebug() << __PRETTY_FUNCTION__;
159
160     m_ui->setUsername(m_facebookAuthenticator->loadUsername());
161 }
162
163 void SituareEngine::initializeGpsAndAutocentering()
164 {
165     qDebug() << __PRETTY_FUNCTION__;
166
167     QSettings settings(DIRECTORY_NAME, FILE_NAME);
168     QVariant gpsEnabled = settings.value(SETTINGS_GPS_ENABLED);
169     QVariant autoCenteringEnabled = settings.value(SETTINGS_AUTO_CENTERING_ENABLED);     
170
171     if (gpsEnabled.toString().isEmpty()) { // First start. Situare.conf file does not exists
172
173         connect(m_gps, SIGNAL(position(QPointF,qreal)),
174                 this, SLOT(setFirstStartZoomLevel(QPointF,qreal)));
175
176         changeAutoCenteringSetting(true);
177         enableGPS(true);
178
179         m_ui->showMaemoInformationBox(tr("GPS enabled"));
180         m_ui->showMaemoInformationBox(tr("Auto centering enabled"));
181     } else { // Normal start
182         changeAutoCenteringSetting(autoCenteringEnabled.toBool());
183         enableGPS(gpsEnabled.toBool());
184
185         if (gpsEnabled.toBool())
186             m_ui->showMaemoInformationBox(tr("GPS enabled"));
187
188         if (gpsEnabled.toBool() && autoCenteringEnabled.toBool())
189             m_ui->showMaemoInformationBox(tr("Auto centering enabled"));        
190     } 
191 }
192
193 void SituareEngine::invalidCredentials()
194 {
195     qDebug() << __PRETTY_FUNCTION__;
196
197     m_facebookAuthenticator->clearAccountInformation(true); // keep username = true
198     m_ui->clearCookieJar();
199     m_ui->showMaemoInformationBox(tr("Session expired. Please login again"), true);
200     m_facebookAuthenticator->start();
201 }
202
203 void SituareEngine::loginActionPressed()
204 {
205     qDebug() << __PRETTY_FUNCTION__;
206
207     if(m_loggedIn) {
208         logout();
209         m_situareService->clearUserData();
210     }
211     else {
212         m_facebookAuthenticator->start();
213     }
214 }
215
216 void SituareEngine::loginOk()
217 {
218     qDebug() << __PRETTY_FUNCTION__;
219
220     m_loggedIn = true;
221     m_ui->loggedIn(m_loggedIn);
222
223     if(!m_ui->username().isEmpty())
224         m_facebookAuthenticator->saveUsername(m_ui->username());
225
226     m_ui->show();
227     m_situareService->fetchLocations(); // request user locations
228 }
229
230 void SituareEngine::loginProcessCancelled()
231 {
232     qDebug() << __PRETTY_FUNCTION__;
233
234     m_ui->toggleProgressIndicator(false);
235     m_ui->showPanels(m_loggedIn);
236 }
237
238 void SituareEngine::logout()
239 {
240     qDebug() << __PRETTY_FUNCTION__;
241
242     m_loggedIn = false;
243     m_ui->loggedIn(m_loggedIn);
244     m_facebookAuthenticator->clearAccountInformation(); // clear all
245 }
246
247 void SituareEngine::refreshUserData()
248 {
249     qDebug() << __PRETTY_FUNCTION__;
250
251     m_ui->toggleProgressIndicator(true);
252
253     m_situareService->fetchLocations();
254 }
255
256 void SituareEngine::requestAddress()
257 {
258     qDebug() << __PRETTY_FUNCTION__;
259
260     if (m_gps->isRunning())
261         m_situareService->reverseGeo(m_gps->lastPosition());
262     else
263         m_situareService->reverseGeo(m_mapEngine->centerGeoCoordinate());
264 }
265
266 void SituareEngine::requestUpdateLocation(const QString &status, bool publish)
267 {
268     qDebug() << __PRETTY_FUNCTION__;
269
270     m_ui->toggleProgressIndicator(true);
271
272     if (m_gps->isRunning())
273         m_situareService->updateLocation(m_gps->lastPosition(), status, publish);
274     else
275         m_situareService->updateLocation(m_mapEngine->centerGeoCoordinate(), status, publish);
276 }
277
278 void SituareEngine::setFirstStartZoomLevel(QPointF latLonCoordinate, qreal accuracy)
279 {
280     qDebug() << __PRETTY_FUNCTION__;
281
282     Q_UNUSED(latLonCoordinate);
283     Q_UNUSED(accuracy);
284
285     if (m_autoCenteringEnabled) // autocentering is disabled when map is scrolled        
286         m_mapEngine->setZoomLevel(DEFAULT_ZOOM_LEVEL_WHEN_GPS_IS_AVAILABLE);
287
288     disconnect(m_gps, SIGNAL(position(QPointF,qreal)),
289                this, SLOT(setFirstStartZoomLevel(QPointF,qreal)));
290 }
291
292 void SituareEngine::signalsFromFacebookAuthenticator()
293 {
294     qDebug() << __PRETTY_FUNCTION__;
295
296     connect(m_facebookAuthenticator, SIGNAL(credentialsReady(FacebookCredentials)),
297             m_situareService, SLOT(credentialsReady(FacebookCredentials)));
298
299     connect(m_facebookAuthenticator, SIGNAL(credentialsReady(FacebookCredentials)),
300             this, SLOT(loginOk()));
301
302     connect(m_facebookAuthenticator, SIGNAL(newLoginRequest(QUrl)),
303             m_ui, SLOT(startLoginProcess(QUrl)));
304
305     connect(m_facebookAuthenticator, SIGNAL(loginFailure()),
306             m_ui, SLOT(loginFailed()));
307
308     connect(m_facebookAuthenticator, SIGNAL(saveCookiesRequest()),
309             m_ui, SLOT(saveCookies()));
310
311     connect(m_facebookAuthenticator, SIGNAL(loginUsingCookies()),
312             m_ui, SLOT(loginUsingCookies()));
313 }
314
315 void SituareEngine::signalsFromGPS()
316 {
317     qDebug() << __PRETTY_FUNCTION__;
318
319     connect(m_gps, SIGNAL(position(QPointF,qreal)),
320             m_mapEngine, SLOT(gpsPositionUpdate(QPointF,qreal)));
321
322     connect(m_gps, SIGNAL(timeout()),
323             m_ui, SLOT(gpsTimeout()));
324
325     connect(m_gps, SIGNAL(error(QString)),
326             m_ui, SLOT(gpsError(QString)));
327 }
328
329 void SituareEngine::signalsFromMainWindow()
330 {
331     qDebug() << __PRETTY_FUNCTION__;    
332
333     connect(m_ui, SIGNAL(loginActionPressed()),
334             this, SLOT(loginActionPressed()));
335
336     connect(m_ui, SIGNAL(updateCredentials(QUrl)),
337             m_facebookAuthenticator, SLOT(updateCredentials(QUrl)));
338
339     connect(m_ui, SIGNAL(fetchUsernameFromSettings()),
340             this, SLOT(fetchUsernameFromSettings()));
341
342     // signals from map view
343     connect(m_ui, SIGNAL(mapViewScrolled(QPoint)),
344             m_mapEngine, SLOT(setLocation(QPoint)));
345
346     connect(m_ui, SIGNAL(mapViewResized(QSize)),
347             m_mapEngine, SLOT(viewResized(QSize)));
348
349     connect(m_ui, SIGNAL(viewZoomFinished()),
350             m_mapEngine, SLOT(viewZoomFinished()));
351
352     // signals from zoom buttons (zoom panel and volume buttons)
353     connect(m_ui, SIGNAL(zoomIn()),
354             m_mapEngine, SLOT(zoomIn()));
355
356     connect(m_ui, SIGNAL(zoomOut()),
357             m_mapEngine, SLOT(zoomOut()));
358
359     // signals from menu buttons
360     connect(m_ui, SIGNAL(autoCenteringTriggered(bool)),
361             this, SLOT(changeAutoCenteringSetting(bool)));
362
363     connect(m_ui, SIGNAL(gpsTriggered(bool)),
364             this, SLOT(enableGPS(bool)));
365
366     //signals from dialogs
367     connect(m_ui, SIGNAL(cancelLoginProcess()),
368             this, SLOT(loginProcessCancelled()));
369
370     connect(m_ui, SIGNAL(requestReverseGeo()),
371             this, SLOT(requestAddress()));
372
373     connect(m_ui, SIGNAL(statusUpdate(QString,bool)),
374             this, SLOT(requestUpdateLocation(QString,bool)));
375
376     // signals from user info tab
377     connect(m_ui, SIGNAL(refreshUserData()),
378             this, SLOT(refreshUserData()));
379
380     connect(m_ui, SIGNAL(findUser(QPointF)),
381             m_mapEngine, SLOT(setViewLocation(QPointF)));
382
383     // signals from friend list tab
384     connect(m_ui, SIGNAL(findFriend(QPointF)),
385             m_mapEngine, SLOT(setViewLocation(QPointF)));
386 }
387
388 void SituareEngine::signalsFromMapEngine()
389 {
390     qDebug() << __PRETTY_FUNCTION__;
391
392     connect(m_mapEngine, SIGNAL(locationChanged(QPoint)),
393             m_ui, SIGNAL(centerToSceneCoordinates(QPoint)));
394
395     connect(m_mapEngine, SIGNAL(zoomLevelChanged(int)),
396             m_ui, SIGNAL(zoomLevelChanged(int)));
397
398     connect(m_mapEngine, SIGNAL(mapScrolledManually()),
399             this, SLOT(disableAutoCentering()));
400
401     connect(m_mapEngine, SIGNAL(maxZoomLevelReached()),
402             m_ui, SIGNAL(maxZoomLevelReached()));
403
404     connect(m_mapEngine, SIGNAL(minZoomLevelReached()),
405             m_ui, SIGNAL(minZoomLevelReached()));
406
407     connect(m_mapEngine, SIGNAL(locationItemClicked(QList<QString>)),
408             m_ui, SIGNAL(locationItemClicked(QList<QString>)));
409 }
410
411 void SituareEngine::signalsFromSituareService()
412 {
413     qDebug() << __PRETTY_FUNCTION__;
414
415     connect(m_situareService, SIGNAL(error(QString)),
416             this, SLOT(error(QString)));
417
418     connect(m_situareService, SIGNAL(invalidSessionCredentials()),
419             this, SLOT(invalidCredentials()));
420
421     connect(m_situareService, SIGNAL(reverseGeoReady(QString)),
422             m_ui, SIGNAL(reverseGeoReady(QString)));
423
424     connect(m_situareService, SIGNAL(userDataChanged(User*, QList<User*>&)),
425             this, SLOT(userDataChanged(User*, QList<User*>&)));
426
427     connect(m_situareService, SIGNAL(updateWasSuccessful()),
428             this, SLOT(updateWasSuccessful()));
429 }
430
431 void SituareEngine::updateWasSuccessful()
432 {
433     qDebug() << __PRETTY_FUNCTION__;
434
435     m_situareService->fetchLocations();
436 }
437
438 void SituareEngine::userDataChanged(User *user, QList<User *> &friendsList)
439 {
440     qDebug() << __PRETTY_FUNCTION__;
441
442     m_ui->toggleProgressIndicator(false);
443
444     emit userLocationReady(user);
445     emit friendsLocationsReady(friendsList);
446 }