source: qutecom-2.2/wengophone/src/presentation/qt/profilebar/QtProfileBar.cpp @ 342:27d67e53e83c

Last change on this file since 342:27d67e53e83c was 342:27d67e53e83c, checked in by laurent@…, 4 years ago

saving profiles with non-ascii characters

File size: 16.5 KB
Line 
1/*
2 * WengoPhone, a voice over Internet phone
3 * Copyright (C) 2004-2007  Wengo
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19
20#include "QtProfileBar.h"
21
22#include "QtIMProfileWidget.h"
23#include "QtEventWidget.h"
24#include "QtCreditWidget.h"
25
26#include <presentation/qt/QtIMAccountHelper.h>
27#include <presentation/qt/QtIMAccountMonitor.h>
28#include <presentation/qt/QtPresenceMenuManager.h>
29#include <presentation/qt/QtPresencePixmapHelper.h>
30#include <presentation/qt/QtWengoPhone.h>
31#include <presentation/qt/profile/QtUserProfile.h>
32#include <presentation/qt/profile/QtProfileDetails.h>
33
34#include <control/CWengoPhone.h>
35#include <control/history/CHistory.h>
36#include <control/profile/CUserProfile.h>
37#include <control/profile/CUserProfileHandler.h>
38
39#include <model/account/wengo/WengoAccount.h>
40#include <model/connect/ConnectHandler.h>
41#include <model/profile/AvatarList.h>
42#include <model/profile/UserProfile.h>
43
44#include <imwrapper/IMAccount.h>
45
46#include <util/Logger.h>
47
48#include <qtutil/WengoStyleLabel.h>
49#include <qtutil/SafeConnect.h>
50
51#include <QtGui/QApplication>
52#include <QtGui/QGridLayout>
53#include <QtGui/QMenu>
54#include <QtGui/QPainter>
55#include <QtCore/QMetaType>
56
57static const char* STATUS_LABEL_OFF_TEMPLATE = ":/pics/profilebar/bar_start_status_%1.png";
58static const char* STATUS_LABEL_ON_TEMPLATE = ":/pics/profilebar/bar_on_start_status_%1.png";
59
60// These constants are used to find the position of the state "ball" in the
61// profilebar pixmap
62static const int STATUS_LABEL_CENTERX = 26;
63static const int STATUS_LABEL_CENTERY = 32;
64static const int STATUS_LABEL_RADIUS  = 10;
65
66// Defines position of the expand indicator in the picture. used in
67// createPixmapWithExpandIndicator
68static const int EXPAND_INDICATOR_OFFSET = 4;
69
70
71/**
72 * This helper functions blit an expand indicator (or contract if @expand is
73 * false) over the pixmap whose name is @name
74 */
75static QPixmap createPixmapWithExpandIndicator(const QString& name, bool expand) {
76        QPixmap bg(":/pics/profilebar/" + name);
77
78        QString indicatorName;
79        if (expand) {
80                indicatorName = "indicator_expand.png";
81        } else {
82                indicatorName = "indicator_contract.png";
83        }
84        QPixmap indicator(":/pics/profilebar/" + indicatorName);
85
86        QPainter painter(&bg);
87
88        int top = (bg.height() - indicator.height()) / 2;
89        painter.drawPixmap(EXPAND_INDICATOR_OFFSET, top, indicator);
90
91        return bg;
92}
93
94
95QtProfileBar::QtProfileBar(QWidget * parent)
96        : QFrame(parent),
97        _cUserProfile(0),
98        _cWengoPhone(0),
99        _qtImAccountMonitor(0) {
100
101        setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
102        QVBoxLayout* mainLayout = new QVBoxLayout(this);
103        mainLayout->setMargin(0);
104        mainLayout->setSpacing(0);
105
106        //The layout containing our three "labels" (status, nickname and credit)
107        QHBoxLayout* labelLayout = new QHBoxLayout();
108        labelLayout->setMargin(0);
109        labelLayout->setSpacing(0);
110
111        mainLayout->addLayout(labelLayout);
112
113        //The status widget
114        _statusLabel = new WengoStyleLabel(this);
115        _statusLabel->setToolTip(tr("Click here to change your status"));
116        _statusLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
117
118        //Nickname label
119        _nicknameLabel = new WengoStyleLabel(this, WengoStyleLabel::Normal);
120#ifdef DISABLE_VOICE_MAIL
121        _nicknameLabel->setPixmaps(
122                                        QPixmap(), //no start
123                                        createPixmapWithExpandIndicator("bar_end.png", true), //end
124                                        //createPixmapWithExpandIndicator("bar_separator.png", true), //end
125                                        QPixmap(":/pics/profilebar/bar_fill.png"), //fill
126                                        QPixmap(),  //no start
127                                        //createPixmapWithExpandIndicator("bar_on_separator_left.png", false), //end
128                                        createPixmapWithExpandIndicator("bar_end.png", false), //end
129                                        QPixmap(":/pics/profilebar/bar_on_fill.png") //fill
130                                        );
131#else   
132        _nicknameLabel->setPixmaps(
133                                        QPixmap(), //no start
134                                        createPixmapWithExpandIndicator("bar_separator.png", true), //end
135                                        QPixmap(":/pics/profilebar/bar_fill.png"), //fill
136                                        QPixmap(),  //no start
137                                        createPixmapWithExpandIndicator("bar_on_separator_left.png", false), //end
138                                        QPixmap(":/pics/profilebar/bar_on_fill.png") //fill
139                                        );
140#endif
141        _nicknameLabel->setTextColor(Qt::white);
142
143        //The credit label
144        _creditLabel = new WengoStyleLabel(this);
145        _creditLabel->setPixmaps(QPixmap(), //no start
146                                        createPixmapWithExpandIndicator("bar_end.png", true),
147                                        QPixmap(":/pics/profilebar/bar_fill.png"),
148                                        QPixmap(),  //no start
149                                        createPixmapWithExpandIndicator("bar_on_end.png", false),
150                                        QPixmap(":/pics/profilebar/bar_on_fill.png")
151                                        );
152        _creditLabel->setTextColor(Qt::white);
153
154        //Add the labels
155        labelLayout->addWidget(_statusLabel);
156        labelLayout->addWidget(_nicknameLabel);
157        labelLayout->addWidget(_creditLabel);
158
159        //create internal widgets
160        _qtImProfileWidget = new QtIMProfileWidget(this);
161        _qtImProfileWidget->getWidget()->setVisible(false);
162        _qtImProfileWidget->getWidget()->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
163        mainLayout->addWidget(_qtImProfileWidget->getWidget());
164
165        _creditWidget = new QtCreditWidget(this);
166        _creditWidget->getWidget()->setVisible(false);
167        _creditWidget->getWidget()->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
168        mainLayout->addWidget(_creditWidget->getWidget());
169
170        //init label tracking vars
171        _currentLabel = 0;
172        _labelWidget[_nicknameLabel] = _qtImProfileWidget->getWidget();
173        _labelWidget[_creditLabel] = _creditWidget->getWidget();
174        ////
175
176        //Objects connection
177        SAFE_CONNECT(_statusLabel, SIGNAL(clicked()), SLOT(statusClicked()));
178        SAFE_CONNECT(_nicknameLabel, SIGNAL(clicked()), SLOT(nicknameClicked()));
179        SAFE_CONNECT(_creditLabel, SIGNAL(clicked()), SLOT(creditClicked()));
180
181        qRegisterMetaType<IMAccount>("IMAccount");
182
183        SAFE_CONNECT_TYPE(this, SIGNAL(wsInfoWengosEvent(float)),
184                SLOT(wsInfoWengosEventSlot(float)), Qt::QueuedConnection);
185        SAFE_CONNECT_TYPE(this, SIGNAL(wsInfoVoiceMailEvent(int)),
186                SLOT(wsInfoVoiceMailEventSlot(int)), Qt::QueuedConnection);
187        SAFE_CONNECT_TYPE(this, SIGNAL(wsInfoLandlineNumberEvent(const QString &)),
188                SLOT(wsInfoLandlineNumberEventSlot(const QString &)), Qt::QueuedConnection);
189        SAFE_CONNECT_TYPE(this, SIGNAL(wsCallForwardInfoEvent(const QString &)),
190                SLOT(wsCallForwardInfoEventSlot(const QString &)), Qt::QueuedConnection);
191        SAFE_CONNECT_TYPE(this, SIGNAL(phoneLineCreatedEvent()),
192                SLOT(phoneLineCreatedEventSlot()), Qt::QueuedConnection);
193       
194#ifdef DISABLE_VOICE_MAIL
195        _creditLabel->hide();
196#endif
197
198        reset();
199}
200
201QtProfileBar::~QtProfileBar() {
202}
203
204void QtProfileBar::init(CWengoPhone* cWengoPhone, CUserProfile* cUserProfile, QtIMAccountMonitor* qtImAccountMonitor) {
205        _cWengoPhone = cWengoPhone;
206        _cUserProfile = cUserProfile;
207        _qtImAccountMonitor = qtImAccountMonitor;
208
209        // Init creditLabel
210        if (_cUserProfile->getUserProfile().hasWengoAccount()) {
211                _creditLabel->setText(QChar(0x20ac) + QString(" 0.00"));
212        } else {
213                _creditLabel->setText(tr("Voice mail"));
214        }
215
216        // Init widgets
217        _qtImProfileWidget->init(_cUserProfile, _qtImAccountMonitor);
218        _creditWidget->init(cWengoPhone, &_cUserProfile->getUserProfile());
219
220        // Connect _cUserProfile
221        _cUserProfile->getUserProfile().wsInfoCreatedEvent +=
222                boost::bind(&QtProfileBar::wsInfoCreatedEventHandler, this, _1, _2);
223
224        _cUserProfile->getUserProfile().phoneLineCreatedEvent +=
225                boost::bind(&QtProfileBar::phoneLineCreatedEventHandler, this, _1, _2);
226
227        // Connect qtImAccountMonitor
228        SAFE_CONNECT_TYPE(_qtImAccountMonitor, SIGNAL(imAccountAdded(QString)),
229                SLOT(updateStatusLabel()), Qt::QueuedConnection);
230        SAFE_CONNECT_TYPE(_qtImAccountMonitor, SIGNAL(imAccountRemoved(QString)),
231                SLOT(updateStatusLabel()), Qt::QueuedConnection);
232        SAFE_CONNECT_TYPE(_qtImAccountMonitor, SIGNAL(imAccountUpdated(QString)),
233                SLOT(updateStatusLabel()), Qt::QueuedConnection);
234
235        //Check if events already occured
236        //FIXME: must not use model class
237        if (_cUserProfile->getUserProfile().getActivePhoneLine()) {
238                phoneLineCreatedEventHandler(_cUserProfile->getUserProfile(), *_cUserProfile->getUserProfile().getActivePhoneLine());
239        }
240
241        if (_cUserProfile->getUserProfile().getWsInfo()) {
242                wsInfoCreatedEventHandler(_cUserProfile->getUserProfile(), *_cUserProfile->getUserProfile().getWsInfo());
243        }
244        ////
245
246        updateStatusLabel();
247        setEnabled(true);
248}
249
250void QtProfileBar::reset() {
251        setEnabled(false);
252        _cUserProfile = 0;
253        _qtImAccountMonitor = 0;
254
255        _statusLabel->setPixmaps(
256                                        QPixmap(":/pics/profilebar/bar_start_status_offline.png"),
257                                        QPixmap(),
258                                        QPixmap(),
259                                        QPixmap(":/pics/profilebar/bar_on_start_status_offline.png"),
260                                        QPixmap(),
261                                        QPixmap()
262                                        );
263
264        _nicknameLabel->setText("");
265        _creditLabel->setText("");
266
267        _qtImProfileWidget->reset();
268}
269
270void QtProfileBar::updateStatusLabel() {
271        if(_cUserProfile)
272        {
273        // Create pixmap
274                IMAccountList accountList = _cUserProfile->getUserProfile().getIMAccountManager().getIMAccountListCopy();
275                QtPresencePixmapHelper helper(accountList);
276                QPixmap off = helper.createPixmap(STATUS_LABEL_OFF_TEMPLATE, 
277                        STATUS_LABEL_CENTERX, 
278                        STATUS_LABEL_CENTERY,
279                        STATUS_LABEL_RADIUS);
280                QPixmap on = helper.createPixmap(STATUS_LABEL_ON_TEMPLATE,
281                        STATUS_LABEL_CENTERX, 
282                        STATUS_LABEL_CENTERY,
283                        STATUS_LABEL_RADIUS);
284
285                _statusLabel->setPixmaps(off,
286                                                QPixmap(), //no end
287                                                QPixmap(), //no fill
288                                                on,
289                                                QPixmap(),  //no end
290                                                QPixmap()
291                                                ); //no fill
292                _statusLabel->update();
293
294                // Sort account using the same order as in the status pixmap
295                QtIMAccountHelper::QtIMAccountPtrVector vector;
296                QtIMAccountHelper::copyListToPtrVector(accountList, &vector);
297                std::sort(vector.begin(), vector.end(), QtIMAccountHelper::compareIMAccountPtrs);
298                ////
299
300                // Create tooltip
301                QStringList tooltipLines;
302                QtIMAccountHelper::QtIMAccountPtrVector::const_iterator
303                        it = vector.begin(),
304                        end = vector.end();
305
306                QList<std::string> list;
307
308                for (;it!=end; ++it) 
309                {
310                        const IMAccount* imAccount = *it;
311                        if(!list.contains(imAccount->getUUID()))
312                        {
313                                QString login = QString::fromStdString(imAccount->getLogin());
314                                QString protocol = QString::fromStdString( EnumIMProtocol::toString(imAccount->getProtocol()) );
315                                QString id = QString::fromStdString(imAccount->getUUID());
316                                QtIMAccountMonitor::IMAccountInfoAutoPtr info = _qtImAccountMonitor->getIMAccountInfo(id);
317
318                                if(info.get())
319                                {
320                                        QString line = QString("<b>%1 (%2):</b> %3").arg(login).arg(protocol).arg(info->message());
321                                        tooltipLines.append(line);
322                                }
323                                list.append(imAccount->getUUID());
324                        }
325                }
326                _statusLabel->setToolTip(tooltipLines.join("<br>\n"));
327        }
328}
329
330void QtProfileBar::statusClicked() {
331
332        // no presence when user got a SIPAccount without presence and no IMAccount
333        if (_cUserProfile) {
334       
335                UserProfile & userProfile = _cUserProfile->getUserProfile();
336                SipAccount * sipAccount = userProfile.getSipAccount();
337               
338                if (userProfile.getIMAccountManager().getIMAccountListCopy().size() <= 1) {
339                        if (!sipAccount /*|| !sipAccount->isPIMEnabled()*/) {
340                                return;
341                        }
342                }
343        }
344        ////
345       
346        // by default we crete the menu
347        createStatusMenu();
348}
349
350void QtProfileBar::nicknameClicked() {
351        toggleLabel(_nicknameLabel);
352}
353
354void QtProfileBar::creditClicked() {
355        toggleLabel(_creditLabel);
356}
357
358void QtProfileBar::toggleLabel(WengoStyleLabel* label) {
359        setUpdatesEnabled(false);
360        Q_ASSERT(_cUserProfile);
361        Q_ASSERT(label);
362        if (_currentLabel) {
363                // Hide current
364                _currentLabel->setSelected(false);
365                _labelWidget[_currentLabel]->hide();
366        }
367
368        if (label == _currentLabel) {
369                // Clicked on current, no more _currentLabel
370                _currentLabel = 0;
371        } else {
372                // Clicked on another label, there is a new _currentLabel
373                label->setSelected(true);
374                Q_ASSERT(_labelWidget.contains(label));
375               
376                // Make sure all internal widgets are at the same height
377                // Only do so for wengo accounts because in the case of a SIP account,
378                // the credit widget is quite empty
379                if (_cUserProfile->getUserProfile().hasWengoAccount()) {
380                        int imProfileHeight = _qtImProfileWidget->getWidget()->minimumSizeHint().height();
381                        int creditHeight = _creditWidget->getWidget()->minimumSizeHint().height();
382                        int height = qMax(imProfileHeight, creditHeight);
383                        _qtImProfileWidget->getWidget()->setFixedHeight(height);
384                        _creditWidget->getWidget()->setFixedHeight(height);
385                }
386               
387                _labelWidget[label]->show();
388                _currentLabel = label;
389        }
390
391        setUpdatesEnabled(true);
392}
393
394void QtProfileBar::createStatusMenu() {
395        QMenu* menu = new QMenu(this);
396        QtPresenceMenuManager* manager = new QtPresenceMenuManager(menu, 
397                &_cWengoPhone->getCUserProfileHandler(),
398                dynamic_cast<QtWengoPhone*>(_cWengoPhone->getPresentation())
399        );
400
401        QAction* action = menu->addAction(tr("Set global presence to:"));
402        action->setEnabled(false);
403        manager->addPresenceActions(menu);
404
405        QPoint p = _statusLabel->pos();
406        p.setY(p.y() + _statusLabel->rect().bottom() - 18);
407        menu->popup(mapToGlobal(p));
408}
409
410void QtProfileBar::wsInfoCreatedEventHandler(UserProfile & sender, WsInfo & wsInfo) {
411        wsInfo.wsInfoWengosEvent += boost::bind(&QtProfileBar::wsInfoWengosEventHandler, this, _1, _2, _3, _4);
412        wsInfo.wsInfoVoiceMailEvent += boost::bind(&QtProfileBar::wsInfoVoiceMailEventHandler, this, _1, _2, _3, _4);
413        wsInfo.wsInfoLandlineNumberEvent += boost::bind(&QtProfileBar::wsInfoLandlineNumberEventHandler, this, _1, _2, _3, _4);
414        wsInfo.wsCallForwardInfoEvent += boost::bind(&QtProfileBar::wsCallForwardInfoEventHandler, this, _1, _2, _3, _4, _5, _6, _7, _8);
415
416        wsInfo.getWengosCount(true);
417        wsInfo.getUnreadVoiceMail(true);
418        wsInfo.getCallForwardInfo(true);
419        wsInfo.getLandlineNumber(true);
420        wsInfo.execute();
421}
422
423void QtProfileBar::wsInfoWengosEventHandler(WsInfo & sender, int id, WsInfo::WsInfoStatus status, float wengos) {
424        if (status == WsInfo::WsInfoStatusOk) {
425                wsInfoWengosEvent(wengos);
426        }
427}
428
429void QtProfileBar::wsInfoVoiceMailEventHandler(WsInfo & sender, int id, WsInfo::WsInfoStatus status, int voicemail) {
430        if (status == WsInfo::WsInfoStatusOk) {
431                wsInfoVoiceMailEvent(voicemail);
432        }
433}
434
435void QtProfileBar::wsInfoLandlineNumberEventHandler(WsInfo & sender, int id, WsInfo::WsInfoStatus status, std::string number) {
436        if (status == WsInfo::WsInfoStatusOk) {
437                wsInfoLandlineNumberEvent(QString::fromStdString(number));
438        }
439}
440
441void QtProfileBar::wsCallForwardInfoEventHandler(WsInfo & sender, int id, WsInfo::WsInfoStatus status,
442        WsInfo::WsInfoCallForwardMode mode, bool voicemail, std::string dest1, std::string dest2, std::string dest3) {
443
444        if (status == WsInfo::WsInfoStatusOk) {
445
446                switch(mode) {
447                case WsInfo::WsInfoCallForwardModeVoicemail:
448                        wsCallForwardInfoEvent(tr("active") + " (" + tr("voicemail") + ")");
449                        break;
450                case WsInfo::WsInfoCallForwardModeNumber:
451                        wsCallForwardInfoEvent(tr("active") + " (" + QString::fromStdString(dest1) + ")");
452                        break;
453                case WsInfo::WsInfoCallForwardModeDisabled:
454                        wsCallForwardInfoEvent(tr("inactive"));
455                        break;
456                case WsInfo::WsInfoCallForwardModeUnauthorized:
457                        wsCallForwardInfoEvent(tr("unauthorized"));
458                        break;
459                }
460        }
461}
462
463void QtProfileBar::phoneLineCreatedEventHandler(UserProfile & sender, IPhoneLine & phoneLine) {
464        phoneLineCreatedEvent();
465}
466
467void QtProfileBar::phoneLineCreatedEventSlot() {
468        if(_cUserProfile)
469        {
470                _nicknameLabel->setText("  " + QString::fromLocal8Bit(_cUserProfile->getUserProfile().getSipAccount()->getDisplayName().c_str()));
471        }
472}
473
474void QtProfileBar::paintEvent(QPaintEvent * event) {
475        if (_currentLabel) {
476                QRect r = rect();
477
478                QLinearGradient lg(QPointF(1, r.top()), QPointF(1, r.bottom()));
479
480                lg.setColorAt(0, palette().color(QPalette::Window));
481                QColor dest = palette().color(QPalette::Window);
482
483                float red = ((float) dest.red()) / 1.3f;
484                float blue = ((float) dest.blue()) / 1.3f;
485                float green = ((float) dest.green()) / 1.3f;
486
487                dest = QColor((int) red, (int) green, (int) blue);
488                lg.setColorAt(1, dest);
489
490                QPainter painter(this);
491                painter.fillRect(r, QBrush(lg));
492                painter.end();
493        } else {
494                QFrame::paintEvent(event);
495        }
496}
497
498void QtProfileBar::wsInfoWengosEventSlot(float wengos) {
499        //0x20ac is the unicode code for the euros currency symbol
500        _creditLabel->setText(QString() + QChar(0x20ac) + QString(" %1").arg(wengos));
501}
502
503void QtProfileBar::wsInfoVoiceMailEventSlot(int count) {
504        // FIXME: Show VoiceMail info somewhere
505}
506
507void QtProfileBar::wsInfoLandlineNumberEventSlot(const QString & number) {
508        // FIXME: Show landline number somewhere
509}
510
511void QtProfileBar::wsCallForwardInfoEventSlot(const QString & mode) {
512        _creditWidget->setCallForwardMode(mode);
513}
Note: See TracBrowser for help on using the repository browser.