aeaedac1098999b00843b4c20624d361c8bf1adf
[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 <QtAlgorithms>
28 #include <QtWebKit>
29
30 #include <QAction>
31 #include <QApplication>
32 #include <QMenuBar>
33 #include <QMessageBox>
34
35 #include "common.h"
36 #include "error.h"
37 #include "friendlistpanel.h"
38 #include "fullscreenbutton.h"
39 #include "indicatorbuttonpanel.h"
40 #include "locationsearchpanel.h"
41 #include "map/mapcommon.h"
42 #include "map/mapview.h"
43 #include "mapscale.h"
44 #include "panelcommon.h"
45 #include "routingpanel.h"
46 #include "searchdialog.h"
47 #include "settingsdialog.h"
48 #include "situareservice/situarecommon.h"
49 #include "tabbedpanel.h"
50 #include "updatelocation/updatelocationdialog.h"
51 #include "userinfopanel.h"
52 #include "zoombuttonpanel.h"
53
54 #include "mainwindow.h"
55
56 // These MUST BE HERE, compiling for Maemo fails if moved
57 #ifdef Q_WS_MAEMO_5
58 #include <QtMaemo5/QMaemo5InformationBox>
59 #include <QtGui/QX11Info>
60 #include <X11/Xatom.h>
61 #include <X11/Xlib.h>
62 #endif // Q_WS_MAEMO_5
63
64 #if defined(Q_WS_MAEMO_5) & defined(ARMEL)
65 #include "ossoabookdialog.h"
66 #endif
67
68 MainWindow::MainWindow(QWidget *parent)
69     : QMainWindow(parent),
70       m_errorShown(false),
71       m_loggedIn(false),
72       m_refresh(false),
73       m_mapCenterHorizontalShifting(0),
74       m_progressIndicatorCount(0),
75       m_loginDialog(0),
76       m_crosshair(0),
77       m_fullScreenButton(0),
78       m_indicatorButtonPanel(0),
79       m_mapScale(0),
80       m_updateLocation(0)
81 {
82     qDebug() << __PRETTY_FUNCTION__;
83
84     buildMap();
85
86     // map view is the only widget which size & location is handled automatically by the system
87     // default functionality
88     setCentralWidget(m_mapView);
89
90     buildPanels();
91
92     createMenus();
93     setWindowTitle(tr("Situare"));
94
95     // set stacking order of widgets (from top to bottom)
96     // m_tabbedPanel is the topmost one
97     if (m_fullScreenButton) {
98         m_fullScreenButton->stackUnder(m_tabbedPanel);
99         m_crosshair->stackUnder(m_fullScreenButton);
100     } else {
101         m_crosshair->stackUnder(m_tabbedPanel);
102     }
103     m_zoomButtonPanel->stackUnder(m_crosshair);
104     m_indicatorButtonPanel->stackUnder(m_zoomButtonPanel);
105     m_osmLicense->stackUnder(m_indicatorButtonPanel);
106     m_mapScale->stackUnder(m_osmLicense);
107     m_mapView->stackUnder(m_mapScale);
108
109     grabZoomKeys(true);
110
111     // Set default screen size
112     resize(DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_HEIGHT);
113 #ifdef Q_WS_MAEMO_5
114     setAttribute(Qt::WA_Maemo5StackedWindow);
115 #endif
116 }
117
118 MainWindow::~MainWindow()
119 {
120     qDebug() << __PRETTY_FUNCTION__;
121
122     grabZoomKeys(false);
123
124     qDeleteAll(m_queue.begin(), m_queue.end());
125     m_queue.clear();
126
127     qDeleteAll(m_error_queue.begin(), m_error_queue.end());
128     m_error_queue.clear();
129
130     QSettings settings(SETTINGS_ORGANIZATION_NAME, SETTINGS_APPLICATION_NAME);
131
132     if (!m_backupMessage.isEmpty()) {
133         settings.setValue(USER_UNSEND_MESSAGE, m_backupMessage.toAscii());
134         settings.setValue(USER_UNSEND_MESSAGE_PUBLISH, m_backupFacebookPublishPolicity);
135     } else {
136         settings.remove(USER_UNSEND_MESSAGE);
137         settings.remove(USER_UNSEND_MESSAGE_PUBLISH);
138     }
139 }
140
141 void MainWindow::automaticUpdateDialogFinished(int result)
142 {
143     qDebug() << __PRETTY_FUNCTION__;
144
145     if (result == QMessageBox::Yes) {
146         readAutomaticLocationUpdateSettings();
147     } else {
148         QSettings settings(SETTINGS_ORGANIZATION_NAME, SETTINGS_APPLICATION_NAME);
149         settings.setValue(SETTINGS_AUTOMATIC_UPDATE_ENABLED, false);
150         readAutomaticLocationUpdateSettings();
151     }
152
153     m_automaticUpdateLocationDialog->deleteLater();
154 }
155
156 void MainWindow::backupUpdateLocationDialogData(const QString &status, bool publish)
157 {
158     qDebug() << __PRETTY_FUNCTION__;
159
160     m_backupMessage = status;
161     m_backupFacebookPublishPolicity = publish;
162 }
163
164 void MainWindow::buildCrosshair()
165 {
166     qDebug() << __PRETTY_FUNCTION__;
167
168     m_crosshair = new QLabel(this);
169     QPixmap crosshairImage(":/res/images/sight.png");
170     m_crosshair->setPixmap(crosshairImage);
171     m_crosshair->setFixedSize(crosshairImage.size());
172     m_crosshair->hide();
173     m_crosshair->setAttribute(Qt::WA_TransparentForMouseEvents, true);
174
175     connect(m_mapView, SIGNAL(viewResized(QSize)),
176             this, SLOT(moveCrosshair()));
177
178     connect(m_mapView, SIGNAL(horizontalShiftingChanged(int)),
179             this, SLOT(mapCenterHorizontalShiftingChanged(int)));
180 }
181
182 void MainWindow::buildFriendListPanel()
183 {
184     qDebug() << __PRETTY_FUNCTION__;
185
186     m_friendsListPanel = new FriendListPanel(this);
187
188     connect(this, SIGNAL(friendsLocationsReady(QList<User*>&)),
189             m_friendsListPanel, SLOT(friendInfoReceived(QList<User*>&)));
190
191     connect(this, SIGNAL(locationItemClicked(QList<QString>)),
192             m_friendsListPanel, SLOT(showFriendsInList(QList<QString>)));
193
194     connect(m_friendsListPanel, SIGNAL(findFriend(GeoCoordinate)),
195             this, SIGNAL(centerToCoordinates(GeoCoordinate)));
196
197     connect(this, SIGNAL(friendImageReady(User*)),
198             m_friendsListPanel, SLOT(friendImageReady(User*)));
199
200     connect(m_friendsListPanel, SIGNAL(routeToFriend(const GeoCoordinate&)),
201             this, SIGNAL(routeTo(const GeoCoordinate&)));
202
203     connect(m_friendsListPanel, SIGNAL(requestContactDialog(const QString &)),
204             this, SIGNAL(requestContactDialog(const QString &)));
205 }
206
207 void MainWindow::buildFullScreenButton()
208 {
209     qDebug() << __PRETTY_FUNCTION__;
210
211 #ifdef Q_WS_MAEMO_5
212     m_fullScreenButton = new FullScreenButton(this);
213
214     if (m_fullScreenButton) {
215         connect(m_fullScreenButton, SIGNAL(clicked()),
216                 this, SLOT(toggleFullScreen()));
217
218         connect(qApp, SIGNAL(showFullScreenButton()),
219                 m_fullScreenButton, SLOT(invoke()));
220     }
221 #endif // Q_WS_MAEMO_5
222 }
223
224 void MainWindow::buildIndicatorButtonPanel()
225 {
226     qDebug() << __PRETTY_FUNCTION__;
227
228     m_indicatorButtonPanel = new IndicatorButtonPanel(this);
229
230     connect(m_indicatorButtonPanel, SIGNAL(autoCenteringTriggered(bool)),
231         this, SIGNAL(autoCenteringTriggered(bool)));
232
233     connect(m_mapView, SIGNAL(viewResized(QSize)),
234             m_indicatorButtonPanel, SLOT(screenResized(QSize)));
235
236     connect(this, SIGNAL(directionIndicatorValuesUpdate(qreal, qreal, bool)),
237             m_indicatorButtonPanel, SIGNAL(directionIndicatorValuesUpdate(qreal, qreal, bool)));
238
239     connect(m_indicatorButtonPanel, SIGNAL(draggingModeTriggered()),
240             this, SIGNAL(draggingModeTriggered()));
241 }
242
243 void MainWindow::buildInformationBox(const QString &message, bool modal)
244 {
245     qDebug() << __PRETTY_FUNCTION__;
246
247     QString errorMessage = message;
248
249 #ifdef Q_WS_MAEMO_5
250
251     QMaemo5InformationBox *msgBox = new QMaemo5InformationBox(this);
252
253     if(modal) {
254         msgBox->setTimeout(QMaemo5InformationBox::NoTimeout);
255         // extra line changes are needed to make error notes broader
256         errorMessage.prepend("\n");
257         errorMessage.append("\n");
258     } else {
259         msgBox->setTimeout(QMaemo5InformationBox::DefaultTimeout);
260     }
261     QLabel *label = new QLabel(msgBox);
262     label->setAlignment(Qt::AlignCenter);
263     label->setText(errorMessage);
264     msgBox->setWidget(label);
265 #else
266     QMessageBox *msgBox = new QMessageBox(this);
267     msgBox->button(QMessageBox::Ok);
268     msgBox->setText(errorMessage);
269     msgBox->setModal(modal);
270 #endif
271
272     queueDialog(msgBox);
273 }
274
275 void MainWindow::buildLocationSearchPanel()
276 {
277     qDebug() << __PRETTY_FUNCTION__;
278
279     m_locationSearchPanel = new LocationSearchPanel(this);
280
281     connect(this, SIGNAL(locationDataParsed(const QList<Location>&)),
282             m_locationSearchPanel, SLOT(populateLocationListView(const QList<Location>&)));
283
284     connect(m_locationSearchPanel, SIGNAL(locationItemClicked(const GeoCoordinate&, const GeoCoordinate&)),
285             this, SIGNAL(locationItemClicked(const GeoCoordinate&, const GeoCoordinate&)));
286
287     connect(m_locationSearchPanel, SIGNAL(routeToLocation(const GeoCoordinate&)),
288             this, SIGNAL(routeTo(const GeoCoordinate&)));
289
290     connect(m_locationSearchPanel, SIGNAL(requestSearchLocation()),
291             this, SLOT(startLocationSearch()));
292
293     connect(this, SIGNAL(searchForLocation(QString)),
294             m_locationSearchPanel, SLOT(prependSearchHistory(QString)));
295
296     connect(m_locationSearchPanel, SIGNAL(searchHistoryItemClicked(QString)),
297             this, SIGNAL(searchHistoryItemClicked(QString)));
298 }
299
300 void MainWindow::buildLoginDialog(QWebView *browser)
301 {
302     qWarning() << __PRETTY_FUNCTION__;
303
304     if (!m_loginDialog) {
305         m_loginDialog = new QDialog(this);
306         if (m_loginDialog) {
307             m_loginDialog->setWindowTitle(tr("Login"));
308             m_loginDialog->setLayout(new QVBoxLayout());
309             m_loginDialog->layout()->addWidget(browser);
310             m_loginDialog->layout()->setContentsMargins(QMargins()); // zero margins
311             connect(m_loginDialog, SIGNAL(rejected()), this, SLOT(destroyLoginDialog()));
312         }
313     }
314
315     if (m_loginDialog)
316         m_loginDialog->show();
317 }
318
319 void MainWindow::buildMap()
320 {
321     qDebug() << __PRETTY_FUNCTION__;
322
323     m_mapView = new MapView(this);
324
325     buildZoomButtonPanel();
326     buildOsmLicense();
327     buildCrosshair();
328     buildFullScreenButton();
329     buildIndicatorButtonPanel();
330     buildMapScale();
331
332     connect(m_mapView, SIGNAL(viewScrolled(SceneCoordinate)),
333             this, SIGNAL(mapViewScrolled(SceneCoordinate)));
334
335     connect(this, SIGNAL(centerToSceneCoordinates(SceneCoordinate)),
336             m_mapView, SLOT(centerToSceneCoordinates(SceneCoordinate)));
337
338     connect(m_mapView, SIGNAL(viewResized(QSize)),
339             this, SIGNAL(mapViewResized(QSize)));
340
341     connect(m_mapView, SIGNAL(viewResized(QSize)),
342             this, SLOT(drawFullScreenButton(QSize)));
343
344     connect(m_mapView, SIGNAL(viewResized(QSize)),
345             this, SLOT(drawMapScale(QSize)));
346
347     connect(m_mapView, SIGNAL(viewResized(QSize)),
348              this, SLOT(moveCrosshair()));
349
350     connect(this, SIGNAL(zoomLevelChanged(int)),
351             m_mapView, SLOT(setZoomLevel(int)));
352
353     connect(m_mapView, SIGNAL(viewZoomFinished()),
354             this, SIGNAL(viewZoomFinished()));
355
356     connect(m_mapView, SIGNAL(zoomIn()),
357             this, SIGNAL(zoomIn()));
358 }
359
360 void MainWindow::buildMapScale()
361 {
362     m_mapScale = new MapScale(this);
363     connect(this, SIGNAL(newMapResolution(qreal)),
364             m_mapScale, SLOT(updateMapResolution(qreal)));
365 }
366
367 void MainWindow::buildOsmLicense()
368 {
369     qDebug() << __PRETTY_FUNCTION__;
370
371     m_osmLicense = new QLabel(this);
372     m_osmLicense->setAttribute(Qt::WA_TranslucentBackground, true);
373     m_osmLicense->setAttribute(Qt::WA_TransparentForMouseEvents, true);
374     m_osmLicense->setText("<font color='black'>" + OSM_LICENSE + "</font>");
375     m_osmLicense->setFont(QFont("Nokia Sans", 9));
376     m_osmLicense->resize(m_osmLicense->fontMetrics().width(OSM_LICENSE),
377                          m_osmLicense->fontMetrics().height());
378
379     connect(m_mapView, SIGNAL(viewResized(QSize)),
380             this, SLOT(drawOsmLicense(QSize)));
381 }
382
383 void MainWindow::buildPanels()
384 {
385     qDebug() << __PRETTY_FUNCTION__;
386
387     buildUserInfoPanel();
388     buildFriendListPanel();
389     buildLocationSearchPanel();
390     buildRoutingPanel();
391
392     m_tabbedPanel = new TabbedPanel(this);
393
394     //Save Situare related tab indexes so tabs can be enabled/disabled when logged in/out
395     m_situareTabsIndexes.append(
396             m_tabbedPanel->addTab(m_userInfoPanel, QIcon(":/res/images/user_info.png")));
397     m_situareTabsIndexes.append(
398             m_tabbedPanel->addTab(m_friendsListPanel, QIcon(":/res/images/friend_list.png")));
399
400     m_tabbedPanel->addTab(m_locationSearchPanel, QIcon(":/res/images/location_search.png"));
401     m_tabbedPanel->addTab(m_routingPanel, QIcon(":/res/images/routing.png"));
402
403     connect(m_mapView, SIGNAL(viewResized(QSize)),
404             m_tabbedPanel, SLOT(resizePanel(QSize)));
405
406     connect(m_friendsListPanel, SIGNAL(openPanelRequested(QWidget*)),
407             m_tabbedPanel, SLOT(openPanel(QWidget*)));
408
409     connect(m_routingPanel, SIGNAL(openPanelRequested(QWidget*)),
410             m_tabbedPanel, SLOT(openPanel(QWidget*)));
411
412     connect(m_tabbedPanel, SIGNAL(panelClosed()),
413             m_friendsListPanel, SLOT(anyPanelClosed()));
414
415     connect(m_tabbedPanel, SIGNAL(panelOpened()),
416             m_friendsListPanel, SLOT(anyPanelOpened()));
417
418     connect(m_tabbedPanel, SIGNAL(panelClosed()),
419             m_routingPanel, SLOT(clearListsSelections()));
420
421     connect(m_tabbedPanel, SIGNAL(panelClosed()),
422             m_mapView, SLOT(disableCenterShift()));
423
424     connect(m_tabbedPanel, SIGNAL(panelOpened()),
425             m_mapView, SLOT(enableCenterShift()));
426
427     connect(m_tabbedPanel, SIGNAL(panelClosed()),
428             m_userInfoPanel, SIGNAL(collapse()));
429
430     connect(m_tabbedPanel, SIGNAL(currentChanged(int)),
431             m_userInfoPanel, SIGNAL(collapse()));
432
433     // signals for showing and hiding list item context buttons
434     connect(m_friendsListPanel, SIGNAL(listItemSelectionChanged(bool)),
435             m_tabbedPanel, SIGNAL(listItemSelectionChanged(bool)));
436
437     connect(m_locationSearchPanel, SIGNAL(listItemSelectionChanged(bool)),
438             m_tabbedPanel, SIGNAL(listItemSelectionChanged(bool)));
439
440     connect(m_routingPanel, SIGNAL(listItemSelectionChanged(bool)),
441             m_tabbedPanel, SIGNAL(listItemSelectionChanged(bool)));
442 }
443
444 void MainWindow::buildRoutingPanel()
445 {
446     qDebug() << __PRETTY_FUNCTION__;
447
448     m_routingPanel = new RoutingPanel(this);
449
450     connect(m_routingPanel, SIGNAL(routeToCursor()),
451             this, SIGNAL(routeToCursor()));
452
453     connect(this, SIGNAL(routeParsed(Route&)),
454             m_routingPanel, SLOT(setRoute(Route&)));
455
456     connect(m_routingPanel, SIGNAL(routeWaypointItemClicked(GeoCoordinate)),
457             this, SIGNAL(centerToCoordinates(GeoCoordinate)));
458
459     connect(m_routingPanel, SIGNAL(clearRoute()),
460             this, SIGNAL(clearRoute()));
461 }
462
463 void MainWindow::buildUserInfoPanel()
464 {
465     qDebug() << __PRETTY_FUNCTION__;
466
467     m_userInfoPanel = new UserInfoPanel(this);
468
469     connect(this, SIGNAL(userLocationReady(User*)),
470             m_userInfoPanel, SLOT(userDataReceived(User*)));
471
472     connect(m_userInfoPanel, SIGNAL(findUser(GeoCoordinate)),
473             this, SIGNAL(centerToCoordinates(GeoCoordinate)));
474
475     connect(m_userInfoPanel, SIGNAL(refreshUserData()),
476             this, SIGNAL(refreshUserData()));
477
478     connect(m_userInfoPanel, SIGNAL(updateLocationMessageButtonClicked()),
479             this, SLOT(showUpdateLocationDialog()));
480 }
481
482 void MainWindow::buildZoomButtonPanel()
483 {
484     qDebug() << __PRETTY_FUNCTION__;
485
486     m_zoomButtonPanel = new ZoomButtonPanel(this);
487
488     connect(m_zoomButtonPanel->zoomInButton(), SIGNAL(clicked()),
489             this, SIGNAL(zoomIn()));
490
491     connect(m_zoomButtonPanel->zoomOutButton(), SIGNAL(clicked()),
492             this, SIGNAL(zoomOut()));
493
494     connect(this, SIGNAL(zoomLevelChanged(int)),
495             m_zoomButtonPanel, SLOT(resetButtons()));
496
497     connect(this, SIGNAL(maxZoomLevelReached()),
498             m_zoomButtonPanel, SLOT(disableZoomInButton()));
499
500     connect(this, SIGNAL(minZoomLevelReached()),
501             m_zoomButtonPanel, SLOT(disableZoomOutButton()));
502
503     connect(m_mapView, SIGNAL(viewResized(QSize)),
504             m_zoomButtonPanel, SLOT(screenResized(QSize)));
505
506     connect(m_zoomButtonPanel, SIGNAL(draggingModeTriggered()),
507             this, SIGNAL(draggingModeTriggered()));
508 }
509
510 void MainWindow::clearUpdateLocationDialogData()
511 {
512     qDebug() << __PRETTY_FUNCTION__;
513
514     m_backupMessage.clear();
515     m_backupFacebookPublishPolicity = false;
516 }
517
518 void MainWindow::createMenus()
519 {
520     qDebug() << __PRETTY_FUNCTION__;
521
522     // login/logout
523     m_loginAct = new QAction(tr("Login"), this);
524     connect(m_loginAct, SIGNAL(triggered()),
525             this, SIGNAL(loginActionPressed()));
526
527     // settings
528     m_toSettingsAct = new QAction(tr("Settings"), this);
529     connect(m_toSettingsAct, SIGNAL(triggered()),
530         this, SLOT(openSettingsDialog()));
531
532     // GPS
533     m_gpsToggleAct = new QAction(tr("GPS"), this);
534     m_gpsToggleAct->setCheckable(true);
535
536     connect(m_gpsToggleAct, SIGNAL(triggered(bool)),
537             this, SIGNAL(gpsTriggered(bool)));
538
539     // build the actual menu
540     m_viewMenu = menuBar()->addMenu(tr("Main"));
541     m_viewMenu->addAction(m_loginAct);
542     m_viewMenu->addAction(m_toSettingsAct);
543     m_viewMenu->addAction(m_gpsToggleAct);
544     m_viewMenu->setObjectName(tr("Menu"));
545 }
546
547 void MainWindow::destroyLoginDialog()
548 {
549     qWarning() << __PRETTY_FUNCTION__;
550
551     if (m_loginDialog) {
552         m_loginDialog->hide();
553         m_loginDialog->deleteLater();
554         m_loginDialog = 0;
555     }
556 }
557
558 void MainWindow::dialogFinished(int status)
559 {
560     qDebug() << __PRETTY_FUNCTION__;
561
562     QDialog *dialog = m_queue.takeFirst();
563     SearchDialog *searchDialog = qobject_cast<SearchDialog *>(dialog);
564     if ((searchDialog) && (status != 0))
565         emit searchForLocation(searchDialog->input());
566
567     dialog->deleteLater();
568
569     if(!m_error_queue.isEmpty() && m_errorShown == false) {
570         showErrorInformationBox();
571     } else {
572         if(!m_queue.isEmpty()) {
573             showInformationBox();
574         }
575     }
576 }
577
578 void MainWindow::drawFullScreenButton(const QSize &size)
579 {
580     qDebug() << __PRETTY_FUNCTION__ << size.width() << "x" << size.height();
581
582     if (m_fullScreenButton) {
583         m_fullScreenButton->move(size.width() - m_fullScreenButton->size().width(),
584                                  size.height() - m_fullScreenButton->size().height());
585     }
586 }
587
588 void MainWindow::drawMapScale(const QSize &size)
589 {
590     qDebug() << __PRETTY_FUNCTION__;
591
592     const int LEFT_SCALE_MARGIN = 10;
593     const int BOTTOM_SCALE_MARGIN = 2;
594
595     m_mapScale->move(LEFT_SCALE_MARGIN,
596                      size.height() - m_mapScale->size().height() - BOTTOM_SCALE_MARGIN);
597 }
598
599 void MainWindow::drawOsmLicense(const QSize &size)
600 {
601     qDebug() << __PRETTY_FUNCTION__ << size.width() << "x" << size.height();
602
603     m_osmLicense->move(size.width() - m_osmLicense->fontMetrics().width(OSM_LICENSE)
604                        - PANEL_BAR_WIDTH,
605                        size.height() - m_osmLicense->fontMetrics().height());
606 }
607
608 void MainWindow::errorDialogFinished(int status)
609 {
610     qDebug() << __PRETTY_FUNCTION__;
611
612     qDebug() << status;
613     QDialog *dialog = m_error_queue.takeFirst();
614
615     dialog->deleteLater();
616     m_errorShown = false;
617
618     if(!m_error_queue.isEmpty())
619         showErrorInformationBox();
620     else if(!m_queue.isEmpty())
621         showInformationBox();
622 }
623
624 void MainWindow::gpsTimeout()
625 {
626     qDebug() << __PRETTY_FUNCTION__;
627
628     buildInformationBox(tr("GPS timeout"));
629 }
630
631 void MainWindow::grabZoomKeys(bool grab)
632 {
633     qDebug() << __PRETTY_FUNCTION__;
634
635 #ifdef Q_WS_MAEMO_5
636     // Can't grab keys unless we have a window id
637     if (!winId())
638         return;
639
640     unsigned long val = (grab) ? 1 : 0;
641     Atom atom = XInternAtom(QX11Info::display(), "_HILDON_ZOOM_KEY_ATOM", False);
642     if (!atom)
643         return;
644
645     XChangeProperty (QX11Info::display(),
646                      winId(),
647                      atom,
648                      XA_INTEGER,
649                      32,
650                      PropModeReplace,
651                      reinterpret_cast<unsigned char *>(&val),
652                      1);
653 #else
654     Q_UNUSED(grab);
655 #endif // Q_WS_MAEMO_5
656 }
657
658 void MainWindow::keyPressEvent(QKeyEvent* event)
659 {
660     qDebug() << __PRETTY_FUNCTION__;
661
662     switch (event->key()) {
663     case Qt::Key_F7:
664         event->accept();
665         emit zoomIn();
666         break;
667
668     case Qt::Key_F8:
669         event->accept();
670         emit zoomOut();
671         break;
672     }
673     QWidget::keyPressEvent(event);
674 }
675
676 void MainWindow::loggedIn(bool logged)
677 {
678     qDebug() << __PRETTY_FUNCTION__;
679
680     m_loggedIn = logged;
681
682     if(logged) {
683         m_loginAct->setText(tr("Logout"));
684     } else {
685         m_loginAct->setText(tr("Login"));
686         m_userInfoPanel->showUserInfo(false);
687     }
688     updateItemVisibility(logged);
689 }
690
691 void MainWindow::mapCenterHorizontalShiftingChanged(int shifting)
692 {
693     m_mapCenterHorizontalShifting = shifting;
694     moveCrosshair();
695 }
696
697 void MainWindow::moveCrosshair()
698 {
699     qDebug() << __PRETTY_FUNCTION__;
700
701     if (m_crosshair) {
702         int mapHeight = m_mapView->size().height();
703         int mapWidth = m_mapView->size().width();
704         m_crosshair->move(mapWidth / 2 - m_crosshair->pixmap()->width() / 2
705                           - m_mapCenterHorizontalShifting,
706                           mapHeight / 2 - m_crosshair->pixmap()->height() / 2);
707     }
708 }
709
710 void MainWindow::openSettingsDialog()
711 {
712     qDebug() << __PRETTY_FUNCTION__;
713
714     SettingsDialog *settingsDialog = new SettingsDialog(this);
715     settingsDialog->enableSituareSettings((m_loggedIn && m_gpsToggleAct->isChecked()));
716     connect(settingsDialog, SIGNAL(accepted()), this, SLOT(settingsDialogAccepted()));
717
718     settingsDialog->show();
719 }
720
721 void MainWindow::queueDialog(QDialog *dialog)
722 {
723     qDebug() << __PRETTY_FUNCTION__;
724
725     // check is dialog is modal, for now all modal dialogs have hihger priority i.e. errors
726     if(dialog->isModal()) {
727         m_error_queue.append(dialog);
728     } else {
729         m_queue.append(dialog);
730     }
731
732     // show error dialog if there is only one error dialog in the queue and no error dialog is shown
733     if(m_error_queue.count() == 1 && m_errorShown == false)
734         showErrorInformationBox();
735     else if(m_queue.count() == 1 && m_errorShown == false)
736         showInformationBox();
737 }
738
739 void MainWindow::readAutomaticLocationUpdateSettings()
740 {
741     qDebug() << __PRETTY_FUNCTION__;
742
743     QSettings settings(SETTINGS_ORGANIZATION_NAME, SETTINGS_APPLICATION_NAME);
744     bool automaticUpdateEnabled = settings.value(SETTINGS_AUTOMATIC_UPDATE_ENABLED, false).toBool();
745     QTime automaticUpdateInterval = settings.value(SETTINGS_AUTOMATIC_UPDATE_INTERVAL, QTime())
746                                       .toTime();
747
748     if (automaticUpdateEnabled && automaticUpdateInterval.isValid()) {
749         QTime time;
750         emit enableAutomaticLocationUpdate(true, time.msecsTo(automaticUpdateInterval));
751     } else {
752         emit enableAutomaticLocationUpdate(false);
753     }
754 }
755
756 void MainWindow::restoreUnsendMessage()
757 {
758     qDebug() << __PRETTY_FUNCTION__;
759
760     QSettings settings(SETTINGS_ORGANIZATION_NAME, SETTINGS_APPLICATION_NAME);
761     m_backupMessage = settings.value(USER_UNSEND_MESSAGE).toString();
762     m_backupFacebookPublishPolicity = settings.value(USER_UNSEND_MESSAGE_PUBLISH, false).toBool();
763 }
764
765 void MainWindow::setCrosshairVisibility(bool visibility)
766 {
767     qDebug() << __PRETTY_FUNCTION__;
768
769     if (visibility) {
770         m_crosshair->show();
771         moveCrosshair();
772     } else {
773         m_crosshair->hide();
774     }
775 }
776
777 void MainWindow::setGPSButtonEnabled(bool enabled)
778 {
779     qDebug() << __PRETTY_FUNCTION__;
780
781     m_gpsToggleAct->setChecked(enabled);
782 }
783
784 void MainWindow::setIndicatorButtonEnabled(bool enabled)
785 {
786     qDebug() << __PRETTY_FUNCTION__;
787
788     m_indicatorButtonPanel->setIndicatorButtonEnabled(enabled);
789 }
790
791 void MainWindow::setMapViewScene(QGraphicsScene *scene)
792 {
793     qDebug() << __PRETTY_FUNCTION__;
794
795     m_mapView->setScene(scene);
796 }
797
798 void MainWindow::settingsDialogAccepted()
799 {
800     qDebug() << __PRETTY_FUNCTION__;
801
802     readAutomaticLocationUpdateSettings();
803 }
804
805 void MainWindow::showContactDialog(const QString &guid)
806 {
807     qDebug() << __PRETTY_FUNCTION__;
808
809 #if defined(Q_WS_MAEMO_5) & defined(ARMEL)
810     OssoABookDialog::showContactDialog(guid);
811 #else
812     Q_UNUSED(guid);
813     buildInformationBox(tr("Contact dialog works only on phone!"), true);
814 #endif
815 }
816
817 void MainWindow::showEnableAutomaticUpdateLocationDialog(const QString &text)
818 {
819     qDebug() << __PRETTY_FUNCTION__;
820
821     m_automaticUpdateLocationDialog = new QMessageBox(QMessageBox::Question,
822                                                       tr("Automatic location update"), text,
823                                                       QMessageBox::Yes | QMessageBox::No |
824                                                       QMessageBox::Cancel, this);
825     connect(m_automaticUpdateLocationDialog, SIGNAL(finished(int)),
826             this, SLOT(automaticUpdateDialogFinished(int)));
827
828     m_automaticUpdateLocationDialog->show();
829 }
830
831 void MainWindow::showErrorInformationBox()
832 {
833     qDebug() << __PRETTY_FUNCTION__;
834
835     if(m_error_queue.count()) {
836         m_errorShown = true;
837         QDialog *dialog = m_error_queue.first();
838         connect(dialog, SIGNAL(finished(int)),
839                 this, SLOT(errorDialogFinished(int)));
840         dialog->show();
841     }
842 }
843
844 void MainWindow::showInformationBox()
845 {
846     qDebug() << __PRETTY_FUNCTION__;
847
848     if(m_queue.count()) {
849         QDialog *dialog = m_queue.first();
850         connect(dialog, SIGNAL(finished(int)),
851                 this, SLOT(dialogFinished(int)));
852         dialog->show();
853     }
854 }
855
856 void MainWindow::showUpdateLocationDialog()
857 {
858     qDebug() << __PRETTY_FUNCTION__;
859
860     delete m_updateLocation;
861     m_updateLocation = new UpdateLocationDialog(m_backupMessage, m_backupFacebookPublishPolicity,
862                                                 this);
863
864     connect(this, SIGNAL(reverseGeoReady(QString)),
865             m_updateLocation, SLOT(setAddress(QString)));
866
867     connect(m_updateLocation, SIGNAL(statusUpdate(QString, bool)),
868             this, SIGNAL(statusUpdate(QString, bool)));
869
870     connect(m_updateLocation, SIGNAL(statusUpdate(QString, bool)),
871             this, SLOT(backupUpdateLocationDialogData(QString, bool)));
872
873     connect(m_updateLocation, SIGNAL(finished(int)),
874             this, SLOT(updateLocationDialogFinished(int)));
875
876     m_updateLocation->show();
877
878     emit requestReverseGeo();
879 }
880
881 void MainWindow::sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
882 {
883     qWarning() << __PRETTY_FUNCTION__;
884
885     reply->ignoreSslErrors();
886 }
887
888 void MainWindow::startLocationSearch()
889 {
890     qDebug() << __PRETTY_FUNCTION__;
891
892     SearchDialog *searchDialog = new SearchDialog();
893     queueDialog(searchDialog);
894 }
895
896 void MainWindow::toggleFullScreen()
897 {
898     qDebug() << __PRETTY_FUNCTION__;
899
900     if(windowState() == Qt::WindowNoState)
901         showFullScreen();
902     else
903         showNormal();
904 }
905
906 void MainWindow::toggleProgressIndicator(bool value)
907 {
908     qDebug() << __PRETTY_FUNCTION__;
909
910 #ifdef Q_WS_MAEMO_5
911     if(value) {
912         m_progressIndicatorCount++;
913         setAttribute(Qt::WA_Maemo5ShowProgressIndicator, true);
914     } else {
915         if(m_progressIndicatorCount > 0)
916             m_progressIndicatorCount--;
917
918         if(m_progressIndicatorCount == 0)
919             setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false);
920     }
921 #else
922     Q_UNUSED(value);
923 #endif // Q_WS_MAEMO_5
924 }
925
926 void MainWindow::updateItemVisibility(bool loggedIn)
927 {
928     qDebug() << __PRETTY_FUNCTION__;
929
930     m_tabbedPanel->setTabsEnabled(m_situareTabsIndexes, loggedIn);
931 }
932
933 void MainWindow::updateLocationDialogFinished(int reason)
934 {
935     qDebug() << __PRETTY_FUNCTION__;
936
937     Q_UNUSED(reason);
938
939     if (m_updateLocation) {
940         disconnect(this, SIGNAL(reverseGeoReady(QString)),
941                 m_updateLocation, SLOT(setAddress(QString)));
942
943         disconnect(m_updateLocation, SIGNAL(statusUpdate(QString,bool)),
944                 this, SIGNAL(statusUpdate(QString,bool)));
945
946         disconnect(m_updateLocation, SIGNAL(statusUpdate(QString,bool)),
947                 this, SLOT(backupUpdateLocationDialogData(QString,bool)));
948
949         disconnect(m_updateLocation, SIGNAL(finished(int)),
950                 this, SLOT(updateLocationDialogFinished(int)));
951
952         m_updateLocation->deleteLater();
953         m_updateLocation = 0;
954     }
955 }