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