Fixed situare settings related misbehaviour when GPS is disabled
[situare] / src / ui / mainwindow.cpp
1 /*
2    Situare - A location system for Facebook
3    Copyright (C) 2010  Ixonos Plc. Authors:
4
5       Henri Lampela - henri.lampela@ixonos.com
6       Kaj Wallin - kaj.wallin@ixonos.com
7       Jussi Laitinen jussi.laitinen@ixonos.com
8       Sami Rämö - sami.ramo@ixonos.com
9       Ville Tiensuu - ville.tiensuu@ixonos.com
10
11    Situare is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License
13    version 2 as published by the Free Software Foundation.
14
15    Situare is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with Situare; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
23    USA.
24 */
25
26 #include <QtGui>
27 #include <QtWebKit>
28 #include <QtAlgorithms>
29
30 #include "common.h"
31 #include "facebookservice/facebookauthentication.h"
32 #include "friendlistpanel.h"
33 #include "logindialog.h"
34 #include "map/mapview.h"
35 #include "settingsdialog.h"
36 #include "userinfopanel.h"
37 #include "zoombuttonpanel.h"
38 #include "mapscale.h"
39
40 #include "mainwindow.h"
41
42 // These MUST BE HERE, compiling for Maemo fails if moved
43 #ifdef Q_WS_MAEMO_5
44 #include <QtMaemo5/QMaemo5InformationBox>
45 #include <QtGui/QX11Info>
46 #include <X11/Xatom.h>
47 #include <X11/Xlib.h>
48 #endif // Q_WS_MAEMO_5
49
50 // values for setting screen size in desktop matching N900 screen size
51 const int N900_APP_WIDTH = 800;
52 const int N900_APP_HEIGHT = 449;
53
54 MainWindow::MainWindow(QWidget *parent)
55     : QMainWindow(parent),
56     m_drawOwnLocationCrosshair(false),
57     m_errorShown(false),
58     m_loggedIn(false),
59     m_refresh(false),
60     m_ownLocationCrosshair(0),
61     m_email(),    
62     m_password(),
63     m_fullScreenButton(0),
64     m_webView(0),
65     m_mapScale(0),
66     m_cookieJar(0)
67 {
68     qDebug() << __PRETTY_FUNCTION__;
69
70     buildMap();
71
72     // build main layout
73     QHBoxLayout *layout = new QHBoxLayout;
74     layout->addWidget(m_mapView);
75     layout->setMargin(0);
76     setCentralWidget(new QWidget());
77     centralWidget()->setLayout(layout);
78
79     buildFriendListPanel();
80     buildUserInfoPanel();
81
82     createMenus();
83     setWindowTitle(tr("Situare"));
84
85     // set stacking order of widgets
86     m_zoomButtonPanel->stackUnder(m_userPanel);
87     if(m_fullScreenButton) {
88         m_fullScreenButton->stackUnder(m_zoomButtonPanel);
89         m_osmLicense->stackUnder(m_fullScreenButton);
90     } else {
91         m_osmLicense->stackUnder(m_zoomButtonPanel);
92     }
93     m_ownLocationCrosshair->stackUnder(m_osmLicense);
94     m_mapScale->stackUnder(m_ownLocationCrosshair);
95     m_mapView->stackUnder(m_mapScale);
96
97     this->toggleProgressIndicator(true);
98
99     grabZoomKeys(true);
100
101     // set screen size in desktop matching N900 screen size
102     resize(N900_APP_WIDTH, N900_APP_HEIGHT);
103 #ifdef Q_WS_MAEMO_5
104     setAttribute(Qt::WA_Maemo5StackedWindow);
105 #endif
106 }
107
108 MainWindow::~MainWindow()
109 {
110     qDebug() << __PRETTY_FUNCTION__;
111
112     grabZoomKeys(false);
113
114     if(m_webView)
115         delete m_webView;
116
117     qDeleteAll(m_queue.begin(), m_queue.end());
118     m_queue.clear();
119
120     qDeleteAll(m_error_queue.begin(), m_error_queue.end());
121     m_error_queue.clear();
122 }
123
124 void MainWindow::automaticUpdateDialogFinished(int result)
125 {
126     qDebug() << __PRETTY_FUNCTION__;
127
128     if (result == QMessageBox::Yes) {
129         readAutomaticLocationUpdateSettings();
130     } else if (result == QMessageBox::No) {
131         QSettings settings(DIRECTORY_NAME, FILE_NAME);
132         settings.setValue(SETTINGS_AUTOMATIC_UPDATE_ENABLED, false);
133         readAutomaticLocationUpdateSettings();
134     }
135
136     m_automaticUpdateLocationDialog->deleteLater();
137 }
138
139 void MainWindow::buildFullScreenButton()
140 {
141     qDebug() << __PRETTY_FUNCTION__;
142 #ifdef Q_WS_MAEMO_5
143     m_fullScreenButton = new QToolButton(this);
144     m_fullScreenButton->setIcon(QIcon::fromTheme(QLatin1String("general_fullsize")));
145     m_fullScreenButton->setFixedSize(m_fullScreenButton->sizeHint());
146     connect(m_fullScreenButton, SIGNAL(clicked()),
147             this, SLOT(toggleFullScreen()));
148 #endif // Q_WS_MAEMO_5
149
150 }
151
152 void MainWindow::buildFriendListPanel()
153 {
154     qDebug() << __PRETTY_FUNCTION__;
155
156     m_friendsListPanel = new FriendListPanel(this);
157     m_friendsListPanelSidebar = new PanelSideBar(this, RIGHT);
158
159     m_friendsListPanel->stackUnder(m_friendsListPanelSidebar);
160
161     connect(this, SIGNAL(friendsLocationsReady(QList<User*>&)),
162             m_friendsListPanel, SLOT(friendInfoReceived(QList<User*>&)));
163
164     connect(m_friendsListPanel, SIGNAL(findFriend(QPointF)),
165             this, SIGNAL(findFriend(QPointF)));
166
167     connect(m_mapView, SIGNAL(viewResized(QSize)),
168             m_friendsListPanel, SLOT(screenResized(QSize)));
169
170     connect(this, SIGNAL(locationItemClicked(QList<QString>)),
171             m_friendsListPanel, SLOT(showFriendsInList(QList<QString>)));
172
173     connect(m_mapView, SIGNAL(viewResized(QSize)),
174             m_friendsListPanelSidebar, SLOT(reDrawSidebar(QSize)));
175 }
176
177 void MainWindow::buildInformationBox(const QString &message, bool modal)
178 {
179     qDebug() << __PRETTY_FUNCTION__;
180
181     QString errorMessage = message;
182
183 #ifdef Q_WS_MAEMO_5
184
185     QMaemo5InformationBox *msgBox = new QMaemo5InformationBox(this);
186
187     if(modal) {
188         msgBox->setTimeout(QMaemo5InformationBox::NoTimeout);
189         // extra line changes are needed to make error notes broader
190         errorMessage.prepend("\n");
191         errorMessage.append("\n");
192     } else {
193         msgBox->setTimeout(QMaemo5InformationBox::DefaultTimeout);
194     }
195     QLabel *label = new QLabel(msgBox);
196     label->setAlignment(Qt::AlignCenter);
197     label->setText(errorMessage);
198     msgBox->setWidget(label);
199 #else
200     QMessageBox *msgBox = new QMessageBox(this);
201     msgBox->button(QMessageBox::Ok);
202     msgBox->setText(errorMessage);
203     msgBox->setModal(modal);
204 #endif
205
206     queueDialog(msgBox);
207 }
208
209 void MainWindow::buildManualLocationCrosshair()
210 {
211     qDebug() << __PRETTY_FUNCTION__;
212
213     m_ownLocationCrosshair = new QLabel(this);
214     QPixmap crosshairImage(":/res/images/sight.png");
215     m_ownLocationCrosshair->setPixmap(crosshairImage);
216     m_ownLocationCrosshair->setFixedSize(crosshairImage.size());
217     m_ownLocationCrosshair->hide();
218     m_ownLocationCrosshair->setAttribute(Qt::WA_TransparentForMouseEvents, true);
219
220     connect(m_mapView, SIGNAL(viewResized(QSize)),
221             this, SLOT(drawOwnLocationCrosshair(QSize)));
222 }
223
224 void MainWindow::buildMap()
225 {
226     qDebug() << __PRETTY_FUNCTION__;
227
228     m_mapView = new MapView(this);
229
230     buildZoomButtonPanel();
231     buildOsmLicense();
232     buildManualLocationCrosshair();
233     buildFullScreenButton();
234     buildMapScale();
235
236     connect(m_mapView, SIGNAL(viewScrolled(QPoint)),
237             this, SIGNAL(mapViewScrolled(QPoint)));
238
239     connect(this, SIGNAL(centerToSceneCoordinates(QPoint)),
240             m_mapView, SLOT(centerToSceneCoordinates(QPoint)));
241
242     connect(m_mapView, SIGNAL(viewResized(QSize)),
243             this, SIGNAL(mapViewResized(QSize)));
244
245     connect(m_mapView, SIGNAL(viewResized(QSize)),
246             this, SLOT(drawFullScreenButton(QSize)));
247
248     connect(m_mapView, SIGNAL(viewResized(QSize)),
249             this, SLOT(drawMapScale(QSize)));
250
251     connect(m_mapView, SIGNAL(viewResized(QSize)),
252              this, SLOT(setViewPortSize(QSize)));
253
254     connect(this, SIGNAL(zoomLevelChanged(int)),
255             m_mapView, SLOT(setZoomLevel(int)));
256
257     connect(m_mapView, SIGNAL(viewZoomFinished()),
258             this, SIGNAL(viewZoomFinished()));
259 }
260
261 void MainWindow::buildMapScale()
262 {
263     m_mapScale = new MapScale(this);
264     connect(this, SIGNAL(newMapResolution(qreal)),
265             m_mapScale, SLOT(updateMapResolution(qreal)));
266 }
267
268 void MainWindow::buildOsmLicense()
269 {
270     qDebug() << __PRETTY_FUNCTION__;
271
272     m_osmLicense = new QLabel(this);
273     m_osmLicense->setAttribute(Qt::WA_TranslucentBackground, true);
274     m_osmLicense->setAttribute(Qt::WA_TransparentForMouseEvents, true);
275     m_osmLicense->setText("<font color='black'>" + OSM_LICENSE + "</font>");
276     m_osmLicense->setFont(QFont("Nokia Sans", 9));
277     m_osmLicense->resize(m_osmLicense->fontMetrics().width(OSM_LICENSE),
278                          m_osmLicense->fontMetrics().height());
279
280     connect(m_mapView, SIGNAL(viewResized(QSize)),
281             this, SLOT(drawOsmLicense(QSize)));
282 }
283
284 void MainWindow::buildUserInfoPanel()
285 {
286     qDebug() << __PRETTY_FUNCTION__;
287
288     m_userPanel = new UserInfoPanel(this);
289     m_userPanelSidebar = new PanelSideBar(this, LEFT);
290
291     m_userPanelSidebar->stackUnder(m_friendsListPanel);
292     m_userPanel->stackUnder(m_userPanelSidebar);
293
294     connect(m_userPanel, SIGNAL(findUser(QPointF)),
295             this, SIGNAL(findUser(QPointF)));
296
297     connect(this, SIGNAL(userLocationReady(User*)),
298             m_userPanel, SLOT(userDataReceived(User*)));
299
300     connect(m_userPanel, SIGNAL(requestReverseGeo()),
301             this, SIGNAL(requestReverseGeo()));
302
303     connect(this, SIGNAL(reverseGeoReady(QString)),
304             m_userPanel, SIGNAL(reverseGeoReady(QString)));
305
306     connect(m_userPanel, SIGNAL(statusUpdate(QString,bool)),
307             this, SIGNAL(statusUpdate(QString,bool)));
308
309     connect(m_userPanel, SIGNAL(refreshUserData()),
310             this, SIGNAL(refreshUserData()));
311
312     connect(m_mapView, SIGNAL(viewResized(QSize)),
313             m_userPanel, SLOT(screenResized(QSize)));
314
315     connect(this, SIGNAL(clearUpdateLocationDialogData()),
316             m_userPanel, SIGNAL(clearUpdateLocationDialogData()));
317
318     connect(this, SIGNAL(messageSendingFailed(int)),
319             m_userPanel, SIGNAL(messageSendingFailed(int)));
320
321     connect(m_userPanel, SIGNAL(notificateUpdateFailing(QString, bool)),
322             this, SLOT(buildInformationBox(QString, bool)));
323 }
324
325 void MainWindow::buildWebView()
326 {
327     qDebug() << __PRETTY_FUNCTION__;
328
329     if(!m_webView) {
330         m_webView = new QWebView;
331
332         if(!m_cookieJar)
333             m_cookieJar = new NetworkCookieJar(new QNetworkCookieJar(this));
334
335         m_webView->page()->networkAccessManager()->setCookieJar(m_cookieJar);
336
337         connect(m_webView->page()->networkAccessManager(), SIGNAL(finished(QNetworkReply*)),
338                 this, SLOT(webViewRequestFinished(QNetworkReply*)));
339         connect(m_webView, SIGNAL(urlChanged(const QUrl &)),
340                 this, SIGNAL(updateCredentials(QUrl)));
341         connect(m_webView, SIGNAL(loadFinished(bool)),
342                 this, SLOT(loadDone(bool)));
343
344         m_webView->hide();
345     }
346 }
347
348 void MainWindow::buildZoomButtonPanel()
349 {
350     qDebug() << __PRETTY_FUNCTION__;
351
352     m_zoomButtonPanel = new ZoomButtonPanel(this);
353
354     connect(m_zoomButtonPanel->zoomInButton(), SIGNAL(clicked()),
355             this, SIGNAL(zoomIn()));
356
357     connect(m_zoomButtonPanel->zoomOutButton(), SIGNAL(clicked()),
358             this, SIGNAL(zoomOut()));
359
360     connect(this, SIGNAL(zoomLevelChanged(int)),
361             m_zoomButtonPanel, SLOT(resetButtons()));
362
363     connect(this, SIGNAL(maxZoomLevelReached()),
364             m_zoomButtonPanel, SLOT(disableZoomInButton()));
365
366     connect(this, SIGNAL(minZoomLevelReached()),
367             m_zoomButtonPanel, SLOT(disableZoomOutButton()));
368
369     connect(m_mapView, SIGNAL(viewResized(QSize)),
370             m_zoomButtonPanel, SLOT(screenResized(QSize)));
371 }
372
373 void MainWindow::clearCookieJar()
374 {
375     qDebug() << __PRETTY_FUNCTION__;
376
377     buildWebView();
378
379     m_webView->stop();
380
381     if(!m_cookieJar) {
382         m_cookieJar = new NetworkCookieJar(new QNetworkCookieJar(this));
383     }
384     QList<QNetworkCookie> emptyList;
385     emptyList.clear();
386
387     m_cookieJar->setAllCookies(emptyList);
388     m_webView->page()->networkAccessManager()->setCookieJar(m_cookieJar);
389 }
390
391 void MainWindow::createMenus()
392 {
393     qDebug() << __PRETTY_FUNCTION__;
394
395     // login/logout
396     m_loginAct = new QAction(tr("Login"), this);
397     connect(m_loginAct, SIGNAL(triggered()),
398             this, SIGNAL(loginActionPressed()));
399
400     // settings
401     m_toSettingsAct = new QAction(tr("Settings"), this);
402     connect(m_toSettingsAct, SIGNAL(triggered()),
403         this, SLOT(openSettingsDialog()));
404
405     // GPS
406     m_gpsToggleAct = new QAction(tr("GPS"), this);
407     m_gpsToggleAct->setCheckable(true);
408
409     connect(m_gpsToggleAct, SIGNAL(triggered(bool)),
410             this, SIGNAL(gpsTriggered(bool)));
411
412     // automatic centering
413     m_autoCenteringAct = new QAction(tr("Auto centering"), this);
414     m_autoCenteringAct->setCheckable(true);
415     connect(m_autoCenteringAct, SIGNAL(triggered(bool)),
416         this, SIGNAL(autoCenteringTriggered(bool)));
417
418     // build the actual menu
419     m_viewMenu = menuBar()->addMenu(tr("Main"));
420     m_viewMenu->addAction(m_loginAct);
421     m_viewMenu->addAction(m_toSettingsAct);
422     m_viewMenu->addAction(m_gpsToggleAct);
423     m_viewMenu->addAction(m_autoCenteringAct);
424     m_viewMenu->setObjectName(tr("Menu"));
425 }
426
427 void MainWindow::dialogFinished(int status)
428 {
429     qDebug() << __PRETTY_FUNCTION__;
430
431     QDialog *dialog = m_queue.takeFirst();
432     LoginDialog *loginDialog = qobject_cast<LoginDialog *>(dialog);
433     if(loginDialog) {
434         if(status != 0) {
435             buildWebView();
436             loginDialog->userInput(m_email, m_password);
437
438             QStringList urlParts;
439             urlParts.append(FACEBOOK_LOGINBASE);
440             urlParts.append(SITUARE_PUBLIC_FACEBOOKAPI_KEY);
441             urlParts.append(INTERVAL1);
442             urlParts.append(SITUARE_LOGIN_SUCCESS);
443             urlParts.append(INTERVAL2);
444             urlParts.append(SITUARE_LOGIN_FAILURE);
445             urlParts.append(FACEBOOK_LOGIN_ENDING);
446
447             emit saveUsername(m_email);
448             m_refresh = true;
449             m_webView->load(QUrl(urlParts.join(EMPTY)));
450             toggleProgressIndicator(true);
451         } else {
452             emit cancelLoginProcess();
453         }
454     }
455
456     dialog->deleteLater();
457
458     if(!m_error_queue.isEmpty() && m_errorShown == false) {
459         showErrorInformationBox();
460     } else {
461         if(!m_queue.isEmpty()) {
462             showInformationBox();
463         }
464     }
465 }
466
467 void MainWindow::drawFullScreenButton(const QSize &size)
468 {
469     qDebug() << __PRETTY_FUNCTION__ << size.width() << "x" << size.height();
470
471     if(m_fullScreenButton) {
472         m_fullScreenButton->move(size.width() - m_fullScreenButton->size().width()
473                                  - PANEL_PEEK_AMOUNT,
474                                  size.height() - m_fullScreenButton->size().height());
475     }
476 }
477
478 void MainWindow::drawMapScale(const QSize &size)
479 {
480     const int LEFT_SCALE_MARGIN = 10;
481     const int BOTTOM_SCALE_MARGIN = 2;
482     qDebug() << __PRETTY_FUNCTION__ << size.width() << "x" << size.height();
483
484     m_mapScale->move(PANEL_PEEK_AMOUNT + LEFT_SCALE_MARGIN,
485                      size.height() - m_mapScale->size().height() - BOTTOM_SCALE_MARGIN);
486 }
487
488 void MainWindow::drawOsmLicense(const QSize &size)
489 {
490     qDebug() << __PRETTY_FUNCTION__ << size.width() << "x" << size.height();
491
492     m_osmLicense->move(size.width() - m_osmLicense->fontMetrics().width(OSM_LICENSE)
493                        - PANEL_PEEK_AMOUNT,
494                        size.height() - m_osmLicense->fontMetrics().height());
495 }
496
497 void MainWindow::drawOwnLocationCrosshair(const QSize &size)
498 {
499     qDebug() << __PRETTY_FUNCTION__;
500
501     if (m_drawOwnLocationCrosshair && m_ownLocationCrosshair != 0) {
502         m_ownLocationCrosshair->move(size.width()/2 - m_ownLocationCrosshair->pixmap()->width()/2,
503                             size.height()/2 - m_ownLocationCrosshair->pixmap()->height()/2);
504     }
505 }
506
507 void MainWindow::errorDialogFinished(int status)
508 {
509     qDebug() << __PRETTY_FUNCTION__;
510
511     qDebug() << status;
512     QDialog *dialog = m_error_queue.takeFirst();
513
514     dialog->deleteLater();
515     m_errorShown = false;
516
517     if(!m_error_queue.isEmpty())
518         showErrorInformationBox();
519     else if(!m_queue.isEmpty())
520         showInformationBox();
521 }
522
523 void MainWindow::gpsTimeout()
524 {
525     qDebug() << __PRETTY_FUNCTION__;
526
527     buildInformationBox(tr("GPS timeout"));
528 }
529
530 void MainWindow::grabZoomKeys(bool grab)
531 {
532     qDebug() << __PRETTY_FUNCTION__;
533
534 #ifdef Q_WS_MAEMO_5
535     // Can't grab keys unless we have a window id
536     if (!winId())
537         return;
538
539     unsigned long val = (grab) ? 1 : 0;
540     Atom atom = XInternAtom(QX11Info::display(), "_HILDON_ZOOM_KEY_ATOM", False);
541     if (!atom)
542         return;
543
544     XChangeProperty (QX11Info::display(),
545                      winId(),
546                      atom,
547                      XA_INTEGER,
548                      32,
549                      PropModeReplace,
550                      reinterpret_cast<unsigned char *>(&val),
551                      1);
552 #else
553     Q_UNUSED(grab);
554 #endif // Q_WS_MAEMO_5
555 }
556
557 void MainWindow::keyPressEvent(QKeyEvent* event)
558 {
559     qDebug() << __PRETTY_FUNCTION__;
560
561     switch (event->key()) {
562     case Qt::Key_F7:
563         event->accept();
564         emit zoomIn();
565         break;
566
567     case Qt::Key_F8:
568         event->accept();
569         emit zoomOut();
570         break;
571     }
572     QWidget::keyPressEvent(event);
573 }
574
575 void MainWindow::loadCookies()
576 {
577     qDebug() << __PRETTY_FUNCTION__;
578
579     QSettings settings(DIRECTORY_NAME, FILE_NAME);
580
581     QStringList list = settings.value(COOKIES, EMPTY).toStringList();
582
583     if(!list.isEmpty()) {
584         QList<QNetworkCookie> cookieList;
585         for(int i=0;i<list.count();i++) {
586             cookieList.append(QNetworkCookie::parseCookies(list.at(i).toAscii()));
587         }
588
589         if(!m_cookieJar)
590                m_cookieJar = new NetworkCookieJar(new QNetworkCookieJar(this));
591
592         m_cookieJar->setAllCookies(cookieList);
593         m_webView->page()->networkAccessManager()->setCookieJar(m_cookieJar);
594
595     }
596 }
597
598 void MainWindow::loadDone(bool done)
599 {
600     qDebug() << __PRETTY_FUNCTION__;
601
602     // for the first time the login page is opened, we need to refresh it to get cookies working
603     if(m_refresh) {
604         m_webView->reload();
605         m_refresh = false;
606     }
607
608     if (done)
609     {
610         QWebFrame* frame = m_webView->page()->currentFrame();
611         if (frame!=NULL)
612         {
613             // set email box
614             QWebElementCollection emailCollection = frame->findAllElements("input[name=email]");
615
616             foreach (QWebElement element, emailCollection) {
617                 element.setAttribute("value", m_email.toAscii());
618             }
619             // set password box
620             QWebElementCollection passwordCollection = frame->findAllElements("input[name=pass]");
621             foreach (QWebElement element, passwordCollection) {
622                 element.setAttribute("value", m_password.toAscii());
623             }
624             // find connect button
625             QWebElementCollection buttonCollection = frame->findAllElements("input[name=login]");
626             foreach (QWebElement element, buttonCollection)
627             {
628                 QPoint pos(element.geometry().center());
629
630                 // send a mouse click event to the web page
631                 QMouseEvent event0(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton,
632                                    Qt::NoModifier);
633                 QApplication::sendEvent(m_webView->page(), &event0);
634                 QMouseEvent event1(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton,
635                                    Qt::NoModifier);
636                 QApplication::sendEvent(m_webView->page(), &event1);
637             }
638         }
639     }
640 }
641
642 void MainWindow::loggedIn(bool logged)
643 {
644     qDebug() << __PRETTY_FUNCTION__;
645
646     m_loggedIn = logged;
647
648     if(logged) {
649         m_loginAct->setText(tr("Logout"));
650     } else {
651         clearCookieJar();
652         m_email.clear();
653         m_password.clear();
654
655         m_loginAct->setText(tr("Login"));
656     }
657     updateItemVisibility();
658 }
659
660 void MainWindow::loginFailed()
661 {
662     qDebug() << __PRETTY_FUNCTION__;
663
664     clearCookieJar();
665
666     toggleProgressIndicator(false);
667
668     startLoginProcess();
669 }
670
671 bool MainWindow::loginState()
672 {
673     qDebug() << __PRETTY_FUNCTION__;
674
675     return m_loggedIn;
676 }
677
678 void MainWindow::loginUsingCookies()
679 {
680     qDebug() << __PRETTY_FUNCTION__;
681
682     buildWebView();
683     loadCookies();
684     
685     QStringList urlParts;
686     urlParts.append(FACEBOOK_LOGINBASE);
687     urlParts.append(SITUARE_PUBLIC_FACEBOOKAPI_KEY);
688     urlParts.append(INTERVAL1);
689     urlParts.append(SITUARE_LOGIN_SUCCESS);
690     urlParts.append(INTERVAL2);
691     urlParts.append(SITUARE_LOGIN_FAILURE);
692     urlParts.append(FACEBOOK_LOGIN_ENDING);
693
694     m_webView->load(QUrl(urlParts.join(EMPTY)));
695
696 }
697
698 void MainWindow::openSettingsDialog()
699 {
700     qDebug() << __PRETTY_FUNCTION__;
701
702     SettingsDialog *settingsDialog = new SettingsDialog(this);
703     settingsDialog->enableSituareSettings((m_loggedIn && m_gpsToggleAct->isChecked()));
704     connect(settingsDialog, SIGNAL(accepted()), this, SLOT(settingsDialogAccepted()));
705
706     settingsDialog->show();
707 }
708
709 void MainWindow::readAutomaticLocationUpdateSettings()
710 {
711     qDebug() << __PRETTY_FUNCTION__;
712
713     QSettings settings(DIRECTORY_NAME, FILE_NAME);
714     bool automaticUpdateEnabled = settings.value(SETTINGS_AUTOMATIC_UPDATE_ENABLED, false).toBool();
715     QTime automaticUpdateInterval = settings.value(SETTINGS_AUTOMATIC_UPDATE_INTERVAL, QTime())
716                                       .toTime();
717
718     if (automaticUpdateEnabled && automaticUpdateInterval.isValid()) {
719         QTime time;
720         emit enableAutomaticLocationUpdate(true, time.msecsTo(automaticUpdateInterval));
721     } else {
722         emit enableAutomaticLocationUpdate(false);
723     }
724 }
725
726 void MainWindow::queueDialog(QDialog *dialog)
727 {
728     qDebug() << __PRETTY_FUNCTION__;
729
730     // check is dialog is modal, for now all modal dialogs have hihger priority i.e. errors
731     if(dialog->isModal()) {
732         m_error_queue.append(dialog);
733     } else {
734         m_queue.append(dialog);
735     }
736
737     // show error dialog if there is only one error dialog in the queue and no error dialog is shown
738     if(m_error_queue.count() == 1 && m_errorShown == false)
739         showErrorInformationBox();
740     else if(m_queue.count() == 1 && m_errorShown == false)
741         showInformationBox();
742 }
743
744 void MainWindow::saveCookies()
745 {
746     qDebug() << __PRETTY_FUNCTION__;
747
748     if(!m_cookieJar)
749         m_cookieJar = new NetworkCookieJar(new QNetworkCookieJar(this));
750
751     QList<QNetworkCookie> cookieList = m_cookieJar->allCookies();
752     QStringList list;
753
754     for(int i=0;i<cookieList.count();i++) {
755         QNetworkCookie cookie = cookieList.at(i);
756         QByteArray byteArray = cookie.toRawForm(QNetworkCookie::Full);
757         list.append(QString(byteArray));
758     }
759     list.removeDuplicates();
760
761     QSettings settings(DIRECTORY_NAME, FILE_NAME);
762     settings.setValue(COOKIES, list);
763 }
764
765 void MainWindow::setAutoCenteringButtonEnabled(bool enabled)
766 {
767     qDebug() << __PRETTY_FUNCTION__;
768
769     m_autoCenteringAct->setChecked(enabled);
770 }
771
772 void MainWindow::setGPSButtonEnabled(bool enabled)
773 {
774     qDebug() << __PRETTY_FUNCTION__;
775
776     m_gpsToggleAct->setChecked(enabled);
777
778     setOwnLocationCrosshairVisibility(!enabled);
779
780     m_autoCenteringAct->setVisible(enabled);
781 }
782
783 void MainWindow::setMapViewScene(QGraphicsScene *scene)
784 {
785     qDebug() << __PRETTY_FUNCTION__;
786
787     m_mapView->setScene(scene);
788 }
789
790 void MainWindow::setOwnLocationCrosshairVisibility(bool visibility)
791 {
792     qDebug() << __PRETTY_FUNCTION__;
793
794     if (visibility && m_loggedIn) {
795         m_ownLocationCrosshair->show();
796         m_drawOwnLocationCrosshair = true;
797         drawOwnLocationCrosshair(QSize(m_viewPortWidth, m_viewPortHeight));
798     } else {
799         m_ownLocationCrosshair->hide();
800         m_drawOwnLocationCrosshair = false;
801     }
802 }
803
804 void MainWindow::settingsDialogAccepted()
805 {
806     qDebug() << __PRETTY_FUNCTION__;
807
808     readAutomaticLocationUpdateSettings();
809 }
810
811 void MainWindow::setUsername(const QString &username)
812 {
813     qDebug() << __PRETTY_FUNCTION__;
814
815     m_email = username;
816 }
817
818 void MainWindow::setViewPortSize(const QSize &size)
819 {
820     qDebug() << __PRETTY_FUNCTION__;
821
822     m_viewPortWidth = size.width();
823     m_viewPortHeight = size.height();
824 }
825
826 void MainWindow::showEnableAutomaticUpdateLocationDialog(const QString &text)
827 {
828     qDebug() << __PRETTY_FUNCTION__;
829
830     m_automaticUpdateLocationDialog = new QMessageBox(QMessageBox::Question,
831                                                       tr("Automatic location update"), text,
832                                                       QMessageBox::Yes | QMessageBox::No |
833                                                       QMessageBox::Cancel, this);
834     connect(m_automaticUpdateLocationDialog, SIGNAL(finished(int)),
835             this, SLOT(automaticUpdateDialogFinished(int)));
836
837     m_automaticUpdateLocationDialog->show();
838 }
839
840 void MainWindow::toggleFullScreen()
841 {
842     qDebug() << __PRETTY_FUNCTION__;
843
844     if(windowState() == Qt::WindowNoState)
845         showFullScreen();
846     else
847         showNormal();
848 }
849
850 void MainWindow::showErrorInformationBox()
851 {
852     qDebug() << __PRETTY_FUNCTION__;
853
854     if(m_error_queue.count()) {
855         m_errorShown = true;
856         QDialog *dialog = m_error_queue.first();
857         connect(dialog, SIGNAL(finished(int)),
858                 this, SLOT(errorDialogFinished(int)));
859         dialog->show();
860     }
861 }
862
863 void MainWindow::showInformationBox()
864 {
865     qDebug() << __PRETTY_FUNCTION__;
866
867     if(m_queue.count()) {
868         QDialog *dialog = m_queue.first();
869         connect(dialog, SIGNAL(finished(int)),
870                 this, SLOT(dialogFinished(int)));
871         dialog->show();
872     }
873 }
874
875 void MainWindow::startLoginProcess()
876 {
877     qDebug() << __PRETTY_FUNCTION__;
878
879     LoginDialog *loginDialog = new LoginDialog();
880
881     emit fetchUsernameFromSettings();
882
883     loginDialog->clearTextFields();
884
885     if(!m_email.isEmpty())
886         loginDialog->setEmailField(m_email);
887
888     queueDialog(loginDialog);
889 }
890
891 void MainWindow::toggleProgressIndicator(bool value)
892 {
893     qDebug() << __PRETTY_FUNCTION__;
894
895 #ifdef Q_WS_MAEMO_5
896     setAttribute(Qt::WA_Maemo5ShowProgressIndicator, value);
897 #else
898     Q_UNUSED(value);
899 #endif // Q_WS_MAEMO_5
900 }
901
902 void MainWindow::updateItemVisibility()
903 {
904     qDebug() << __PRETTY_FUNCTION__;
905     
906     if(m_loggedIn) {
907         m_friendsListPanel->show();
908         m_friendsListPanelSidebar->show();
909         m_userPanel->show();
910         m_userPanelSidebar->show();
911
912         if(!m_gpsToggleAct->isChecked())
913             setOwnLocationCrosshairVisibility(true);
914     } else {
915         m_friendsListPanel->closePanel();
916         m_friendsListPanel->hide();
917         m_friendsListPanelSidebar->hide();
918         m_userPanel->closePanel();
919         m_userPanel->hide();
920         m_userPanelSidebar->hide();
921         setOwnLocationCrosshairVisibility(false);
922     }
923 }
924
925 const QString MainWindow::username()
926 {
927     qDebug() << __PRETTY_FUNCTION__;
928     
929     return m_email;
930 }
931
932 void MainWindow::webViewRequestFinished(QNetworkReply *reply)
933 {
934     qDebug() << __PRETTY_FUNCTION__;
935
936     // omit QNetworkReply::OperationCanceledError due to it's nature to be called when ever
937     // qwebview starts to load a new page while the current page loading is not finished
938     if(reply->error() != QNetworkReply::OperationCanceledError &&
939        reply->error() != QNetworkReply::NoError) {
940         emit error(reply->error());
941         toggleProgressIndicator(false);
942     }
943 }
944