Updated some changes to userinfo
[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
9    Situare is free software; you can redistribute it and/or
10    modify it under the terms of the GNU General Public License
11    version 2 as published by the Free Software Foundation.
12
13    Situare is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with Situare; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
21    USA.
22 */
23
24 #include <QtGui>
25
26 #ifdef Q_WS_MAEMO_5
27 #include <QtMaemo5/QMaemo5InformationBox>
28 #endif // Q_WS_MAEMO_5
29
30 #include "mainwindow.h"
31 #include "mapviewscreen.h"
32 #include "settingsdialog.h"
33 #include "facebookservice/facebookauthentication.h"
34 #include "situarecommon.h"
35
36 #include <QtGui/QX11Info>
37 #include <X11/Xlib.h>
38 #include <X11/Xatom.h>
39
40 MainWindow::MainWindow(QWidget *parent)
41     : QMainWindow(parent),
42     m_email(),
43     m_loginUrl(),
44     m_password(),
45     m_refresh(0),
46     m_webView(0)
47 {
48     qDebug() << __PRETTY_FUNCTION__;
49
50     m_mapViewScreen = new MapViewScreen(this);
51     setCentralWidget(m_mapViewScreen);
52     createMenus();
53     setWindowTitle(tr("Situare"));
54         show();
55
56     m_locationDialog = new UpdateLocationDialog(this);
57
58     connect(this, SIGNAL(reverseGeoReady(QString)),
59             m_mapViewScreen, SIGNAL(reverseGeoReady(QString)));
60     connect(m_mapViewScreen, SIGNAL(statusUpdate(QString,bool)),
61             this, SIGNAL(statusUpdate(QString,bool)));
62
63     connect(this, SIGNAL(userLocationReady(User*)),
64             m_mapViewScreen, SIGNAL(userLocationReady(User*)));
65     connect(this, SIGNAL(friendsLocationsReady(QList<User*>&)),
66             m_mapViewScreen, SIGNAL(friendsLocationsReady(QList<User*>&)));
67
68         connect(this, SIGNAL(autoCentering(bool)),
69             m_mapViewScreen, SLOT(enableAutoCentering(bool)));
70     connect(this, SIGNAL(positionReceived(QPointF, qreal)),
71             m_mapViewScreen, SLOT(positionReceived(QPointF, qreal)));
72     connect(m_mapViewScreen, SIGNAL(mapLocationChanged()),
73             this, SLOT(mapLocationChanged()));
74
75     connect(this, SIGNAL(zoomInKeyPressed()),
76             m_mapViewScreen, SIGNAL(zoomInKeyPressed()));
77     connect(this, SIGNAL(zoomOutKeyPressed()),
78             m_mapViewScreen, SIGNAL(zoomOutKeyPressed()));
79
80     connect(m_mapViewScreen, SIGNAL(requestReverseGeo()),
81             this, SIGNAL(requestReverseGeo()));
82
83     connect(m_mapViewScreen, SIGNAL(refreshUserData()),
84             this, SIGNAL(refreshUserData()));
85
86     this->toggleProgressIndicator(true);
87
88     grabZoomKeys(true);
89 }
90
91 MainWindow::~MainWindow()
92 {
93     qDebug() << __PRETTY_FUNCTION__;
94
95     grabZoomKeys(false);
96
97     if(m_webView)
98         delete m_webView;
99 }
100
101 void MainWindow::toggleProgressIndicator(bool value)
102 {
103     qDebug() << __PRETTY_FUNCTION__;
104 #ifdef Q_WS_MAEMO_5
105     setAttribute(Qt::WA_Maemo5ShowProgressIndicator, value);
106 #else
107     Q_UNUSED(value);
108 #endif // Q_WS_MAEMO_5
109 }
110
111 void MainWindow::createMenus()
112 {
113     qDebug() << __PRETTY_FUNCTION__;
114
115     m_toSettingsAct = new QAction(tr("Settings"), this);
116     m_toSettingsAct->setObjectName(tr("Settings"));
117     connect(m_toSettingsAct, SIGNAL(triggered()),
118         this, SLOT(openSettingsDialog()));
119     m_gpsToggleAct = new QAction(tr("GPS"), this);
120     m_gpsToggleAct->setCheckable(true);
121     m_gpsToggleAct->setChecked(true);
122     connect(m_gpsToggleAct, SIGNAL(toggled(bool)),
123         this, SLOT(gpsActionToggled(bool)));
124     m_autoCenteringAct = new QAction(tr("Auto centering"), this);
125     m_autoCenteringAct->setCheckable(true);
126     m_autoCenteringAct->setChecked(true);
127     connect(m_autoCenteringAct, SIGNAL(toggled(bool)),
128         this, SLOT(autoCenteringToggled(bool)));    
129         
130         m_viewMenu = menuBar()->addMenu(tr("Main"));
131
132     m_viewMenu->addAction(m_toSettingsAct);
133         m_viewMenu->addAction(m_gpsToggleAct);
134     m_viewMenu->addAction(m_autoCenteringAct);
135     m_viewMenu->setObjectName(tr("Menu"));
136 }
137
138 void MainWindow::openSettingsDialog()
139 {
140     qDebug() << __PRETTY_FUNCTION__;
141     SettingsDialog *dialog = new SettingsDialog(this);
142     dialog->show();
143 }
144
145 void MainWindow::gpsToggled(bool checked)
146 {
147     qDebug() << __PRETTY_FUNCTION__;
148
149     if (checked)
150         emit enableGPS(true);
151     else
152         emit enableGPS(false);
153 }
154
155 void MainWindow::setGPSButton(bool enabled)
156 {
157     qDebug() << __PRETTY_FUNCTION__;
158
159     if (enabled) {
160         showMaemoInformationBox(tr("GPS enabled"));
161         m_gpsToggleAct->setChecked(true);
162         m_autoCenteringAct->setVisible(true);
163     }
164     else {
165         showMaemoInformationBox(tr("GPS disabled"));
166         m_gpsToggleAct->setChecked(false);
167         m_autoCenteringAct->setVisible(false);
168     }
169 }
170
171 void MainWindow::setAutoCenteringButton(bool enabled)
172 {
173     if (enabled) {
174         showMaemoInformationBox(tr("Auto centering enabled"));
175         m_autoCenteringAct->setChecked(true);
176     }
177     else {
178         showMaemoInformationBox(tr("Auto centering disabled"));
179         m_autoCenteringAct->setChecked(false);
180     }
181 }
182
183 void MainWindow::gpsTimeout()
184 {
185     qDebug() << __PRETTY_FUNCTION__;
186
187     showMaemoInformationBox(tr("GPS timeout"));
188 }
189
190 void MainWindow::gpsError(const QString &message)
191 {
192     qDebug() << __PRETTY_FUNCTION__;
193
194     showMaemoInformationBox(message);
195 }
196
197 void MainWindow::mapLocationChanged()
198 {
199     qDebug() << __PRETTY_FUNCTION__;
200
201     emit enableAutoCentering(false);
202 }
203
204 void MainWindow::autoCenteringToggled(bool checked)
205 {
206     qDebug() << __PRETTY_FUNCTION__ << checked;
207
208     if (checked)
209         emit enableAutoCentering(true);
210     else
211         emit enableAutoCentering(false);
212 }
213
214 void MainWindow::autoCenteringEnabled(bool enabled)
215 {
216     qDebug() << __PRETTY_FUNCTION__ << enabled;
217
218     emit autoCentering(enabled);
219 }
220
221 void MainWindow::showMaemoInformationBox(const QString &message)
222 {
223     qDebug() << __PRETTY_FUNCTION__;
224
225 #ifdef Q_WS_MAEMO_5
226     QMaemo5InformationBox::information(this, message, QMaemo5InformationBox::DefaultTimeout);
227 #else
228     Q_UNUSED(message);
229 #endif
230 }
231
232 void MainWindow::startLoginProcess(const QUrl &url)
233 {
234     qDebug() << __PRETTY_FUNCTION__;
235
236     m_loginUrl = url;
237     m_webView = new QWebView;
238     m_loginDialog = new LoginDialog(this);
239
240     connect(m_webView, SIGNAL(urlChanged(const QUrl &)),
241             this, SIGNAL(updateCredentials(QUrl)));
242     connect(m_webView, SIGNAL(loadFinished(bool)),
243             this, SLOT(loadDone(bool)));
244
245     connect(m_loginDialog, SIGNAL(loginDialogDone(QString,QString)),
246             this, SLOT(loginDialogDone(QString,QString)));
247
248     m_webView->hide();
249
250     if(m_loginDialog->exec() != QDialog::Accepted) {
251         // if login dialog was canceled we need to stop processing webview
252         // stop and disconnect m_webView;
253         m_webView->stop();
254         disconnect(m_webView, SIGNAL(loadFinished(bool)),
255                    this, SLOT(loadDone(bool)));
256         disconnect(m_webView, SIGNAL(urlChanged(const QUrl &)),
257                    this, SLOT(updateCredentials(const QUrl &)));
258
259         emit cancelLoginProcess();
260     }
261     else {
262         m_webView->load(m_loginUrl);
263         toggleProgressIndicator(true);
264         m_refresh = true;
265     }
266 }
267
268 void MainWindow::loginDialogDone(const QString &email, const QString &password)
269 {
270     qDebug() << __PRETTY_FUNCTION__;
271
272     m_email = email;
273     m_password = password;
274 }
275
276 void MainWindow::loginFailed()
277 {
278     qDebug() << __PRETTY_FUNCTION__;
279
280     m_email.clear();
281     m_password.clear();
282
283     toggleProgressIndicator(false);
284
285 #ifdef Q_WS_MAEMO_5
286     QMaemo5InformationBox::information(this, tr("Invalid E-mail address or password"),
287                                        QMaemo5InformationBox::NoTimeout);
288
289 #endif // Q_WS_MAEMO_5
290
291     if(m_loginDialog->exec() != QDialog::Accepted) {
292         // if login dialog was canceled we need to stop processing webview
293         // stop and disconnect m_webView;
294         m_webView->stop();
295         disconnect(m_webView, SIGNAL(loadFinished(bool)),
296                    this, SLOT(loadDone(bool)));
297         disconnect(m_webView, SIGNAL(urlChanged(const QUrl &)),
298                    this, SLOT(updateCredentials(const QUrl &)));
299
300         emit cancelLoginProcess();
301     }
302     else {
303         // re-load login page for webview
304         toggleProgressIndicator(true);
305         m_webView->load(m_loginUrl);
306     }
307 }
308
309 void MainWindow::loadDone(bool done)
310 {
311     qDebug() << __PRETTY_FUNCTION__;
312
313     // for the first time the login page is opened, we need to refresh it to get cookies working
314     if(m_refresh) {
315         m_webView->reload();
316         m_refresh = false;
317     }
318
319     if (done)
320     {
321         QWebFrame* frame = m_webView->page()->currentFrame();
322         if (frame!=NULL)
323         {
324             // set email box
325             QWebElementCollection emailCollection = frame->findAllElements("input[name=email]");
326
327             foreach (QWebElement element, emailCollection) {
328                 element.setAttribute("value", m_email.toAscii());
329             }
330             // set password box
331             QWebElementCollection passwordCollection = frame->findAllElements("input[name=pass]");
332             foreach (QWebElement element, passwordCollection) {
333                 element.setAttribute("value", m_password.toAscii());
334             }
335             // find connect button
336             QWebElementCollection buttonCollection = frame->findAllElements("input[name=login]");
337             foreach (QWebElement element, buttonCollection)
338             {
339                 QPoint pos(element.geometry().center());
340
341                 // send a mouse click event to the web page
342                 QMouseEvent event0(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton,
343                                    Qt::NoModifier);
344                 QApplication::sendEvent(m_webView->page(), &event0);
345                 QMouseEvent event1(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton,
346                                    Qt::NoModifier);
347                 QApplication::sendEvent(m_webView->page(), &event1);
348             }
349         }
350     }
351 }
352
353 void MainWindow::grabZoomKeys(bool grab)
354 {
355     qDebug() << __PRETTY_FUNCTION__;
356 #ifdef Q_WS_MAEMO_5
357     // Can't grab keys unless we have a window id
358     if (!winId())
359         return;
360
361     unsigned long val = (grab) ? 1 : 0;
362     Atom atom = XInternAtom(QX11Info::display(), "_HILDON_ZOOM_KEY_ATOM", False);
363     if (!atom)
364         return;
365
366     XChangeProperty (QX11Info::display(),
367                      winId(),
368                      atom,
369                      XA_INTEGER,
370                      32,
371                      PropModeReplace,
372                      reinterpret_cast<unsigned char *>(&val),
373                      1);
374 #else
375     Q_UNUSED(grab);
376 #endif // Q_WS_MAEMO_5
377 }
378
379 void MainWindow::keyPressEvent(QKeyEvent* event)
380 {
381     qDebug() << __PRETTY_FUNCTION__;
382
383     switch (event->key()) {
384     case Qt::Key_F7:
385         event->accept();
386         emit zoomInKeyPressed();
387         break;
388
389     case Qt::Key_F8:
390         event->accept();
391         emit zoomOutKeyPressed();
392         break;
393     }
394     QWidget::keyPressEvent(event);
395 }