Merge branch 'stacked_friends'
authorSami Rämö <sami.ramo@ixonos.com>
Tue, 11 May 2010 07:46:44 +0000 (10:46 +0300)
committerSami Rämö <sami.ramo@ixonos.com>
Tue, 11 May 2010 07:46:44 +0000 (10:46 +0300)
Conflicts:
doc/test_cases/functionality-tests.doc
src/src.pro
src/ui/mapviewscreen.cpp
src/ui/mapviewscreen.h

1  2 
images.qrc
src/situareservice/situareservice.cpp
src/situareservice/situareservice.h
src/src.pro
src/ui/mainwindow.cpp
src/ui/mapviewscreen.cpp
src/ui/mapviewscreen.h

diff --cc images.qrc
Simple merge
diff --cc src/situareservice/situareservice.cpp
index 6563f59,9e81150..0000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,367 -1,375 +1,0 @@@
--/*
--   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 <QtAlgorithms>
--#include <QDebug>
--#include <QtGlobal>
- #include <QStringList>
- #include <QPixmap>
- #include <QNetworkReply>
- #include "situareservice.h"
- #include "situarecommon.h"
- #include "../cookiehandler/cookiehandler.h"
- #include "parser.h"
- SituareService::SituareService(QObject *parent)
-         : QObject(parent)
- {
-     qDebug() << __PRETTY_FUNCTION__;
-     m_networkManager = new QNetworkAccessManager;
-     connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), SLOT(requestFinished(QNetworkReply*)));
-     m_imageFetcher = new ImageFetcher(new QNetworkAccessManager(this), this);
-     connect(this, SIGNAL(fetchImage(QUrl)), m_imageFetcher, SLOT(fetchImage(QUrl)));
-     connect(m_imageFetcher, SIGNAL(imageReceived(QUrl,QPixmap)), this,
-             SLOT(imageReceived(QUrl, QPixmap)));
-     connect(m_imageFetcher, SIGNAL(error(QString)), this, SIGNAL(error(QString)));
-     m_user = 0;
- }
- SituareService::~SituareService()
- {
-     qDebug() << __PRETTY_FUNCTION__;
-     delete m_networkManager;
-     m_networkManager = 0;
-     if(m_user) {
-         delete m_user;
-         m_user = 0;
-     }
-     delete m_imageFetcher;
-     m_imageFetcher = 0;
-     qDeleteAll(m_friendsList.begin(), m_friendsList.end());
-     m_friendsList.clear();
- }
- void SituareService::fetchLocations()
- {
-     qDebug() << __PRETTY_FUNCTION__;
-     CookieHandler cookieHandler;
-     QString cookie = cookieHandler.formCookie(API_KEY, m_credentials.expires(), m_credentials.userID(),
-                                               m_credentials.sessionKey(), m_credentials.sessionSecret(),
-                                               m_credentials.sig(), EN_LOCALE);
-     QUrl url = formUrl(SITUARE_URL, GET_LOCATIONS);
-     sendRequest(url, COOKIE, cookie);
- }
- void SituareService::reverseGeo(const QPointF &coordinates)
- {
-     qDebug() << __PRETTY_FUNCTION__;
-     CookieHandler cookieHandler;
-     QString cookie = cookieHandler.formCookie(API_KEY, m_credentials.expires(), m_credentials.userID(),
-                                               m_credentials.sessionKey(), m_credentials.sessionSecret(),
-                                               m_credentials.sig(), EN_LOCALE);
-     QString urlParameters = formUrlParameters(coordinates);
-     QUrl url = formUrl(SITUARE_URL, REVERSE_GEO, urlParameters);
-     sendRequest(url, COOKIE, cookie);
- }
- void SituareService::updateLocation(const QPointF &coordinates, const QString &status,
-                                     const bool &publish)
- {
-     qDebug() << __PRETTY_FUNCTION__;
-     CookieHandler cookieHandler;
-     QString cookie = cookieHandler.formCookie(API_KEY, m_credentials.expires(), m_credentials.userID(),
-                                               m_credentials.sessionKey(), m_credentials.sessionSecret(),
-                                               m_credentials.sig(), EN_LOCALE);
-     QString publishValue;
-     if(publish) {
-         publishValue = PUBLISH_TRUE;
-     }
-     else {
-         publishValue = PUBLISH_FALSE;
-     }
-     QString urlParameters = formUrlParameters(coordinates, status, publishValue);
-     QUrl url = formUrl(SITUARE_URL, UPDATE_LOCATION, urlParameters);
-     sendRequest(url, COOKIE, cookie);
- }
- QUrl SituareService::formUrl(const QString &baseUrl, const QString &phpScript, QString urlParameters)
- {
-     qDebug() << __PRETTY_FUNCTION__;
-     QString urlString;
-     urlString.append(baseUrl);
-     urlString.append(phpScript);
-     if(!urlParameters.isEmpty())
-         urlString.append(urlParameters);
-     QUrl url = QUrl(urlString);
-     qDebug() << url;
-     return url;
- }
- QString SituareService::formUrlParameters(const QPointF &coordinates, QString status, QString publish)
- {
-     QString parameters;
-     parameters.append(QUESTION_MARK);
-     parameters.append(LATITUDE);
-     parameters.append(EQUAL_MARK);
-     parameters.append(QString::number(coordinates.x()));
-     parameters.append(AMBERSAND_MARK);
-     parameters.append(LONGTITUDE);
-     parameters.append(EQUAL_MARK);
-     parameters.append(QString::number(coordinates.y()));
-     if(publish.compare(PUBLISH_TRUE) == 0) {
-         parameters.append(AMBERSAND_MARK);
-         parameters.append(PUBLISH);
-         parameters.append(EQUAL_MARK);
-         parameters.append(PUBLISH_TRUE);
-     }
-     else if(publish.compare(PUBLISH_FALSE) == 0) {
-         parameters.append(AMBERSAND_MARK);
-         parameters.append(PUBLISH);
-         parameters.append(EQUAL_MARK);
-         parameters.append(PUBLISH_FALSE);
-     }
-     if(!status.isEmpty()) {
-         parameters.append(AMBERSAND_MARK);
-         parameters.append(DATA);
-         parameters.append(EQUAL_MARK);
-         parameters.append(status);
-     }
-     return parameters;
- }
- void SituareService::sendRequest(const QUrl &url, const QString &cookieType, const QString &cookie)
- {
-     qDebug() << __PRETTY_FUNCTION__ << "url: " << url;
-     QNetworkRequest request;
-     request.setUrl(url);
-     request.setRawHeader(cookieType.toAscii(), cookie.toUtf8());
-     QNetworkReply *reply = m_networkManager->get(request);
-     m_currentRequests.append(reply);
- }
- void SituareService::requestFinished(QNetworkReply *reply)
- {
-     qDebug() << __PRETTY_FUNCTION__;
-     QUrl url = reply->url();
-     qDebug() << "BytesAvailable: " << reply->bytesAvailable();
-     if (reply->error()) {
-         qDebug() << reply->errorString();
-         emit error(reply->errorString());
-     }
-     else {
-         qint64 max = reply->size();
-         QByteArray replyArray = reply->read(max);
-         qDebug() << "Reply from: " << url << "reply " << replyArray;
-         // ToDo: results handling includes Situare's errors
-         // works like situare's error handling i.e. both lat & lon are missing/wrong
-         // -> we get only error for wrong lon
-         if(replyArray == ERROR_LAT.toAscii()) {
-             qDebug() << "Error: " << ERROR_LAT;
-             emit error(replyArray);
-         }
-         else if(replyArray == ERROR_LON.toAscii()) {
-             qDebug() << "Error: " << ERROR_LON;
-             emit error(replyArray);
-         }
-         else if(replyArray.contains(ERROR_SESSION.toAscii())) {
-             qDebug() << "Error: " << ERROR_SESSION;
-             emit error(replyArray);
-         }
-         else if(replyArray.startsWith(OPENING_BRACE_MARK.toAscii())) {
-             qDebug() << "JSON string";
-             parseUserData(replyArray);
-         }
-         else if(replyArray == "") {
-                       if(url.toString().contains(UPDATE_LOCATION.toAscii())) {
-                 emit updateWasSuccessful();
-             }
-             else {
-                 // server error!
-             }
-         }
-         else {
-             // Street address ready
-             QString address(replyArray);
-             emit reverseGeoReady(address);
-         }
-     }
-     m_currentRequests.removeAll(reply);
-     reply->deleteLater();
- }
- void SituareService::credentialsReady(const FacebookCredentials &credentials)
- {
-     qDebug() << __PRETTY_FUNCTION__;
-     m_credentials = credentials;
-     
- }
- void SituareService::parseUserData(const QByteArray &jsonReply)
- {
-     qDebug() << __PRETTY_FUNCTION__;
-     m_visited = 0;
-     m_nbrOfImages = 0;
-     m_defaultImage = false;
-     qDeleteAll(m_friendsList.begin(), m_friendsList.end());
-     m_friendsList.clear();
-     if(m_user) {
-         delete m_user;
-         m_user = 0;
-     }
-     QJson::Parser parser;
-     bool ok;
-     QVariantMap result = parser.parse (jsonReply, &ok).toMap();
-     if (!ok) {
-         qFatal("An error occurred during parsing");
-         exit (1);
-     }
-     QVariant userVariant = result.value("user");
-     QMap<QString, QVariant> userMap = userVariant.toMap();
-     QPointF coordinates(userMap["longitude"].toReal(), userMap["latitude"].toReal());
-     QUrl imageUrl = userMap["profile_pic"].toUrl();
-     if(imageUrl.isEmpty()) {
-         // user doesn't have profile image, so we need to get him a silhouette image
-         m_defaultImage = true;
-     }
-     m_user = new User(userMap["address"].toString(), coordinates, userMap["name"].toString(),
-                   userMap["note"].toString(), imageUrl, userMap["timestamp"].toString(),
-                   true, userMap["uid"].toString());
-     foreach (QVariant friendsVariant, result["friends"].toList()) {
-       QMap<QString, QVariant> friendMap = friendsVariant.toMap();
-       QVariant distance = friendMap["distance"];
-       QMap<QString, QVariant> distanceMap = distance.toMap();
-       QPointF coordinates(friendMap["longitude"].toReal(), friendMap["latitude"].toReal());
-       QUrl imageUrl = friendMap["profile_pic"].toUrl();
-       if(imageUrl.isEmpty()) {
-           // friend doesn't have profile image, so we need to get him a silhouette image
-           m_defaultImage = true;
-       }
-       User *user = new User(friendMap["address"].toString(), coordinates, friendMap["name"].toString(),
-                             friendMap["note"].toString(), imageUrl, friendMap["timestamp"].toString(),
-                             false, friendMap["uid"].toString(), distanceMap["units"].toString(),
-                             distanceMap["value"].toDouble());
-       m_friendsList.append(user);
-     }
-     addProfileImages();
- }
- void SituareService::imageReceived(const QUrl &url, const QPixmap &image)
- {
-     qDebug() << __PRETTY_FUNCTION__;
-     qDebug() << "Image URL: " << url << " size :" << image.size();
-     // 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(image);
-         }
-         for(int i=0;i < m_friendsList.count();i++) {
-             if(m_friendsList.at(i)->profileImageUrl().isEmpty()) {
-                 m_friendsList.at(i)->setProfileImage(image);
-             }
-         }
-     }
-     if(m_user->profileImageUrl() == url) {
-         m_user->setProfileImage(image);
-     }
-     for(int i=0;i<m_friendsList.count();i++) {
-         if(m_friendsList.at(i)->profileImageUrl() == url) {
-             m_friendsList.at(i)->setProfileImage(image);
-             m_nbrOfImages++; // indicates how many friend profile images has been downloaded
-         }
-     }
-     if(m_nbrOfImages == m_visited) {
-         qDebug() << "m_nbrOfImages: " << m_nbrOfImages << " m_visited: " << m_visited;
-         qDebug() << "emit userDataChanged";
-         emit userDataChanged(m_user, m_friendsList);
-     }
- }
- void SituareService::addProfileImages()
- {
-     qDebug() << __PRETTY_FUNCTION__;
-     // reduce net traffic by sending only one download request for facebook silhouette image
-     if(m_defaultImage) {
-         emit fetchImage(QUrl(SILHOUETTE_URL));
-     }
-     if(!m_user->profileImageUrl().isEmpty() && m_user->profileImageUrl().isValid()) {
-         emit fetchImage(m_user->profileImageUrl());
-     }
-     for(int i=0;i<m_friendsList.count();i++) {
-         if(!m_friendsList.at(i)->profileImageUrl().isEmpty() &&
-            m_friendsList.at(i)->profileImageUrl().isValid()) {
-             m_visited++; // indicates how many friends that have profile image
-             emit fetchImage(m_friendsList.at(i)->profileImageUrl());
-         }
-     }
- }
 -#include <QString>
 -#include <QStringList>
 -#include <QPixmap>
 -#include <QNetworkReply>
 -#include "situareservice.h"
 -#include "situarecommon.h"
 -#include "../cookiehandler/cookiehandler.h"
 -#include "parser.h"
 -
 -SituareService::SituareService(QObject *parent)
 -        : QObject(parent)
 -{
 -    qDebug() << __PRETTY_FUNCTION__;
 -
 -    m_networkManager = new QNetworkAccessManager;
 -    connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), SLOT(requestFinished(QNetworkReply*)));
 -
 -    m_imageFetcher = new ImageFetcher(new QNetworkAccessManager(this), this);
 -    connect(this, SIGNAL(fetchImage(QUrl)), m_imageFetcher, SLOT(fetchImage(QUrl)));
 -    connect(m_imageFetcher, SIGNAL(imageReceived(QUrl,QPixmap)), this,
 -            SLOT(imageReceived(QUrl, QPixmap)));
 -    connect(m_imageFetcher, SIGNAL(error(QString)), this, SIGNAL(error(QString)));
 -
 -    m_user = 0;
 -}
 -
 -SituareService::~SituareService()
 -{
 -    qDebug() << __PRETTY_FUNCTION__;
 -
 -    delete m_networkManager;
 -    m_networkManager = 0;
 -    if(m_user) {
 -        delete m_user;
 -        m_user = 0;
 -    }
 -    delete m_imageFetcher;
 -    m_imageFetcher = 0;
 -
 -    qDeleteAll(m_friendsList.begin(), m_friendsList.end());
 -    m_friendsList.clear();
 -}
 -
 -void SituareService::debugData()
 -{
 -    qWarning() << __PRETTY_FUNCTION__;
 -    QFile file("/home/ramosam-local/situare_debug_data.txt");
 -    qWarning() << __PRETTY_FUNCTION__ << "file size: " << file.size();
 -    qWarning() << __PRETTY_FUNCTION__ << "file open success?" << file.open(QIODevice::ReadOnly);
 -    QByteArray debugReplyArray = file.readAll();
 -    qWarning() << __PRETTY_FUNCTION__ << "did read" << debugReplyArray.size();
 -    parseUserData(debugReplyArray);
 -}
 -
 -void SituareService::fetchLocations()
 -{
 -    qDebug() << __PRETTY_FUNCTION__;
 -
 -    CookieHandler cookieHandler;
 -
 -    QString cookie = cookieHandler.formCookie(API_KEY, m_credentials.expires(), m_credentials.userID(),
 -                                              m_credentials.sessionKey(), m_credentials.sessionSecret(),
 -                                              m_credentials.sig(), EN_LOCALE);
 -
 -    QUrl url = formUrl(SITUARE_URL, GET_LOCATIONS);
 -    sendRequest(url, COOKIE, cookie);
 -}
 -
 -void SituareService::reverseGeo(const QPointF &coordinates)
 -{
 -    qDebug() << __PRETTY_FUNCTION__;
 -
 -    CookieHandler cookieHandler;
 -
 -    QString cookie = cookieHandler.formCookie(API_KEY, m_credentials.expires(), m_credentials.userID(),
 -                                              m_credentials.sessionKey(), m_credentials.sessionSecret(),
 -                                              m_credentials.sig(), EN_LOCALE);
 -
 -    QString urlParameters = formUrlParameters(coordinates);
 -    QUrl url = formUrl(SITUARE_URL, REVERSE_GEO, urlParameters);
 -
 -    sendRequest(url, COOKIE, cookie);
 -}
 -
 -void SituareService::updateLocation(const QPointF &coordinates, const QString &status,
 -                                    const bool &publish)
 -{
 -    qDebug() << __PRETTY_FUNCTION__;
 -
 -    CookieHandler cookieHandler;
 -
 -    QString cookie = cookieHandler.formCookie(API_KEY, m_credentials.expires(), m_credentials.userID(),
 -                                              m_credentials.sessionKey(), m_credentials.sessionSecret(),
 -                                              m_credentials.sig(), EN_LOCALE);
 -
 -
 -    QString publishValue;
 -    if(publish) {
 -        publishValue = PUBLISH_TRUE;
 -    }
 -    else {
 -        publishValue = PUBLISH_FALSE;
 -    }
 -    QString urlParameters = formUrlParameters(coordinates, status, publishValue);
 -    QUrl url = formUrl(SITUARE_URL, UPDATE_LOCATION, urlParameters);
 -
 -    sendRequest(url, COOKIE, cookie);
 -}
 -
 -QUrl SituareService::formUrl(const QString &baseUrl, const QString &phpScript, QString urlParameters)
 -{
 -    qDebug() << __PRETTY_FUNCTION__;
 -    QString urlString;
 -
 -    urlString.append(baseUrl);
 -    urlString.append(phpScript);
 -    if(!urlParameters.isEmpty())
 -        urlString.append(urlParameters);
 -
 -    QUrl url = QUrl(urlString);
 -
 -    qDebug() << url;
 -
 -    return url;
 -}
 -
 -QString SituareService::formUrlParameters(const QPointF &coordinates, QString status, QString publish)
 -{
 -    QString parameters;
 -
 -    parameters.append(QUESTION_MARK);
 -    parameters.append(LATITUDE);
 -    parameters.append(EQUAL_MARK);
 -    parameters.append(QString::number(coordinates.x()));
 -    parameters.append(AMBERSAND_MARK);
 -    parameters.append(LONGTITUDE);
 -    parameters.append(EQUAL_MARK);
 -    parameters.append(QString::number(coordinates.y()));
 -
 -    if(publish.compare(PUBLISH_TRUE) == 0) {
 -        parameters.append(AMBERSAND_MARK);
 -        parameters.append(PUBLISH);
 -        parameters.append(EQUAL_MARK);
 -        parameters.append(PUBLISH_TRUE);
 -    }
 -    else if(publish.compare(PUBLISH_FALSE) == 0) {
 -        parameters.append(AMBERSAND_MARK);
 -        parameters.append(PUBLISH);
 -        parameters.append(EQUAL_MARK);
 -        parameters.append(PUBLISH_FALSE);
 -    }
 -
 -    if(!status.isEmpty()) {
 -        parameters.append(AMBERSAND_MARK);
 -        parameters.append(DATA);
 -        parameters.append(EQUAL_MARK);
 -        parameters.append(status);
 -    }
 -
 -    return parameters;
 -}
 -
 -void SituareService::sendRequest(const QUrl &url, const QString &cookieType, const QString &cookie)
 -{
 -    qDebug() << __PRETTY_FUNCTION__ << "url: " << url;
 -
 -    QNetworkRequest request;
 -
 -    request.setUrl(url);
 -    request.setRawHeader(cookieType.toAscii(), cookie.toUtf8());
 -
 -    QNetworkReply *reply = m_networkManager->get(request);
 -
 -    m_currentRequests.append(reply);
 -}
 -
 -void SituareService::requestFinished(QNetworkReply *reply)
 -{
 -    qDebug() << __PRETTY_FUNCTION__;
 -
 -    QUrl url = reply->url();
 -    qDebug() << "BytesAvailable: " << reply->bytesAvailable();
 -    if (reply->error()) {
 -        qDebug() << reply->errorString();
 -        emit error(reply->errorString());
 -    }
 -    else {
 -        qint64 max = reply->size();
 -        QByteArray replyArray = reply->read(max);
 -        qDebug() << "Reply from: " << url << "reply " << replyArray;
 -        // ToDo: results handling includes Situare's errors
 -        // works like situare's error handling i.e. both lat & lon are missing/wrong
 -        // -> we get only error for wrong lon
 -        if(replyArray == ERROR_LAT.toAscii()) {
 -            qDebug() << "Error: " << ERROR_LAT;
 -            emit error(replyArray);
 -        }
 -        else if(replyArray == ERROR_LON.toAscii()) {
 -            qDebug() << "Error: " << ERROR_LON;
 -            emit error(replyArray);
 -        }
 -        else if(replyArray.contains(ERROR_SESSION.toAscii())) {
 -            qDebug() << "Error: " << ERROR_SESSION;
 -            emit error(replyArray);
 -        }
 -        else if(replyArray.startsWith(OPENING_BRACE_MARK.toAscii())) {
 -            qDebug() << "JSON string";
 -            parseUserData(replyArray);
 -        }
 -        else if(replyArray == "") {
 -            qDebug() << "No error, update was successful";
 -            emit updateWasSuccessful();
 -        }
 -        else {
 -            // Street address ready
 -            QString address(replyArray);
 -            emit reverseGeoReady(address);
 -        }
 -    }
 -    m_currentRequests.removeAll(reply);
 -    reply->deleteLater();
 -}
 -
 -void SituareService::credentialsReady(const FacebookCredentials &credentials)
 -{
 -    qDebug() << __PRETTY_FUNCTION__;
 -    m_credentials = credentials;
 -    
 -}
 -
 -void SituareService::parseUserData(const QByteArray &jsonReply)
 -{
 -    qDebug() << __PRETTY_FUNCTION__;
 -
 -    m_visited = 0;
 -    m_nbrOfImages = 0;
 -    m_defaultImage = false;
 -    qDeleteAll(m_friendsList.begin(), m_friendsList.end());
 -    m_friendsList.clear();
 -
 -    if(m_user) {
 -        delete m_user;
 -        m_user = 0;
 -    }
 -
 -    QJson::Parser parser;
 -    bool ok;
 -
 -    QVariantMap result = parser.parse (jsonReply, &ok).toMap();
 -    if (!ok) {
 -
 -        qFatal("An error occurred during parsing");
 -        exit (1);
 -    }
 -
 -    QVariant userVariant = result.value("user");
 -    QMap<QString, QVariant> userMap = userVariant.toMap();
 -
 -    QPointF coordinates(userMap["longitude"].toReal(), userMap["latitude"].toReal());
 -
 -    QUrl imageUrl = userMap["profile_pic"].toUrl();
 -
 -    if(imageUrl.isEmpty()) {
 -        // user doesn't have profile image, so we need to get him a silhouette image
 -        m_defaultImage = true;
 -    }
 -
 -    m_user = new User(userMap["address"].toString(), coordinates, userMap["name"].toString(),
 -                  userMap["note"].toString(), imageUrl, userMap["timestamp"].toString(),
 -                  true, userMap["uid"].toString());
 -
 -    foreach (QVariant friendsVariant, result["friends"].toList()) {
 -      QMap<QString, QVariant> friendMap = friendsVariant.toMap();
 -      QVariant distance = friendMap["distance"];
 -      QMap<QString, QVariant> distanceMap = distance.toMap();
 -
 -      QPointF coordinates(friendMap["longitude"].toReal(), friendMap["latitude"].toReal());
 -
 -      QUrl imageUrl = friendMap["profile_pic"].toUrl();
 -
 -      if(imageUrl.isEmpty()) {
 -          // friend doesn't have profile image, so we need to get him a silhouette image
 -          m_defaultImage = true;
 -      }
 -
 -      User *user = new User(friendMap["address"].toString(), coordinates, friendMap["name"].toString(),
 -                            friendMap["note"].toString(), imageUrl, friendMap["timestamp"].toString(),
 -                            false, friendMap["uid"].toString(), distanceMap["units"].toString(),
 -                            distanceMap["value"].toDouble());
 -
 -      m_friendsList.append(user);
 -    }
 -    addProfileImages();
 -}
 -
 -void SituareService::imageReceived(const QUrl &url, const QPixmap &image)
 -{
 -    qDebug() << __PRETTY_FUNCTION__;
 -    qDebug() << "Image URL: " << url << " size :" << image.size();
 -
 -    // 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(image);
 -        }
 -        for(int i=0;i < m_friendsList.count();i++) {
 -            if(m_friendsList.at(i)->profileImageUrl().isEmpty()) {
 -                m_friendsList.at(i)->setProfileImage(image);
 -            }
 -        }
 -    }
 -
 -    if(m_user->profileImageUrl() == url) {
 -        m_user->setProfileImage(image);
 -    }
 -
 -    for(int i=0;i<m_friendsList.count();i++) {
 -        if(m_friendsList.at(i)->profileImageUrl() == url) {
 -            m_friendsList.at(i)->setProfileImage(image);
 -            m_nbrOfImages++; // indicates how many friend profile images has been downloaded
 -        }
 -    }
 -
 -    if(m_nbrOfImages == m_visited) {
 -        qDebug() << "m_nbrOfImages: " << m_nbrOfImages << " m_visited: " << m_visited;
 -        qDebug() << "emit userDataChanged";
 -        emit userDataChanged(m_user, m_friendsList);
 -    }
 -}
 -
 -void SituareService::addProfileImages()
 -{
 -    qDebug() << __PRETTY_FUNCTION__;
 -
 -    // reduce net traffic by sending only one download request for facebook silhouette image
 -    if(m_defaultImage) {
 -        emit fetchImage(QUrl(SILHOUETTE_URL));
 -    }
 -
 -    if(!m_user->profileImageUrl().isEmpty() && m_user->profileImageUrl().isValid()) {
 -        emit fetchImage(m_user->profileImageUrl());
 -    }
 -
 -    for(int i=0;i<m_friendsList.count();i++) {
 -        if(!m_friendsList.at(i)->profileImageUrl().isEmpty() &&
 -           m_friendsList.at(i)->profileImageUrl().isValid()) {
 -            m_visited++; // indicates how many friends that have profile image
 -            emit fetchImage(m_friendsList.at(i)->profileImageUrl());
 -        }
 -    }
 -}
diff --cc src/situareservice/situareservice.h
index 605dfe9,2594877..0000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,218 -1,220 +1,0 @@@
--/*
--   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 SITUARESERVICE_H
--#define SITUARESERVICE_H
--
--#include <QObject>
--#include "../facebookservice/facebookcredentials.h"
--#include "../user/user.h"
--#include "imagefetcher.h"
--
--class QNetworkAccessManager;
--class QNetworkReply;
--class QNetworkRequest;
--class QPointF;
--class QUrl;
--
--/**
--* @brief SituareService class for communicating with Situare server
--*
--* @author Henri Lampela
--* @class SituareService situareservice.h "situareservice/situareservice.h"
--*/
--class SituareService : public QObject
--{
--    Q_OBJECT
--
--public:
--
--    /**
--    * @brief Default constructor
--    *
--    * @param parent instance of parent
--    */
--    SituareService(QObject *parent = 0);
--
--    /**
--    * @brief Destructor
--    *
--    */
--    ~SituareService();
--
--/*******************************************************************************
-- * MEMBER FUNCTIONS AND SLOTS
-- ******************************************************************************/
--
-     /**
-     * @brief Retrieves location user and friends information from Situare server
-     *
-     */
-     void fetchLocations();
-     /**
-     * @brief Translates coordinates to street address via Situare server
-     *
-     * @param coordinates coordinates to be translated
-     */
-     void reverseGeo(const QPointF &coordinates);
-     /**
-     * @brief Updates location to the Situare server
-     *
-     * @param coordinates current cordinates
-     * @param status message
-     * @param publish publish location on Facebook wall (true/false)
-     */
-     void updateLocation(const QPointF &coordinates, const QString &status, const bool &publish);
- public slots:
-     /**
-     * @brief Public slot, which indicates when http request has been completed
-     *
-     * @param reply storage for http reply
-     */
-     void requestFinished(QNetworkReply *reply);
-     /**
-     * @brief Public slot, which indicates when facebook credentials are ready
-     *
-     * @param credentials New credentials
-     */
-     void credentialsReady(const FacebookCredentials &credentials);
- private:
-     /**
-     * @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 = 0);
-     /**
-     * @brief Forms url parameters
-     *
-     * @param coordinates current coordinates
-     * @param status optional status message
-     * @param publish optional publish location on Facebook wall (true/false)
-     * @return QString
-     */
-     QString formUrlParameters(const QPointF &coordinates, QString status = 0, QString publish = 0);
-     /**
-     * @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 Requests ImageFetcher if user/friend has a profile image
-     *        uses members: m_user and m_friendsList
-     *
-     */
-     void addProfileImages();
- private slots:
-     /**
-     * @brief Slot for received images
-     *
-     * @param url Image url
-     * @param image Received image
-     */
-     void imageReceived(const QUrl &url, const QPixmap &image);
- /*******************************************************************************
-  * SIGNALS
-  ******************************************************************************/
- signals:
-     /**
-     * @brief Signals error
-     *
-     * @param error error message
-     */
-     void error(const QString &error);
-     /**
-     * @brief Signal for image fetching
-     *
-     * @param url Image url
-     */
-     void fetchImage(const QUrl &url);
-     /**
-     * @brief Signals when address data is retrieved
-     *
-     * @param address Street address
-     */
-     void reverseGeoReady(const QString &address);
-     /**
-     * @brief Signals when updateLocation request finished successfully
-     *
-     */
-     void updateWasSuccessful();
-     /**
-     * @brief Signals when user data is retrieved
-     *
-     * @param user instance of user
-     * @param friendList list of friends
-     */
-     void userDataChanged(User *user, QList<User *> &friendList);
- /*******************************************************************************
-  * DATA MEMBERS
-  ******************************************************************************/
- private:
-     FacebookCredentials m_credentials; ///< handle for FacebookCredentials
-     QList<QNetworkReply *> m_currentRequests; ///< List of current http requests
-     QNetworkAccessManager *m_networkManager; ///< Pointer to QNetworkAccessManager
-     ImageFetcher *m_imageFetcher; ///< Instance of the image fetcher
-     User *m_user; ///< Pointer to User
-     QList<User *> m_friendsList; ///< List of friends(User)
-     int m_visited; ///< Indicates number of friends with profile images
-     int m_nbrOfImages; ///< Indicates number of friends whose profile images have been downloaded
-     bool m_defaultImage; ///< Indicates if some of the friends or the user does not have a profile image
- };
- #endif // SITUARESERVICE_H
 -    void debugData();
 -
 -    /**
 -    * @brief Retrieves location user and friends information from Situare server
 -    *
 -    */
 -    void fetchLocations();
 -
 -    /**
 -    * @brief Translates coordinates to street address via Situare server
 -    *
 -    * @param coordinates coordinates to be translated
 -    */
 -    void reverseGeo(const QPointF &coordinates);
 -
 -    /**
 -    * @brief Updates location to the Situare server
 -    *
 -    * @param coordinates current cordinates
 -    * @param status message
 -    * @param publish publish location on Facebook wall (true/false)
 -    */
 -    void updateLocation(const QPointF &coordinates, const QString &status, const bool &publish);
 -
 -public slots:
 -
 -    /**
 -    * @brief Public slot, which indicates when http request has been completed
 -    *
 -    * @param reply storage for http reply
 -    */
 -    void requestFinished(QNetworkReply *reply);
 -
 -    /**
 -    * @brief Public slot, which indicates when facebook credentials are ready
 -    *
 -    * @param credentials New credentials
 -    */
 -    void credentialsReady(const FacebookCredentials &credentials);
 -
 -private:
 -
 -    /**
 -    * @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 Forms url parameters
 -    *
 -    * @param coordinates current coordinates
 -    * @param status optional status message
 -    * @param publish optional publish location on Facebook wall (true/false)
 -    * @return QString
 -    */
 -    QString formUrlParameters(const QPointF &coordinates, QString status = QString(), QString publish = QString());
 -
 -    /**
 -    * @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 Requests ImageFetcher if user/friend has a profile image
 -    *        uses members: m_user and m_friendsList
 -    *
 -    */
 -    void addProfileImages();
 -
 -private slots:
 -
 -    /**
 -    * @brief Slot for received images
 -    *
 -    * @param url Image url
 -    * @param image Received image
 -    */
 -    void imageReceived(const QUrl &url, const QPixmap &image);
 -
 -/*******************************************************************************
 - * SIGNALS
 - ******************************************************************************/
 -
 -signals:
 -
 -    /**
 -    * @brief Signals error
 -    *
 -    * @param error error message
 -    */
 -    void error(const QString &error);
 -
 -    /**
 -    * @brief Signal for image fetching
 -    *
 -    * @param url Image url
 -    */
 -    void fetchImage(const QUrl &url);
 -
 -    /**
 -    * @brief Signals when address data is retrieved
 -    *
 -    * @param address Street address
 -    */
 -    void reverseGeoReady(const QString &address);
 -
 -    /**
 -    * @brief Signals when updateLocation request finished successfully
 -    *
 -    */
 -    void updateWasSuccessful();
 -
 -    /**
 -    * @brief Signals when user data is retrieved
 -    *
 -    * @param user instance of user
 -    * @param friendList list of friends
 -    */
 -    void userDataChanged(User *user, QList<User *> &friendList);
 -
 -/*******************************************************************************
 - * DATA MEMBERS
 - ******************************************************************************/
 -
 -private:
 -
 -    FacebookCredentials m_credentials; ///< handle for FacebookCredentials
 -    QList<QNetworkReply *> m_currentRequests; ///< List of current http requests
 -    QNetworkAccessManager *m_networkManager; ///< Pointer to QNetworkAccessManager
 -    ImageFetcher *m_imageFetcher; ///< Instance of the image fetcher
 -
 -    User *m_user; ///< Pointer to User
 -    QList<User *> m_friendsList; ///< List of friends(User)
 -    int m_visited; ///< Indicates number of friends with profile images
 -    int m_nbrOfImages; ///< Indicates number of friends whose profile images have been downloaded
 -    bool m_defaultImage; ///< Indicates if some of the friends or the user does not have a profile image
 -};
 -
 -#endif // SITUARESERVICE_H
diff --cc src/src.pro
@@@ -32,16 -32,13 +32,18 @@@ SOURCES += main.cpp 
      ui/friendlistview.cpp \
      ui/friendlistitem.cpp \
      user/user.cpp \
 -    ui/situareuser.cpp \
 +    ui/avatarimage.cpp \
      engine/engine.cpp \
      ui/settingsdialog.cpp \
 +    ui/logindialog.cpp \
      map/maptilerequest.cpp \
      ui/imagebutton.cpp \
 +    ui/friendlistpanel.cpp \
 +    ui/userpanel.cpp \
 +    ui/panelsidebar.cpp \
-     ui/panelsliderbar.cpp
++    ui/panelsliderbar.cpp \
+     map/friendgroupitem.cpp \
+     map/frienditemshandler.cpp
  HEADERS += ui/mainwindow.h \
      ui/mapviewscreen.h \
      ui/listviewscreen.h \
      ui/friendlistview.h \
      ui/friendlistitem.h \
      user/user.h \
 -    ui/situareuser.h \
 +    ui/avatarimage.h \
      engine/engine.h \
      ui/settingsdialog.h \
 +    ui/logindialog.h \
      map/maptilerequest.h \
      ui/imagebutton.h \
 +    ui/friendlistpanel.h \
 +    ui/userpanel.h \
 +    ui/panelcommon.h \
 +    ui/panelsidebar.h \
-     ui/panelsliderbar.h
++    ui/panelsliderbar.h \
+     map/friendgroupitem.h \
+     map/frienditemshandler.h
  QT += network \
      webkit
 +
  DEFINES += QT_NO_DEBUG_OUTPUT
  
 -!maemo5 { 
 +!maemo5 {
      message(QJson built in)
      message(Make sure you have QJson development headers installed)
      message(install headers with: sudo apt-get install libqjson-dev)
@@@ -50,14 -49,14 +50,14 @@@ MainWindow::MainWindow(QWidget *parent
              SIGNAL(statusUpdate(QString,bool)));
  
      connect(this, SIGNAL(userLocationReady(User*)),
-             m_mapViewScreen, SLOT(userLocationReady(User*)));
+             m_mapViewScreen, SIGNAL(userLocationReady(User*)));
      connect(this, SIGNAL(friendsLocationsReady(QList<User*>&)),
-             m_mapViewScreen, SLOT(friendsLocationsReady(QList<User*>&)));
+             m_mapViewScreen, SIGNAL(friendsLocationsReady(QList<User*>&)));
  
 -    connect(this, SIGNAL(userLocationReady(User*)), m_listViewScreen,
 -            SLOT(userDataReceived(User*)));
 -    connect(this, SIGNAL(friendsLocationsReady(QList<User*>&)), m_listViewScreen,
 -            SLOT(friendInfoReceived(QList<User*>&)));
 +    connect(this, SIGNAL(userLocationReady(User*)),
 +            m_listViewScreen, SLOT(userDataReceived(User*)));
 +    connect(this, SIGNAL(friendsLocationsReady(QList<User*>&)),
 +            m_listViewScreen, SLOT(friendInfoReceived(QList<User*>&)));
      connect(m_listViewScreen, SIGNAL(updateFriendsData()),
              this, SIGNAL(refreshUserData()));
  
@@@ -37,39 -32,39 +37,43 @@@ MapViewScreen::MapViewScreen(QWidget *p
      mapEngine = new MapEngine(this);
      mapView->setScene(mapEngine->scene());
  
 -    connect(mapView, SIGNAL(viewScrolled(QPoint)), mapEngine, SLOT(setLocation(QPoint)));
 +    FriendListPanel *friendsListPanel = new FriendListPanel(this);
 +    UserInfoPanel *userPanel = new UserInfoPanel(this);
 +    PanelSideBar *userPanelSidebar = new PanelSideBar(this, LEFT);
 +    PanelSideBar *friendsListPanelSidebar = new PanelSideBar(this, RIGHT);
 +
 +    connect(mapView, SIGNAL(viewScrolled(QPoint)),
 +            mapEngine, SLOT(setLocation(QPoint)));
      connect(mapEngine, SIGNAL(locationChanged(QPoint)),
              mapView, SLOT(centerToSceneCoordinates(QPoint)));
 -    connect(mapEngine, SIGNAL(zoomLevelChanged(int)), mapView, SLOT(setZoomLevel(int)));
 -    connect(mapView, SIGNAL(viewResized(QSize)), mapEngine, SLOT(viewResized(QSize)));
 +    connect(mapEngine, SIGNAL(zoomLevelChanged(int)),
 +            mapView, SLOT(setZoomLevel(int)));
 +    connect(mapView, SIGNAL(viewResized(QSize)),
 +            mapEngine, SLOT(viewResized(QSize)));
      connect(mapView, SIGNAL(viewContentChanged(QPoint)),
              mapEngine, SLOT(alignImmovableItems(QPoint)));
 -    connect(mapView, SIGNAL(viewZoomFinished()), mapEngine, SLOT(viewZoomFinished()));
 +    connect(mapView, SIGNAL(viewZoomFinished()),
 +            mapEngine, SLOT(viewZoomFinished()));
 +
      connect(mapView, SIGNAL(viewResizedNewSize(int,int)),
              this, SLOT(drawOsmLicense(int, int)));
 +
 +    connect(mapView, SIGNAL(viewResizedNewSize(int,int)),
 +            friendsListPanel, SLOT(reDrawFriendsPanel(int,int)));
 +    connect(mapView, SIGNAL(viewResizedNewSize(int,int)),
 +            userPanel, SLOT(reDrawUserPanel(int,int)));
 +    connect(mapView, SIGNAL(viewResizedNewSize(int,int)),
 +            friendsListPanelSidebar, SLOT(reDrawSidebar(int,int)));
 +
-     connect(this, SIGNAL(SIG_friendsLocationsReady(QList<User*>&)),
++    connect(this, SIGNAL(friendsLocationsReady(QList<User*>&)),
 +            friendsListPanel, SLOT(friendInfoReceived(QList<User*>&)));
 +
+     connect(this, SIGNAL(userLocationReady(User*)),
+             mapEngine, SLOT(receiveOwnLocation(User*)));
+     connect(this, SIGNAL(friendsLocationsReady(QList<User*>&)),
+             mapEngine, SIGNAL(friendsLocationsReady(QList<User*>&)));
  
      QHBoxLayout *mapViewLayout = new QHBoxLayout;
 -    //DEBUG
 -//    QVBoxLayout *mapControlLayout = new QVBoxLayout;
 -//    QWidget *mapControl = new QWidget(this);
 -//    mapControl->setLayout(mapControlLayout);
 -//    search = new QPushButton("Search", this);
 -//    zoomOut = new QPushButton("-", this);
 -//    zoomIn = new QPushButton("+", this);
 -//    mapControlLayout->addWidget(&latLine);
 -//    mapControlLayout->addWidget(&lonLine);
 -//    mapControlLayout->addWidget(search);
 -//    mapControlLayout->addWidget(zoomIn);
 -//    mapControlLayout->addWidget(zoomOut);
 -//    mapViewLayout->addWidget(mapControl);
 -//    connect(search, SIGNAL(clicked()), this, SLOT(searchMap()));
 -//    connect(zoomIn, SIGNAL(clicked()), mapEngine, SLOT(zoomIn()));
 -//    connect(zoomOut, SIGNAL(clicked()), mapEngine, SLOT(zoomOut()));
 -    //DEBUG
  
      osmLicense = new QLabel(this);
      osmLicense->setAttribute(Qt::WA_TranslucentBackground, true);
      setObjectName("Map view");
  }
  
--void MapViewScreen::searchMap()
--{
--    qreal lat = latLine.text().toFloat();
--    qreal lon = lonLine.text().toFloat();
--
--    qDebug() << lat << "," << lon;
--
--    mapEngine->setViewLocation(QPointF(lon, lat));
--}
--
- void MapViewScreen::userLocationReady(User *user)
- {
-     qDebug() << __PRETTY_FUNCTION__;
-     mapEngine->receiveOwnLocation(user);
- }
- void MapViewScreen::friendsLocationsReady(QList<User *> &friendsList)
- {
-     qDebug() << __PRETTY_FUNCTION__;
-     mapEngine->receiveFriendLocations(friendsList);
- }
  void MapViewScreen::drawOsmLicense(int width, int height)
  {
      qDebug() << __PRETTY_FUNCTION__ << width << "x" << height;
@@@ -52,25 -50,11 +52,6 @@@ public
  
  private slots:
      /**
--    * @brief Debug method for centering to given coordinates
--    */
--    void searchMap();
-     
-     /**
-     * @brief Slot to catch signal when user location is fetched
-     *
-     * @param user User data
-     */
-     void userLocationReady(User *user);
--
--    /**
-     * @brief Slot to catch signal when friend list locations are fetched
-     *
-     * @param friendsList Friends list data
-     */
-     void friendsLocationsReady(QList<User *> &friendsList);
-     /**
      * @brief Slot for drawing the Open Street Map license text
      *
      * @param width Width of the viewport
   ******************************************************************************/
  signals:
      /**
-     * @brief Forwarding signal for friends list refresh in the friends list panel
+     * @brief Signal when user location is fetched
      *
-     * @param friendsList
+     * @param user User data
      */
-     void SIG_friendsLocationsReady(QList<User *> &friendsList);
+     void userLocationReady(User *user);
+     /**
+     * @brief Signal when friend list locations are fetched
+     *
++    * Forwarded to map engine and friends list panel
++    *
+     * @param friendsList Friends list data
+     */
+     void friendsLocationsReady(QList<User *> &friendsList);
  
  /*******************************************************************************
   * DATA MEMBERS
   ******************************************************************************/
 +
  private:
 +    FriendListPanel *friendsListPanel; ///< Instance of friends list panel
-     UserInfoPanel *userPanel; ///< Instance of the user information panel
      MapEngine *mapEngine; ///< MapEngine
--    //DEBUG
      QLabel *osmLicense; ///< Label for Open Street Map license
--    QPushButton *zoomIn; ///< Debug button for zooming in
--    QPushButton *zoomOut; ///< Debug button for zooming out
--    QLineEdit latLine; ///< Debug input field for latitude
--    QLineEdit lonLine; ///< Debug input field for longitude
--    QPushButton *search; ///< Debug button for centering to given coordinates
++    UserInfoPanel *userPanel; ///< Instance of the user information panel
  };
  
  #endif // MAPVIEWTAB_H