Merge branch 'master' into listview
[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 "imagebutton.h"
37 #include "../common.h"
38 #include "listcommon.h"
39
40 const int WALK_DISTANCE = 5;        ///< Walk distance limit for distance icon
41 const int CAR_DISTANCE = 500;       ///< Car distance limit for distance icon
42 const int AEROPLANE_DISTANCE = 5000;///< Aeroplane distance limit for distance icon
43
44 FriendListItem::FriendListItem()
45     : m_selected(false)
46     , m_user(0)
47 {
48     qDebug() << __PRETTY_FUNCTION__;
49
50     setData(ITEM_SIZE_HINT_INDEX, QSize(ITEM_WIDTH, ITEM_MIN_HEIGHT));
51 }
52
53 void FriendListItem::calculateTextRects()
54 {
55     qDebug() << __PRETTY_FUNCTION__;
56
57     //Dummy value to get painter font metrics.
58     QPixmap p = QPixmap(ICON_WIDTH, ICON_HEIGHT);
59     QPainter painter(&p);
60     painter.setFont(NOKIA_FONT_SMALL);
61     QFontMetrics smallFontMetrics = painter.fontMetrics();
62
63     QRect distanceRect = smallFontMetrics.boundingRect(m_distanceText);
64     QRect statusTextRect = smallFontMetrics.boundingRect(m_user->note());
65     QRect updatedRect = smallFontMetrics.boundingRect(m_user->timestamp());
66     QRect locationRect = smallFontMetrics.boundingRect(m_user->address());
67
68     int statusTextRectFactor = statusTextRect.width() / LABEL_MAX_WIDTH;
69     statusTextRectFactor++;
70     m_statusTextRect = QRect(0, 0, LABEL_MAX_WIDTH, ICON_HEIGHT * statusTextRectFactor);
71     int updatedRectFactor = updatedRect.width() / LABEL_MAX_WIDTH;
72     updatedRectFactor++;
73     m_updatedRect = QRect(0, 0, LABEL_MAX_WIDTH, ICON_HEIGHT * updatedRectFactor);
74     int locationRectFactor = locationRect.width() / LABEL_MAX_WIDTH;
75     locationRectFactor++;
76     m_locationRect = QRect(0, 0, LABEL_MAX_WIDTH, ICON_HEIGHT * locationRectFactor);
77
78     m_expandedHeight = ITEM_MIN_HEIGHT + ((statusTextRectFactor + updatedRectFactor +
79                                            locationRectFactor - 3) * ICON_HEIGHT);
80
81     setData(DISTANCE_SIZE_HINT_INDEX, distanceRect);
82 }
83
84 QPointF FriendListItem::coordinates()
85 {
86     qDebug() << __PRETTY_FUNCTION__;
87
88     return m_user->coordinates();
89 }
90
91 QString FriendListItem::id() const
92 {
93     qDebug() << __PRETTY_FUNCTION__;
94
95     return m_user->userId();
96 }
97
98 void FriendListItem::setUserData(User *user)
99 {
100     qDebug() << __PRETTY_FUNCTION__;
101
102     if(user) {
103         m_user = user;
104
105         setData(AVATAR_IMAGE_INDEX, m_user->profileImage());
106
107         QString unit;
108         double value;
109         m_user->distance(value, unit);
110         m_distanceText = QString::number(value) + " " + unit;
111         setData(DISTANCE_TEXT_DISPLAY_INDEX, m_distanceText);
112         setDistanceIcon(value, unit);
113
114         shortenTexts();
115         calculateTextRects();
116         setText(false);
117     }
118 }
119
120 void FriendListItem::setAvatarImage(const QPixmap &image)
121 {
122     qDebug() << __PRETTY_FUNCTION__;
123
124     if(!image.isNull())
125         setData(AVATAR_IMAGE_INDEX, m_user->profileImage());
126 }
127
128 void FriendListItem::setDistanceIcon(double value, const QString &unit)
129 {
130     qDebug() << __PRETTY_FUNCTION__;
131
132     QPixmap distanceImage;
133
134     if ((unit == "m") || (value < WALK_DISTANCE))
135         distanceImage.load(":/res/images/walk_icon_gray.png");
136     else if (value < CAR_DISTANCE)
137         distanceImage.load(":/res/images/car_icon_gray.png");
138     else if (value < AEROPLANE_DISTANCE)
139         distanceImage.load(":/res/images/aeroplane_icon_gray.png");
140     else
141         distanceImage.load(":/res/images/rocket_icon_gray.png");
142
143     setData(DISTANCE_IMAGE_INDEX, distanceImage);
144 }
145
146 void FriendListItem::shortenTexts()
147 {
148     qDebug() << __PRETTY_FUNCTION__;
149
150     //Dummy value to get painter font metrics.
151     QPixmap p = QPixmap(ICON_WIDTH, ICON_HEIGHT);
152     QPainter painter(&p);
153     painter.setFont(NOKIA_FONT_NORMAL);
154     QFontMetrics nameLabelMetrics = painter.fontMetrics();
155     painter.setFont(NOKIA_FONT_SMALL);
156     QFontMetrics otherLabelsMetrics = painter.fontMetrics();
157
158     QString name = m_user->name();
159     QString updated = m_user->timestamp();
160     QString statusText = m_user->note();
161     QString location = m_user->address();
162
163     int nameIndex = name.indexOf('\n');
164     int updatedIndex = updated.indexOf('\n');
165     int statusTextIndex = statusText.indexOf('\n');
166     int locationIndex = location.indexOf('\n');
167
168     if (nameIndex > 0) {
169         name.truncate(nameIndex);
170         name.append("...");
171     }
172     if (updatedIndex > 0) {
173         updated.truncate(updatedIndex);
174         updated.append("...");
175     }
176     if (statusTextIndex > 0) {
177         statusText.truncate(statusTextIndex);
178         statusText.append("...");
179     }
180     if (locationIndex > 0) {
181         location.truncate(locationIndex);
182         location.append("...");
183     }
184
185     int distanceLabelWidth = otherLabelsMetrics.width(m_distanceText) + MARGIN;
186     m_shortenedName = nameLabelMetrics.elidedText(name, Qt::ElideRight, NAME_LABEL_MAX_WIDTH
187                                                   - distanceLabelWidth);
188     m_shortenedStatusText = otherLabelsMetrics.elidedText(statusText, Qt::ElideRight,
189                                                           LABEL_MAX_WIDTH);
190     m_shortenedUpdated = otherLabelsMetrics.elidedText(updated, Qt::ElideRight, LABEL_MAX_WIDTH);
191     m_shortenedLocation = otherLabelsMetrics.elidedText(location, Qt::ElideRight, LABEL_MAX_WIDTH);
192
193     setData(NAME_DISPLAY_INDEX, m_shortenedName);
194 }
195
196 void FriendListItem::setText(bool expanded)
197 {
198     qDebug() << __PRETTY_FUNCTION__;
199
200     if (expanded) {
201         setData(STATUS_TEXT_DISPLAY_INDEX, m_user->note());
202         setData(LOCATION_DISPLAY_INDEX, m_user->address());
203         setData(UPDATED_DISPLAY_INDEX, m_user->timestamp());
204
205         setData(STATUS_TEXT_SIZE_HINT_INDEX, m_statusTextRect);
206         setData(LOCATION_SIZE_HINT_INDEX, m_locationRect);
207         setData(UPDATED_SIZE_HINT_INDEX, m_updatedRect);
208
209     }
210     else {
211         setData(STATUS_TEXT_DISPLAY_INDEX, m_shortenedStatusText);
212         setData(LOCATION_DISPLAY_INDEX, m_shortenedLocation);
213         setData(UPDATED_DISPLAY_INDEX, m_shortenedUpdated);
214
215         setData(STATUS_TEXT_SIZE_HINT_INDEX, QRect(0, 0, LABEL_MAX_WIDTH, ICON_HEIGHT));
216         setData(LOCATION_SIZE_HINT_INDEX, QRect(0, 0, LABEL_MAX_WIDTH, ICON_HEIGHT));
217         setData(UPDATED_SIZE_HINT_INDEX, QRect(0, 0, LABEL_MAX_WIDTH, ICON_HEIGHT));
218     }
219 }
220
221 bool FriendListItem::toggleSelection()
222 {
223     qDebug() << __PRETTY_FUNCTION__;
224
225     setSelected(!m_selected);
226     return m_selected;
227 }
228
229 void FriendListItem::setSelected(bool selected)
230 {
231     qDebug() << __PRETTY_FUNCTION__;
232
233     m_selected = selected;
234
235     if (m_selected) {
236         setText(true);
237         setData(ITEM_SIZE_HINT_INDEX, QSize(ITEM_WIDTH, m_expandedHeight));
238     }
239     else {
240         setText(false);
241         setData(ITEM_SIZE_HINT_INDEX, QSize(ITEM_WIDTH, ITEM_MIN_HEIGHT));
242     }
243 }