Changed context buttons images
[situare] / src / ui / userinfo.cpp
1 /*
2    Situare - A location system for Facebook
3    Copyright (C) 2010  Ixonos Plc. Authors:
4
5        Jukka Saastamoinen - jukka.saastamoinen@ixonos.com
6        Jussi Laitinen - jussi.laitinen@ixonos.com
7        Katri Kaikkonen - katri.kaikkonen@ixonos.com
8        Henri Lampela - henri.lampela@ixonos.com
9        Ville Tiensuu - ville.tiensuu@ixonos.com
10
11    Situare is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License
13    version 2 as published by the Free Software Foundation.
14
15    Situare is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with Situare; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
23    USA.
24 */
25
26 #include <QFormLayout>
27 #include <QLabel>
28 #include <QPainter>
29 #include <QSettings>
30 #include <QVBoxLayout>
31
32 #include "common.h"
33 #include "imagebutton.h"
34 #include "user/user.h"
35
36 #include "userinfo.h"
37
38 const int BACKGROUND_WIDTH = 368;           ///< Width for item
39 const int BACKGROUND_TOP_HEIGHT = 20;       ///< Height for item top
40 const int BACKGROUND_BOTTOM_HEIGHT = 15;    ///< Height for item bottom
41 const int ICON_HEIGHT = 24;                 ///< Icon height
42 const int ICON_WIDTH = 24;                  ///< Icon width
43 const int MARGIN = 5;                       ///< Icon margin
44 const int LINE_LENGTH = 27;                 ///< Line length
45 const int MOUSE_PRESS_AREA_WIDTH = 20;      ///< Area width for item height toggling
46 const int MOUSE_PRESS_AREA_HEIGHT = 20;     ///< Area height for item height toggling
47
48 /**
49 * @var LABEL_MAX_WIDTH
50 *
51 * @brief All label's maximum width
52 */
53 const int LABEL_MAX_WIDTH = BACKGROUND_WIDTH - 3 * MARGIN - ICON_WIDTH + 130;
54
55 UserInfo::UserInfo(QWidget *parent)
56     : QWidget(parent),
57       m_expanded(false),
58       m_updateLocation(0)
59 {
60     qDebug() << __PRETTY_FUNCTION__;
61
62     QVBoxLayout *verticalLayout = new QVBoxLayout(this);
63     verticalLayout->setContentsMargins(MARGIN * 2, 0, MARGIN * 2, MARGIN * 2);
64     verticalLayout->setSpacing(0);
65     setLayout(verticalLayout);
66
67     QFormLayout *infoLayout = new QFormLayout();
68     infoLayout->setMargin(0);
69     infoLayout->setSpacing(0);
70
71     QLabel *envelopeLabel = new QLabel();
72     envelopeLabel->setPixmap(QPixmap(":/res/images/envelope.png"));
73     envelopeLabel->setContentsMargins(0, 0, MARGIN, 0);
74     envelopeLabel->setFixedSize(ICON_WIDTH + MARGIN, ICON_HEIGHT);
75     QLabel *compassLabel = new QLabel();
76     compassLabel->setPixmap(QPixmap(":/res/images/compass.png"));
77     compassLabel->setContentsMargins(0, 0, MARGIN, 0);
78     compassLabel->setFixedSize(ICON_WIDTH + MARGIN, ICON_HEIGHT);
79     QLabel *clockLabel = new QLabel();
80     clockLabel->setPixmap(QPixmap(":/res/images/clock.png"));
81     clockLabel->setContentsMargins(0, 0, MARGIN, 0);
82     clockLabel->setFixedSize(ICON_WIDTH + MARGIN, ICON_HEIGHT);
83
84     m_findButton = new ImageButton();
85
86     m_nameLabel = new QLabel();
87     m_nameLabel->setWordWrap(true);
88
89     m_statusTextLabel = new QLabel();
90     m_statusTextLabel->setWordWrap(true);
91     m_locationLabel = new QLabel();
92     m_locationLabel->setWordWrap(true);
93     m_updatedLabel = new QLabel();
94     m_updatedLabel->setWordWrap(true);
95
96     infoLayout->addRow(envelopeLabel, m_statusTextLabel);
97     infoLayout->addRow(compassLabel, m_locationLabel);
98     infoLayout->addRow(clockLabel, m_updatedLabel);
99
100     verticalLayout->addWidget(m_findButton, 0, Qt::AlignHCenter);
101     verticalLayout->addWidget(m_nameLabel, 0, Qt::AlignHCenter);
102     verticalLayout->addLayout(infoLayout);
103
104     connect(m_findButton, SIGNAL(clicked()),
105             this, SLOT(findButtonClicked()));
106
107     setFixedWidth(BACKGROUND_WIDTH);
108
109     this->setFont(NOKIA_FONT_SMALL);
110     m_nameLabel->setFont(NOKIA_FONT_NORMAL);
111     QPalette itemPalette = palette();
112     itemPalette.setColor(QPalette::Foreground, COLOR_GRAY);
113     setPalette(itemPalette);
114     QPalette namePalette = m_nameLabel->palette();
115     namePalette.setColor(QPalette::Foreground, Qt::white);
116     m_nameLabel->setPalette(namePalette);
117
118     m_backgroundTopImage.load(":/res/images/list_item_top.png");
119     m_backgroundMiddleImage.load(":/res/images/list_item_middle.png");
120     m_backgroundBottomImage.load(":/res/images/list_item_bottom.png");
121
122     restoreUnsendMessage();
123 }
124
125 UserInfo::~UserInfo()
126 {
127     qDebug() << __PRETTY_FUNCTION__;
128
129     QSettings settings(DIRECTORY_NAME, FILE_NAME);
130
131     if (!m_backupMessage.isEmpty()) {
132         settings.setValue(USER_UNSEND_MESSAGE, m_backupMessage.toAscii());
133         settings.setValue(USER_UNSEND_MESSAGE_PUBLISH, m_backupFacebookPublishPolicity);
134     } else {
135         settings.remove(USER_UNSEND_MESSAGE);
136         settings.remove(USER_UNSEND_MESSAGE_PUBLISH);
137     }
138 }
139
140 void UserInfo::setAddress(const QString &address)
141 {
142     qDebug() << __PRETTY_FUNCTION__;
143
144     m_locationLabel->setText(address);
145 }
146
147 void UserInfo::setCoordinates(const GeoCoordinate &coordinates)
148 {
149     qDebug() << __PRETTY_FUNCTION__;
150
151     m_coordinates = coordinates;
152 }
153
154 void UserInfo::setMessageText(const QString &text)
155 {
156     qDebug() << __PRETTY_FUNCTION__;
157
158     m_messageText = text;
159     m_expandedMessageText.clear();
160     QString temp = "";
161     for(int i=0;i < text.length();i++) {
162         if(fontMetrics().width(temp.append(text.at(i))) > 170) {
163             temp.append("\n");
164             if(temp.startsWith(QString(" ")))
165                 temp.remove(0, 1);
166
167             m_expandedMessageText.append(temp);
168             temp.clear();
169         }
170     }
171     m_expandedMessageText.append(temp);
172     setText(false);
173 }
174
175 void UserInfo::setProfileImage(const QPixmap &image)
176 {
177     qDebug() << __PRETTY_FUNCTION__;
178
179     if(!image.isNull())
180         m_findButton->setButtonIcon(image);
181 }
182
183 void UserInfo::setTime(const QString &time)
184 {
185     qDebug() << __PRETTY_FUNCTION__;
186
187     m_updatedLabel->setText(time);
188 }
189
190 void UserInfo::setUserName(const QString &name)
191 {
192     qDebug() << __PRETTY_FUNCTION__;
193
194     m_userName = name;
195     setText(false);
196 }
197
198 void UserInfo::setText(bool expanded)
199 {
200     qDebug() << __PRETTY_FUNCTION__;
201
202     if (expanded) {
203         m_statusTextLabel->setText(m_expandedMessageText);
204     }
205     else {
206         m_nameLabel->setText(shortenText(m_nameLabel, m_userName, LABEL_MAX_WIDTH));
207         m_statusTextLabel->setText(shortenText(m_statusTextLabel, m_messageText,
208                                                LABEL_MAX_WIDTH));
209     }
210 }
211
212 void UserInfo::backupUpdateLocationDialogData(const QString &status, bool publish)
213 {
214     qDebug() << __PRETTY_FUNCTION__;
215
216     m_backupMessage = status;
217     m_backupFacebookPublishPolicity = publish;
218 }
219
220 void UserInfo::clearUpdateLocationDialogData()
221 {
222     qDebug() << __PRETTY_FUNCTION__;
223
224     m_backupMessage.clear();
225     m_backupFacebookPublishPolicity = false;
226 }
227
228 void UserInfo::findButtonClicked()
229 {
230     qDebug() << __PRETTY_FUNCTION__;
231
232     emit findUser(m_coordinates);
233 }
234
235 void UserInfo::mouseReleaseEvent(QMouseEvent *event)
236 {
237     qDebug() << __PRETTY_FUNCTION__ << " " << event->pos();
238
239     if ((abs(m_mousePosition.y() - event->pos().y()) <= MOUSE_PRESS_AREA_WIDTH) &&
240         (abs(m_mousePosition.x() - event->pos().x()) <= MOUSE_PRESS_AREA_HEIGHT)) {
241         if (m_expanded) {
242             setText(false);
243             m_expanded = false;
244         }
245         else {
246             setText(true);
247             m_expanded = true;
248         }
249     }
250 }
251
252 void UserInfo::mousePressEvent(QMouseEvent *event)
253 {
254     qDebug() << __PRETTY_FUNCTION__ << " " << event->pos();
255
256     m_mousePosition = event->pos();
257 }
258
259 void UserInfo::messageUpdate()
260 {
261     qDebug() << __PRETTY_FUNCTION__;
262
263     delete m_updateLocation;
264     m_updateLocation = new UpdateLocationDialog(m_backupMessage, m_backupFacebookPublishPolicity,
265                                                 this);
266
267     connect(this, SIGNAL(reverseGeoReady(QString)),
268             m_updateLocation, SLOT(setAddress(QString)));
269
270     connect(m_updateLocation, SIGNAL(statusUpdate(QString,bool)),
271             this, SIGNAL(statusUpdate(QString,bool)));
272
273     connect(m_updateLocation, SIGNAL(statusUpdate(QString,bool)),
274             this, SLOT(backupUpdateLocationDialogData(QString,bool)));
275
276     connect(m_updateLocation, SIGNAL(finished(int)),
277             this, SLOT(updateLocationDialogFinished(int)));
278
279     m_updateLocation->show();
280
281     emit requestReverseGeo();
282 }
283
284 void UserInfo::paintEvent(QPaintEvent *aPaintEvent)
285 {
286     qDebug() << __PRETTY_FUNCTION__ << " " << aPaintEvent->rect();
287
288     QPainter painter(this);
289
290     QRect topRect = QRect(0, MARGIN, BACKGROUND_WIDTH, BACKGROUND_TOP_HEIGHT);
291 ///< @todo Overlaps with topRect?
292     QRect middleRect = QRect(0, topRect.bottom(), BACKGROUND_WIDTH,
293                              this->height() - BACKGROUND_TOP_HEIGHT - BACKGROUND_BOTTOM_HEIGHT);
294 ///< @todo Overlaps with middleRect
295     QRect bottomRect = QRect(topRect.left(), middleRect.bottom(), BACKGROUND_WIDTH,
296                              BACKGROUND_BOTTOM_HEIGHT);
297
298     painter.drawPixmap(topRect, m_backgroundTopImage);
299     painter.drawPixmap(middleRect, m_backgroundMiddleImage);
300     painter.drawPixmap(bottomRect, m_backgroundBottomImage);
301 }
302
303 void UserInfo::restoreUnsendMessage()
304 {
305     qDebug() << __PRETTY_FUNCTION__;
306
307     QSettings settings(DIRECTORY_NAME, FILE_NAME);
308     m_backupMessage = settings.value(USER_UNSEND_MESSAGE, EMPTY).toString();
309     m_backupFacebookPublishPolicity =
310             settings.value(USER_UNSEND_MESSAGE_PUBLISH, false).toBool();
311 }
312
313 QString UserInfo::shortenText(const QLabel *label, const QString &text, int textMaxWidth)
314 {
315     qDebug() << __PRETTY_FUNCTION__;
316
317     QFontMetrics labelMetrics = label->fontMetrics();
318     QString textParam = text;
319     int index = textParam.indexOf('\n');
320     int textWidth = fontMetrics().width(textParam);
321
322         if (index > 0) {
323             textParam.truncate(index);
324             textParam.append("...");
325         }
326             if (textWidth > 250) ///< @todo magic number
327                 textParam.insert(LINE_LENGTH, QString("\n"));
328
329    return labelMetrics.elidedText(textParam, Qt::ElideRight, textMaxWidth);
330 }
331
332 void UserInfo::updateLocationDialogFinished(int reason)
333 {
334     qDebug() << __PRETTY_FUNCTION__;
335
336     Q_UNUSED(reason);
337
338     if (m_updateLocation) {
339         disconnect(this, SIGNAL(reverseGeoReady(QString)),
340                 m_updateLocation, SLOT(setAddress(QString)));
341
342         disconnect(m_updateLocation, SIGNAL(statusUpdate(QString,bool)),
343                 this, SIGNAL(statusUpdate(QString,bool)));
344
345         disconnect(m_updateLocation, SIGNAL(statusUpdate(QString,bool)),
346                 this, SLOT(backupUpdateLocationDialogData(QString,bool)));
347
348         disconnect(m_updateLocation, SIGNAL(finished(int)),
349                 this, SLOT(updateLocationDialogFinished(int)));
350
351         m_updateLocation->deleteLater();
352         m_updateLocation = 0;
353     }
354 }