Added method to group friends by distance.
[situare] / src / ui / meetpeoplepanel.cpp
1 #include <QDebug>
2 #include <QVBoxLayout>
3
4 #include "headerlistitemdelegate.h"
5 #include "personlistitem.h"
6 #include "friendlistitemdelegate.h"
7 #include "personlistview.h"
8 #include "imagebutton.h"
9 #include "panelcommon.h"
10 #include "../user/user.h"
11
12 #include "meetpeoplepanel.h"
13
14 MeetPeoplePanel::MeetPeoplePanel(QWidget *parent)
15     : PanelBase(parent),
16       m_headerListItemDelegate(0)
17 {
18     qDebug() << __PRETTY_FUNCTION__;
19
20     QVBoxLayout *meetPeopleLayout = new QVBoxLayout;
21     meetPeopleLayout->setMargin(0);
22     meetPeopleLayout->setSpacing(0);
23     setLayout(meetPeopleLayout);
24
25     m_personListView = new PersonListView(this);
26     m_personListItemDelegate = new FriendListItemDelegate(this);
27     initItemDelegates();
28     connect(m_personListView, SIGNAL(listItemSelectionChanged()),
29             this, SLOT(listItemSelectionHandler()));
30     connect(m_personListView, SIGNAL(personItemClicked(GeoCoordinate)),
31             this, SIGNAL(findPerson(GeoCoordinate)));
32
33     QVBoxLayout *listViewLayout = new QVBoxLayout;
34     listViewLayout->setContentsMargins(PANEL_MARGIN_LEFT, PANEL_MARGIN_TOP,
35                                        PANEL_MARGIN_RIGHT, PANEL_MARGIN_BOTTOM);
36     listViewLayout->addWidget(m_personListView);
37     meetPeopleLayout->addLayout(listViewLayout);
38
39     ImageButton *refreshInterestingPeopleButton = new ImageButton(":/res/images/refresh.png",
40                                                                   ":/res/images/refresh_s.png",
41                                                                   "", this);
42     connect(refreshInterestingPeopleButton, SIGNAL(clicked()),
43             this, SIGNAL(requestInterestingPeople()));
44
45     ImageButton *searchPeopleButton = new ImageButton(":/res/images/search.png",
46                                                       ":/res/images/search_s.png", "", this);
47     connect(searchPeopleButton, SIGNAL(clicked()),
48             this, SIGNAL(requestInterestingPeopleSearch()));
49
50     m_friendListButton = new ImageButton(":/res/images/friend_list_btn.png",
51                                                  ":/res/images/friend_list_btn_s.png",
52                                                  ":/res/images/friend_list_btn_d.png", this);
53     connect(m_friendListButton, SIGNAL(clicked()),
54             this, SLOT(showFriend()));
55
56     ImageButton *messageButton = new ImageButton(":/res/images/chat_btn.png",
57                                                  ":/res/images/chat_btn_s.png",
58                                                  ":/res/images/chat_btn_d.png", this);
59     connect(messageButton, SIGNAL(clicked()),
60             this, SLOT(messageButtonPressed()));
61
62     m_genericButtonsLayout->addWidget(refreshInterestingPeopleButton);
63     m_genericButtonsLayout->addWidget(searchPeopleButton);
64     m_itemButtonsLayout->addWidget(m_friendListButton);
65     m_itemButtonsLayout->addWidget(messageButton);
66 }
67
68 void MeetPeoplePanel::addHeaderItem(const QString &key, const QString &title)
69 {
70     m_personListView->setItemDelegateForRow(m_personListView->count(), m_headerListItemDelegate);
71     ExtendedListItem *friendsHeaderItem = new ExtendedListItem(0, QListWidgetItem::UserType);
72     friendsHeaderItem->setTitle(title);
73     m_personListView->addListItem(key, friendsHeaderItem);
74 }
75
76 void MeetPeoplePanel::anyPanelClosed()
77 {
78     qDebug() << __PRETTY_FUNCTION__;
79
80     m_personListView->clearItemSelection();
81 }
82
83 bool MeetPeoplePanel::friendDistanceLessThan(const User &user1, const User &user2)
84 {
85     double user1Value;
86     QString user1Unit;
87     double user2Value;
88     QString user2Unit;
89
90     user1.distance(user1Value, user1Unit);
91     user2.distance(user2Value, user2Unit);
92
93     static int KM_FACTOR = 1000;
94
95     if (user1Unit == "km")
96         user1Value *= KM_FACTOR;
97     if (user2Unit == "km")
98         user2Value *= KM_FACTOR;
99
100     return user1Value < user2Value;
101 }
102
103 QList<QList<User> > MeetPeoplePanel::groupFriendsByDistance(const QList<User> &friends)
104 {
105     const int AEROPLANE_DISTANCE = 5000;///< Aeroplane distance limit
106     const int CAR_DISTANCE = 500;       ///< Car distance limit
107     const int WALK_DISTANCE = 5;        ///< Walk distance limit
108
109     QList<QList<User> > groupedFriends;
110     QList<User> walkingDistanceUsers;
111     QList<User> drivingDistanceUsers;
112     QList<User> flyingDistanceUsers;
113     QList<User> rocketDistanceUsers;
114
115     foreach (const User user, friends) {
116         double value;
117         QString unit;
118         user.distance(value, unit);
119
120         if ((unit == "m") || (value < WALK_DISTANCE))
121             walkingDistanceUsers.append(user);
122         else if (value < CAR_DISTANCE)
123             drivingDistanceUsers.append(user);
124         else if (value < AEROPLANE_DISTANCE)
125             flyingDistanceUsers.append(user);
126         else
127             rocketDistanceUsers.append(user);
128     }
129
130     qSort(walkingDistanceUsers.begin(), walkingDistanceUsers.end(), friendDistanceLessThan);
131     qSort(drivingDistanceUsers.begin(), drivingDistanceUsers.end(), friendDistanceLessThan);
132     qSort(flyingDistanceUsers.begin(), flyingDistanceUsers.end(), friendDistanceLessThan);
133     qSort(rocketDistanceUsers.begin(), rocketDistanceUsers.end(), friendDistanceLessThan);
134
135     groupedFriends.append(walkingDistanceUsers);
136     groupedFriends.append(drivingDistanceUsers);
137     groupedFriends.append(flyingDistanceUsers);
138     groupedFriends.append(rocketDistanceUsers);
139
140     return groupedFriends;
141 }
142
143 void MeetPeoplePanel::hideEvent(QHideEvent *event)
144 {
145     qDebug() << __PRETTY_FUNCTION__;
146
147     QWidget::hideEvent(event);
148
149     m_personListView->clearItemSelection();
150 }
151
152 void MeetPeoplePanel::initItemDelegates()
153 {
154     qDebug() << __PRETTY_FUNCTION__;
155
156     m_personListView->setItemDelegate(m_personListItemDelegate);
157
158     if (m_headerListItemDelegate)
159         delete m_headerListItemDelegate;
160     m_headerListItemDelegate = new HeaderListItemDelegate(this);
161 }
162
163 void MeetPeoplePanel::listItemSelectionHandler()
164 {
165     qDebug() << __PRETTY_FUNCTION__;
166
167     PersonListItem *personItem = dynamic_cast<PersonListItem*>(m_personListView->selectedItem());
168
169     if (personItem) {
170         if (personItem->isFriend())
171             m_friendListButton->setEnabled(true);
172         else
173             m_friendListButton->setDisabled(true);
174     } else {
175         m_friendListButton->setDisabled(true);
176     }
177
178     onListItemSelectionChanged();
179 }
180
181 void MeetPeoplePanel::messageButtonPressed()
182 {
183     qDebug() << __PRETTY_FUNCTION__;
184
185     PersonListItem *personItem = dynamic_cast<PersonListItem*>(m_personListView->selectedItem());
186
187     if (personItem) {
188         m_personListView->clearItemSelection();
189         emit requestMessageDialog(QPair<QString, QString>(personItem->facebookId(),
190                                                           personItem->title()));
191     }
192 }
193
194 void MeetPeoplePanel::setImage(const QString &id, const QPixmap &image)
195 {
196     qDebug() << __PRETTY_FUNCTION__;
197
198     PersonListItem *personItem = dynamic_cast<PersonListItem*>(m_personListView->listItem(id));
199     if (personItem)
200         personItem->setAvatarImage(image);
201 }
202
203 void MeetPeoplePanel::showFriend()
204 {
205     qDebug() << __PRETTY_FUNCTION__;
206
207     PersonListItem *personItem = dynamic_cast<PersonListItem*>(m_personListView->selectedItem());
208     if (personItem) {
209         m_personListView->clearItemSelection();
210         QList<QString> userIds;
211         userIds.append(personItem->facebookId());
212         emit requestShowFriend(userIds);
213     }
214 }
215
216 void MeetPeoplePanel::populateInterestingPeopleListView(QList<User> &friends, QList<User> &others)
217 {
218     qDebug() << __PRETTY_FUNCTION__;
219
220     m_personListView->clearList();
221     initItemDelegates();
222
223     if (friends.count() > 0) {
224         QStringList headers;
225         headers.append(tr("Walking distance:"));
226         headers.append(tr("Driving distance:"));
227         headers.append(tr("Flying distance:"));
228         headers.append(tr("Rocket distance:"));
229
230         QList<QList<User> > groupedFriends = groupFriendsByDistance(friends);
231
232         foreach (QList<User> group, groupedFriends) {
233             qWarning() << group.count();
234             QString header = headers.takeFirst();
235             if (group.count() > 0) {
236                 addHeaderItem(header, header);
237
238                 foreach (User user, group) {
239                     PersonListItem *item = new PersonListItem();
240                     item->setPersonData(user, true);
241                     m_personListView->addListItem(user.userId(), item);
242                 }
243             }
244         }
245     }
246
247     if (others.count() > 0) {
248         addHeaderItem("othersHeader", tr("Distance unknown:"));
249
250         foreach (User user, others) {
251             PersonListItem *item = new PersonListItem();
252             item->setPersonData(user, false);
253             m_personListView->addListItem(user.userId(), item);
254         }
255     }
256
257     m_personListView->scrollToTop();
258 }