m_situareService, SLOT(credentialsReady(FacebookCredentials)));
connect(m_facebookAuthenticator, SIGNAL(credentialsReady(FacebookCredentials)),
this, SLOT(loginOk()));
-
- connect(m_ui, SIGNAL(requestReverseGeo()), this, SLOT(requestAddress()));
- connect(m_situareService, SIGNAL(reverseGeoReady(QString)), m_ui, SIGNAL(reverseGeoReady(QString)));
- connect(m_ui, SIGNAL(statusUpdate(QString,bool)), this, SLOT(requestUpdateLocation(QString,bool)));
+ connect(m_facebookAuthenticator, SIGNAL(quitSituare()),
+ this, SLOT(quitApplication()));
+
+ connect(m_ui, SIGNAL(requestReverseGeo()),
+ this, SLOT(requestAddress()));
+ connect(m_situareService, SIGNAL(reverseGeoReady(QString)),
+ m_ui, SIGNAL(reverseGeoReady(QString)));
+ connect(m_ui, SIGNAL(statusUpdate(QString,bool)),
+ this, SLOT(requestUpdateLocation(QString,bool)));
connect(m_situareService, SIGNAL(userDataChanged(User*,QList<User*>&)),
this, SLOT(userDataChanged(User*,QList<User*>&)));
- connect(this, SIGNAL(userLocationReady(User*)), m_ui, SIGNAL(userLocationReady(User*)));
- connect(this, SIGNAL(friendsLocationsReady(QList<User*>&)), m_ui, SIGNAL(friendsLocationsReady(QList<User*>&)));
- connect(m_situareService, SIGNAL(error(QString)), this, SLOT(error(QString)));
- connect(m_situareService, SIGNAL(updateWasSuccessful()), this, SLOT(updateWasSuccessful()));
-
- connect(m_ui, SIGNAL(refreshUserData()), this, SLOT(refreshUserData()));
+ connect(this, SIGNAL(userLocationReady(User*)),
+ m_ui, SIGNAL(userLocationReady(User*)));
+ connect(this, SIGNAL(friendsLocationsReady(QList<User*>&)),
+ m_ui, SIGNAL(friendsLocationsReady(QList<User*>&)));
+ connect(m_situareService, SIGNAL(error(QString)),
+ this, SLOT(error(QString)));
+ connect(m_situareService, SIGNAL(updateWasSuccessful()),
+ this, SLOT(updateWasSuccessful()));
+
+ connect(m_ui, SIGNAL(refreshUserData()),
+ this, SLOT(refreshUserData()));
m_facebookAuthenticator->start();
}
{
qDebug() << __PRETTY_FUNCTION__;
delete m_ui;
- delete m_facebookAuthenticator;
+}
+
+void SituareEngine::quitApplication()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ m_facebookAuthenticator->setAttribute(Qt::WA_DeleteOnClose);
+ m_facebookAuthenticator->close();
}
void SituareEngine::error(const QString &error)
void SituareEngine::loginOk()
{
qDebug() << __PRETTY_FUNCTION__;
- m_facebookAuthenticator->hide();
+
+ m_facebookAuthenticator->setAttribute(Qt::WA_DeleteOnClose);
+ m_facebookAuthenticator->close();
m_ui->show();
m_situareService->fetchLocations(); // request user locations
}
*/
void userDataChanged(User *user, QList<User *> &friendsList);
+ /**
+ * @brief Slot to intercept signal when user has cancelled login process
+ *
+ */
+ void quitApplication();
+
/*******************************************************************************
* SIGNALS
******************************************************************************/
Ville Tiensuu - ville.tiensuu@ixonos.com
Kaj Wallin - kaj.wallin@ixonos.com
+ Henri Lampela - henri.lampela@ixonos.com
Situare is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
#include <QtGui>
#include <QtDebug>
#include <QDateTime>
+
+#ifdef Q_WS_MAEMO_5
+#include <QMaemo5InformationBox>
+#endif // Q_WS_MAEMO_5
+
#include "facebookauthentication.h"
#include "facebookcommon.h"
{
qDebug() << __PRETTY_FUNCTION__;
+ m_refresh = false;
+ m_email.clear();
+ m_password.clear();
+ m_loginAttempts = 0;
+
+ m_loginDialog = new LoginDialog(this);
+
m_webView = new QWebView;
m_mainlayout = new QHBoxLayout;
connect(m_webView, SIGNAL(urlChanged(const QUrl &)),
this, SLOT(updateCredentials(const QUrl &)));
+ connect(m_webView, SIGNAL(loadFinished(bool)),
+ this, SLOT(loadDone(bool)));
+
+ connect(m_loginDialog, SIGNAL(loginDialogDone(QString,QString)),
+ this, SLOT(loginDialogDone(QString,QString)));
+
+ connect(this, SIGNAL(loginFailure()),
+ this, SLOT(loginFailed()));
readCredentials(m_loginCredentials);
}
FacebookAuthentication::~FacebookAuthentication()
{
qDebug() << __PRETTY_FUNCTION__;
- delete m_webView;
- delete m_mainlayout;
+
+ if(m_webView) {
+ delete m_webView;
+ m_webView = 0;
+ }
+ if(m_mainlayout) {
+ delete m_mainlayout;
+ m_mainlayout = 0;
+ }
+ if(m_loginDialog) {
+ delete m_loginDialog;
+ m_loginDialog = 0;
+ }
+}
+
+void FacebookAuthentication::loginDialogDone(const QString &email, const QString &password)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ m_email.append(email);
+ m_password.append(password);
}
void FacebookAuthentication::start()
{
qDebug() << __PRETTY_FUNCTION__;
if (!verifyCredentials(m_loginCredentials)){
+ if(m_loginDialog->exec() != QDialog::Accepted) {
+ // if login dialog was canceled we need to stop processing webview
+ // stop and disconnect m_webView;
+ m_webView->stop();
+ disconnect(m_webView, SIGNAL(loadFinished(bool)),
+ this, SLOT(loadDone(bool)));
+ disconnect(m_webView, SIGNAL(urlChanged(const QUrl &)),
+ this, SLOT(updateCredentials(const QUrl &)));
+
+ emit quitSituare();
+ }
m_webView->setZoomFactor(FACEBOOK_LOGINPAGE_FONT_SIZE);
m_webView->load(m_facebookLoginPage);
+ this->toggleProgressIndicator(true);
+ m_refresh = true;
setCentralWidget(m_webView);
+ m_webView->hide();
this->show();
}
else
emit credentialsReady(m_loginCredentials);
}
+void FacebookAuthentication::loadDone(bool done)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ // for the first time the login page is opened, we need to refresh it to get cookies working
+ if(m_refresh) {
+ m_webView->load(m_facebookLoginPage);
+ m_refresh = false;
+ }
+
+ if (done)
+ {
+ this->toggleProgressIndicator(false);
+ QWebFrame* frame = m_webView->page()->currentFrame();
+ if (frame!=NULL)
+ {
+ // set email box
+ QWebElementCollection emailCollection = frame->findAllElements("input[name=email]");
+
+ foreach (QWebElement element, emailCollection) {
+ element.setAttribute("value", m_email.toAscii());
+ }
+ // set password box
+ QWebElementCollection passwordCollection = frame->findAllElements("input[name=pass]");
+ foreach (QWebElement element, passwordCollection) {
+ element.setAttribute("value", m_password.toAscii());
+ }
+ // find connect button
+ QWebElementCollection buttonCollection = frame->findAllElements("input[name=login]");
+ foreach (QWebElement element, buttonCollection)
+ {
+ QPoint pos(element.geometry().center());
+
+ // send a mouse click event to the web page
+ QMouseEvent event0(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ QApplication::sendEvent(m_webView->page(), &event0);
+ QMouseEvent event1(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ QApplication::sendEvent(m_webView->page(), &event1);
+ }
+ }
+ }
+}
+
+void FacebookAuthentication::loginFailed()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ m_email.clear();
+ m_password.clear();
+
+#ifdef Q_WS_MAEMO_5
+ QMaemo5InformationBox::information(this, tr("Invalid E-mail address or password"),
+ QMaemo5InformationBox::NoTimeout);
+
+#endif // Q_WS_MAEMO_5
+
+ if(m_loginDialog->exec() != QDialog::Accepted) {
+ // if login dialog was canceled we need to stop processing webview
+ // stop and disconnect m_webView;
+ m_webView->stop();
+ disconnect(m_webView, SIGNAL(loadFinished(bool)),
+ this, SLOT(loadDone(bool)));
+ disconnect(m_webView, SIGNAL(urlChanged(const QUrl &)),
+ this, SLOT(updateCredentials(const QUrl &)));
+
+ emit quitSituare();
+ }
+ else {
+ // re-load login page for webview
+ this->toggleProgressIndicator(true);
+ m_webView->setZoomFactor(FACEBOOK_LOGINPAGE_FONT_SIZE);
+ m_webView->load(m_facebookLoginPage);
+ }
+}
bool FacebookAuthentication::updateCredentials(const QUrl &url)
{
if ( callbackUrl.indexOf(LOGIN_SUCCESS_REPLY) == 0 ){
qDebug() << "login success" << endl;
+ disconnect(m_webView, SIGNAL(loadFinished(bool)),
+ this, SLOT(loadDone(bool)));
+ disconnect(m_webView, SIGNAL(urlChanged(const QUrl &)),
+ this, SLOT(updateCredentials(const QUrl &)));
+
// let's find out session key
int indexOfCredential = callbackUrl.indexOf(SESSION_KEY);
else if ( callbackUrl.indexOf(LOGIN_FAILURE_REPLY) == 0){
qWarning() << "login failure" << endl;
- emit loginFailure();
+ qDebug() << callbackUrl;
+ ++m_loginAttempts;
+ /* emit loginFailure for every second login attemps, since webview loads login
+ error page (loadingDone() signal is emitted) and we need to avoid that because
+ at this point we don't have new login parameters */
+ if(m_loginAttempts % 2) {
+ emit loginFailure();
+ }
}
else if ( callbackUrl.indexOf(LOGIN_PAGE) == 0){
else {
qDebug() << "totally wrong webPage";
+ // we should not get a wrong page at this point
emit loginFailure();
- start();
}
}
else {
qDebug() << " Loading of page failed invalid URL" << endl;
+ // we should not get a wrong page at this point
emit loginFailure();
return FALSE;
}
-
return (foundSessionKey && foundUserID && foundExpires && foundSessionSecret && foundSig);
}
return loginPage;
}
+
+ void FacebookAuthentication::toggleProgressIndicator(bool value)
+ {
+ qDebug() << __PRETTY_FUNCTION__;
+ #ifdef Q_WS_MAEMO_5
+ setAttribute(Qt::WA_Maemo5ShowProgressIndicator, value);
+ #else
+ Q_UNUSED(value);
+ #endif // Q_WS_MAEMO_5
+ }
Ville Tiensuu - ville.tiensuu@ixonos.com
Kaj Wallin - kaj.wallin@ixonos.com
+ Henri Lampela - henri.lampela@ixonos.com
Situare is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
#include <QtWebKit>
#include <QString>
#include <QLayout>
+
#include "facebookcredentials.h"
+#include "ui/logindialog.h"
/**
* @brief FacebookAuthentication class takes care of transmitting username and password to facebook.
FacebookCredentials loginCredentials() const;
public slots:
+
/**
* @brief Shows the m_webView and loads page that is specified in the m_facebookLoginPage
* variable. Specifies font size for the page.
*/
void start();
+ /**
+ * @brief Slot to intercept signal when user has pressed connect button from loginDialog
+ *
+ * @param email E-mail
+ * @param password Password
+ */
+ void loginDialogDone(const QString &email, const QString &password);
+
+ /**
+ * @brief Toggle progress indicator.
+ *
+ * @param state true if progress indicator should be shown, false otherwise
+ */
+ void toggleProgressIndicator(bool state);
+
private:
/**
*/
bool updateCredentials(const QUrl & url);
+ /**
+ * @brief Slot to intercept signal when webview has finished loading webpage
+ *
+ * @param done Status of the loading
+ */
+ void loadDone(bool done);
+
+ /**
+ * @brief Slot to intercept signal when login has failed (loginFailure signal)
+ *
+ */
+ void loginFailed();
+
signals:
/**
*/
void loginFailure();
-private:
-
/**
- * @brief String that contantains URL of facebook loginpage.
+ * @brief Signal that indicates when user has cancelled login process
*
- * @var m_facebookLoginPage
*/
- QString m_facebookLoginPage;
+ void quitSituare();
+
+private:
/**
* @brief Dataclass that contains authorization to use facebook. Dataclass is composed of five
*/
FacebookCredentials m_loginCredentials;
- /**
- * @brief Lays out m_webView in window.
- *
- * @var m_mainlayout
- */
- QHBoxLayout *m_mainlayout;
-
- /**
- * @brief Shows facebook login page.
- *
- * @var m_webView
- */
- QWebView *m_webView;
+ QString m_email; ///< Placeholder for email
+ QString m_facebookLoginPage; ///< String that contantains URL of facebook loginpage.
+ int m_loginAttempts; ///< Indicates login attempts
+ LoginDialog *m_loginDialog; ///< Login dialog
+ QHBoxLayout *m_mainlayout; ///< Lays out m_webView in window.
+ QString m_password; ///< Placeholder for password
+ bool m_refresh; ///< Indicates when webpage is refreshed
+ QWebView *m_webView; ///< Shows facebook login page.
};
#endif // FACEBOOKAUTHENTICATION_H
const QString DIRECTORY_NAME = "Ixonos";
const QString FILE_NAME = "Situare";
-
-
-
-
-
-
#endif // FACEBOOKCOMMON_H
parseUserData(replyArray);
}
else if(replyArray == "") {
- qDebug() << "No error, update was successful";
- emit updateWasSuccessful();
+ if(url.toString().contains(UPDATE_LOCATION.toAscii())) {
+ emit updateWasSuccessful();
+ }
+ else {
+ // server error!
+ }
}
else {
// Street address ready
ui/situareuser.cpp \
engine/engine.cpp \
ui/settingsdialog.cpp \
+ ui/logindialog.cpp \
map/maptilerequest.cpp \
ui/imagebutton.cpp
HEADERS += ui/mainwindow.h \
ui/situareuser.h \
engine/engine.h \
ui/settingsdialog.h \
+ ui/logindialog.h \
map/maptilerequest.h \
ui/imagebutton.h
QT += network \
webkit
-#DEFINES += QT_NO_DEBUG_OUTPUT
+#DEFINES += QT_NO_DEBUG_OUTPUT
!maemo5 {
message(QJson built in)
message(Make sure you have QJson development headers installed)
message(install headers with: sudo apt-get install libqjson-dev)
}
maemo5 {
+ QT += maemo5
message(QJson built in)
message(Make sure you have QJson development headers installed)
message(add: deb http://repository.maemo.org/extras-devel fremantle free non-free)
--- /dev/null
+/*
+ Situare - A location system for Facebook
+ Copyright (C) 2010 Ixonos Plc. Authors:
+
+ Henri Lampela - henri.lampela@ixonos.com
+
+ Situare is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ Situare is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Situare; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.
+*/
+
+#include <QtGui>
+#include <QDebug>
+#include <QFormLayout>
+#include "logindialog.h"
+
+LoginDialog::LoginDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ setWindowTitle(tr("Login to Situare with Facebook account"));
+
+ m_emailEdit = new QLineEdit();
+ m_passwordEdit = new QLineEdit();
+ m_passwordEdit->setEchoMode(QLineEdit::Password);
+
+ QGridLayout *gridLayout = new QGridLayout(this);
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(Qt::Vertical);
+ QPushButton *connectButton = buttonBox->addButton(QDialogButtonBox::Ok);
+ QPushButton *cancelButton = buttonBox->addButton(QDialogButtonBox::Cancel);
+ connectButton->setText(tr("Connect"));
+
+ QFormLayout *form = new QFormLayout();
+ form->addRow(new QLabel(tr("E-mail:")), m_emailEdit);
+ form->addRow(new QLabel(tr("Password:")), m_passwordEdit);
+
+ gridLayout->addLayout(form, 0, 0, 2, 1);
+ gridLayout->addWidget(buttonBox, 0, 1, 1, 1);
+
+ connect(connectButton, SIGNAL(clicked()),
+ this, SLOT(connectPressed()));
+ connect(cancelButton, SIGNAL(clicked()),
+ this, SLOT(reject()));
+
+ setLayout(gridLayout);
+}
+
+void LoginDialog::connectPressed()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ emit loginDialogDone(m_emailEdit->text(), m_passwordEdit->text());
+
+ accept();
+}
--- /dev/null
+/*
+ Situare - A location system for Facebook
+ Copyright (C) 2010 Ixonos Plc. Authors:
+
+ Henri Lampela - henri.lampela@ixonos.com
+
+ Situare is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ Situare is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Situare; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.
+*/
+
+#ifndef LOGINDIALOG_H
+#define LOGINDIALOG_H
+
+#include <QDialog>
+
+class QDialogButtonBox;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+
+/**
+* @brief Custom login dialog. Email and password inserted into dialog will be forwarded to webview
+* Email and password will not be saved.
+*
+* @author Henri Lampela
+*/
+class LoginDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+
+ /**
+ * @brief Default constructor
+ *
+ * @param parent Instance of parent widget
+ */
+ LoginDialog(QWidget *parent = 0);
+
+/*******************************************************************************
+ * MEMBER FUNCTIONS AND SLOTS
+ ******************************************************************************/
+
+private slots:
+
+ /**
+ * @brief Private slot for connect button
+ *
+ */
+ void connectPressed();
+
+signals:
+
+ /**
+ * @brief Signal for sending email and password to facebookauthentication class
+ *
+ * @param email E-mail
+ * @param password Password
+ */
+ void loginDialogDone(const QString &email, const QString &password);
+
+/*******************************************************************************
+ * DATA MEMBERS
+ ******************************************************************************/
+
+private:
+
+ QLineEdit *m_emailEdit; ///< Pointer to email line edit
+ QLineEdit *m_passwordEdit; ///< Pointer to password line edit
+
+};
+
+
+
+#endif // LOGINDIALOG_H