2 Situare - A location system for Facebook
3 Copyright (C) 2010 Ixonos Plc. Authors:
5 Sami Rämö - sami.ramo@ixonos.com
7 Situare is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 version 2 as published by the Free Software Foundation.
11 Situare is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Situare; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25 #include "friendgroupitem.h"
26 #include "friendlocationitem.h"
27 #include "mapengine.h"
29 #include "user/user.h"
31 #include "frienditemshandler.h"
33 FriendItemsHandler::FriendItemsHandler(MapScene *mapScene, QObject *parent)
38 qDebug() << __PRETTY_FUNCTION__;
41 void FriendItemsHandler::checkAllFriendsForCollidingFriends()
43 qDebug() << __PRETTY_FUNCTION__;
45 QLinkedList<FriendLocationItem *>::iterator iter = m_friendItems.begin();
46 while (iter != m_friendItems.end()) {
47 // check only friends which are not part of group already
48 if (!(*iter)->isPartOfGroup()) {
49 checkFriendForCollidingFriends(*iter);
55 void FriendItemsHandler::checkAllGroupsForCollidingFriends()
57 qDebug() << __PRETTY_FUNCTION__;
59 // loop through all groups
60 QLinkedList<FriendGroupItem *>::iterator iter = m_friendGroupItems.begin();
61 while (iter != m_friendGroupItems.end()) {
62 checkGroupForCollidingFriends(*iter);
67 void FriendItemsHandler::checkFriendForCollidingFriends(FriendLocationItem *item)
69 // checkGroupsForCollisions() is used for checking if groups collide with another
70 // groups or friend items, so this method doesn't have to check against groups
72 qDebug() << __PRETTY_FUNCTION__;
74 FriendGroupItem *group = 0;
75 QRect itemSceneRect = item->sceneTransformedBoundingRect(m_zoomLevel);
77 // loop through all friend items
78 QLinkedList<FriendLocationItem *>::iterator iter = m_friendItems.begin();
79 while (iter != m_friendItems.end()) {
80 // but don't check myself and friends which are already part of a group
81 if (item != *iter && !(*iter)->isPartOfGroup()) {
82 if (itemSceneRect.intersects((*iter)->sceneTransformedBoundingRect(m_zoomLevel))) {
84 group = new FriendGroupItem(item);
85 m_mapScene->addItem(group);
86 m_friendGroupItems.append(group);
88 group->joinFriend(*iter);
95 void FriendItemsHandler::checkGroupForCollidingFriends(FriendGroupItem *group)
97 qDebug() << __PRETTY_FUNCTION__;
99 QRect groupSceneRect = group->sceneTransformedBoundingRect(m_zoomLevel);
101 // loop through all friend items
102 QLinkedList<FriendLocationItem *>::iterator iter = m_friendItems.begin();
103 while (iter != m_friendItems.end()) {
104 // but don't check friends which are already part of a group
105 if (!(*iter)->isPartOfGroup()) {
106 if (groupSceneRect.intersects((*iter)->sceneTransformedBoundingRect(m_zoomLevel))) {
107 group->joinFriend(*iter);
114 void FriendItemsHandler::checkGroupForCollidingGroups(FriendGroupItem *group)
116 qDebug() << __PRETTY_FUNCTION__;
118 QRect groupSceneRect = group->sceneTransformedBoundingRect(m_zoomLevel);
120 // loop through all groups
121 QLinkedList<FriendGroupItem *>::iterator iter = m_friendGroupItems.begin();
122 while (iter != m_friendGroupItems.end()) {
123 // but don't check myself
124 if (group != *iter) {
125 if (groupSceneRect.intersects((*iter)->sceneTransformedBoundingRect(m_zoomLevel))) {
126 (*iter)->mergeWithGroup(group);
127 m_mapScene->removeItem(*iter);
129 iter = m_friendGroupItems.erase(iter);
141 void FriendItemsHandler::mergeCollidingGroups()
143 qDebug() << __PRETTY_FUNCTION__;
145 // loop through all groups
146 QLinkedList<FriendGroupItem *>::iterator iter = m_friendGroupItems.begin();
147 while (iter != m_friendGroupItems.end()) {
148 checkGroupForCollidingGroups(*iter);
153 void FriendItemsHandler::cleanOldFriendData(const QList<User *> &friendsList)
155 qDebug() << __PRETTY_FUNCTION__;
157 // loop through all m_friendItem items
158 QLinkedList<FriendLocationItem *>::iterator iter = m_friendItems.begin();
159 while (iter != m_friendItems.end()) {
160 bool friendFound = false;
162 // check against each item in the friendsList
163 QList<User *>::const_iterator j;
164 for (j = friendsList.begin(); j != friendsList.end(); j++) {
165 if ((**iter).userId() == (**j).userId()) {
172 m_mapScene->removeItem(*iter);
174 iter = m_friendItems.erase(iter);
182 void FriendItemsHandler::dropOutOfGroupFriends()
184 qDebug() << __PRETTY_FUNCTION__;
186 // loop through all group items and drop friends which doesn't collide anymore
187 // delete group if possible
188 foreach (FriendGroupItem *group, m_friendGroupItems) {
189 if (group->dropFriends(m_zoomLevel)) {
190 m_friendGroupItems.removeAll(group);
191 m_mapScene->removeItem(group);
197 void FriendItemsHandler::receiveFriendLocations(QList<User *> &friendsList)
199 qDebug() << __PRETTY_FUNCTION__;
201 static int receiveFriendsLocationsCounter = 0;
203 if (receiveFriendsLocationsCounter == 0) {
204 receiveFriendsLocationsCounter++;
205 updateFriendItemList(friendsList);
209 /// @todo VILLE: New friends are never added to list & scene
210 receiveFriendsLocationsCounter++;
211 updateFriendLocationsAndImages(friendsList);
212 cleanOldFriendData(friendsList);
215 refactorFriendItems(m_zoomLevel);
218 void FriendItemsHandler::refactorFriendItems(int zoomLevel)
220 qDebug() << __PRETTY_FUNCTION__;
222 m_zoomLevel = zoomLevel;
224 mergeCollidingGroups();
225 dropOutOfGroupFriends();
226 checkAllGroupsForCollidingFriends();
227 checkAllFriendsForCollidingFriends();
230 void FriendItemsHandler::updateFriendItemList(const QList<User *> &friendsList)
232 qDebug() << __PRETTY_FUNCTION__;
234 qDeleteAll(m_friendItems.begin(),m_friendItems.end());
235 m_friendItems.clear();
238 for (int i=0; i<friendsList.count(); i++) {
239 FriendLocationItem *friendLocation
240 = new FriendLocationItem(friendsList.at(i)->profileImage(),
241 friendsList.at(i)->coordinates(),0);
243 friendLocation->setUserId(friendsList.at(i)->userId());
244 m_friendItems.append(friendLocation);
245 m_mapScene->addItem(friendLocation);
247 refactorFriendItems(m_zoomLevel);
251 void FriendItemsHandler::updateFriendLocationsAndImages(const QList<User *> &friendsList)
253 qDebug() << __PRETTY_FUNCTION__;
255 for (int i=0; i<friendsList.count(); i++) {
257 QLinkedList<FriendLocationItem *>::iterator iter;
258 for (iter = m_friendItems.begin(); iter!= m_friendItems.end(); iter++) {
260 if ((*iter)->userId() == friendsList.at(i)->userId()) {
262 if ((*iter)->position()
263 != MapEngine::convertLatLonToSceneCoordinate(friendsList.at(i)->coordinates()))
264 (*iter)->setPosition(friendsList.at(i)->coordinates());
266 if ((*iter)->profileImageUrl()
267 != friendsList.at(i)->profileImageUrl()) {
268 (*iter)->setPixmap(friendsList.at(i)->profileImage());
269 (*iter)->setProfileImageUrl(friendsList.at(i)->profileImageUrl());