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::addFriendItem(User *friendData)
43 qDebug() << __PRETTY_FUNCTION__;
45 FriendLocationItem *item = new FriendLocationItem(friendData->userId());
47 item->setProfileImage(friendData->profileImage(), friendData->profileImageUrl());
48 item->setPos(MapEngine::convertLatLonToSceneCoordinate(friendData->coordinates()));
49 m_friendItems.append(item);
50 m_mapScene->addItem(item);
53 void FriendItemsHandler::checkAllFriendsForCollidingFriends()
55 qDebug() << __PRETTY_FUNCTION__;
57 QLinkedList<FriendLocationItem *>::iterator iter = m_friendItems.begin();
58 while (iter != m_friendItems.end()) {
59 // check only friends which are not part of group already
60 if (!(*iter)->isPartOfGroup()) {
61 checkFriendForCollidingFriends(*iter);
67 void FriendItemsHandler::checkAllGroupsForCollidingFriends()
69 qDebug() << __PRETTY_FUNCTION__;
71 // loop through all groups
72 QLinkedList<FriendGroupItem *>::iterator iter = m_friendGroupItems.begin();
73 while (iter != m_friendGroupItems.end()) {
74 checkGroupForCollidingFriends(*iter);
79 void FriendItemsHandler::checkFriendForCollidingFriends(FriendLocationItem *item)
81 // checkGroupsForCollisions() is used for checking if groups collide with another
82 // groups or friend items, so this method doesn't have to check against groups
84 qDebug() << __PRETTY_FUNCTION__;
86 FriendGroupItem *group = 0;
87 QRect itemSceneRect = item->sceneTransformedBoundingRect(m_zoomLevel);
89 // loop through all friend items
90 QLinkedList<FriendLocationItem *>::iterator iter = m_friendItems.begin();
91 while (iter != m_friendItems.end()) {
92 // but don't check myself and friends which are already part of a group
93 if (item != *iter && !(*iter)->isPartOfGroup()) {
94 if (itemSceneRect.intersects((*iter)->sceneTransformedBoundingRect(m_zoomLevel))) {
96 group = new FriendGroupItem(item);
97 m_mapScene->addItem(group);
98 m_friendGroupItems.append(group);
100 group->joinFriend(*iter);
107 void FriendItemsHandler::checkGroupForCollidingFriends(FriendGroupItem *group)
109 qDebug() << __PRETTY_FUNCTION__;
111 QRect groupSceneRect = group->sceneTransformedBoundingRect(m_zoomLevel);
113 // loop through all friend items
114 QLinkedList<FriendLocationItem *>::iterator iter = m_friendItems.begin();
115 while (iter != m_friendItems.end()) {
116 // but don't check friends which are already part of a group
117 if (!(*iter)->isPartOfGroup()) {
118 if (groupSceneRect.intersects((*iter)->sceneTransformedBoundingRect(m_zoomLevel))) {
119 group->joinFriend(*iter);
126 void FriendItemsHandler::checkGroupForCollidingGroups(FriendGroupItem *group)
128 qDebug() << __PRETTY_FUNCTION__;
130 QRect groupSceneRect = group->sceneTransformedBoundingRect(m_zoomLevel);
132 // loop through all groups
133 QLinkedList<FriendGroupItem *>::iterator iter = m_friendGroupItems.begin();
134 while (iter != m_friendGroupItems.end()) {
135 // but don't check myself
136 if (group != *iter) {
137 if (groupSceneRect.intersects((*iter)->sceneTransformedBoundingRect(m_zoomLevel))) {
138 (*iter)->mergeWithGroup(group);
139 m_mapScene->removeItem(*iter);
141 iter = m_friendGroupItems.erase(iter);
153 void FriendItemsHandler::mergeCollidingGroups()
155 qDebug() << __PRETTY_FUNCTION__;
157 // loop through all groups
158 QLinkedList<FriendGroupItem *>::iterator iter = m_friendGroupItems.begin();
159 while (iter != m_friendGroupItems.end()) {
160 checkGroupForCollidingGroups(*iter);
165 void FriendItemsHandler::deleteFriendItem(FriendLocationItem *item)
167 qDebug() << __PRETTY_FUNCTION__;
169 dropFriendFromAllGroups(item);
170 m_mapScene->removeItem(item);
174 void FriendItemsHandler::dropFriendFromAllGroups(FriendLocationItem *item)
176 qDebug() << __PRETTY_FUNCTION__;
178 foreach (FriendGroupItem *group, m_friendGroupItems) {
179 group->dropFriend(item);
183 void FriendItemsHandler::dropOutOfGroupFriends()
185 qDebug() << __PRETTY_FUNCTION__;
187 // loop through all group items and drop friends which doesn't collide anymore
188 // delete group if possible
189 foreach (FriendGroupItem *group, m_friendGroupItems) {
190 if (group->dropFriends(m_zoomLevel)) {
191 m_friendGroupItems.removeAll(group);
192 m_mapScene->removeItem(group);
198 void FriendItemsHandler::friendListUpdated(QList<User *> &friendsList)
200 qDebug() << __PRETTY_FUNCTION__;
202 // loop through friend items and find matching friend data. If matching data
203 // is not found then remove item
204 QLinkedList<FriendLocationItem *>::iterator iter = m_friendItems.begin();
205 while (iter != m_friendItems.end()) {
207 foreach (User * friendData, friendsList) {
208 if (friendData->userId() == (*iter)->userId()) {
214 // data for friend item was not found so item must be deleted
215 deleteFriendItem(*iter);
216 iter = m_friendItems.erase(iter);
223 // loop through new friend data, find matching friend items and update them, or add new items
224 // if old items are not found
225 foreach (User * friendData, friendsList) {
227 foreach (FriendLocationItem *friendItem, m_friendItems) {
228 if (friendData->userId() == friendItem->userId()) {
229 // friend item was found so update the data
230 updateFriendItem(friendItem, friendData);
236 // friend item was not found so new item must be added
237 addFriendItem(friendData);
241 refactorFriendItems(m_zoomLevel);
244 void FriendItemsHandler::refactorFriendItems(int zoomLevel)
246 qDebug() << __PRETTY_FUNCTION__;
248 m_zoomLevel = zoomLevel;
250 mergeCollidingGroups();
251 dropOutOfGroupFriends();
252 checkAllGroupsForCollidingFriends();
253 checkAllFriendsForCollidingFriends();
256 void FriendItemsHandler::updateFriendItem(FriendLocationItem *friendItem, User *friendData)
258 qDebug() << __PRETTY_FUNCTION__;
261 QPoint newPosition = MapEngine::convertLatLonToSceneCoordinate(friendData->coordinates());
262 if (friendItem->pos().toPoint() != newPosition)
263 friendItem->setPos(newPosition);
266 if (friendItem->profileImageUrl() != friendData->profileImageUrl())
267 friendItem->setProfileImage(friendData->profileImage(), friendData->profileImageUrl());