#include "friendgroupitem.h"
#include "friendlocationitem.h"
+#include "mapcommon.h"
#include "mapengine.h"
#include "mapscene.h"
#include "user/user.h"
FriendItemsHandler::FriendItemsHandler(MapScene *mapScene, QObject *parent)
: QObject(parent),
- m_mapScene(mapScene)
+ m_mapScene(mapScene),
+ m_zoomLevel(0)
{
+ qDebug() << __PRETTY_FUNCTION__;
}
-FriendItemsHandler::~FriendItemsHandler()
+void FriendItemsHandler::addFriendItem(User *friendData)
{
- qDeleteAll(m_friendItems.begin(),m_friendItems.end());
- m_friendItems.clear();
+ qDebug() << __PRETTY_FUNCTION__;
+
+ FriendLocationItem *item = new FriendLocationItem(friendData->userId());
+
+ item->setProfileImage(friendData->profileImage(), friendData->profileImageUrl());
+ item->setPos(MapEngine::convertLatLonToSceneCoordinate(friendData->coordinates()));
+ m_friendItems.append(item);
+ m_mapScene->addItem(item);
+
+ connect(item, SIGNAL(locationItemClicked(QList<QString>)),
+ this, SIGNAL(locationItemClicked(QList<QString>)));
}
void FriendItemsHandler::checkAllFriendsForCollidingFriends()
{
- qWarning() << __PRETTY_FUNCTION__;
+ qDebug() << __PRETTY_FUNCTION__;
- QLinkedList<FriendLocationItem *>::iterator i = m_friendItems.begin();
- while (i != m_friendItems.end()) {
- checkFriendForCollidingFriends(*i);
- i++;
+ QLinkedList<FriendLocationItem *>::iterator iter = m_friendItems.begin();
+ while (iter != m_friendItems.end()) {
+ // check only friends which are not part of group already
+ if (!(*iter)->isPartOfGroup()) {
+ checkFriendForCollidingFriends(*iter);
+ }
+ iter++;
}
-
-// foreach(FriendGroupItem *item, m_friendGroupItems) {
-// m_friendGroupItems.removeAll(item);
-// m_mapScene->removeItem(item);
-// }
-
-// int lastItem = m_friendItems.size() - 1;
-// for (int checking = 0; checking <= lastItem; checking++) {
-// QRect beginItemRect = m_friendItems.at(checking)->sceneTransformedBoundingRect(m_zoomLevel);
-
-// // don't check items which are already part of a group (and thus unvisible)
-// if (m_friendItems.at(checking)->isPartOfGroup())
-// continue;
-
-// // check all other items
-// for (int another = 0; another <= lastItem; another++)
-// {
-// // don't check against itself
-// if (checking == another)
-// continue;
-
-// // don't check against items which are already part of a group (and thus unvisible)
-// if (m_friendItems.at(another)->isPartOfGroup())
-// continue;
-
-// // does items collide
-// QRect iterItemRect = m_friendItems.at(another)->sceneTransformedBoundingRect(m_zoomLevel);
-// if (beginItemRect.intersects(iterItemRect)) {
-// qWarning() << __PRETTY_FUNCTION__ << "collision found" << checking << another;
-// FriendGroupItem *group = new FriendGroupItem();
-// m_friendGroupItems.append(group);
-// group->setPos(m_friendItems.at(checking)->pos());
-// group->joinFriend(m_friendItems.at(checking));
-// group->joinFriend(m_friendItems.at(another));
-// m_mapScene->addItem(group);
-// break;
-// }
-// }
-// }
}
void FriendItemsHandler::checkAllGroupsForCollidingFriends()
{
- // check against colliding friends
- // join friends to group
- /// @todo IMPLEMENT
+ qDebug() << __PRETTY_FUNCTION__;
+
+ // loop through all groups
+ QLinkedList<FriendGroupItem *>::iterator iter = m_friendGroupItems.begin();
+ while (iter != m_friendGroupItems.end()) {
+ checkGroupForCollidingFriends(*iter);
+ iter++;
+ }
}
void FriendItemsHandler::checkFriendForCollidingFriends(FriendLocationItem *item)
qDebug() << __PRETTY_FUNCTION__;
FriendGroupItem *group = 0;
- QRect itemSceneRect = item->sceneTransformedBoundingRect(m_zoomLevel);
// loop through all friend items
- QLinkedList<FriendLocationItem *>::iterator i = m_friendItems.begin();
- while (i != m_friendItems.end()) {
+ QLinkedList<FriendLocationItem *>::iterator iter = m_friendItems.begin();
+ while (iter != m_friendItems.end()) {
// but don't check myself and friends which are already part of a group
- if (item != *i && !(*i)->isPartOfGroup()) {
- if (itemSceneRect.intersects((*i)->sceneTransformedBoundingRect(m_zoomLevel))) {
+ if (item != *iter && !(*iter)->isPartOfGroup()) {
+ if (collides(item, *iter)) {
if (!group) {
group = new FriendGroupItem(item);
m_mapScene->addItem(group);
m_friendGroupItems.append(group);
+
+ connect(group, SIGNAL(locationItemClicked(QList<QString>)),
+ this, SIGNAL(locationItemClicked(QList<QString>)));
}
- group->joinFriend(*i);
+ group->joinFriend(*iter);
}
}
- i++;
+ iter++;
}
}
-void FriendItemsHandler::checkGroupForCollidingGroups(FriendGroupItem *group)
+void FriendItemsHandler::checkGroupForCollidingFriends(FriendGroupItem *group)
{
qDebug() << __PRETTY_FUNCTION__;
- QRect groupSceneRect = group->sceneTransformedBoundingRect(m_zoomLevel);
-
// loop through all friend items
- QLinkedList<FriendGroupItem *>::iterator i = m_friendGroupItems.begin();
- while (i != m_friendGroupItems.end()) {
- // but don't check myself
- if (group != *i) {
- if (groupSceneRect.intersects((*i)->sceneTransformedBoundingRect(m_zoomLevel))) {
- /// @todo MERGE GROUP i TO group
- /// get other group friends, remove from scene and list, delete
+ QLinkedList<FriendLocationItem *>::iterator iter = m_friendItems.begin();
+ while (iter != m_friendItems.end()) {
+ // but don't check friends which are already part of a group
+ if (!(*iter)->isPartOfGroup()) {
+ if (collides(group, *iter)) {
+ group->joinFriend(*iter);
}
}
- i++;
+ iter++;
}
}
-void FriendItemsHandler::mergeCollidingGroups()
+void FriendItemsHandler::checkGroupForCollidingGroups(FriendGroupItem *group)
{
+ qDebug() << __PRETTY_FUNCTION__;
+
// loop through all groups
+ QLinkedList<FriendGroupItem *>::iterator iter = m_friendGroupItems.begin();
+ while (iter != m_friendGroupItems.end()) {
+ // but don't check myself
+ if (group != *iter) {
+ if (collides(group, *iter)) {
+ (*iter)->mergeWithGroup(group);
+ m_mapScene->removeItem(*iter);
+ delete *iter;
+ iter = m_friendGroupItems.erase(iter);
+ }
+ else {
+ iter++;
+ }
+ }
+ else {
+ iter++;
+ }
+ }
+}
- // merge groups
+bool FriendItemsHandler::collides(BaseLocationItem *item1, BaseLocationItem *item2)
+{
+ QRect rect = item1->sceneTransformedBoundingRect(m_zoomLevel);
+
+ if (rect.intersects(item2->sceneTransformedBoundingRect(m_zoomLevel)))
+ return true;
- /// @todo IMPLEMENT
+ if (rect.left() < MAP_MIN_PIXEL_X) {
+ QRect translated = rect.translated(MAP_PIXELS_X, 0);
+ if (translated.intersects(item2->sceneTransformedBoundingRect(m_zoomLevel)))
+ return true;
+ }
+
+ if (rect.right() > MAP_MAX_PIXEL_X) {
+ QRect translated = rect.translated(-MAP_PIXELS_X, 0);
+ if (translated.intersects(item2->sceneTransformedBoundingRect(m_zoomLevel)))
+ return true;
+ }
+
+ return false;
}
-void FriendItemsHandler::cleanOldFriendData(const QList<User *> &friendsList)
+void FriendItemsHandler::deleteFriendItem(FriendLocationItem *item)
{
- // loop through all m_friendItem items
- QLinkedList<FriendLocationItem *>::iterator i = m_friendItems.begin();
- while (i != m_friendItems.end()) {
- bool friendFound = false;
-
- // check against each item in the friendsList
- QList<User *>::const_iterator j;
- for (j = friendsList.begin(); j != friendsList.end(); j++) {
- if ((**i).userId() == (**j).userId()) {
- friendFound = true;
- break;
- }
- }
+ qDebug() << __PRETTY_FUNCTION__;
- if (!friendFound) {
- m_mapScene->removeItem(*i);
- i = m_friendItems.erase(i);
- }
- else {
- i++;
- }
+ dropFriendFromAllGroups(item);
+ m_mapScene->removeItem(item);
+ delete item;
+}
+
+void FriendItemsHandler::dropFriendFromAllGroups(FriendLocationItem *item)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ foreach (FriendGroupItem *group, m_friendGroupItems) {
+ group->dropFriend(item);
}
}
void FriendItemsHandler::dropOutOfGroupFriends()
{
+ qDebug() << __PRETTY_FUNCTION__;
+
// loop through all group items and drop friends which doesn't collide anymore
// delete group if possible
foreach (FriendGroupItem *group, m_friendGroupItems) {
}
}
-void FriendItemsHandler::receiveFriendLocations(QList<User *> &friendsList)
+void FriendItemsHandler::friendListUpdated(QList<User *> &friendsList)
{
- qWarning() << __PRETTY_FUNCTION__;
+ qDebug() << __PRETTY_FUNCTION__;
- static int receiveFriendsLocationsCounter = 0;
+ // loop through friend items and find matching friend data. If matching data
+ // is not found then remove item
+ QLinkedList<FriendLocationItem *>::iterator iter = m_friendItems.begin();
+ while (iter != m_friendItems.end()) {
+ bool found = false;
+ foreach (User * friendData, friendsList) {
+ if (friendData->userId() == (*iter)->userId()) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ // data for friend item was not found so item must be deleted
+ deleteFriendItem(*iter);
+ iter = m_friendItems.erase(iter);
+ }
+ else {
+ iter++;
+ }
+ }
- if (receiveFriendsLocationsCounter == 0) {
- receiveFriendsLocationsCounter++;
- updateFriendItemList(friendsList);
+ // loop through new friend data, find matching friend items and update them, or add new items
+ // if old items are not found
+ foreach (User * friendData, friendsList) {
+ bool found = false;
+ foreach (FriendLocationItem *friendItem, m_friendItems) {
+ if (friendData->userId() == friendItem->userId()) {
+ // friend item was found so update the data
+ updateFriendItem(friendItem, friendData);
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ // friend item was not found so new item must be added
+ addFriendItem(friendData);
+ }
}
- else {
- /// @todo VILLE: New friends are never added to list & scene
- receiveFriendsLocationsCounter++;
- updateFriendLocationsAndImages(friendsList);
- cleanOldFriendData(friendsList);
+ refactorFriendItems(m_zoomLevel);
+}
+
+void FriendItemsHandler::mergeCollidingGroups()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ // loop through all groups
+ QLinkedList<FriendGroupItem *>::iterator iter = m_friendGroupItems.begin();
+ while (iter != m_friendGroupItems.end()) {
+ checkGroupForCollidingGroups(*iter);
+ iter++;
}
}
void FriendItemsHandler::refactorFriendItems(int zoomLevel)
{
+ qDebug() << __PRETTY_FUNCTION__;
+
m_zoomLevel = zoomLevel;
mergeCollidingGroups();
checkAllFriendsForCollidingFriends();
}
-void FriendItemsHandler::updateFriendItemList(const QList<User *> &friendsList)
+void FriendItemsHandler::updateFriendItem(FriendLocationItem *friendItem, User *friendData)
{
qDebug() << __PRETTY_FUNCTION__;
- qDeleteAll(m_friendItems.begin(),m_friendItems.end());
- m_friendItems.clear();
+ // update position
+ QPoint newPosition = MapEngine::convertLatLonToSceneCoordinate(friendData->coordinates());
+ if (friendItem->pos().toPoint() != newPosition)
+ friendItem->setPos(newPosition);
-
- for (int i=0; i<friendsList.count(); i++) {
- FriendLocationItem *friendLocation
- = new FriendLocationItem(friendsList.at(i)->profileImage(),
- friendsList.at(i)->coordinates(),0);
-
- friendLocation->setUserId(friendsList.at(i)->userId());
- m_friendItems.append(friendLocation);
- m_mapScene->addItem(friendLocation);
-
- //refactorFriendItems(m_zoomLevel);
- }
-}
-
-void FriendItemsHandler::updateFriendLocationsAndImages(const QList<User *> &friendsList)
-{
- for (int i=0; i<friendsList.count(); i++) {
-
- QLinkedList<FriendLocationItem *>::iterator j;
- for (j = m_friendItems.begin(); j!= m_friendItems.end(); j++) {
-
- if ((*j)->userId() == friendsList.at(i)->userId()) {
-
- if ((*j)->position()
- != MapEngine::convertLatLonToSceneCoordinate(friendsList.at(i)->coordinates()))
- (*j)->setPosition(friendsList.at(i)->coordinates());
-
- if ((*j)->profileImageUrl()
- != friendsList.at(i)->profileImageUrl()) {
- (*j)->setPixmap(friendsList.at(i)->profileImage());
- }
- }
- }
- }
+ // update image
+ if (friendItem->profileImageUrl() != friendData->profileImageUrl())
+ friendItem->setProfileImage(friendData->profileImage(), friendData->profileImageUrl());
}