Merge branch 'master' into cookies_refactored
[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_facebookAuthenticator->start();
199     m_ui->loginUsingCookies();
200 }
201
202 void SituareEngine::loginActionPressed()
203 {
204     qDebug() << __PRETTY_FUNCTION__;
205
206     if(m_loggedIn) {
207         logout();
208         m_situareService->clearUserData();
209     }
210     else {
211         m_facebookAuthenticator->start();
212     }
213 }
214
215 void SituareEngine::loginOk()
216 {
217     qDebug() << __PRETTY_FUNCTION__;
218
219     m_loggedIn = true;
220     m_ui->loggedIn(m_loggedIn);
221
222     if(!m_ui->username().isEmpty())
223         m_facebookAuthenticator->saveUsername(m_ui->username());
224
225     m_ui->show();
226     m_situareService->fetchLocations(); // request user locations
227 }
228
229 void SituareEngine::loginProcessCancelled()
230 {
231     qDebug() << __PRETTY_FUNCTION__;
232
233     m_ui->toggleProgressIndicator(false);
234     m_ui->showPanels(m_loggedIn);
235 }
236
237 void SituareEngine::logout()
238 {
239     qDebug() << __PRETTY_FUNCTION__;
240
241     m_loggedIn = false;
242     m_ui->loggedIn(m_loggedIn);
243     m_facebookAuthenticator->clearAccountInformation();
244 }
245
246 void SituareEngine::refreshUserData()
247 {
248     qDebug() << __PRETTY_FUNCTION__;
249
250     m_ui->toggleProgressIndicator(true);
251
252     m_situareService->fetchLocations();
253 }
254
255 void SituareEngine::requestAddress()
256 {
257     qDebug() << __PRETTY_FUNCTION__;
258
259     if (m_gps->isRunning())
260         m_situareService->reverseGeo(m_gps->lastPosition());
261     else
262         m_situareService->reverseGeo(m_mapEngine->centerGeoCoordinate());
263 }
264
265 void SituareEngine::requestUpdateLocation(const QString &status, bool publish)
266 {
267     qDebug() << __PRETTY_FUNCTION__;
268
269     m_ui->toggleProgressIndicator(true);
270
271     if (m_gps->isRunning())
272         m_situareService->updateLocation(m_gps->lastPosition(), status, publish);
273     else
274         m_situareService->updateLocation(m_mapEngine->centerGeoCoordinate(), status, publish);
275 }
276
277 void SituareEngine::setFirstStartZoomLevel(QPointF latLonCoordinate, qreal accuracy)
278 {
279     qDebug() << __PRETTY_FUNCTION__;
280
281     Q_UNUSED(latLonCoordinate);
282     Q_UNUSED(accuracy);
283
284     if (m_autoCenteringEnabled) // autocentering is disabled when map is scrolled        
285         m_mapEngine->setZoomLevel(DEFAULT_ZOOM_LEVEL_WHEN_GPS_IS_AVAILABLE);
286
287     disconnect(m_gps, SIGNAL(position(QPointF,qreal)),
288                this, SLOT(setFirstStartZoomLevel(QPointF,qreal)));
289 }
290
291 void SituareEngine::signalsFromFacebookAuthenticator()
292 {
293     qDebug() << __PRETTY_FUNCTION__;
294
295     connect(m_facebookAuthenticator, SIGNAL(credentialsReady(FacebookCredentials)),
296             m_situareService, SLOT(credentialsReady(FacebookCredentials)));
297
298     connect(m_facebookAuthenticator, SIGNAL(credentialsReady(FacebookCredentials)),
299             this, SLOT(loginOk()));
300
301     connect(m_facebookAuthenticator, SIGNAL(newLoginRequest(QUrl)),
302             m_ui, SLOT(startLoginProcess(QUrl)));
303
304     connect(m_facebookAuthenticator, SIGNAL(loginFailure()),
305             m_ui, SLOT(loginFailed()));
306
307     connect(m_facebookAuthenticator, SIGNAL(saveCookiesRequest()),
308             m_ui, SLOT(saveCookies()));
309
310     connect(m_facebookAuthenticator, SIGNAL(loginUsingCookies()),
311             m_ui, SLOT(loginUsingCookies()));
312 }
313
314 void SituareEngine::signalsFromGPS()
315 {
316     qDebug() << __PRETTY_FUNCTION__;
317
318     connect(m_gps, SIGNAL(position(QPointF,qreal)),
319             m_mapEngine, SLOT(gpsPositionUpdate(QPointF,qreal)));
320
321     connect(m_gps, SIGNAL(timeout()),
322             m_ui, SLOT(gpsTimeout()));
323
324     connect(m_gps, SIGNAL(error(QString)),
325             m_ui, SLOT(gpsError(QString)));
326 }
327
328 void SituareEngine::signalsFromMainWindow()
329 {
330     qDebug() << __PRETTY_FUNCTION__;    
331
332     connect(m_ui, SIGNAL(loginActionPressed()),
333             this, SLOT(loginActionPressed()));
334
335     connect(m_ui, SIGNAL(updateCredentials(QUrl)),
336             m_facebookAuthenticator, SLOT(updateCredentials(QUrl)));
337
338     connect(m_ui, SIGNAL(fetchUsernameFromSettings()),
339             this, SLOT(fetchUsernameFromSettings()));
340
341     // signals from map view
342     connect(m_ui, SIGNAL(mapViewScrolled(QPoint)),
343             m_mapEngine, SLOT(setLocation(QPoint)));
344
345     connect(m_ui, SIGNAL(mapViewResized(QSize)),
346             m_mapEngine, SLOT(viewResized(QSize)));
347
348     connect(m_ui, SIGNAL(viewZoomFinished()),
349             m_mapEngine, SLOT(viewZoomFinished()));
350
351     // signals from zoom buttons (zoom panel and volume buttons)
352     connect(m_ui, SIGNAL(zoomIn()),
353             m_mapEngine, SLOT(zoomIn()));
354
355     connect(m_ui, SIGNAL(zoomOut()),
356             m_mapEngine, SLOT(zoomOut()));
357
358     // signals from menu buttons
359     connect(m_ui, SIGNAL(autoCenteringTriggered(bool)),
360             this, SLOT(changeAutoCenteringSetting(bool)));
361
362     connect(m_ui, SIGNAL(gpsTriggered(bool)),
363             this, SLOT(enableGPS(bool)));
364
365     //signals from dialogs
366     connect(m_ui, SIGNAL(cancelLoginProcess()),
367             this, SLOT(loginProcessCancelled()));
368
369     connect(m_ui, SIGNAL(requestReverseGeo()),
370             this, SLOT(requestAddress()));
371
372     connect(m_ui, SIGNAL(statusUpdate(QString,bool)),
373             this, SLOT(requestUpdateLocation(QString,bool)));
374
375     // signals from user info tab
376     connect(m_ui, SIGNAL(refreshUserData()),
377             this, SLOT(refreshUserData()));
378
379     connect(m_ui, SIGNAL(findUser(QPointF)),
380             m_mapEngine, SLOT(setViewLocation(QPointF)));
381
382     // signals from friend list tab
383     connect(m_ui, SIGNAL(findFriend(QPointF)),
384             m_mapEngine, SLOT(setViewLocation(QPointF)));
385 }
386
387 void SituareEngine::signalsFromMapEngine()
388 {
389     qDebug() << __PRETTY_FUNCTION__;
390
391     connect(m_mapEngine, SIGNAL(locationChanged(QPoint)),
392             m_ui, SIGNAL(centerToSceneCoordinates(QPoint)));
393
394     connect(m_mapEngine, SIGNAL(zoomLevelChanged(int)),
395             m_ui, SIGNAL(zoomLevelChanged(int)));
396
397     connect(m_mapEngine, SIGNAL(mapScrolledManually()),
398             this, SLOT(disableAutoCentering()));
399
400     connect(m_mapEngine, SIGNAL(maxZoomLevelReached()),
401             m_ui, SIGNAL(maxZoomLevelReached()));
402
403     connect(m_mapEngine, SIGNAL(minZoomLevelReached()),
404             m_ui, SIGNAL(minZoomLevelReached()));
405
406     connect(m_mapEngine, SIGNAL(locationItemClicked(QList<QString>)),
407             m_ui, SIGNAL(locationItemClicked(QList<QString>)));
408 }
409
410 void SituareEngine::signalsFromSituareService()
411 {
412     qDebug() << __PRETTY_FUNCTION__;
413
414     connect(m_situareService, SIGNAL(error(QString)),
415             this, SLOT(error(QString)));
416
417     connect(m_situareService, SIGNAL(invalidSessionCredentials()),
418             this, SLOT(invalidCredentials()));
419
420     connect(m_situareService, SIGNAL(reverseGeoReady(QString)),
421             m_ui, SIGNAL(reverseGeoReady(QString)));
422
423     connect(m_situareService, SIGNAL(userDataChanged(User*, QList<User*>&)),
424             this, SLOT(userDataChanged(User*, QList<User*>&)));
425
426     connect(m_situareService, SIGNAL(updateWasSuccessful()),
427             this, SLOT(updateWasSuccessful()));
428 }
429
430 void SituareEngine::updateWasSuccessful()
431 {
432     qDebug() << __PRETTY_FUNCTION__;
433
434     m_situareService->fetchLocations();
435 }
436
437 void SituareEngine::userDataChanged(User *user, QList<User *> &friendsList)
438 {
439     qDebug() << __PRETTY_FUNCTION__;
440
441     m_ui->toggleProgressIndicator(false);
442
443     emit userLocationReady(user);
444     emit friendsLocationsReady(friendsList);
445 }