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);
52 connect(item, SIGNAL(friendItemClicked(QString)),
53 this, SIGNAL(friendItemClicked(QString)));
56 void FriendItemsHandler::checkAllFriendsForCollidingFriends()
58 qDebug() << __PRETTY_FUNCTION__;
60 QLinkedList<FriendLocationItem *>::iterator iter = m_friendItems.begin();
61 while (iter != m_friendItems.end()) {
62 // check only friends which are not part of group already
63 if (!(*iter)->isPartOfGroup()) {
64 checkFriendForCollidingFriends(*iter);
70 void FriendItemsHandler::checkAllGroupsForCollidingFriends()
72 qDebug() << __PRETTY_FUNCTION__;
74 // loop through all groups
75 QLinkedList<FriendGroupItem *>::iterator iter = m_friendGroupItems.begin();
76 while (iter != m_friendGroupItems.end()) {
77 checkGroupForCollidingFriends(*iter);
82 void FriendItemsHandler::checkFriendForCollidingFriends(FriendLocationItem *item)
84 // checkGroupsForCollisions() is used for checking if groups collide with another
85 // groups or friend items, so this method doesn't have to check against groups
87 qDebug() << __PRETTY_FUNCTION__;
89 FriendGroupItem *group = 0;
90 QRect itemSceneRect = item->sceneTransformedBoundingRect(m_zoomLevel);
92 // loop through all friend items
93 QLinkedList<FriendLocationItem *>::iterator iter = m_friendItems.begin();
94 while (iter != m_friendItems.end()) {
95 // but don't check myself and friends which are already part of a group
96 if (item != *iter && !(*iter)->isPartOfGroup()) {
97 if (itemSceneRect.intersects((*iter)->sceneTransformedBoundingRect(m_zoomLevel))) {
99 group = new FriendGroupItem(item);
100 m_mapScene->addItem(group);
101 m_friendGroupItems.append(group);
103 connect(group, SIGNAL(friendGroupItemClicked(QList<QString>)),
104 this, SIGNAL(friendGroupItemClicked(QList<QString>)));
106 group->joinFriend(*iter);
113 void FriendItemsHandler::checkGroupForCollidingFriends(FriendGroupItem *group)
115 qDebug() << __PRETTY_FUNCTION__;
117 QRect groupSceneRect = group->sceneTransformedBoundingRect(m_zoomLevel);
119 // loop through all friend items
120 QLinkedList<FriendLocationItem *>::iterator iter = m_friendItems.begin();
121 while (iter != m_friendItems.end()) {
122 // but don't check friends which are already part of a group
123 if (!(*iter)->isPartOfGroup()) {
124 if (groupSceneRect.intersects((*iter)->sceneTransformedBoundingRect(m_zoomLevel))) {
125 group->joinFriend(*iter);
132 void FriendItemsHandler::checkGroupForCollidingGroups(FriendGroupItem *group)
134 qDebug() << __PRETTY_FUNCTION__;
136 QRect groupSceneRect = group->sceneTransformedBoundingRect(m_zoomLevel);
138 // loop through all groups
139 QLinkedList<FriendGroupItem *>::iterator iter = m_friendGroupItems.begin();
140 while (iter != m_friendGroupItems.end()) {
141 // but don't check myself
142 if (group != *iter) {
143 if (groupSceneRect.intersects((*iter)->sceneTransformedBoundingRect(m_zoomLevel))) {
144 (*iter)->mergeWithGroup(group);
145 m_mapScene->removeItem(*iter);
147 iter = m_friendGroupItems.erase(iter);
159 void FriendItemsHandler::mergeCollidingGroups()
161 qDebug() << __PRETTY_FUNCTION__;
163 // loop through all groups
164 QLinkedList<FriendGroupItem *>::iterator iter = m_friendGroupItems.begin();
165 while (iter != m_friendGroupItems.end()) {
166 checkGroupForCollidingGroups(*iter);
171 void FriendItemsHandler::deleteFriendItem(FriendLocationItem *item)
173 qDebug() << __PRETTY_FUNCTION__;
175 dropFriendFromAllGroups(item);
176 m_mapScene->removeItem(item);
180 void FriendItemsHandler::dropFriendFromAllGroups(FriendLocationItem *item)
182 qDebug() << __PRETTY_FUNCTION__;
184 foreach (FriendGroupItem *group, m_friendGroupItems) {
185 group->dropFriend(item);
189 void FriendItemsHandler::dropOutOfGroupFriends()
191 qDebug() << __PRETTY_FUNCTION__;
193 // loop through all group items and drop friends which doesn't collide anymore
194 // delete group if possible
195 foreach (FriendGroupItem *group, m_friendGroupItems) {
196 if (group->dropFriends(m_zoomLevel)) {
197 m_friendGroupItems.removeAll(group);
198 m_mapScene->removeItem(group);
204 void FriendItemsHandler::friendListUpdated(QList<User *> &friendsList)
206 qDebug() << __PRETTY_FUNCTION__;
208 // loop through friend items and find matching friend data. If matching data
209 // is not found then remove item
210 QLinkedList<FriendLocationItem *>::iterator iter = m_friendItems.begin();
211 while (iter != m_friendItems.end()) {
213 foreach (User * friendData, friendsList) {
214 if (friendData->userId() == (*iter)->userId()) {
220 // data for friend item was not found so item must be deleted
221 deleteFriendItem(*iter);
222 iter = m_friendItems.erase(iter);
229 // loop through new friend data, find matching friend items and update them, or add new items
230 // if old items are not found
231 foreach (User * friendData, friendsList) {
233 foreach (FriendLocationItem *friendItem, m_friendItems) {
234 if (friendData->userId() == friendItem->userId()) {
235 // friend item was found so update the data
236 updateFriendItem(friendItem, friendData);
242 // friend item was not found so new item must be added
243 addFriendItem(friendData);
247 refactorFriendItems(m_zoomLevel);
250 void FriendItemsHandler::refactorFriendItems(int zoomLevel)
252 qDebug() << __PRETTY_FUNCTION__;
254 m_zoomLevel = zoomLevel;
256 mergeCollidingGroups();
257 dropOutOfGroupFriends();
258 checkAllGroupsForCollidingFriends();
259 checkAllFriendsForCollidingFriends();
262 void FriendItemsHandler::updateFriendItem(FriendLocationItem *friendItem, User *friendData)
264 qDebug() << __PRETTY_FUNCTION__;
267 QPoint newPosition = MapEngine::convertLatLonToSceneCoordinate(friendData->coordinates());
268 if (friendItem->pos().toPoint() != newPosition)
269 friendItem->setPos(newPosition);
272 if (friendItem->profileImageUrl() != friendData->profileImageUrl())
273 friendItem->setProfileImage(friendData->profileImage(), friendData->profileImageUrl());