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