Merge branch 'master' of https://vcs.maemo.org/git/situare into list_panel
[situare] / src / ui / friendlistitem.cpp
1 /*
2    Situare - A location system for Facebook
3    Copyright (C) 2010  Ixonos Plc. Authors:
4
5        Jussi Laitinen - jussi.laitinen@ixonos.com
6
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.
10
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.
15
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,
19    USA.
20 */
21
22 #include <QVBoxLayout>
23 #include <QPushButton>
24 #include <QPainter>
25 #include <QDebug>
26 #include <QPaintEvent>
27 #include <QLabel>
28 #include <QPixmap>
29 #include <QFormLayout>
30 #include <QSpacerItem>
31 #include <QStylePainter>
32 #include <math.h>
33
34 #include "friendlistitem.h"
35 #include "../user/user.h"
36 #include "avatarimage.h"
37
38 FriendListItem::FriendListItem(QWidget *parent)
39     : QWidget(parent)
40     , m_expanded(false)
41     , m_user(0)
42 {
43     qDebug() << __PRETTY_FUNCTION__;
44
45     QVBoxLayout *layout = new QVBoxLayout(this);
46     layout->setContentsMargins(MARGIN, 0, MARGIN*2, MARGIN*2);
47     layout->setSpacing(0);
48     setLayout(layout);
49
50     QHBoxLayout *topLayout = new QHBoxLayout();
51     topLayout->setMargin(0);
52     topLayout->setSpacing(0);
53
54     QHBoxLayout *bottomLayout = new QHBoxLayout();
55     bottomLayout->setMargin(0);
56     bottomLayout->setSpacing(0);
57
58     QFormLayout *infoLayout = new QFormLayout();
59     infoLayout->setMargin(0);
60     infoLayout->setSpacing(0);
61     infoLayout->setLabelAlignment(Qt::AlignTop);
62
63     QLabel *clockLabel = new QLabel();
64     clockLabel->setPixmap(QPixmap(":/res/images/clock.png"));
65     clockLabel->setContentsMargins(0, 0, MARGIN, 0);
66     clockLabel->setFixedSize(ICON_WIDTH + MARGIN, ICON_HEIGHT);
67     QLabel *envelopeLabel = new QLabel();
68     envelopeLabel->setPixmap(QPixmap(":/res/images/envelope.png"));
69     envelopeLabel->setContentsMargins(0, 0, MARGIN, 0);
70     envelopeLabel->setFixedSize(ICON_WIDTH + MARGIN, ICON_HEIGHT);
71     QLabel *compassLabel = new QLabel();
72     compassLabel->setPixmap(QPixmap(":/res/images/compass.png"));
73     compassLabel->setContentsMargins(0, 0, MARGIN, 0);
74     compassLabel->setFixedSize(ICON_WIDTH + MARGIN, ICON_HEIGHT);
75
76     m_imageLabel = new QLabel();
77     m_imageLabel->setFixedSize(IMAGE_WIDTH, IMAGE_HEIGHT);
78
79     m_nameLabel = new QLabel();
80     m_nameLabel->setFixedHeight(IMAGE_HEIGHT);
81
82     m_distanceLabel = new QLabel();
83     m_distanceLabel->setFixedHeight(IMAGE_HEIGHT);
84
85     QLabel *button = new QLabel();
86     button->setPixmap(QPixmap(":/res/images/show_position.png"));
87     button->setFixedSize(IMAGE_WIDTH, IMAGE_HEIGHT);
88
89     m_updatedLabel = new QLabel();
90     m_updatedLabel->setWordWrap(true);
91     m_statusTextLabel = new QLabel();
92     m_statusTextLabel->setWordWrap(true);
93     m_locationLabel = new QLabel();
94     m_locationLabel->setWordWrap(true);
95
96     infoLayout->addRow(envelopeLabel, m_statusTextLabel);
97     infoLayout->addRow(compassLabel, m_locationLabel);
98     infoLayout->addRow(clockLabel, m_updatedLabel);
99
100     topLayout->addWidget(m_imageLabel);
101     topLayout->addWidget(m_nameLabel, 1);
102     topLayout->addWidget(m_distanceLabel);
103
104     bottomLayout->addWidget(button, 0, Qt::AlignTop);
105     bottomLayout->addLayout(infoLayout);
106
107     layout->addLayout(topLayout, 0);
108     layout->addLayout(bottomLayout, 1);
109
110     setMinimumSize(ITEM_MIN_WIDTH, ITEM_MIN_HEIGHT);
111     setMaximumSize(ITEM_MIN_WIDTH, ITEM_MAX_HEIGHT);
112
113     setFont(NOKIA_FONT_SMALL);
114     m_nameLabel->setFont(NOKIA_FONT_NORMAL);
115     QPalette itemPalette = palette();
116     itemPalette.setColor(QPalette::Foreground, COLOR_GRAY);
117     setPalette(itemPalette);
118     QPalette namePalette = m_nameLabel->palette();
119     namePalette.setColor(QPalette::Foreground, Qt::white);
120     m_nameLabel->setPalette(namePalette);
121
122     m_backgroundTopImage.load(":/res/images/list_item_top.png");
123     m_backgroundMiddleImage.load(":/res/images/list_item_middle.png");
124     m_backgroundBottomImage.load(":/res/images/list_item_bottom.png");
125 }
126
127 void FriendListItem::setData(User *user)
128 {
129     qDebug() << __PRETTY_FUNCTION__;
130
131     if (user) {
132         m_user = user;
133
134         m_imageLabel->setPixmap(AvatarImage::create(m_user->profileImage()));
135
136         QString unit;
137         double value;
138         user->distance(value, unit);
139         m_distanceLabel->setText(QString::number(value) + " " + unit);
140
141         shortenTexts();
142         setText(false);
143     }
144 }
145
146 void FriendListItem::shortenTexts()
147 {
148     qDebug() << __PRETTY_FUNCTION__;
149
150     QFontMetrics nameLabelMetrics = m_nameLabel->fontMetrics();
151     QFontMetrics otherLabelsMetrics = m_updatedLabel->fontMetrics();
152
153     QString name = m_user->name();
154     QString updated = m_user->timestamp();
155     QString statusText = m_user->note();
156     QString location = m_user->address();
157
158     int nameIndex = name.indexOf('\n');
159     int updatedIndex = updated.indexOf('\n');
160     int statusTextIndex = statusText.indexOf('\n');
161     int locationIndex = location.indexOf('\n');
162
163     if (nameIndex > 0) {
164         name.truncate(nameIndex);
165         name.append("...");
166     }
167     if (updatedIndex > 0) {
168         updated.truncate(updatedIndex);
169         updated.append("...");
170     }
171     if (statusTextIndex > 0) {
172         statusText.truncate(statusTextIndex);
173         statusText.append("...");
174     }
175     if (locationIndex > 0) {
176         location.truncate(locationIndex);
177         location.append("...");
178     }
179
180     int distanceLabelWidth = otherLabelsMetrics.width(m_distanceLabel->text());
181     m_shortenedName = nameLabelMetrics.elidedText(name, Qt::ElideRight, NAME_LABEL_MAX_WIDTH
182                                                   - distanceLabelWidth);
183     m_shortenedUpdated = otherLabelsMetrics.elidedText(updated, Qt::ElideRight, LABEL_MAX_WIDTH);
184     m_shortenedStatusText = otherLabelsMetrics.elidedText(statusText, Qt::ElideRight,
185                                                           LABEL_MAX_WIDTH);
186     m_shortenedLocation = otherLabelsMetrics.elidedText(location, Qt::ElideRight, LABEL_MAX_WIDTH);
187 }
188
189 void FriendListItem::setText(bool expanded)
190 {
191     qDebug() << __PRETTY_FUNCTION__;
192
193     if (expanded) {
194         setUpdatesEnabled(false);
195         m_nameLabel->setText(m_shortenedName);
196         m_updatedLabel->setText(m_user->timestamp());
197         m_statusTextLabel->setText(m_user->note());
198         m_locationLabel->setText(m_user->address());
199         setUpdatesEnabled(true);
200     }
201     else {
202         setUpdatesEnabled(false);
203         m_nameLabel->setText(m_shortenedName);
204         m_updatedLabel->setText(m_shortenedUpdated);
205         m_statusTextLabel->setText(m_shortenedStatusText);
206         m_locationLabel->setText(m_shortenedLocation);
207         setUpdatesEnabled(true);
208     }
209 }
210
211 void FriendListItem::mousePressEvent(QMouseEvent *event)
212 {
213     qDebug() << __PRETTY_FUNCTION__ << " " << event->pos();
214
215     m_mousePosition = event->pos();
216 }
217
218 void FriendListItem::mouseReleaseEvent(QMouseEvent *event)
219 {
220     qDebug() << __PRETTY_FUNCTION__ << " " << event->pos();
221
222     if ((abs(m_mousePosition.y() - event->pos().y()) <= MOUSE_PRESS_AREA_WIDTH) &&
223         (abs(m_mousePosition.x() - event->pos().x()) <= MOUSE_PRESS_AREA_HEIGHT)) {
224         if (m_expanded) {
225             setText(false);
226             m_expanded = false;
227         }
228         else {
229             setText(true);
230             m_expanded = true;
231         }
232     }
233 }
234
235 void FriendListItem::paintEvent(QPaintEvent *event)
236 {
237     qDebug() << __PRETTY_FUNCTION__ << " " << event->rect();
238
239     QPainter painter(this);
240
241     QRect topRect = QRect(0, 0, event->rect().width(), BACKGROUND_TOP_HEIGHT);
242     QRect middleRect = QRect(0, topRect.bottom(), event->rect().width(),
243                              height() - BACKGROUND_TOP_HEIGHT - BACKGROUND_BOTTOM_HEIGHT);
244     QRect bottomRect = QRect(topRect.left(), middleRect.bottom(), event->rect().width(),
245                              BACKGROUND_BOTTOM_HEIGHT);
246
247     painter.drawPixmap(topRect, m_backgroundTopImage);
248     painter.drawPixmap(middleRect, m_backgroundMiddleImage);
249     painter.drawPixmap(bottomRect, m_backgroundBottomImage);
250 }