<file>res/images/walk_icon_gray.png</file>
<file>res/images/zoom_in.png</file>
<file>res/images/zoom_out.png</file>
+ <file>res/images/meet_people.png</file>
+ <file>res/images/chat.png</file>
- <file>res/images/search_history.png</file>
+ <file>res/images/tag_btn.png</file>
+ <file>res/images/tag_btn_d.png</file>
+ <file>res/images/tag_btn_s.png</file>
+ <file>res/images/tag.png</file>
+ <file>res/images/chat_btn.png</file>
+ <file>res/images/chat_btn_d.png</file>
+ <file>res/images/chat_btn_s.png</file>
+ <file>res/images/empty_avatar.png</file>
+ <file>res/images/empty_avatar_big.png</file>
- <file>res/images/calendar.png</file>
+ <file>res/images/message.png</file>
+ <file>res/images/message_unread.png</file>
+ <file>res/images/message_remove_btn.png</file>
+ <file>res/images/message_remove_btn_d.png</file>
+ <file>res/images/message_remove_btn_s.png</file>
+ <file>res/images/friend_list_btn.png</file>
+ <file>res/images/friend_list_btn_d.png</file>
+ <file>res/images/friend_list_btn_s.png</file>
</qresource>
</RCC>
m_gps = new GPSPosition(this);
// build SituareService
- m_situareService = new SituareService(this);
+ m_situareService = new SituareService(m_networkAccessManager,
+ new ImageFetcher(m_networkAccessManager, this), this);
// build FacebookAuthenticator
- m_facebookAuthenticator = new FacebookAuthentication(this);
+ m_facebookAuthenticator = new FacebookAuthentication(m_ui, this);
// build routing service
m_routingService = new RoutingService(this); // create this when needed, not in constructor!
}
}
- void SituareEngine::fetchUsernameFromSettings()
- {
- qDebug() << __PRETTY_FUNCTION__;
-
- m_ui->setUsername(m_facebookAuthenticator->loadUsername());
- }
-
-void SituareEngine::imageReady(User *user)
+void SituareEngine::imageReady(const QString &id, const QPixmap &image)
{
qDebug() << __PRETTY_FUNCTION__;
- if(m_facebookAuthenticator->loginCredentials().userID() == id)
- if(user->type())
- emit userLocationReady(user);
++ if (id.isNull())
+ emit userImageReady(id, image);
else
- emit friendImageReady(user);
+ emit friendImageReady(id, image);
}
void SituareEngine::initializeGpsAndAutocentering()
}
}
+void SituareEngine::requestInterestingPeople()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ QRectF currentSceneRect = m_mapEngine->currentViewSceneRect();
+ SceneCoordinate bottomLeftSceneCoordinate(currentSceneRect.left(), currentSceneRect.bottom());
+ SceneCoordinate topRightSceneCoordinate(currentSceneRect.right(), currentSceneRect.top());
+
+ m_situareService->fetchPeopleWithSimilarInterest(GeoCoordinate(bottomLeftSceneCoordinate),
+ GeoCoordinate(topRightSceneCoordinate));
+}
+
+void SituareEngine::requestSendMessage(const QString &receiverId, const QString &message,
+ bool addCoordinates)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ if (addCoordinates)
+ m_situareService->sendMessage(receiverId, message, m_mapEngine->centerGeoCoordinate());
+ else
+ m_situareService->sendMessage(receiverId, message);
+}
+
-
void SituareEngine::routeParsed(Route &route)
{
qDebug() << __PRETTY_FUNCTION__;
connect(m_ui, SIGNAL(requestReverseGeo()),
this, SLOT(requestAddress()));
- connect(m_ui, SIGNAL(statusUpdate(QString,bool)),
+ connect(m_ui, SIGNAL(locationUpdate(QString,bool)),
+ this, SLOT(setProgressIndicatorEnabled()));
+
- connect(m_ui, SIGNAL(statusUpdate(QString,bool)),
++ connect(m_ui, SIGNAL(locationUpdate(QString,bool)),
this, SLOT(requestUpdateLocation(QString,bool)));
connect(m_ui, SIGNAL(enableAutomaticLocationUpdate(bool, int)),
#include <QObject>
#include <QTime>
+#include <QPair>
#include "coordinates/geocoordinate.h"
- #include "situareservice/situareservice.h"
++#include "../situareservice/situareservice.h"
class QTimer;
}
}
- bool FacebookAuthentication::updateCredentials(const QUrl &url)
+ QString FacebookAuthentication::parseSession(const QUrl &url)
+ {
+ qDebug() << __PRETTY_FUNCTION__;
+
+ const QString END("}");
+
+ QString urlString = url.toString();
+
+ int begin = urlString.indexOf(URL_SESSION_PARAMETER_BEGIN);
+ int end = urlString.indexOf(END, begin);
+
+ if ((begin > -1) && (end > -1))
+ return urlString.mid(begin, end - begin + 1);
+ else
+ return QString();
+ }
+
+ void FacebookAuthentication::sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
+ {
+ qDebug() << __PRETTY_FUNCTION__;
+
+ Q_UNUSED(errors);
+ reply->ignoreSslErrors();
+ }
+
+ void FacebookAuthentication::urlChanged(const QUrl &url)
{
- qDebug() << __PRETTY_FUNCTION__ << url.toString();
+ qDebug() << __PRETTY_FUNCTION__;
- bool found = false;
-
- if (url.isValid()) {
- qDebug() << "url is valid";
-
- QString callbackUrl = url.toString();
- qDebug() << "callbackUrl: " << callbackUrl.toAscii();
-
- if (callbackUrl.indexOf(LOGIN_SUCCESS_REPLY) == 0) {
- qDebug() << "login success";
-
- // let's find out session credentials
- if(callbackUrl.contains(SESSION_KEY)) {
-
- QJson::Parser parser;
- bool ok;
-
- // split string into string part and json part
- QStringList list = url.toString().split("=");
-
- for(int i=0;i<list.count();i++) {
- // if string starts with json item
- if(list.at(i).startsWith("{")) {
- QByteArray jsonString = list.at(i).toAscii();
- QVariantMap result = parser.parse (jsonString, &ok).toMap();
-
- if (!ok) {
- emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
- found = false;
- } else {
- qDebug() << "Session Key" << result[SESSION_KEY].toString();
- m_loginCredentials.setSessionKey(result[SESSION_KEY].toString());
-
- // // commeted out until qjson parser can handle 64-bit integers
- // qDebug() << "userID" << result[USER_ID].toString();
- // m_loginCredentials.setUserID(result[USER_ID].toString().toAscii());
-
- // dirty fix, get user id from session_key
- QStringList list = result[SESSION_KEY].toString().split("-");
- m_loginCredentials.setUserID(list.at(1));
- qDebug() << m_loginCredentials.userID();
-
- qDebug() << "Expires" << result[EXPIRES].toString();
- m_loginCredentials.setExpires(result[EXPIRES].toString());
-
- qDebug() << "Session Secret" << result[SESSION_SECRET].toString();
- m_loginCredentials.setSessionSecret(result[SESSION_SECRET].toString());
-
- qDebug() << "Signature" << result[SIGNATURE].toString();
- m_loginCredentials.setSig(result[SIGNATURE].toString());
-
- found = true;
- m_freshLogin = false;
- emit saveCookiesRequest();
- emit credentialsReady(m_loginCredentials);
- }
- }
- }
- }
- } else if ( callbackUrl.indexOf(LOGIN_FAILURE_REPLY) == 0) {
- qDebug() << "login failure";
- qDebug() << callbackUrl;
- clearAccountInformation(true);
- if(m_freshLogin) {
- emit error(ErrorContext::SITUARE, SituareError::LOGIN_FAILED);
- } else {
- m_freshLogin = true;
- emit error(ErrorContext::SITUARE, SituareError::SESSION_EXPIRED);
- }
- } else if(callbackUrl.indexOf(LOGIN_PAGE) == 0) {
- qDebug() << "correct loginPage";
- } else {
- qDebug() << "totally wrong webPage";
- // we should not get a wrong page at this point
- emit error(ErrorContext::SITUARE, SituareError::LOGIN_FAILED);
+ const QString WALL_POST_PERMISSION = "publish_stream";
+
+ /*
+ URL changes in different use cases:
+ * Login with cookie failed:
+ 1) http://m.facebook.com/login.php?api_key=cf77865a5070f2c2ba3b52cbf3371579&cancel_url=http://www.facebook.com/connect/login_failure.html&display=touch&fbconnect=1&next=http://www.facebook.com/connect/uiserver.php?app_id=286811277465&next=http%3A%2F%2Fwww.facebook.com%2Fconnect%2Flogin_success.html&display=touch&cancel_url=http%3A%2F%2Fwww.facebook.com%2Fconnect%2Flogin_failure.html&perms=publish_stream&return_session=1&session_version=3&fbconnect=1&canvas=0&legacy_return=1&method=permissions.request&return_session=1&session_version=3&v=1.0&req_perms=publish_stream&app_id=286811277465&refsrc=http://www.facebook.com/login.php&fbb=ra985c5e9
+
+ * Login without cookie, not allowed to publish:
+ 1) http://m.facebook.com/login.php?api_key=cf77865a5070f2c2ba3b52cbf3371579&display=touch&fbconnect=1&next=http://www.facebook.com/connect/uiserver.php?app_id=286811277465&next=http%3A%2F%2Fwww.facebook.com%2Fconnect%2Flogin_success.html&display=touch&perms=publish_stream&return_session=1&session_version=3&fbconnect=1&canvas=0&legacy_return=1&method=permissions.request&return_session=1&session_version=3&v=1.0&req_perms=publish_stream&app_id=286811277465&refsrc=http://www.facebook.com/login.php&fbb=r03cdf104"
+ --> browser dialog is invoked, user enters correct username and password
+ 2) http://www.facebook.com/connect/uiserver.php?app_id=286811277465&next=http://www.facebook.com/connect/login_success.html&display=touch&perms=publish_stream&return_session=1&session_version=3&fbconnect=1&canvas=0&legacy_return=1&method=permissions.request&session={"session_key":"2.isKv9bMtGmylvP1N6Il3IQ__.3600.1289394000-100001006647973","uid":100001006647973,"expires":1289394000,"secret":"PWiqZ9_aJjfKKJT4hJMTqA__","sig":"8f054aeca3c4d81e7efce3b90fb17d7e"}&installed=1&refsrc=http://www.facebook.com/login.php&fbb=rff1cc1be&refid=9&m_sess=sozzGNi5-SOBSb3AU
+ --> click allow
+ 3) http://www.facebook.com/connect/uiserver.php
+ 4) http://www.facebook.com/connect/login_success.html?perms=publish_stream&selected_profiles=100001006647973&session={"session_key":"2.isKv9bMtGmylvP1N6Il3IQ__.3600.1289394000-100001006647973","uid":"100001006647973","expires":1289394000,"secret":"PWiqZ9_aJjfKKJT4hJMTqA__","access_token":"286811277465|2.isKv9bMtGmylvP1N6Il3IQ__.3600.1289394000-100001006647973|bo9YniMczKY7PwlUEy9f40w3v5I","sig":"6b80d6928cf8f61b4c0c59d33d3127b6"}
+
+ * Login without cookie, not allowed to publish:
+ 1) http://m.facebook.com/login.php?api_key=cf77865a5070f2c2ba3b52cbf3371579&display=touch&fbconnect=1&next=http://www.facebook.com/connect/uiserver.php?app_id=286811277465&next=http%3A%2F%2Fwww.facebook.com%2Fconnect%2Flogin_success.html&display=touch&perms=publish_stream&return_session=1&session_version=3&fbconnect=1&canvas=0&legacy_return=1&method=permissions.request&return_session=1&session_version=3&v=1.0&req_perms=publish_stream&app_id=286811277465&refsrc=http://www.facebook.com/login.php&fbb=r3fa0d31d
+ --> browser dialog is invoked, user enters correct username and password
+ 2) http://www.facebook.com/connect/uiserver.php?app_id=286811277465&next=http://www.facebook.com/connect/login_success.html&display=touch&perms=publish_stream&return_session=1&session_version=3&fbconnect=1&canvas=0&legacy_return=1&method=permissions.request&session={"session_key":"2.isKv9bMtGmylvP1N6Il3IQ__.3600.1289394000-100001006647973","uid":100001006647973,"expires":1289394000,"secret":"PWiqZ9_aJjfKKJT4hJMTqA__","sig":"8f054aeca3c4d81e7efce3b90fb17d7e"}&installed=1&refsrc=http://www.facebook.com/login.php&fbb=r29076109&refid=9&m_sess=sozzGNi5-SOBSb3AU
+ --> click deny
+ 3) http://www.facebook.com/connect/uiserver.php
+ 4) http://www.facebook.com/connect/login_success.html?perms&selected_profiles=100001006647973&session={"session_key":"2.isKv9bMtGmylvP1N6Il3IQ__.3600.1289394000-100001006647973","uid":"100001006647973","expires":1289394000,"secret":"PWiqZ9_aJjfKKJT4hJMTqA__","access_token":"286811277465|2.isKv9bMtGmylvP1N6Il3IQ__.3600.1289394000-100001006647973|bo9YniMczKY7PwlUEy9f40w3v5I","sig":"6b80d6928cf8f61b4c0c59d33d3127b6"}
+
+ * Login with cookie succeeded, already allowed to publish:
+ 1) http://www.facebook.com/connect/uiserver.php?app_id=286811277465&next=http://www.facebook.com/connect/login_success.html&display=touch&cancel_url=http://www.facebook.com/connect/login_failure.html&perms=publish_stream&return_session=1&session_version=3&fbconnect=1&canvas=0&legacy_return=1&method=permissions.request&session={"session_key":"2.iHXi5fLKlHktva2R71xSAw__.3600.1289228400-100001006647973","uid":100001006647973,"expires":1289228400,"secret":"q4_Hn5qRdxnVT_qh3ztv5w__","sig":"c9d29ca857bacec48b952e7d2826a3ca"}&fbb=rb28f24e5
+ 2) http://www.facebook.com/connect/login_success.html?perms=publish_stream&selected_profiles=100001006647973&session={"session_key":"2.iHXi5fLKlHktva2R71xSAw__.3600.1289228400-100001006647973","uid":"100001006647973","expires":1289228400,"secret":"q4_Hn5qRdxnVT_qh3ztv5w__","access_token":"286811277465|2.iHXi5fLKlHktva2R71xSAw__.3600.1289228400-100001006647973|LVTHGW82A98SGvv6Fl43DlCrFT0","sig":"8edd8d611047bcd162abbe9983b25a56"}
+ */
+
+ const QString urlString = url.toString();
+ if (!urlString.contains(URL_SESSION_PARAMETER_BEGIN)) {
+ // login page url doesn't contain session
+ /// @todo INVOKE DIALOG ALSO WHEN STOPPED TO PERMISSION PAGE
+ /// @todo case: set cookie, remove situare app, re-login, 1 extra allow page before permissions, redirect from extra page when denying?
+ m_mainWindow->buildLoginDialog(m_browser);
+ } else if (urlString.startsWith(FB_LOGIN_SUCCESS_URL)) {
+ // login succeeded, permissions granted/declined
+ const QString session = parseSession(url);
+ qDebug() << __PRETTY_FUNCTION__ << "login finished, parsed session:" << session;
+ if (!session.isEmpty()) {
+ destroyLogin();
+ m_loggedIn = true;
+ emit loggedIn(session, urlString.contains(WALL_POST_PERMISSION));
}
- } else {
- qDebug() << " Loading of page failed invalid URL" << endl;
- // we should not get a wrong page at this point
- emit error(ErrorContext::SITUARE, SituareError::LOGIN_FAILED);
}
- return found;
+ else {
+ qCritical() << __PRETTY_FUNCTION__ << "new url was not recognised, url:" << urlString;
+ }
}
USA.
*/
- #include "parser.h"
+ #include <qjson/parser.h>
- #include <QtAlgorithms>
#include <QDebug>
-#include <QNetworkReply>
+#include <QtNetwork/QNetworkReply>
#include <QPixmap>
#include <QStringList>
+ #include <QtAlgorithms>
#include <QtGlobal>
+#include "database.h"
- #include "error.h"
+ #include "../error.h"
#include "network/networkaccessmanager.h"
#include "situarecommon.h"
#include "ui/avatarimage.h"
m_friendsList.clear();
}
- void SituareService::fetchMessages()
-void SituareService::addProfileImages(const QList<QUrl> &imageUrlList)
++void SituareService::addProfileImages(const QHash<QString, QUrl> &imageUrlList)
{
qDebug() << __PRETTY_FUNCTION__;
- //Request sent to server does not need the UID
- QByteArray arr = m_database->getNotifications(613374451);
- foreach(QUrl url, imageUrlList) {
- emit fetchImage(url);
++ QHashIterator<QString, QUrl> imageUrlListIterator(imageUrlList);
+
- parseMessagesData(arr);
++ while (imageUrlListIterator.hasNext()) {
++ imageUrlListIterator.next();
++ emit fetchImage(imageUrlListIterator.key(), imageUrlListIterator.value());
+ }
}
- void SituareService::fetchPeopleWithSimilarInterest(const GeoCoordinate &southWestCoordinates,
- const GeoCoordinate &northEastCoordinates)
++void SituareService::addTags(const QStringList &tags)
+{
- qDebug() << __PRETTY_FUNCTION__;
++ qWarning() << __PRETTY_FUNCTION__ << tags.count();
+
- //Request sent to server does not need the UID
- QByteArray arr = m_database->getInterestingPeople(613374451,
- southWestCoordinates,
- northEastCoordinates);
++ foreach (QString tag, tags)
++ m_database->addTag(613374451, tag);
+
- parseInterestingPeopleData(arr);
++ emit updateWasSuccessful(SituareService::SuccessfulAddTags);
+}
+
- void SituareService::fetchPopularTags()
+ void SituareService::appendAccessToken(QString &requestUrl)
{
qDebug() << __PRETTY_FUNCTION__;
{
qDebug() << __PRETTY_FUNCTION__;
- QString cookie;
- QString apiKey;
- QString user;
- QString expires;
- QString sessionKey;
- QString sessionSecret;
- QString locale;
- QString variable;
- QString signature = EQUAL_MARK;
- QStringList variableList;
-
- signature.append(signatureValue);
- apiKey.append(apiKeyValue);
- apiKey.append(UNDERLINE_MARK);
-
- user.append(USER);
- user.append(EQUAL_MARK);
- expires.append(EXPIRES);
- expires.append(EQUAL_MARK);
- sessionKey.append(SESSION_KEY);
- sessionKey.append(EQUAL_MARK);
- sessionSecret.append(SESSION_SECRET);
- sessionSecret.append(EQUAL_MARK);
- locale.append(LOCALE);
- locale.append(EQUAL_MARK);
- locale.append(localeValue);
-
- variableList.append(expires.append(expiresValue.append(BREAK_MARK)));
- variableList.append(sessionKey.append(sessionKeyValue.append(BREAK_MARK)));
- variableList.append(user.append(userValue).append(BREAK_MARK));
- variableList.append(sessionSecret.append(sessionSecretValue.append(BREAK_MARK)));
-
- cookie.append(BREAK_MARK);
-
- foreach(variable, variableList) {
- cookie.append(apiKey);
- cookie.append(variable);
- }
- apiKey.remove(UNDERLINE_MARK);
- cookie.append(apiKey);
- cookie.append(signature);
- cookie.append(BREAK_MARK);
- cookie.append(locale);
-
- qDebug() << cookie;
+ // one scene pixel is about 5.4e-6 degrees, the integer part is max three digits and one
+ // additional digit is added for maximum precision
+ const int PRECISION = 10;
- return cookie;
+ return QString::number(degrees, 'f', PRECISION);
}
- QUrl SituareService::formUrl(const QString &baseUrl, const QString &phpScript,
- QString urlParameters)
++void SituareService::fetchMessages()
+{
+ qDebug() << __PRETTY_FUNCTION__;
- QString urlString;
-
- urlString.append(baseUrl);
- urlString.append(phpScript);
- if(!urlParameters.isEmpty())
- urlString.append(urlParameters);
+
- QUrl url = QUrl(urlString);
-
- qDebug() << url;
++ //Request sent to server does not need the UID
++ QByteArray arr = m_database->getNotifications(613374451);
+
- return url;
++ parseMessagesData(arr);
+}
+
- QString SituareService::formUrlParameters(const GeoCoordinate &coordinates, QString status,
- bool publish)
++void SituareService::fetchPeopleWithSimilarInterest(const GeoCoordinate &southWestCoordinates,
++ const GeoCoordinate &northEastCoordinates)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
- // one scene pixel is about 5.4e-6 degrees, the integer part is max three digits and one
- // additional digit is added for maximum precision
- const int COORDINATE_PRECISION = 10;
-
- QString parameters;
-
- parameters.append(QUESTION_MARK);
- parameters.append(LATITUDE);
- parameters.append(EQUAL_MARK);
- parameters.append(QString::number(coordinates.latitude(), 'f', COORDINATE_PRECISION));
- parameters.append(AMBERSAND_MARK);
- parameters.append(LONGTITUDE);
- parameters.append(EQUAL_MARK);
- parameters.append(QString::number(coordinates.longitude(), 'f', COORDINATE_PRECISION));
-
- parameters.append(AMBERSAND_MARK);
- parameters.append(PUBLISH);
- parameters.append(EQUAL_MARK);
-
- if(publish)
- parameters.append(PUBLISH_TRUE);
- else
- parameters.append(PUBLISH_FALSE);
-
- if(!status.isEmpty()) {
- parameters.append(AMBERSAND_MARK);
- parameters.append(DATA);
- parameters.append(EQUAL_MARK);
- parameters.append(status);
- }
++ //Request sent to server does not need the UID
++ QByteArray arr = m_database->getInterestingPeople(613374451,
++ southWestCoordinates,
++ northEastCoordinates);
+
- return parameters;
++ parseInterestingPeopleData(arr);
+}
+
- void SituareService::sendMessage(const QString &receiverId, const QString &message,
- const GeoCoordinate &coordinates)
++void SituareService::fetchPopularTags()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
- if (m_database->sendMessage(613374451, receiverId.toULongLong(), message, coordinates))
- emit updateWasSuccessful(SituareService::SuccessfulSendMessage);
++ QByteArray arr = m_database->getPopularTags();
++
++ parsePopularTagsData(arr);
+}
+
- void SituareService::sendRequest(const QUrl &url, const QString &cookieType, const QString &cookie)
+ void SituareService::fetchLocations()
{
qDebug() << __PRETTY_FUNCTION__;
- QNetworkRequest request;
-
- request.setUrl(url);
- request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false);
- request.setRawHeader(cookieType.toAscii(), cookie.toUtf8());
-
- QNetworkReply *reply = m_networkManager->get(request, true);
+ QHash<QString, QString> parameters;
+ parameters.insert("extra_user_data", NORMAL_SIZE_PROFILE_IMAGE);
- m_currentRequests.append(reply);
+ buildRequest(GET_LOCATIONS, parameters);
}
- void SituareService::requestFinished(QNetworkReply *reply)
-void SituareService::imageReceived(const QUrl &url, const QPixmap &image)
++QHash<QString, QString> SituareService::getTags(const QString &userId)
{
qDebug() << __PRETTY_FUNCTION__;
- qDebug() << "Image URL: " << url << " size :" << image.size();
- //Reply from situare
- if (m_currentRequests.contains(reply)) {
-
- qDebug() << "BytesAvailable: " << reply->bytesAvailable();
-
- if (reply->error()) {
- emit error(ErrorContext::NETWORK, reply->error());
- } else {
- QByteArray replyArray = reply->readAll();
- qDebug() << "Reply from: " << reply->url() << "reply " << replyArray;
-
- if(replyArray == ERROR_LAT.toAscii()) {
- qDebug() << "Error: " << ERROR_LAT;
- emit error(ErrorContext::SITUARE, SituareError::UPDATE_FAILED);
- } else if(replyArray == ERROR_LON.toAscii()) {
- qDebug() << "Error: " << ERROR_LON;
- emit error(ErrorContext::SITUARE, SituareError::UPDATE_FAILED);
- } else if(replyArray.contains(ERROR_SESSION.toAscii())) {
- qDebug() << "Error: " << ERROR_SESSION;
- emit error(ErrorContext::SITUARE, SituareError::SESSION_EXPIRED);
- } else if(replyArray.startsWith(OPENING_BRACE_MARK.toAscii())) {
- qDebug() << "JSON string";
- parseUserData(replyArray);
- } else if(replyArray.isEmpty()) {
- if(reply->url().toString().contains(UPDATE_LOCATION.toAscii())) {
- emit updateWasSuccessful(SituareService::SuccessfulUpdateLocation);
- } else {
- // session credentials are invalid
- emit error(ErrorContext::SITUARE, SituareError::SESSION_EXPIRED);
- }
- } else {
- // unknown reply
- emit error(ErrorContext::SITUARE, SituareError::ERROR_GENERAL);
- }
- }
- m_currentRequests.removeAll(reply);
- reply->deleteLater();
- }
- // assign facebook silhouette image to all who doesn't have a profile image
- if(url == QUrl(SILHOUETTE_URL)) {
- if(m_user->profileImageUrl().isEmpty()) {
- m_user->setProfileImage(AvatarImage::create(image, AvatarImage::Large));
- emit imageReady(m_user);
- }
- foreach(User *friendItem, m_friendsList) {
- if(friendItem->profileImageUrl().isEmpty()) {
- friendItem->setProfileImage(AvatarImage::create(image, AvatarImage::Small));
- emit imageReady(friendItem);
++ return m_database->getTags(userId.toInt());
+}
+
- void SituareService::credentialsReady(const FacebookCredentials &credentials)
++void SituareService::imageReceived(const QString &id, const QPixmap &image)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
- m_credentials = credentials;
++ if (m_user->userId() == id)
++ emit imageReady(QString(), AvatarImage::create(image, AvatarImage::Large));
++ else
++ emit imageReady(id, AvatarImage::create(image, AvatarImage::Small));
+}
+
+void SituareService::parseInterestingPeopleData(const QByteArray &jsonReply)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ QJson::Parser parser;
+ bool ok;
+
+ QVariantMap result = parser.parse(jsonReply, &ok).toMap();
+
+ if (!ok) {
+ emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
+ return;
+ } else {
+ QVariant people = result["people"];
+
+ QList<User> friends;
+ QList<User> others;
+
+ foreach (QVariant personVariant, people.toMap().value("friends").toList()) {
+ User user;
+ QMap<QString, QVariant> person = personVariant.toMap();
+ user.setUserId(person["uid"].toString());
+ user.setName(person["name"].toString());
+ user.setProfileImage(AvatarImage::create(
+ QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
+ user.setProfileImageUrl(person["image_url"].toUrl());
+ user.setTags(person["tags"].toList());
+
+ bool latOk;
+ qreal latitude = person["latitude"].toReal(&latOk);
+ bool lonOk;
+ qreal longitude = person["longitude"].toReal(&lonOk);
+
+ if (latOk && lonOk) {
+ user.setCoordinates(GeoCoordinate(latitude, longitude));
+
+ //This should be from the server
+ GeoCoordinate myCoord(65.008, 25.5523);
+ qreal meters = myCoord.distanceTo(user.coordinates());
+ qreal value;
+ QString unit;
+ if (meters < 1000) {
+ value = meters;
+ unit = "m";
+ } else {
+ value = meters/1000;
+ unit = "km";
+ }
+ user.setDistance(value, unit);
}
+
+ friends.append(user);
+
+ //Remove comment when the actual server is used
+ //emit fetchImage(user.userId(), user.profileImageUrl());
}
- }
- if (m_user->profileImageUrl() == url) {
- m_user->setProfileImage(AvatarImage::create(image, AvatarImage::Large));
- emit imageReady(m_user);
- }
+ foreach (QVariant personVariant, people.toMap().value("others").toList()) {
+ User user;
+ QMap<QString, QVariant> person = personVariant.toMap();
+ user.setUserId(person["uid"].toString());
+ user.setName(person["name"].toString());
+ user.setProfileImage(AvatarImage::create(
+ QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
+ user.setProfileImageUrl(person["image_url"].toUrl());
+ user.setTags(person["tags"].toList());
- foreach(User *friendItem, m_friendsList) {
- if(friendItem->profileImageUrl() == url) {
- friendItem->setProfileImage(AvatarImage::create(image, AvatarImage::Small));
- emit imageReady(friendItem);
+ others.append(user);
+
+ //Remove comment when the actual server is used
+ //emit fetchImage(user.userId(), user.profileImageUrl());
}
+
+ emit interestingPeopleReceived(friends, others);
}
}
}
}
- void SituareService::imageReceived(const QString &id, const QPixmap &image)
++void SituareService::parseMessagesData(const QByteArray &jsonReply)
+{
- qDebug() << __PRETTY_FUNCTION__;
++ QJson::Parser parser;
++ bool ok;
+
- if (m_user->userId() == id)
- emit imageReady(id, AvatarImage::create(image, AvatarImage::Large));
- else
- emit imageReady(id, AvatarImage::create(image, AvatarImage::Small));
- }
++ QVariantMap result = parser.parse(jsonReply, &ok).toMap();
+
- void SituareService::addProfileImages(const QHash<QString, QUrl> &imageUrlList)
- {
- qDebug() << __PRETTY_FUNCTION__;
++ if (!ok) {
++ emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
++ return;
++ } else {
++ QVariant messages = result["messages"];
+
- QHashIterator<QString, QUrl> imageUrlListIterator(imageUrlList);
++ QList<Message> received;
++ QList<Message> sent;
+
- while (imageUrlListIterator.hasNext()) {
- imageUrlListIterator.next();
- emit fetchImage(imageUrlListIterator.key(), imageUrlListIterator.value());
++ foreach (QVariant messageVariant, messages.toMap().value("received").toList()) {
++ Message message(Message::MessageTypeReceived);
++ QMap<QString, QVariant> messageMap = messageVariant.toMap();
++ message.setId(messageMap["id"].toString());
++ message.setSenderId(messageMap["sender_id"].toString());
++ message.setReceiverId(messageMap["receiver_id"].toString());
++ message.setSenderName(messageMap["sender_name"].toString());
++ uint timestampSeconds = messageMap["timestamp"].toUInt();
++ message.setTimestamp(QDateTime::fromTime_t(timestampSeconds));
++ message.setText(messageMap["text"].toString());
++ message.setImage(AvatarImage::create(
++ QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
++
++ bool latOk;
++ qreal latitude = messageMap["latitude"].toReal(&latOk);
++ bool lonOk;
++ qreal longitude = messageMap["longitude"].toReal(&lonOk);
++
++ if (latOk && lonOk) {
++ message.setAddress(messageMap["address"].toString());
++ message.setCoordinates(GeoCoordinate(latitude, longitude));
++ }
++
++ received.append(message);
++
++ //emit fetchImage(message.id(), messageMap["image_url"].toString());
++ }
++
++ foreach (QVariant messageVariant, messages.toMap().value("sent").toList()) {
++ Message message(Message::MessageTypeSent);
++ QMap<QString, QVariant> messageMap = messageVariant.toMap();
++ message.setId(messageMap["id"].toString());
++ message.setSenderId(messageMap["sender_id"].toString());
++ message.setReceiverId(messageMap["receiver_id"].toString());
++ message.setSenderName(messageMap["sender_name"].toString());
++ uint timestampSeconds = messageMap["timestamp"].toUInt();
++ message.setTimestamp(QDateTime::fromTime_t(timestampSeconds));
++ message.setText(messageMap["text"].toString());
++ message.setImage(AvatarImage::create(
++ QPixmap(":/res/images/empty_avatar.png"), AvatarImage::Small));
++
++ bool latOk;
++ qreal latitude = messageMap["latitude"].toReal(&latOk);
++ bool lonOk;
++ qreal longitude = messageMap["longitude"].toReal(&lonOk);
++
++ if (latOk && lonOk) {
++ message.setAddress(messageMap["address"].toString());
++ message.setCoordinates(GeoCoordinate(latitude, longitude));
++ }
++
++ sent.append(message);
++
++ //emit fetchImage(message.id(), messageMap["image_url"].toString());
++ }
++
++ emit messagesReceived(received, sent);
+ }
+}
+
- void SituareService::clearUserData()
++void SituareService::parsePopularTagsData(const QByteArray &jsonReply)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
- qDeleteAll(m_friendsList.begin(), m_friendsList.end());
- m_friendsList.clear();
++ QJson::Parser parser;
++ bool ok;
+
- if(m_user) {
- delete m_user;
- m_user = 0;
++ QVariantMap result = parser.parse(jsonReply, &ok).toMap();
++
++ if (!ok) {
++ emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
++ return;
++ } else {
++ QHash<QString, QString> popularTags;
++
++ foreach (QVariant tagVariant, result["popular_tags"].toList()) {
++ QMap<QString, QVariant> tag = tagVariant.toMap();
++ popularTags.insert(tag["id"].toString(), tag["name"].toString());
++ }
++
++ emit popularTagsReceived(popularTags);
+ }
- emit userDataChanged(m_user, m_friendsList);
+}
+
- QHash<QString, QString> SituareService::getTags(const QString &userId)
++void SituareService::removeMessage(const QString &id)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
- return m_database->getTags(userId.toInt());
++ if (m_database->removeMessage(613374451, id))
++ emit updateWasSuccessful(SituareService::SuccessfulRemoveMessage);
+}
+
++
+void SituareService::removeTags(const QStringList &tags)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ if (m_database->removeTags(613374451, tags))
+ emit updateWasSuccessful(SituareService::SuccessfulRemoveTags);
+}
+
- void SituareService::removeMessage(const QString &id)
+ void SituareService::requestFinished(QNetworkReply *reply)
{
qDebug() << __PRETTY_FUNCTION__;
- if (m_database->removeMessage(613374451, id))
- emit updateWasSuccessful(SituareService::SuccessfulRemoveMessage);
+ //Reply from situare
+ if (m_currentRequests.contains(reply)) {
+
+ qDebug() << "BytesAvailable: " << reply->bytesAvailable();
+
+ if (reply->error()) {
+ emit error(ErrorContext::NETWORK, reply->error());
+ } else {
+ QByteArray replyArray = reply->readAll();
+ qDebug() << "Reply from: " << reply->url() << "reply " << replyArray;
+
+ if(replyArray == ERROR_LAT.toAscii()) {
+ qDebug() << "Error: " << ERROR_LAT;
+ emit error(ErrorContext::SITUARE, SituareError::UPDATE_FAILED);
+ } else if(replyArray == ERROR_LON.toAscii()) {
+ qDebug() << "Error: " << ERROR_LON;
+ emit error(ErrorContext::SITUARE, SituareError::UPDATE_FAILED);
+ } else if(replyArray.contains(ERROR_SESSION.toAscii())) {
+ qDebug() << "Error: " << ERROR_SESSION;
+ emit error(ErrorContext::SITUARE, SituareError::SESSION_EXPIRED);
+ } else if(replyArray.startsWith(OPENING_BRACE_MARK.toAscii())) {
+ qDebug() << "JSON string";
+ parseUserData(replyArray);
+ } else if(replyArray.isEmpty()) {
+ if(reply->url().toString().contains(UPDATE_LOCATION.toAscii())) {
- emit updateWasSuccessful();
++ emit updateWasSuccessful(SituareService::SuccessfulUpdateLocation);
+ } else {
+ // session credentials are invalid
+ emit error(ErrorContext::SITUARE, SituareError::SESSION_EXPIRED);
+ }
+ } else {
+ // unknown reply
+ emit error(ErrorContext::SITUARE, SituareError::ERROR_GENERAL);
+ }
+ }
+ m_currentRequests.removeAll(reply);
+ reply->deleteLater();
+ }
}
- void SituareService::addTags(const QStringList &tags)
+ void SituareService::reverseGeo(const GeoCoordinate &coordinates)
{
- qWarning() << __PRETTY_FUNCTION__ << tags.count();
+ qDebug() << __PRETTY_FUNCTION__;
- foreach (QString tag, tags)
- m_database->addTag(613374451, tag);
+ QHash<QString, QString> parameters;
+ parameters.insert("lat", degreesToString(coordinates.latitude()));
+ parameters.insert("lon", degreesToString(coordinates.longitude()));
+ parameters.insert("format", "json");
- emit updateWasSuccessful(SituareService::SuccessfulAddTags);
+ buildRequest(REVERSE_GEO, parameters);
}
+void SituareService::searchPeopleByTag(const QString &tag)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ QByteArray arr = m_database->getInterestingPeopleByTag(613374451, tag);
+
+ parseInterestingPeopleData(arr);
+}
++
++void SituareService::sendMessage(const QString &receiverId, const QString &message,
++ const GeoCoordinate &coordinates)
++{
++ qDebug() << __PRETTY_FUNCTION__;
++
++ if (m_database->sendMessage(613374451, receiverId.toULongLong(), message, coordinates))
++ emit updateWasSuccessful(SituareService::SuccessfulSendMessage);
++}
++
+ void SituareService::sendRequest(const QString &requestUrl)
+ {
+ qDebug() << __PRETTY_FUNCTION__ << "requestUrl" << requestUrl;
+
+ // make and send the request
+ QNetworkRequest request;
+ request.setUrl(QUrl(requestUrl));
+ request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false);
+ QNetworkReply *reply = m_networkManager->get(request, true);
+ m_currentRequests.append(reply);
+ }
+
+ void SituareService::updateSession(const QString &session)
+ {
+ qDebug() << __PRETTY_FUNCTION__;
+
+ m_session = session;
+
+ if (m_session.isEmpty())
+ clearUserData();
+ }
+
+ void SituareService::updateLocation(const GeoCoordinate &coordinates, const QString &status,
+ const bool &publish)
+ {
+ qDebug() << __PRETTY_FUNCTION__;
+
+ QHash<QString, QString> parameters;
+ parameters.insert("lat", degreesToString(coordinates.latitude()));
+ parameters.insert("lon", degreesToString(coordinates.longitude()));
+ parameters.insert("publish", publish ? "true" : "false");
+ parameters.insert("data", status); ///< @todo if !empty ???
+
+ buildRequest(UPDATE_LOCATION, parameters);
+ }
Copyright (C) 2010 Ixonos Plc. Authors:
Henri Lampela - henri.lampela@ixonos.com
+ Jussi Laitinen - jussi.laitinen@ixonos.com
+ Sami Rämö - sami.ramo@ixonos.com
Situare is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
#define SITUARESERVICE_H
#include <QObject>
- #include "../facebookservice/facebookcredentials.h"
+
#include "../user/user.h"
#include "imagefetcher.h"
+#include "message.h"
+class Database;
class NetworkAccessManager;
class QNetworkReply;
class QNetworkRequest;
* @brief SituareService class for communicating with Situare server
*
* @author Henri Lampela
- * @class SituareService situareservice.h "situareservice/situareservice.h"
++* @author Jussi Laitinen - jussi.laitinen (at) ixonos.com
+ * @author Sami Rämö - sami.ramo (at) ixonos.com
*/
class SituareService : public QObject
{
void updateLocation(const GeoCoordinate &coordinates, const QString &status, const bool &publish);
public slots:
+ /**
+ * @brief Adds tags to the Situare server
+ *
+ * CURRENTLY TAGS ARE UPDATED TO THE LOCAL DATABASE, NOT SITUARE SERVER
+ * @param tags list of user's tags
+ */
+ void addTags(const QStringList &tags);
/**
+ * @brief Public slot, to clear user data
+ *
+ */
+ void clearUserData();
+
+ /**
+ * @brief Retrieves messages sent to user.
+ */
+ void fetchMessages();
+
+ /**
+ * @brief Retrieves popular tags.
+ *
+ * Tags are fetch from local database instead of Situare server.
+ */
+ void fetchPopularTags();
+
+ /**
- * @brief Public slot, to clear user data
- *
- */
- void clearUserData();
-
- /**
- * @brief Public slot, which indicates when facebook credentials are ready
- *
- * @param credentials New credentials
- */
- void credentialsReady(const FacebookCredentials &credentials);
-
- /**
+ * @brief Removes message.
+ *
+ * @param id message ID
+ */
+ void removeMessage(const QString &id);
+
+ /**
+ * @brief Removes tags.
+ *
+ * @param tags list of tags to remove
+ */
+ void removeTags(const QStringList &tags);
+
+ /**
* @brief Public slot, which indicates when http request has been completed
*
* @param reply storage for http reply
void requestFinished(QNetworkReply *reply);
/**
+ * @brief Searches people by tag name.
+ *
+ * @param tag tag name
+ */
+ void searchPeopleByTag(const QString &tag);
+
+ /**
+ * @brief Sends a message to a person.
+ *
+ * @param receiverId Facebook user ID
+ * @param message message text
+ * @param message coordinates
+ */
+ void sendMessage(const QString &receiverId, const QString &message,
+ const GeoCoordinate &coordinates = GeoCoordinate());
+
++ /**
+ * @brief Update session data
+ *
+ * @param session New session data
+ */
+ void updateSession(const QString &session);
+
private:
-
/**
* @brief Requests ImageFetcher if user/friend has a profile image
* uses members: m_user and m_friendsList
*
* @param imageUrlList list of image urls
*/
- void addProfileImages(const QList<QUrl> &imageUrlList);
+ void addProfileImages(const QHash<QString, QUrl> &imageUrlList);
/**
- * @brief Forms a http cookie
- *
- * @param apiKeyValue application key
- * @param expiresValue session expire date&time from Facebook
- * @param userValue user id from Facebook
- * @param sessionKeyValue session key from Facebook
- * @param sessionSecretValue session secret from Facebook
- * @param signatureValue md5 generated signature
- * @param localeValue used locale
- * @return QString formed cookie
- */
- QString formCookie(const QString &apiKeyValue, QString expiresValue, QString userValue,
- QString sessionKeyValue, QString sessionSecretValue,
- const QString &signatureValue, const QString &localeValue);
+ * @brief Append access_token and other session data to the reques url
+ *
+ * @param[in,out] requestUrl Request URL with other request parameters and ending to &
+ */
+ void appendAccessToken(QString &requestUrl);
/**
- * @brief Forms a http url
- *
- * @param baseUrl Server url
- * @param phpScript Server script
- * @param urlParameters optional parameters for url
- * @return QUrl formed url
- */
- QUrl formUrl(const QString &baseUrl, const QString &phpScript,
- QString urlParameters = QString());
++ * @brief Build and send request
++ *
++ * Appends script pathname and parameters to the server base URL. Access token is appended and
++ * the request sent if the access token is available, otherwise the request is queued.
++ *
++ * @param script Requested script pathname
++ * @param parameters Hash containing parameter key/value pairs.
++ */
++ void buildRequest(const QString &script, const QHash<QString,QString> ¶meters);
+
+ /**
- * @brief Forms url parameters
- *
- * @param coordinates current coordinates
- * @param status optional status message
- * @param publish optional publish location on Facebook wall
- * @return QString
- */
- QString formUrlParameters(const GeoCoordinate &coordinates, QString status = QString(),
- bool publish = false);
+ * @brief Convert coordinate value in degrees (double) to string with enough precision
+ *
+ * @param degrees Coordinate value in degrees
+ * @returns Coordinate value as string
+ */
+ QString degreesToString(double degrees);
/**
- * @brief Parses user and friend data from JSON string
+ * @brief Temporary method to get tags.
+ *
+ * Tags are fetch from local database instead of Situare server.
+ * @param userId
+ * @return QStringList list of tags
+ */
+ QHash<QString, QString> getTags(const QString &userId);
+
+ /**
+ * @brief Parses interesting people data from JSON string
*
* @param jsonReply JSON string
*/
- void parseUserData(const QByteArray &jsonReply);
+ void parseInterestingPeopleData(const QByteArray &jsonReply);
/**
- * @brief Build and send request
- *
- * Appends script pathname and parameters to the server base URL. Access token is appended and
- * the request sent if the access token is available, otherwise the request is queued.
- *
- * @param script Requested script pathname
- * @param parameters Hash containing parameter key/value pairs.
- */
- void buildRequest(const QString &script, const QHash<QString,QString> ¶meters);
+ * @brief Parses messages data from JSON string
+ *
+ * @param jsonReply JSON string
+ */
+ void parseMessagesData(const QByteArray &jsonReply);
+
+ /**
+ * @brief Parses popular tags data from JSON string
+ *
+ * @param jsonReply JSON string
+ */
+ void parsePopularTagsData(const QByteArray &jsonReply);
+
+ /**
+ * @brief Parses user and friend data from JSON string
+ *
+ * @param jsonReply JSON string
+ */
+ void parseUserData(const QByteArray &jsonReply);
/**
- * @brief Sends http request
- *
- * @param url destination
- * @param cookieType type of the cookie
- * @param cookie http cookie
- */
- void sendRequest(const QUrl &url, const QString &cookieType, const QString &cookie);
+ * @brief Send request
+ *
+ * @param requestUrl Request URL containing also all parameters
+ */
+ void sendRequest(const QString &requestUrl);
private slots:
/**
/**
* @brief Signal for image fetching
*
+ * @param id Image id
* @param url Image url
*/
- void fetchImage(const QUrl &url);
+ void fetchImage(const QString &id, const QUrl &url);
/**
-- * @brief Signals when user's/friend's image is downloaded
- *
- * @param user Instance of user/friend
- */
- void imageReady(User *user);
-
- /**
+ * @brief Signals when image is downloaded
*
- * @param user Instance of user/friend
+ * @param id image ID
+ * @param image image pixmap
*/
- void imageReady(User *user);
+ void imageReady(const QString &id, const QPixmap &image);
+
+ /**
+ * @brief Signal when fetchPeopleWithSimilarInterest request is finished
+ *
+ * @param friends list of friends
+ * @param others list of other people
+ */
+ void interestingPeopleReceived(QList<User> &friends, QList<User> &others);
+
+ /**
+ * @brief Signal when fetchMessages request is finished
+ *
+ * @param messages list of messages sent to user
+ */
+ void messagesReceived(QList<Message> &received, QList<Message> &sent);
+
+ /**
+ * @brief Signals when fetchPopularTags request is finished
+ *
+ * @param popularTags list of popular tags
+ */
+ void popularTagsReceived(QHash<QString, QString> &popularTags);
/**
* @brief Signals when address data is retrieved
/**
* @brief Signals when updateLocation request finished successfully
- *
*/
- void updateWasSuccessful();
+ void updateWasSuccessful(SituareService::SuccessfulMethod successfulMethod);
/**
* @brief Signals when user data is retrieved
private:
bool m_defaultImage; ///< Indicates if some of the friends/user doesn't have a image
- QList<QNetworkReply *> m_currentRequests; ///< List of current http requests
- QList<User *> m_friendsList; ///< List of friends(User)
+ QList<QNetworkReply *> m_currentRequests; ///< List of current http requests
+ QList<User *> m_friendsList; ///< List of friends(User)
+
+ QString m_session; ///< Session data
+ Database *m_database; ///< Instance of the database
- NetworkAccessManager *m_networkManager; ///< Pointer to QNetworkAccessManager
- FacebookCredentials m_credentials; ///< handle for FacebookCredentials
- ImageFetcher *m_imageFetcher; ///< Instance of the image fetcher
++ ImageFetcher *m_imageFetcher; ///< Instance of the image fetcher
+ NetworkAccessManager *m_networkManager; ///< Pointer to QNetworkAccessManager
-
- ImageFetcher *m_imageFetcher; ///< Instance of the image fetcher
User *m_user; ///< Pointer to User
};
ui/zoombuttonpanel.cpp \
user/user.cpp \
ui/listitemcontextbuttonbar.cpp \
+ ui/meetpeoplepanel.cpp \
+ situareservice/database.cpp \
+ ui/tagsdialog.cpp \
+ ui/messagelistview.cpp \
+ ui/messagelistitem.cpp \
+ ui/headerlistitemdelegate.cpp \
+ ui/messagepanel.cpp \
+ situareservice/message.cpp \
+ ui/personlistitem.cpp \
+ ui/personlistview.cpp \
+ ui/messagedialog.cpp \
- ui/tagcompletion.cpp
++ ui/tagcompletion.cpp \
+ engine/updatelocation.cpp
HEADERS += application.h \
common.h \
coordinates/geocoordinate.h \
ui/zoombuttonpanel.h \
user/user.h \
ui/listitemcontextbuttonbar.h \
+ ui/meetpeoplepanel.h \
+ situareservice/database.h \
+ ui/tagsdialog.h \
+ ui/messagelistview.h \
+ ui/messagelistitem.h \
+ ui/headerlistitemdelegate.h \
+ ui/messagepanel.h \
+ situareservice/message.h \
+ ui/personlistitem.h \
+ ui/personlistview.h \
+ ui/messagedialog.h \
- ui/tagcompletion.h
++ ui/tagcompletion.h \
+ engine/updatelocation.h
QT += network \
- webkit
+ webkit \
+ sql
DEFINES += QT_NO_DEBUG_OUTPUT
simulator {
#include "map/mapcommon.h"
#include "map/mapview.h"
#include "mapscale.h"
+#include "meetpeoplepanel.h"
++#include "messagedialog.h"
+#include "messagepanel.h"
#include "panelcommon.h"
#include "routingpanel.h"
#include "searchdialog.h"
connect(m_userInfoPanel, SIGNAL(refreshUserData()),
this, SIGNAL(refreshUserData()));
- connect(m_userInfoPanel, SIGNAL(notificateUpdateFailing(QString, bool)),
- this, SLOT(buildInformationBox(QString, bool)));
-
- connect(m_userInfoPanel, SIGNAL(updateLocationMessageButtonClicked()),
- this, SLOT(showUpdateLocationDialog()));
+ connect(this, SIGNAL(userImageReady(QString,QPixmap)),
+ m_userInfoPanel, SLOT(setImage(QString,QPixmap)));
+
+ connect(m_userInfoPanel, SIGNAL(addTags(QStringList)),
+ this, SIGNAL(addTags(QStringList)));
+
+ connect(m_userInfoPanel, SIGNAL(removeTags(QStringList)),
+ this, SIGNAL(removeTags(QStringList)));
+
+ connect(this, SIGNAL(popularTagsReceived(QHash<QString,QString>&)),
+ m_userInfoPanel, SLOT(populatePopularTags(QHash<QString,QString>&)));
+
+ connect(m_userInfoPanel, SIGNAL(requestPopularTags()),
+ this, SIGNAL(requestPopularTags()));
}
- void MainWindow::buildWebView()
- {
- qDebug() << __PRETTY_FUNCTION__;
-
- if(!m_webView) {
- m_webView = new QWebView;
-
- if(!m_cookieJar)
- m_cookieJar = new NetworkCookieJar(new QNetworkCookieJar(this));
-
- m_webView->page()->networkAccessManager()->setCookieJar(m_cookieJar);
-
- connect(m_webView->page()->networkAccessManager(), SIGNAL(finished(QNetworkReply*)),
- this, SLOT(webViewRequestFinished(QNetworkReply*)));
- connect(m_webView, SIGNAL(urlChanged(const QUrl &)),
- this, SIGNAL(updateCredentials(QUrl)));
- connect(m_webView, SIGNAL(loadFinished(bool)),
- this, SLOT(loadDone(bool)));
-
- //Remove
- connect(m_webView->page()->networkAccessManager(), SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
- this, SLOT(sslErrors(QNetworkReply*,QList<QSslError>)));
-
- m_webView->hide();
- }
- }
-
void MainWindow::buildZoomButtonPanel()
{
qDebug() << __PRETTY_FUNCTION__;
qDebug() << __PRETTY_FUNCTION__;
QDialog *dialog = m_queue.takeFirst();
- LoginDialog *loginDialog = qobject_cast<LoginDialog *>(dialog);
SearchDialog *searchDialog = qobject_cast<SearchDialog *>(dialog);
- MessageDialog *messageDialog = qobject_cast<MessageDialog *>(dialog);
- if(loginDialog) {
- if(status != 0) {
- buildWebView();
- loginDialog->userInput(m_email, m_password);
-
- QStringList urlParts;
- urlParts.append(FACEBOOK_LOGINBASE);
- urlParts.append(SITUARE_PUBLIC_FACEBOOKAPI_KEY);
- urlParts.append(INTERVAL1);
- urlParts.append(SITUARE_LOGIN_SUCCESS);
- urlParts.append(INTERVAL2);
- urlParts.append(SITUARE_LOGIN_FAILURE);
- urlParts.append(FACEBOOK_LOGIN_ENDING);
-
- emit saveUsername(m_email);
- m_refresh = true;
- m_webView->load(QUrl(urlParts.join(EMPTY)));
- toggleProgressIndicator(true);
- } else {
- emit cancelLoginProcess();
- }
- } else if(searchDialog) {
- if(status != 0) {
- if (searchDialog->type() == SearchDialog::Location)
- emit searchForLocation(searchDialog->input());
- else if (searchDialog->type() == SearchDialog::PeopleTag)
- emit requestSearchPeopleByTag(searchDialog->input());
- }
- }
- else if (messageDialog) {
- if (status != 0)
- emit sendMessage(messageDialog->input().first, messageDialog->input().second,
- messageDialog->isAddCoordinatesSelected());
- if ((searchDialog) && (status != 0))
- emit searchForLocation(searchDialog->input());
++ MessageDialog *messageDialog = qobject_cast<MessageDialog *>(dialog);
++
++ if ((searchDialog) && (status != 0)) {
++ if (searchDialog->type() == SearchDialog::Location)
++ emit searchForLocation(searchDialog->input());
++ else if (searchDialog->type() == SearchDialog::PeopleTag)
++ emit requestSearchPeopleByTag(searchDialog->input());
++ } else if ((messageDialog) && (status != 0)) {
++ emit sendMessage(messageDialog->input().first, messageDialog->input().second,
++ messageDialog->isAddCoordinatesSelected());
+ }
dialog->deleteLater();
}
}
+ void MainWindow::showUpdateLocationDialog()
+ {
+ qDebug() << __PRETTY_FUNCTION__;
+
+ UpdateLocationDialog *updateLocationDialog
+ = new UpdateLocationDialog(m_updateLocationController, this);
+
+ connect(this, SIGNAL(reverseGeoReady(QString)),
+ updateLocationDialog, SLOT(setAddress(QString)));
+
+ updateLocationDialog->show();
+
+ emit requestReverseGeo();
+ }
+
-void MainWindow::sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
+void MainWindow::startLocationSearch()
{
qDebug() << __PRETTY_FUNCTION__;
queueDialog(searchDialog);
}
- void MainWindow::startLoginProcess()
++void MainWindow::sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
- LoginDialog *loginDialog = new LoginDialog();
-
- emit fetchUsernameFromSettings();
-
- loginDialog->clearTextFields();
-
- if(!m_email.isEmpty())
- loginDialog->setEmailField(m_email);
-
- queueDialog(loginDialog);
++ Q_UNUSED(errors)
++ reply->ignoreSslErrors();
+}
+
void MainWindow::toggleFullScreen()
{
qDebug() << __PRETTY_FUNCTION__;
#define MAINWINDOW_H
#include <QtGui/QMainWindow>
+ #include <QSslError>
#include <QUrl>
+//Remove this
+#include <QNetworkReply>
+#include <QSslError>
+
+#include "situareservice/message.h"
#include "network/networkcookiejar.h"
+ class QDialog;
class QGraphicsScene;
class QLabel;
class QMessageBox;
void showContactDialog(const QString &guid);
/**
+ * @brief Shows message dialog.
+ *
+ * @param receiver receiver ID and name
+ */
+ void showMessageDialog(const QPair<QString, QString> &receiver);
+
+ /**
- * @brief Public slot to intercept signal when old cerdentials are invalid or credentials
- * doesn't exist yet
- */
- void startLoginProcess();
-
- /**
* @brief Toggle progress indicator.
*
* @param state true if progress indicator should be shown, false otherwise
void moveCrosshair();
/**
- * @brief Slot to save cookies to settings
+ * @brief Slot for settings dialog accepted.
*/
- void saveCookies();
+ void settingsDialogAccepted();
/**
- * @brief Slot for settings dialog accepted.
+ * @brief Show update location dialog
*/
- void settingsDialogAccepted();
+ void showUpdateLocationDialog();
/**
- * @brief Ignore SSL error from the reply
- */
- void sslErrors(QNetworkReply *reply, const QList<QSslError> &errors);
-
- /**
* @brief Start location search (open search dialog)
*/
void startLocationSearch();
*/
void toggleFullScreen();
+ /**
- * @brief Slot to intercept signal from webview's networkaccessmanager
- *
- * @param reply Network reply (contains errors)
- */
- void webViewRequestFinished(QNetworkReply* reply);
-
- /**
+ * REMOVE THIS, FIXES WEBVIEW BUG IN SCRATCHBOX
+ */
+ void sslErrors(QNetworkReply *reply, const QList<QSslError> &errors);
+
/*******************************************************************************
* SIGNALS
******************************************************************************/
void searchHistoryItemClicked(const QString &searchString);
/**
+ * @brief Sends a message to a person.
+ *
+ * @param receiverId Facebook user ID
+ * @param message message text
+ * @param addCoordinates true if coordinates should be added, false otherwise
+ */
+ void sendMessage(const QString &receiverId, const QString &message, bool addCoordinates);
+
+ /**
- * @brief Signal for requestLocationUpdate from SituareEngine
- *
- * @param status Status message
- * @param publish Publish on Facebook
- */
- void statusUpdate(const QString &status, const bool &publish);
-
- /**
- * @brief Signals when webview's urlChanged signal is emitted
- *
- * @param url New url
- */
- void updateCredentials(const QUrl &url);
-
- /**
+ * @brief Signals when image is downloaded
+ *
+ * @param id image ID
+ * @param image image pixmap
+ */
+ void userImageReady(const QString &id, const QPixmap &image);
+
+ /**
- * @brief Signals when updateLocationDialog's data must be cleared
- *
- */
- void clearUpdateLocationDialogData();
-
- /**
* @brief Dragging mode triggered.
*/
void draggingModeTriggered();
void viewZoomFinished();
/**
+ * @brief Requests interesting people from current map viewport.
+ *
+ * Interesting people is defined by people with same tags as user has.
+ */
+ void requestInterestingPeople();
+
+ /**
+ * @brief Requests messages sent to the user.
+ */
+ void requestMessages();
+
+ /**
+ * @brief Signals when updateLocation request finished successfully
+ */
+ void updateWasSuccessful();
+
+ /**
* @brief Signal for use location ready.
*
* @param user User object
LocationSearchPanel *m_locationSearchPanel; ///< Location search panel
MapScale *m_mapScale; ///< Instance of the map scale
MapView *m_mapView; ///< Instance of the map view
+ MeetPeoplePanel *m_meetPeoplePanel; ///< Instance of MeetPeoplePanel
- NetworkCookieJar *m_cookieJar; ///< Placeholder for QNetworkCookies
+ MessagePanel *m_messagePanel; ///< Instance of MessagePanel
RoutingPanel *m_routingPanel; ///< Instance of routing panel
TabbedPanel *m_tabbedPanel; ///< Widget for tabbed panels
+ UpdateLocation *m_updateLocationController; ///< Controller for update location dialog
UserInfoPanel *m_userInfoPanel; ///< Instance of the user information panel
ZoomButtonPanel *m_zoomButtonPanel; ///< Instance of zoom button panel
};
UserInfo::UserInfo(QWidget *parent)
: QWidget(parent),
- m_expanded(false)
+ m_expanded(false),
- m_tagsDialog(0),
- m_updateLocation(0)
++ m_tagsDialog(0)
{
qDebug() << __PRETTY_FUNCTION__;
m_backgroundTopImage.load(":/res/images/list_item_top.png");
m_backgroundMiddleImage.load(":/res/images/list_item_middle.png");
m_backgroundBottomImage.load(":/res/images/list_item_bottom.png");
+ m_backgroundTopSelectedImage.load(":/res/images/list_item_top_selected.png");
+ m_backgroundMiddleSelectedImage.load(":/res/images/list_item_middle_selected.png");
+ m_backgroundBottomSelectedImage.load(":/res/images/list_item_bottom_selected.png");
-
- restoreUnsendMessage();
}
UserInfo::~UserInfo()
QRect topRect = QRect(0, MARGIN, BACKGROUND_WIDTH, BACKGROUND_TOP_HEIGHT);
- QRect middleRect = QRect(topRect.left(), topRect.bottom() + 1, BACKGROUND_WIDTH,
- this->height() - BACKGROUND_TOP_HEIGHT - BACKGROUND_BOTTOM_HEIGHT);
+ QRect middleRect = QRect(topRect.left(), topRect.bottom(), BACKGROUND_WIDTH,
+ height() - BACKGROUND_TOP_HEIGHT - BACKGROUND_BOTTOM_HEIGHT);
- QRect bottomRect = QRect(topRect.left(), middleRect.bottom() + 1, BACKGROUND_WIDTH,
+ QRect bottomRect = QRect(topRect.left(), middleRect.bottom(), BACKGROUND_WIDTH,
BACKGROUND_BOTTOM_HEIGHT);
- painter.drawPixmap(topRect, m_backgroundTopImage);
- painter.drawPixmap(middleRect, m_backgroundMiddleImage);
- painter.drawPixmap(bottomRect, m_backgroundBottomImage);
+ if (m_expanded) {
+ painter.drawPixmap(topRect, m_backgroundTopSelectedImage);
+ painter.drawPixmap(middleRect, m_backgroundMiddleSelectedImage);
+ painter.drawPixmap(bottomRect, m_backgroundBottomSelectedImage);
+ } else {
+ painter.drawPixmap(topRect, m_backgroundTopImage);
+ painter.drawPixmap(middleRect, m_backgroundMiddleImage);
+ painter.drawPixmap(bottomRect, m_backgroundBottomImage);
+ }
}
- void UserInfo::restoreUnsendMessage()
- {
- qDebug() << __PRETTY_FUNCTION__;
-
- QSettings settings(DIRECTORY_NAME, FILE_NAME);
- m_backupMessage = settings.value(USER_UNSEND_MESSAGE, EMPTY).toString();
- m_backupFacebookPublishPolicity = settings.value(USER_UNSEND_MESSAGE_PUBLISH, false).toBool();
- }
-
void UserInfo::setAddress(const QString &address)
{
qDebug() << __PRETTY_FUNCTION__;
m_nameLabel->setText(TextModifier::shortenText(m_nameLabel->fontMetrics(), m_userName,
LABEL_MAX_WIDTH));
}
+
+void UserInfo::showTagsDialog()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ m_tagsDialog = new TagsDialog(m_userTags, this);
+ connect(m_tagsDialog, SIGNAL(finished(int)),
+ this, SLOT(tagsDialogFinished(int)));
+ m_tagsDialog->show();
+}
+
+void UserInfo::tagsDialogFinished(int reason)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ if (m_tagsDialog) {
+ if (reason == QDialog::Accepted) {
+ QStringList removedTagsIds;
+
+ foreach (QString removedTag, m_tagsDialog->removedTags())
+ removedTagsIds.append(m_userTags.key(removedTag));
+
+ if (!removedTagsIds.isEmpty())
+ emit removeTags(removedTagsIds);
+ if (!m_tagsDialog->newTags().isEmpty())
+ emit addTags(m_tagsDialog->newTags());
+ }
+
+ m_tagsDialog->deleteLater();
+ m_tagsDialog = 0;
+ }
+}
-
- void UserInfo::updateLocationDialogFinished(int reason)
- {
- qDebug() << __PRETTY_FUNCTION__;
-
- Q_UNUSED(reason);
-
- if (m_updateLocation) {
- disconnect(this, SIGNAL(reverseGeoReady(QString)),
- m_updateLocation, SLOT(setAddress(QString)));
-
- disconnect(m_updateLocation, SIGNAL(statusUpdate(QString,bool)),
- this, SIGNAL(statusUpdate(QString,bool)));
-
- disconnect(m_updateLocation, SIGNAL(statusUpdate(QString,bool)),
- this, SLOT(backupUpdateLocationDialogData(QString,bool)));
-
- disconnect(m_updateLocation, SIGNAL(finished(int)),
- this, SLOT(updateLocationDialogFinished(int)));
-
- m_updateLocation->deleteLater();
- m_updateLocation = 0;
- }
- }
#include <QWidget>
#include "coordinates/geocoordinate.h"
- #include "updatelocation/updatelocationdialog.h"
+
+ class QLabel;
class ImageButton;
+class TagsDialog;
/**
* @brief UserInfo shows user's data in expandable item.
void setProfileImage(const QPixmap &image);
/**
- * @brief Sets the user tags
- *
- * @param tags list of tags
- */
- void setProfileImage(const QStringList &tags);
-
- /**
+ * @brief Sets the user tags
+ *
+ * @param tags list of tags
+ */
+ void setTags(const QHash<QString, QString> &tags);
+
+ /**
+ * @brief Sets the popular tags
+ *
+ * @param tags list of tags
+ */
+ void setPopularTags(const QHash<QString, QString> &tags);
+
+ /**
* @brief Sets the time of updated message
*
* @param time Reference to time when message was sent.
*/
void setUserName(const QString &name);
+ /**
+ * @brief Shows users tags dialog.
+ */
+ void showTagsDialog();
+
public slots:
/**
- * @brief Saves status message and Facebook publish setting
- *
- * @param status message that user sends. Message is stored to m_backupMessage data member
- * @param publish setting that determines whether the user status message is published on
- * Facebook. This value is stored to m_backupFacebookPublishPolicity data member.
- */
- void backupUpdateLocationDialogData(const QString &status, bool publish);
-
- /**
- * @brief Clears backups of message and publish on Facebook setting
- */
- void clearUpdateLocationDialogData();
-
- /**
* @brief Sets the message text
*
* @param text Reference to user message
*/
void findButtonClicked();
+ /**
- * @brief Slot function to forward messageUpdate launch signal
- */
- void messageUpdate();
-
- /**
+ * @brief Slot to handle changes in tags dialog.
+ */
+ void tagsDialogFinished(int reason);
+
- /**
- * @brief Slot function to get indication when dialog is finished
- */
- void updateLocationDialogFinished(int reason);
-
/******************************************************************************
* SIGNALS
******************************************************************************/
*/
void findUser(const GeoCoordinate &coordinates);
+ /**
- * @brief Signal that used to inform user that his message/location update tp Situare server
- * was failed.
- * This signal is originally sended from UserInfo
- * @param message message for notification
- * @param modal true if modal notification otherwice false
- */
- void notificateUpdateFailing(const QString &message, bool modal);
-
- /**
- * @brief Signal for requesting reverseGeo from SituareEngine
- */
- void requestReverseGeo();
-
- /**
+ * @brief Signal for removing tags.
+ *
+ * @param tags tags to add
+ */
+ void removeTags(const QStringList &tags);
+
+ /**
- * @brief Signals, when address data is ready
- *
- * @param address Street address
- */
- void reverseGeoReady(const QString &address);
-
- /**
+ * @brief Signals, when item selection changed
+ *
+ * @param address Street address
+ */
+ void itemSelectionChanged(bool selected);
+
- /**
- * @brief Signal for requestLocationUpdate from SituareEngine via MainWindow class
- *
- * @param status Status message
- * @param publish Publish on Facebook
- */
- void statusUpdate(const QString &status, const bool &publish);
-
/******************************************************************************
* DATA MEMBERS
******************************************************************************/
QString m_messageText; ///< User's message
QString m_userName; ///< User's name
+ QHash<QString, QString> m_userTags; ///< User's tags
+
GeoCoordinate m_coordinates; ///< User current coordinates
ImageButton *m_avatar; ///< User find button
+ TagsDialog *m_tagsDialog; ///< Tags dialog
- UpdateLocationDialog *m_updateLocation; ///< Update location dialog
};
#endif // USERINFO_H
this, SIGNAL(refreshUserData()));
connect(updateStatusMessageButton, SIGNAL(clicked()),
- m_userInfo, SLOT(messageUpdate()));
+ this, SIGNAL(updateLocationMessageButtonClicked()));
+ connect(tagButton, SIGNAL(clicked()),
+ this, SLOT(showTagsDialog()));
+
+}
+
+void UserInfoPanel::populatePopularTags(QHash<QString, QString> &popularTags)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ m_userInfo->setPopularTags(popularTags);
+}
+
+void UserInfoPanel::setImage(const QString &id, const QPixmap &image)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ m_userInfo->setProfileImage(image);
}
void UserInfoPanel::showUserInfo(bool logged)
void refreshUserData();
/**
+ * @brief Signal for removing tags.
+ *
+ * @param tags tags to add
+ */
+ void removeTags(const QStringList &tags);
+
+ /**
+ * @brief Signal for requesting popular tags
+ */
+ void requestPopularTags();
+
+ /**
- * @brief Signal for requesting reverseGeo from SituareEngine
- */
- void requestReverseGeo();
-
- /**
- * @brief Signals, when address data is ready
- *
- * @param address Street address
- */
- void reverseGeoReady(const QString &address);
-
- /**
- * @brief Signal Signal for requestLocationUpdate from SituareEngine via MainWindow class
- *
- * @param status Status message
- * @param publish Publish on Facebook
- */
- void statusUpdate(const QString &status, const bool &publish);
-
- /**
- * @brief Signals when updateLocationDialog's data must be cleared
- */
- void clearUpdateLocationDialogData();
-
+ * @brief Notify that update location message button was clicked
+ */
+ void updateLocationMessageButtonClicked();
/*******************************************************************************
* DATA MEMBERS