Merge branch 'master' into locationlistview
[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 #include <cmath>
26
27 #include <QMessageBox>
28 #include <QNetworkReply>
29
30 #ifdef Q_WS_MAEMO_5
31 #include "application.h"
32 #endif
33
34 #include "common.h"
35 #include "error.h"
36 #include "facebookservice/facebookauthentication.h"
37 #include "gps/gpsposition.h"
38 #include "map/mapengine.h"
39 #include "routing/geocodingservice.h"
40 #include "routing/routingservice.h"
41 #include "mce.h"
42 #include "network/networkaccessmanager.h"
43 #include "situareservice/situareservice.h"
44 #include "ui/mainwindow.h"
45
46 #include "engine.h"
47
48 const QString SETTINGS_GPS_ENABLED = "GPS_ENABLED"; ///< GPS setting
49 const QString SETTINGS_AUTO_CENTERING_ENABLED = "AUTO_CENTERING_ENABLED";///< Auto centering setting
50 const int DEFAULT_ZOOM_LEVEL_WHEN_GPS_IS_AVAILABLE = 12;  ///< Default zoom level when GPS available
51 const qreal USER_MOVEMENT_MINIMUM_LONGITUDE_DIFFERENCE = 0.003;///< Min value for user move latitude
52 const qreal USER_MOVEMENT_MINIMUM_LATITUDE_DIFFERENCE = 0.001;///< Min value for user move longitude
53 const int MIN_UPDATE_INTERVAL_MSECS = 5*60*1000;
54
55 SituareEngine::SituareEngine()
56     : m_autoCenteringEnabled(false),
57       m_automaticUpdateFirstStart(true),
58       m_automaticUpdateRequest(false),
59       m_userMoved(false),
60       m_automaticUpdateIntervalTimer(0),
61       m_lastUpdatedGPSPosition(GeoCoordinate())
62 {
63     qDebug() << __PRETTY_FUNCTION__;
64
65     m_ui = new MainWindow;
66     m_ui->updateItemVisibility();
67
68 #ifdef Q_WS_MAEMO_5
69     m_app = static_cast<Application *>(qApp);
70     m_app->registerWindow(m_ui->winId());
71
72     connect(m_app, SIGNAL(topmostChanged(bool)),
73             this, SLOT(enablePowerSave(bool)));
74 #endif
75
76     m_networkAccessManager = new NetworkAccessManager(this);
77
78     // build MapEngine
79     m_mapEngine = new MapEngine(this);
80     m_ui->setMapViewScene(m_mapEngine->scene());
81
82     // build GPS
83     m_gps = new GPSPosition(this);
84
85     // build SituareService
86     m_situareService = new SituareService(this);
87
88     // build FacebookAuthenticator
89     m_facebookAuthenticator = new FacebookAuthentication(this);
90
91     // build routing service
92     m_routingService = new RoutingService(this); // create this when needed, not in constructor!
93
94     // build geocoding service
95     m_geocodingService = new GeocodingService(this);
96
97     // connect signals
98     signalsFromMapEngine();
99     signalsFromGeocodingService();
100     signalsFromGPS();
101     signalsFromRoutingService();
102     signalsFromSituareService();
103     signalsFromMainWindow();
104     signalsFromFacebookAuthenticator();
105
106     connect(this, SIGNAL(userLocationReady(User*)),
107             m_ui, SIGNAL(userLocationReady(User*)));
108
109     connect(this, SIGNAL(friendsLocationsReady(QList<User*>&)),
110             m_ui, SIGNAL(friendsLocationsReady(QList<User*>&)));
111
112     connect(this, SIGNAL(userLocationReady(User*)),
113             m_mapEngine, SLOT(receiveOwnLocation(User*)));
114
115     connect(this, SIGNAL(friendsLocationsReady(QList<User*>&)),
116             m_mapEngine, SIGNAL(friendsLocationsReady(QList<User*>&)));
117
118     connect(this, SIGNAL(friendImageReady(User*)),
119             m_ui, SIGNAL(friendImageReady(User*)));
120
121     connect(this, SIGNAL(friendImageReady(User*)),
122             m_mapEngine, SIGNAL(friendImageReady(User*)));
123
124     m_automaticUpdateIntervalTimer = new QTimer(this);
125     connect(m_automaticUpdateIntervalTimer, SIGNAL(timeout()),
126             this, SLOT(startAutomaticUpdate()));
127
128     // signals connected, now it's time to show the main window
129     // but init the MapEngine before so starting location is set
130     m_mapEngine->init();
131     m_ui->show();
132
133     m_facebookAuthenticator->start();
134
135     m_gps->setMode(GPSPosition::Default);
136     initializeGpsAndAutocentering();
137
138     m_mce = new MCE(this);
139     connect(m_mce, SIGNAL(displayOff(bool)), this, SLOT(enablePowerSave(bool)));
140 }
141
142 SituareEngine::~SituareEngine()
143 {
144     qDebug() << __PRETTY_FUNCTION__;
145
146     delete m_ui;
147
148     QSettings settings(DIRECTORY_NAME, FILE_NAME);
149     settings.setValue(SETTINGS_GPS_ENABLED, m_gps->isRunning());
150     settings.setValue(SETTINGS_AUTO_CENTERING_ENABLED, m_autoCenteringEnabled);
151 }
152
153 void SituareEngine::changeAutoCenteringSetting(bool enabled)
154 {
155     qDebug() << __PRETTY_FUNCTION__ << enabled;
156
157     m_autoCenteringEnabled = enabled;
158     setAutoCentering(enabled);
159 }
160
161 void SituareEngine::disableAutoCentering()
162 {
163     qDebug() << __PRETTY_FUNCTION__;
164
165     changeAutoCenteringSetting(false);
166 }
167
168 void SituareEngine::draggingModeTriggered()
169 {
170     if (m_mce)
171         m_mce->vibrationFeedback();
172 }
173
174 void SituareEngine::enableAutomaticLocationUpdate(bool enabled, int updateIntervalMsecs)
175 {
176     qDebug() << __PRETTY_FUNCTION__;
177
178     //Show automatic update confirmation dialog
179     if (m_automaticUpdateFirstStart && m_gps->isRunning() && enabled) {
180         m_ui->showEnableAutomaticUpdateLocationDialog(
181                 tr("Do you want to enable automatic location update with %1 min update interval?")
182                 .arg(updateIntervalMsecs/1000/60));
183         m_automaticUpdateFirstStart = false;
184     } else {
185         if (enabled && m_gps->isRunning()) {
186             m_ui->buildInformationBox(tr("Automatic location update enabled"));
187             if (updateIntervalMsecs < MIN_UPDATE_INTERVAL_MSECS)
188                 m_automaticUpdateIntervalTimer->setInterval(MIN_UPDATE_INTERVAL_MSECS);
189             else
190                 m_automaticUpdateIntervalTimer->setInterval(updateIntervalMsecs);
191
192             connect(m_gps, SIGNAL(position(GeoCoordinate, qreal)),
193                     this, SLOT(requestAutomaticUpdateIfMoved(GeoCoordinate)));
194
195             m_automaticUpdateIntervalTimer->start();
196
197         } else {
198             disconnect(m_gps, SIGNAL(position(GeoCoordinate, qreal)),
199                     this, SLOT(requestAutomaticUpdateIfMoved(GeoCoordinate)));
200
201             m_automaticUpdateIntervalTimer->stop();
202         }
203     }
204 }
205
206 void SituareEngine::enablePowerSave(bool enabled)
207 {
208     qDebug() << __PRETTY_FUNCTION__ << enabled;
209
210     m_gps->enablePowerSave(enabled);
211
212     if(m_autoCenteringEnabled)
213         m_mapEngine->setAutoCentering(!enabled);
214 }
215
216 void SituareEngine::error(const int context, const int error)
217 {
218     qDebug() << __PRETTY_FUNCTION__;
219
220     switch(error)
221     {
222     case SituareError::ERROR_GENERAL:
223         if(context == ErrorContext::SITUARE) {
224             m_ui->toggleProgressIndicator(false);
225             m_ui->buildInformationBox(tr("Unknown server error"), true);
226         }
227         break;
228     case 1: //errors: SituareError::ERROR_MISSING_ARGUMENT and QNetworkReply::ConnectionRefusedError
229         m_ui->toggleProgressIndicator(false);
230         if(context == ErrorContext::SITUARE) {
231             m_ui->buildInformationBox(tr("Missing parameter from request"), true);
232         } else if(context == ErrorContext::NETWORK) {
233             m_ui->buildInformationBox(tr("Connection refused by the server"), true);
234         }
235         break;
236     case QNetworkReply::RemoteHostClosedError:
237         if(context == ErrorContext::NETWORK) {
238             m_ui->toggleProgressIndicator(false);
239             m_ui->buildInformationBox(tr("Connection closed by the server"), true);
240         }
241         break;
242     case QNetworkReply::HostNotFoundError:
243         if(context == ErrorContext::NETWORK) {
244             m_ui->toggleProgressIndicator(false);
245             m_ui->buildInformationBox(tr("Remote server not found"), true);
246         }
247         break;
248     case QNetworkReply::TimeoutError:
249         if(context == ErrorContext::NETWORK) {
250             m_ui->toggleProgressIndicator(false);
251             m_ui->buildInformationBox(tr("Connection timed out"), true);
252         }
253         break;
254     case QNetworkReply::UnknownNetworkError:
255         if(context == ErrorContext::NETWORK) {
256             m_ui->toggleProgressIndicator(false);
257             m_ui->buildInformationBox(tr("No network connection"), true);
258         }
259         break;
260     case SituareError::SESSION_EXPIRED:
261         m_ui->buildInformationBox(tr("Session expired. Please login again"), true);
262         m_facebookAuthenticator->clearAccountInformation(true); // keep username = true
263         m_situareService->clearUserData();
264         m_ui->loggedIn(false);
265         m_ui->loginFailed();
266         break;
267     case SituareError::LOGIN_FAILED:
268         m_ui->toggleProgressIndicator(false);
269         m_ui->buildInformationBox(tr("Invalid E-mail address or password"), true);
270         m_ui->loginFailed();
271         break;
272     case SituareError::UPDATE_FAILED:
273         m_ui->toggleProgressIndicator(false);
274         m_ui->buildInformationBox(tr("Update failed, please try again"), true);
275         break;
276     case SituareError::DATA_RETRIEVAL_FAILED:
277         m_ui->toggleProgressIndicator(false);
278         m_ui->buildInformationBox(tr("Data retrieval failed, please try again"), true);
279         break;
280     case SituareError::ADDRESS_RETRIEVAL_FAILED:
281     case SituareError::ERROR_GEOLOCATION_REQUEST_FAIL:
282     case SituareError::ERROR_GEOLOCATION_LONLAT_INVALID:
283         m_ui->toggleProgressIndicator(false);
284         m_ui->buildInformationBox(tr("Address retrieval failed"), true);
285         break;
286     case SituareError::IMAGE_DOWNLOAD_FAILED:
287         m_ui->buildInformationBox(tr("Image download failed"), true);
288         break;
289     case SituareError::MAP_IMAGE_DOWNLOAD_FAILED:
290         m_ui->buildInformationBox(tr("Map image download failed"), true);
291         break;
292     case SituareError::GPS_INITIALIZATION_FAILED:
293         setGPS(false);
294         m_ui->buildInformationBox(tr("GPS initialization failed"), true);
295         break;
296     case SituareError::INVALID_JSON:
297         m_ui->buildInformationBox(tr("Malformatted reply from server"), true);
298         m_ui->loggedIn(false);
299         m_facebookAuthenticator->clearAccountInformation(false); // clean all
300         break;
301     case SituareError::ERROR_GEOLOCATION_SERVER_UNAVAILABLE:
302         m_ui->toggleProgressIndicator(false);
303         m_ui->buildInformationBox(tr("Address server not responding"), true);
304         break;
305     default:
306         m_ui->toggleProgressIndicator(false);
307         if(context == ErrorContext::NETWORK)
308             qCritical() << __PRETTY_FUNCTION__ << "QNetworkReply::NetworkError: " << error;
309         else
310             qCritical() << __PRETTY_FUNCTION__ << "Unknown error: " << error;
311
312         break;
313     }
314 }
315
316 void SituareEngine::fetchUsernameFromSettings()
317 {
318     qDebug() << __PRETTY_FUNCTION__;
319
320     m_ui->setUsername(m_facebookAuthenticator->loadUsername());
321 }
322
323 void SituareEngine::imageReady(User *user)
324 {
325     qDebug() << __PRETTY_FUNCTION__;
326
327     if(user->type())
328         emit userLocationReady(user);
329     else
330         emit friendImageReady(user);
331 }
332
333 void SituareEngine::initializeGpsAndAutocentering()
334 {
335     qDebug() << __PRETTY_FUNCTION__;
336
337     QSettings settings(DIRECTORY_NAME, FILE_NAME);
338     QVariant gpsEnabled = settings.value(SETTINGS_GPS_ENABLED);
339     QVariant autoCenteringEnabled = settings.value(SETTINGS_AUTO_CENTERING_ENABLED);
340
341     if (m_gps->isInitialized()) {
342
343         if (gpsEnabled.toString().isEmpty()) { // First start. Situare.conf file does not exists
344
345             connect(m_gps, SIGNAL(position(GeoCoordinate, qreal)),
346                     this, SLOT(setFirstStartZoomLevel()));
347
348             changeAutoCenteringSetting(true);
349             setGPS(true);
350
351             m_ui->buildInformationBox(tr("GPS enabled"));
352
353         } else { // Normal start
354             changeAutoCenteringSetting(autoCenteringEnabled.toBool());
355             setGPS(gpsEnabled.toBool());
356
357             if (gpsEnabled.toBool())
358                 m_ui->buildInformationBox(tr("GPS enabled"));
359         }
360     } else {
361         setGPS(false);
362     }
363 }
364
365 void SituareEngine::locationSearch(QString location)
366 {
367     qDebug() << __PRETTY_FUNCTION__;
368
369     if(!location.isEmpty())
370         m_geocodingService->requestLocation(location);
371 }
372
373 void SituareEngine::loginActionPressed()
374 {
375     qDebug() << __PRETTY_FUNCTION__;
376
377     if (m_networkAccessManager->isConnected()) {
378         if(m_ui->loginState()) {
379             logout();
380             m_situareService->clearUserData();
381         } else {
382             m_facebookAuthenticator->start();
383         }
384     }
385     else {
386         error(ErrorContext::NETWORK, QNetworkReply::UnknownNetworkError);
387     }
388 }
389
390 void SituareEngine::loginOk()
391 {
392     qDebug() << __PRETTY_FUNCTION__;
393
394     m_ui->loggedIn(true);
395
396     m_ui->show();
397     m_situareService->fetchLocations(); // request user locations
398
399     if (m_gps->isRunning())
400         m_ui->readAutomaticLocationUpdateSettings();
401 }
402
403 void SituareEngine::loginProcessCancelled()
404 {
405     qDebug() << __PRETTY_FUNCTION__;
406
407     m_ui->toggleProgressIndicator(false);
408     m_ui->updateItemVisibility();
409 }
410
411 void SituareEngine::logout()
412 {
413     qDebug() << __PRETTY_FUNCTION__;
414
415     m_ui->loggedIn(false);
416
417     // signal to clear locationUpdateDialog's data
418     connect(this, SIGNAL(clearUpdateLocationDialogData()),
419             m_ui, SIGNAL(clearUpdateLocationDialogData()));
420     emit clearUpdateLocationDialogData();
421
422     m_facebookAuthenticator->clearAccountInformation(); // clear all
423     m_automaticUpdateFirstStart = true;
424 }
425
426 void SituareEngine::refreshUserData()
427 {
428     qDebug() << __PRETTY_FUNCTION__;
429
430     if (m_networkAccessManager->isConnected()) {
431         m_ui->toggleProgressIndicator(true);
432         m_situareService->fetchLocations();
433     }
434     else {
435         error(ErrorContext::NETWORK, QNetworkReply::UnknownNetworkError);
436     }
437 }
438
439 void SituareEngine::requestAddress()
440 {
441     qDebug() << __PRETTY_FUNCTION__;
442
443     if (m_networkAccessManager->isConnected()) {
444         if (m_gps->isRunning())
445             m_situareService->reverseGeo(m_gps->lastPosition());
446         else
447             m_situareService->reverseGeo(m_mapEngine->centerGeoCoordinate());
448     }
449     else {
450         error(ErrorContext::NETWORK, QNetworkReply::UnknownNetworkError);
451     }
452 }
453
454 void SituareEngine::requestUpdateLocation(const QString &status, bool publish)
455 {
456     qDebug() << __PRETTY_FUNCTION__;
457
458     if (m_networkAccessManager->isConnected()) {
459         m_ui->toggleProgressIndicator(true);
460
461         if (m_gps->isRunning())
462             m_situareService->updateLocation(m_gps->lastPosition(), status, publish);
463         else
464             m_situareService->updateLocation(m_mapEngine->centerGeoCoordinate(), status, publish);
465     }
466     else {
467         error(ErrorContext::NETWORK, QNetworkReply::UnknownNetworkError);
468     }
469 }
470
471 void SituareEngine::requestAutomaticUpdateIfMoved(GeoCoordinate position)
472 {
473     qDebug() << __PRETTY_FUNCTION__;
474
475     if ((fabs(m_lastUpdatedGPSPosition.longitude() - position.longitude()) >
476          USER_MOVEMENT_MINIMUM_LONGITUDE_DIFFERENCE) ||
477         (fabs(m_lastUpdatedGPSPosition.latitude() - position.latitude()) >
478          USER_MOVEMENT_MINIMUM_LATITUDE_DIFFERENCE)) {
479
480         m_lastUpdatedGPSPosition = position;
481         m_userMoved = true;
482     }
483
484     if (m_automaticUpdateRequest && m_userMoved) {
485         requestUpdateLocation(tr("Automatic location update"));
486         m_automaticUpdateRequest = false;
487         m_userMoved = false;
488     }
489 }
490
491 void SituareEngine::setAutoCentering(bool enabled)
492 {
493     qDebug() << __PRETTY_FUNCTION__ << enabled;
494
495     m_ui->setIndicatorButtonEnabled(enabled);
496     m_mapEngine->setAutoCentering(enabled);
497     m_ui->setOwnLocationCrosshairVisibility(!enabled);
498
499     if (enabled) {
500         setGPS(true);
501         m_gps->requestLastPosition();
502     }
503 }
504
505 void SituareEngine::setFirstStartZoomLevel()
506 {
507     qDebug() << __PRETTY_FUNCTION__;
508
509     if (m_autoCenteringEnabled) // autocentering is disabled when map is scrolled
510         m_mapEngine->setZoomLevel(DEFAULT_ZOOM_LEVEL_WHEN_GPS_IS_AVAILABLE);
511
512     disconnect(m_gps, SIGNAL(position(GeoCoordinate, qreal)),
513                this, SLOT(setFirstStartZoomLevel()));
514 }
515
516 void SituareEngine::setGPS(bool enabled)
517 {
518     qDebug() << __PRETTY_FUNCTION__ << enabled;
519
520     if (m_gps->isInitialized()) {
521         m_ui->setGPSButtonEnabled(enabled);
522         m_mapEngine->setGPSEnabled(enabled);
523
524         if (enabled && !m_gps->isRunning()) {
525             m_gps->start();
526             m_gps->requestLastPosition();
527
528             if(m_ui->loginState())
529                 m_ui->readAutomaticLocationUpdateSettings();
530         }
531         else if (!enabled && m_gps->isRunning()) {
532             m_gps->stop();
533             changeAutoCenteringSetting(false);
534             enableAutomaticLocationUpdate(false);
535         }
536     }
537     else {
538         if (enabled)
539             m_ui->buildInformationBox(tr("Unable to start GPS"));
540         m_ui->setGPSButtonEnabled(false);
541         m_mapEngine->setGPSEnabled(false);
542     }
543 }
544
545 void SituareEngine::signalsFromFacebookAuthenticator()
546 {
547     qDebug() << __PRETTY_FUNCTION__;
548
549     connect(m_facebookAuthenticator, SIGNAL(error(int, int)),
550             this, SLOT(error(int, int)));
551
552     connect(m_facebookAuthenticator, SIGNAL(credentialsReady(FacebookCredentials)),
553             m_situareService, SLOT(credentialsReady(FacebookCredentials)));
554
555     connect(m_facebookAuthenticator, SIGNAL(credentialsReady(FacebookCredentials)),
556             this, SLOT(loginOk()));
557
558     connect(m_facebookAuthenticator, SIGNAL(newLoginRequest()),
559             m_ui, SLOT(startLoginProcess()));
560
561     connect(m_facebookAuthenticator, SIGNAL(saveCookiesRequest()),
562             m_ui, SLOT(saveCookies()));
563
564     connect(m_facebookAuthenticator, SIGNAL(loginUsingCookies()),
565             m_ui, SLOT(loginUsingCookies()));
566 }
567
568 void SituareEngine::signalsFromGeocodingService()
569 {
570     qDebug() << __PRETTY_FUNCTION__;
571
572     connect(m_geocodingService, SIGNAL(locationDataParsed(QList<Location>&)),
573             m_ui, SIGNAL(locationDataParsed(QList<Location>&)));
574 }
575
576 void SituareEngine::signalsFromGPS()
577 {
578     qDebug() << __PRETTY_FUNCTION__;
579
580     connect(m_gps, SIGNAL(position(GeoCoordinate, qreal)),
581             m_mapEngine, SLOT(gpsPositionUpdate(GeoCoordinate, qreal)));
582
583     connect(m_gps, SIGNAL(timeout()),
584             m_ui, SLOT(gpsTimeout()));
585
586     connect(m_gps, SIGNAL(error(int, int)),
587             this, SLOT(error(int, int)));
588 }
589
590 void SituareEngine::signalsFromMainWindow()
591 {
592     qDebug() << __PRETTY_FUNCTION__;
593
594     connect(m_ui, SIGNAL(error(int, int)),
595             this, SLOT(error(int, int)));
596
597     connect(m_ui, SIGNAL(fetchUsernameFromSettings()),
598             this, SLOT(fetchUsernameFromSettings()));
599
600     connect(m_ui, SIGNAL(loginActionPressed()),
601             this, SLOT(loginActionPressed()));
602
603     connect(m_ui, SIGNAL(saveUsername(QString)),
604             m_facebookAuthenticator, SLOT(saveUsername(QString)));
605
606     connect(m_ui, SIGNAL(updateCredentials(QUrl)),
607             m_facebookAuthenticator, SLOT(updateCredentials(QUrl)));
608
609     // signals from map view
610     connect(m_ui, SIGNAL(mapViewScrolled(SceneCoordinate)),
611             m_mapEngine, SLOT(setCenterPosition(SceneCoordinate)));
612
613     connect(m_ui, SIGNAL(mapViewResized(QSize)),
614             m_mapEngine, SLOT(viewResized(QSize)));
615
616     connect(m_ui, SIGNAL(viewZoomFinished()),
617             m_mapEngine, SLOT(viewZoomFinished()));
618
619     // signals from zoom buttons (zoom panel and volume buttons)
620     connect(m_ui, SIGNAL(zoomIn()),
621             m_mapEngine, SLOT(zoomIn()));
622
623     connect(m_ui, SIGNAL(zoomOut()),
624             m_mapEngine, SLOT(zoomOut()));
625
626     // signals from menu buttons
627     connect(m_ui, SIGNAL(gpsTriggered(bool)),
628             this, SLOT(setGPS(bool)));
629
630     //signals from dialogs
631     connect(m_ui, SIGNAL(cancelLoginProcess()),
632             this, SLOT(loginProcessCancelled()));
633
634     connect(m_ui, SIGNAL(requestReverseGeo()),
635             this, SLOT(requestAddress()));
636
637     connect(m_ui, SIGNAL(statusUpdate(QString,bool)),
638             this, SLOT(requestUpdateLocation(QString,bool)));
639
640     connect(m_ui, SIGNAL(enableAutomaticLocationUpdate(bool, int)),
641             this, SLOT(enableAutomaticLocationUpdate(bool, int)));
642
643     // signals from user info tab
644     connect(m_ui, SIGNAL(refreshUserData()),
645             this, SLOT(refreshUserData()));
646
647     connect(m_ui, SIGNAL(findUser(GeoCoordinate)),
648             m_mapEngine, SLOT(centerToCoordinates(GeoCoordinate)));
649
650     // signals from friend list tab
651     connect(m_ui, SIGNAL(findFriend(GeoCoordinate)),
652             m_mapEngine, SLOT(centerToCoordinates(GeoCoordinate)));
653
654     connect(m_ui, SIGNAL(locationItemClicked(GeoCoordinate&,GeoCoordinate&)),
655             m_mapEngine, SLOT(locationItemClicked(GeoCoordinate&,GeoCoordinate&)));
656
657     // signals from distence indicator button
658     connect(m_ui, SIGNAL(autoCenteringTriggered(bool)),
659             this, SLOT(changeAutoCenteringSetting(bool)));
660
661     connect(m_ui, SIGNAL(searchForLocation(QString)),
662             this, SLOT(locationSearch(QString)));
663
664     connect(m_ui, SIGNAL(draggingModeTriggered()),
665             this, SLOT(draggingModeTriggered()));
666 }
667
668 void SituareEngine::signalsFromMapEngine()
669 {
670     qDebug() << __PRETTY_FUNCTION__;
671
672     connect(m_mapEngine, SIGNAL(error(int, int)),
673             this, SLOT(error(int, int)));
674
675     connect(m_mapEngine, SIGNAL(locationChanged(SceneCoordinate)),
676             m_ui, SIGNAL(centerToSceneCoordinates(SceneCoordinate)));
677
678     connect(m_mapEngine, SIGNAL(zoomLevelChanged(int)),
679             m_ui, SIGNAL(zoomLevelChanged(int)));
680
681     connect(m_mapEngine, SIGNAL(mapScrolledManually()),
682             this, SLOT(disableAutoCentering()));
683
684     connect(m_mapEngine, SIGNAL(maxZoomLevelReached()),
685             m_ui, SIGNAL(maxZoomLevelReached()));
686
687     connect(m_mapEngine, SIGNAL(minZoomLevelReached()),
688             m_ui, SIGNAL(minZoomLevelReached()));
689
690     connect(m_mapEngine, SIGNAL(locationItemClicked(QList<QString>)),
691             m_ui, SIGNAL(locationItemClicked(QList<QString>)));
692
693     connect(m_mapEngine, SIGNAL(newMapResolution(qreal)),
694             m_ui, SIGNAL(newMapResolution(qreal)));
695 }
696
697 void SituareEngine::signalsFromRoutingService()
698 {
699     qDebug() << __PRETTY_FUNCTION__;
700
701     connect(m_routingService, SIGNAL(routeParsed(Route&)),
702             m_mapEngine, SLOT(setRoute(Route&)));
703 }
704
705 void SituareEngine::signalsFromSituareService()
706 {
707     qDebug() << __PRETTY_FUNCTION__;
708
709     connect(m_situareService, SIGNAL(error(int, int)),
710             this, SLOT(error(int, int)));
711
712     connect(m_situareService, SIGNAL(imageReady(User*)),
713             this, SLOT(imageReady(User*)));
714
715     connect(m_situareService, SIGNAL(reverseGeoReady(QString)),
716             m_ui, SIGNAL(reverseGeoReady(QString)));
717
718     connect(m_situareService, SIGNAL(userDataChanged(User*, QList<User*>&)),
719             this, SLOT(userDataChanged(User*, QList<User*>&)));
720
721     connect(m_situareService, SIGNAL(updateWasSuccessful()),
722             this, SLOT(updateWasSuccessful()));
723
724     connect(m_situareService, SIGNAL(updateWasSuccessful()),
725             m_ui, SIGNAL(clearUpdateLocationDialogData()));
726 }
727
728 void SituareEngine::startAutomaticUpdate()
729 {
730     qDebug() << __PRETTY_FUNCTION__;
731
732     m_gps->requestUpdate();
733     m_automaticUpdateRequest = true;
734 }
735
736 void SituareEngine::updateWasSuccessful()
737 {
738     qDebug() << __PRETTY_FUNCTION__;
739
740     if (m_networkAccessManager->isConnected())
741         m_situareService->fetchLocations();
742     else
743         error(ErrorContext::NETWORK, QNetworkReply::UnknownNetworkError);
744 }
745
746 void SituareEngine::userDataChanged(User *user, QList<User *> &friendsList)
747 {
748     qDebug() << __PRETTY_FUNCTION__;
749
750     m_ui->toggleProgressIndicator(false);
751     m_ui->showPanels();
752
753     emit userLocationReady(user);
754     emit friendsLocationsReady(friendsList);
755 }