Fixed bugs in FriendListItem::mouseReleaseEvent.
[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
37 const QString BACKGROUND_PATH = ":/res/images/list_item.png";   ///< Background image path
38 const QString BACKGROUND_TOP_PATH = ":/res/images/list_item_top.png";   ///< Background image path
39 const QString BACKGROUND_MIDDLE_PATH = ":/res/images/list_item_middle.png";   ///< Background image path
40 const QString BACKGROUND_BOTTOM_PATH = ":/res/images/list_item_bottom.png";   ///< Background image path
41 const QString CLOCK_PATH = ":/res/images/clock.png";        ///< Clock image path
42 const QString COMPASS_PATH = ":/res/images/compass.png";    ///< Compass image path
43 const QString ENVELOPE_PATH = ":/res/images/envelope.png";  ///< Envelope image path
44
45 const int ICON_MARGIN = 5;   ///< Icon margin
46 const int IMAGE_HEIGHT = 60; ///< Friend image height
47 const int IMAGE_WIDTH = 60;  ///< Friend image width
48
49 const int ITEM_MAX_HEIGHT = 240; ///< Maximum height for item
50 const int ITEM_MAX_WIDTH = 368;  ///< Maximum width for item
51 const int ITEM_MIN_HEIGHT = 141; ///< Minimum height for item
52 const int ITEM_MIN_WIDTH = 368;  ///< Minimum width for item
53 const int LABEL_MAX_WIDTH = 247;   ///< Label maximum width
54
55 const int MOUSE_PRESS_AREA_WIDTH = 20;  ///< Area width for item height toggling
56 const int MOUSE_PRESS_AREA_HEIGHT = 20; ///< Area height for item height toggling
57
58 const QFont NOKIA_FONT_NORMAL = QFont( "Nokia Sans", 18, QFont::Normal);    ///< Normal font
59 const QFont NOKIA_FONT_SMALL = QFont( "Nokia Sans", 13, QFont::Normal);     ///< Small font
60
61 const QString STYLESHEET = "QWidget#listItem { border-image: url(:/res/images/list_item.png) 20%; " \
62                            "border-width: 20px 14px 16px 14px; } " \
63                            "QLabel { color: #989898; }" \
64                            "#nameLabel { color: #ffffff }";
65
66 FriendListItem::FriendListItem(QWidget *parent)
67     : QWidget(parent)
68     , m_expanded(false)
69     , m_user(0)
70 {
71     qDebug() << __PRETTY_FUNCTION__;
72
73     QVBoxLayout *layout = new QVBoxLayout(this);
74     this->setLayout(layout);
75
76     QHBoxLayout *topLayout = new QHBoxLayout();
77     topLayout->setMargin(0);
78     topLayout->setSpacing(0);
79
80     QHBoxLayout *bottomLayout = new QHBoxLayout();
81     bottomLayout->setMargin(0);
82     bottomLayout->setSpacing(0);
83
84     QFormLayout *infoLayout = new QFormLayout();
85     infoLayout->setMargin(0);
86     infoLayout->setSpacing(0);
87
88     QLabel *clockLabel = new QLabel();
89     clockLabel->setPixmap(QPixmap(CLOCK_PATH));
90     clockLabel->setContentsMargins(0, 0, ICON_MARGIN, 0);
91     QLabel *envelopeLabel = new QLabel();
92     envelopeLabel->setPixmap(QPixmap(ENVELOPE_PATH));
93     envelopeLabel->setContentsMargins(0, 0, ICON_MARGIN, 0);
94     QLabel *compassLabel = new QLabel();
95     compassLabel->setPixmap(QPixmap(COMPASS_PATH));
96     compassLabel->setContentsMargins(0, 0, ICON_MARGIN, 0);
97
98     m_imageLabel = new QLabel();
99     m_imageLabel->setFixedSize(IMAGE_WIDTH, IMAGE_HEIGHT);
100
101     m_nameLabel = new QLabel();
102     m_nameLabel->setFixedHeight(IMAGE_HEIGHT);
103     m_nameLabel->setFont(NOKIA_FONT_NORMAL);
104
105     m_updatedLabel = new QLabel();
106     m_updatedLabel->setWordWrap(true);
107     m_statusTextLabel = new QLabel();
108     m_statusTextLabel->setWordWrap(true);
109     m_locationLabel = new QLabel();
110     m_locationLabel->setWordWrap(true);
111
112     infoLayout->addRow(clockLabel, m_updatedLabel);
113     infoLayout->addRow(envelopeLabel, m_statusTextLabel);
114     infoLayout->addRow(compassLabel, m_locationLabel);
115
116     topLayout->addWidget(m_imageLabel);
117     topLayout->addWidget(m_nameLabel);
118
119     bottomLayout->addSpacing(IMAGE_WIDTH);
120     bottomLayout->addLayout(infoLayout, 1);
121
122     layout->addLayout(topLayout, 0);
123     layout->addLayout(bottomLayout, 1);
124
125     setObjectName("listItem");
126     m_nameLabel->setObjectName("nameLabel");
127
128     setFont(NOKIA_FONT_SMALL);
129
130     setStyleSheet(STYLESHEET);
131
132     setMinimumSize(ITEM_MIN_WIDTH, ITEM_MIN_HEIGHT);
133     setMaximumSize(ITEM_MIN_WIDTH, ITEM_MAX_HEIGHT);
134 }
135
136 void FriendListItem::setData(User *user)
137 {
138     qDebug() << __PRETTY_FUNCTION__;
139
140     if (user) {
141         m_user = user;
142         shortenTexts();
143
144         m_imageLabel->setPixmap(m_user->profileImage());
145         setText(false);
146     }
147 }
148
149 void FriendListItem::shortenTexts()
150 {
151     qDebug() << __PRETTY_FUNCTION__;
152
153     QFontMetrics nameLabelMetrics = m_nameLabel->fontMetrics();
154     QFontMetrics otherLabelsMetrics = m_updatedLabel->fontMetrics();
155
156     QString name = m_user->name();
157     QString updated = m_user->timestamp();
158     QString statusText = m_user->note();
159     QString location = m_user->address();
160
161     int nameIndex = name.indexOf('\n');
162     int updatedIndex = updated.indexOf('\n');
163     int statusTextIndex = statusText.indexOf('\n');
164     int locationIndex = location.indexOf('\n');
165
166     if (nameIndex > 0) {
167         name.truncate(nameIndex);
168         name.append("...");
169     }
170     if (updatedIndex > 0) {
171         updated.truncate(updatedIndex);
172         updated.append("...");
173     }
174     if (statusTextIndex > 0) {
175         statusText.truncate(statusTextIndex);
176         statusText.append("...");
177     }
178     if (locationIndex > 0) {
179         location.truncate(locationIndex);
180         location.append("...");
181     }
182
183
184     m_shortenedName = nameLabelMetrics.elidedText(name, Qt::ElideRight, LABEL_MAX_WIDTH + 30);
185     m_shortenedUpdated = otherLabelsMetrics.elidedText(updated, Qt::ElideRight, LABEL_MAX_WIDTH);
186     m_shortenedStatusText = otherLabelsMetrics.elidedText(statusText, Qt::ElideRight,
187                                                           LABEL_MAX_WIDTH);
188     m_shortenedLocation = otherLabelsMetrics.elidedText(location, Qt::ElideRight, LABEL_MAX_WIDTH);
189 }
190
191 void FriendListItem::setText(bool expanded)
192 {
193     qDebug() << __PRETTY_FUNCTION__;
194
195     if (expanded) {
196         m_nameLabel->setText(m_shortenedName);
197         m_updatedLabel->setText(m_user->timestamp());
198         m_statusTextLabel->setText(m_user->note());
199         m_locationLabel->setText(m_user->address());
200     }
201     else {
202         m_nameLabel->setText(m_shortenedName);
203         m_updatedLabel->setText(m_shortenedUpdated);
204         m_statusTextLabel->setText(m_shortenedStatusText);
205         m_locationLabel->setText(m_shortenedLocation);
206     }
207 }
208
209 void FriendListItem::mousePressEvent(QMouseEvent *event)
210 {
211     qDebug() << __PRETTY_FUNCTION__ << " " << event->pos();
212
213     m_mousePosition = event->pos();
214 }
215
216 void FriendListItem::mouseReleaseEvent(QMouseEvent *event)
217 {
218     qDebug() << __PRETTY_FUNCTION__ << " " << event->pos();
219
220     if ((abs(m_mousePosition.y() - event->pos().y()) <= MOUSE_PRESS_AREA_WIDTH) &&
221         (abs(m_mousePosition.x() - event->pos().x()) <= MOUSE_PRESS_AREA_HEIGHT)) {
222         if (m_expanded) {
223             setText(false);
224             m_expanded = false;
225         }
226         else {
227             setText(true);
228             m_expanded = true;
229         }
230     }
231 }
232
233 void FriendListItem::paintEvent(QPaintEvent *event)
234 {
235 //    qDebug() << __PRETTY_FUNCTION__ << " " << event->rect();
236
237     QStyleOption option;
238     option.init(this);
239
240     QStylePainter painter(this);
241     style()->drawPrimitive(QStyle::PE_Widget, &option, &painter, this);
242 }