99da1316c3abd05242b8c19cc9b049a0967713fc
[situare] / src / ui / friendlistpanel.cpp
1 /*
2     Situare - A location system for Facebook
3     Copyright (C) 2010  Ixonos Plc. Authors:
4
5         Kaj Wallin - kaj.wallin@ixonos.com
6         Henri Lampela - henri.lampela@ixonos.com
7         Pekka Nissinen - pekka.nissinen@ixonos.com
8         Sami Rämö - sami.ramo@ixonos.com
9
10     Situare is free software; you can redistribute it and/or
11     modify it under the terms of the GNU General Public License
12     version 2 as published by the Free Software Foundation.
13
14     Situare is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU General Public License for more details.
18
19     You should have received a copy of the GNU General Public License
20     along with Situare; if not, write to the Free Software
21     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
22     USA.
23 */
24
25 #include <QHBoxLayout>
26 #include <QLabel>
27 #include <QPushButton>
28
29 #include "coordinates/geocoordinate.h"
30 #include "friendlistitem.h"
31 #include "friendlistitemdelegate.h"
32 #include "friendlistview.h"
33 #include "panelcommon.h"
34 #include "user/user.h"
35
36 #include "friendlistpanel.h"
37
38 FriendListPanel::FriendListPanel(QWidget *parent)
39     : QWidget(parent),
40       m_mainWindowIsTopmost(false)
41 {
42     qDebug() << __PRETTY_FUNCTION__;
43
44     QVBoxLayout *friendListPanelLayout = new QVBoxLayout();
45     friendListPanelLayout->setMargin(0);
46     friendListPanelLayout->setSpacing(0);
47     setLayout(friendListPanelLayout);
48
49     QHBoxLayout *filterLayout = new QHBoxLayout();
50     filterLayout->setContentsMargins(FRIENDPANEL_FILTER_MARGIN_LEFT, 0,
51                                      FRIENDPANEL_FILTER_MARGIN_RIGHT, 0);
52
53     m_friendListHeaderWidget = new QWidget();
54     m_friendListHeaderWidget->setLayout(filterLayout);
55     m_friendListHeaderWidget->setAutoFillBackground(true);
56
57     m_routeButton = new QPushButton(tr("Route to friend"));
58
59     QPalette labelPalette = m_friendListHeaderWidget->palette();
60     labelPalette.setColor(QPalette::Background, Qt::black);
61
62     m_friendListHeaderWidget->setPalette(labelPalette);
63     m_friendListHeaderWidget->hide();
64     m_friendListLabel = new QLabel(this);
65     m_clearFilterButton = new QPushButton(tr("Show all"));
66
67     filterLayout->addWidget(m_friendListLabel);
68     filterLayout->addWidget(m_clearFilterButton);
69
70     m_friendListView = new FriendListView(this);
71     m_friendListView->setItemDelegate(new FriendListItemDelegate(this));
72
73     QVBoxLayout *listViewLayout = new QVBoxLayout;
74     listViewLayout->setContentsMargins(PANEL_MARGIN_LEFT, 0, PANEL_MARGIN_RIGHT, 0);
75     listViewLayout->addWidget(m_friendListView);
76
77     friendListPanelLayout->addWidget(m_routeButton);
78     friendListPanelLayout->addWidget(m_friendListHeaderWidget);
79     friendListPanelLayout->addLayout(listViewLayout);
80
81     connect(m_friendListView, SIGNAL(friendItemClicked(GeoCoordinate)),
82             this, SIGNAL(findFriend(GeoCoordinate)));
83
84     connect(m_clearFilterButton, SIGNAL(clicked()),
85             this, SLOT(clearFriendListFilter()));
86
87     connect(m_routeButton, SIGNAL(clicked()),
88             this, SLOT(routeToSelectedFriend()));
89
90     /// @todo remove old filterLayout when new panel are merged
91
92     //////////////////////////////////////////////////////////////////////////
93     // NOTE! Do not mix the new filtering layout below with the old one above
94     //////////////////////////////////////////////////////////////////////////
95
96     // filtering layout
97     QHBoxLayout *filteringLayout = new QHBoxLayout();
98     friendListPanelLayout->addLayout(filteringLayout);
99
100     // line edit for filtering
101     m_filterField = new QLineEdit;
102     filteringLayout->addWidget(m_filterField);
103
104     connect(m_filterField, SIGNAL(returnPressed()),
105             this, SLOT(clearFiltering()));
106
107     connect(m_filterField, SIGNAL(textChanged(QString)),
108             this, SLOT(filterTextChanged(QString)));
109
110     // button for clearing the filtering
111     m_filterClearButton = new QPushButton();
112     filteringLayout->addWidget(m_filterClearButton);
113     m_filterClearButton->setIcon(QIcon::fromTheme(QLatin1String("general_close")));
114
115     connect(m_filterClearButton, SIGNAL(clicked()),
116             this, SLOT(clearFiltering()));
117
118     connect(qApp, SIGNAL(topmostWindowChanged(bool)),
119             this, SLOT(topmostWindowChanged(bool)));
120 }
121
122 void FriendListPanel::clearFiltering()
123 {
124     qDebug() << __PRETTY_FUNCTION__;
125
126     ///< @todo Clear the filtering when fried list panel is closed (no hideEvent dispatched)
127
128     // clearing the filtering text field does cause also hiding the filtering layout
129     m_filterField->clear();
130 }
131
132 void FriendListPanel::clearFriendListFilter()
133 {
134     qDebug() << __PRETTY_FUNCTION__;
135
136     m_friendListHeaderWidget->hide();
137     m_friendListView->clearFilter();
138 }
139
140 void FriendListPanel::filterTextChanged(const QString &text)
141 {
142     qDebug() << __PRETTY_FUNCTION__;
143
144     if (m_filterField->isHidden() && !text.isEmpty())
145         setFilteringLayoutVisibility(true);
146     else if (m_filterField->isVisible() && text.isEmpty())
147         setFilteringLayoutVisibility(false);
148
149     m_friendListView->filter(text);
150 }
151
152 void FriendListPanel::friendImageReady(User *user)
153 {
154     qDebug() << __PRETTY_FUNCTION__;
155
156     FriendListItem *item = static_cast<FriendListItem*>(m_friendListView->listItem(user->userId()));
157
158     if (item)
159         item->setAvatarImage(user->profileImage());
160 }
161
162 void FriendListPanel::friendInfoReceived(QList<User *> &friendList)
163 {
164     qDebug() << __PRETTY_FUNCTION__;
165
166     QStringList newUserIDs;
167
168     foreach (User *user, friendList) {
169         FriendListItem *item = 0;
170         if (!m_friendListView->contains(user->userId())) {
171             item = new FriendListItem();
172             item->setUserData(user);
173             m_friendListView->addListItem(user->userId(), item);
174         } else {
175             item = static_cast<FriendListItem *>(m_friendListView->takeListItemFromView(
176                     user->userId()));
177
178             if (item) {
179                 item->setUserData(user);
180                 m_friendListView->addListItemToView(item);
181             }
182         }
183
184         newUserIDs.append(user->userId());
185     }
186
187     m_friendListView->clearUnused(newUserIDs);
188 }
189
190 void FriendListPanel::hideEvent(QHideEvent *event)
191 {
192     qWarning() << __PRETTY_FUNCTION__;
193
194     QWidget::hideEvent(event);
195     updateKeyboardGrabbing();
196     clearFiltering();
197 }
198
199 void FriendListPanel::routeToSelectedFriend()
200 {
201     qDebug() << __PRETTY_FUNCTION__;
202
203     FriendListItem *item = dynamic_cast<FriendListItem *>(m_friendListView->selectedItem());
204
205     if (item)
206         emit routeToFriend(item->coordinates());
207 }
208
209 void FriendListPanel::setFilteringLayoutVisibility(bool visible)
210 {
211     qDebug() << __PRETTY_FUNCTION__;
212
213     m_filterField->setVisible(visible);
214     m_filterClearButton->setVisible(visible);
215 }
216
217 void FriendListPanel::updateKeyboardGrabbing()
218 {
219     qWarning() << __PRETTY_FUNCTION__;
220
221     if (!m_mainWindowIsTopmost || !isVisible()) {
222         if (QWidget::keyboardGrabber() == m_filterField) {
223             m_filterField->releaseKeyboard();
224             qWarning() << __PRETTY_FUNCTION__ << "released";
225         }
226     } else if (m_mainWindowIsTopmost && isVisible()) {
227         if (QWidget::keyboardGrabber() != m_filterField) {
228             m_filterField->grabKeyboard();
229             qWarning() << __PRETTY_FUNCTION__ << "grabbed";
230         }
231     }
232 }
233
234 void FriendListPanel::showEvent(QShowEvent *event)
235 {
236     qWarning() << __PRETTY_FUNCTION__;
237
238     QWidget::showEvent(event);
239     updateKeyboardGrabbing();
240     setFilteringLayoutVisibility(false);
241 }
242
243 void FriendListPanel::showFriendsInList(const QList<QString> &userIDs)
244 {
245     qDebug() << __PRETTY_FUNCTION__;
246
247     m_friendListLabel->setText(tr("Selected: %1").arg(userIDs.count()));
248
249     m_friendListHeaderWidget->show();
250     m_friendListView->filter(userIDs);
251
252     emit showPanelRequested(this);
253 }
254
255 void FriendListPanel::topmostWindowChanged(bool mainWindowIsTopmost)
256 {
257     qWarning() << __PRETTY_FUNCTION__ << mainWindowIsTopmost;
258
259     m_mainWindowIsTopmost = mainWindowIsTopmost;
260     updateKeyboardGrabbing();
261 }