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