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